/******/ (function(modules) { // webpackBootstrap
/******/ 	// install a JSONP callback for chunk loading
/******/ 	var parentJsonpFunction = window["webpackJsonp"];
/******/ 	window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) {
/******/ 		// add "moreModules" to the modules object,
/******/ 		// then flag all "chunkIds" as loaded and fire callback
/******/ 		var moduleId, chunkId, i = 0, callbacks = [];
/******/ 		for(;i < chunkIds.length; i++) {
/******/ 			chunkId = chunkIds[i];
/******/ 			if(installedChunks[chunkId])
/******/ 				callbacks.push.apply(callbacks, installedChunks[chunkId]);
/******/ 			installedChunks[chunkId] = 0;
/******/ 		}
/******/ 		for(moduleId in moreModules) {
/******/ 			modules[moduleId] = moreModules[moduleId];
/******/ 		}
/******/ 		if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);
/******/ 		while(callbacks.length)
/******/ 			callbacks.shift().call(null, __webpack_require__);
/******/
/******/ 	};
/******/
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// object to store loaded and loading chunks
/******/ 	// "0" means "already loaded"
/******/ 	// Array means "loading", array contains callbacks
/******/ 	var installedChunks = {
/******/ 		0:0
/******/ 	};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;
/******/
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/ 	// This file contains only the entry chunk.
/******/ 	// The chunk loading function for additional chunks
/******/ 	__webpack_require__.e = function requireEnsure(chunkId, callback) {
/******/ 		// "0" is the signal for "already loaded"
/******/ 		if(installedChunks[chunkId] === 0)
/******/ 			return callback.call(null, __webpack_require__);
/******/
/******/ 		// an array means "currently loading".
/******/ 		if(installedChunks[chunkId] !== undefined) {
/******/ 			installedChunks[chunkId].push(callback);
/******/ 		} else {
/******/ 			// start chunk loading
/******/ 			installedChunks[chunkId] = [callback];
/******/ 			var head = document.getElementsByTagName('head')[0];
/******/ 			var script = document.createElement('script');
/******/ 			script.type = 'text/javascript';
/******/ 			script.charset = 'utf-8';
/******/ 			script.async = true;
/******/
/******/ 			script.src = __webpack_require__.p + "" + chunkId + ".bundle.js";
/******/ 			head.appendChild(script);
/******/ 		}
/******/ 	};
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "lab/";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var phosphide = __webpack_require__(1);
	
	// ES6 Promise polyfill
	__webpack_require__(66).polyfill();
	
	__webpack_require__(70);
	__webpack_require__(78);
	
	var app = new phosphide.Application({
	  extensions: [
	    __webpack_require__(100).aboutExtension,
	    __webpack_require__(101).consoleExtension,
	    __webpack_require__(283).editorHandlerExtension,
	    __webpack_require__(284).fileBrowserExtension,
	    __webpack_require__(400).helpHandlerExtension,
	    __webpack_require__(402).imageHandlerExtension,
	    __webpack_require__(403).landingExtension,
	    __webpack_require__(404).mainExtension,
	    __webpack_require__(405).notebookHandlerExtension,
	    __webpack_require__(418).shortcutsExtension,
	    __webpack_require__(419).terminalExtension,
	    __webpack_require__(422).widgetManagerExtension,
	    __webpack_require__(470).commandPaletteExtension,
	  ],
	  providers: [
	    __webpack_require__(471).clipboardProvider,
	    __webpack_require__(472).docRegistryProvider,
	    __webpack_require__(405).activeNotebookProvider,
	    __webpack_require__(473).renderMimeProvider,
	    __webpack_require__(282).servicesProvider,
	  ]
	});
	
	window.onload = function() {
	    app.run();
	}


/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var applicationshell_1 = __webpack_require__(2);
	var extensionregistry_1 = __webpack_require__(50);
	var serviceregistry_1 = __webpack_require__(51);
	var commandregistry_1 = __webpack_require__(52);
	var paletteregistry_1 = __webpack_require__(53);
	var shortcutregistry_1 = __webpack_require__(61);
	/**
	 * A class which provides the main Phosphide application logic.
	 *
	 * A phosphide application manages the registration of services and
	 * extensions, and provides the top-level application shell widget.
	 */
	var Application = (function () {
	    /**
	     * Construct a new application.
	     *
	     * @param options - The options for initializing the application.
	     */
	    function Application(options) {
	        this._started = false;
	        this._promise = null;
	        this._shell = null;
	        this._commands = null;
	        this._palette = null;
	        this._shortcuts = null;
	        this._services = new serviceregistry_1.ServiceRegistry();
	        this._extensions = new extensionregistry_1.ExtensionRegistry();
	        if (options)
	            Private.initFrom(this, options);
	    }
	    Object.defineProperty(Application.prototype, "shell", {
	        /**
	         * Get the application shell widget.
	         *
	         * #### Notes
	         * The shell widget is not a service, and can only be accessed as a
	         * property of the application. Since the application object is not
	         * passed to service providers, services do not have access to the
	         * shell. This is by design. The intent is to encourage authors to
	         * maintain a distinct separation between generic services and the
	         * application extensions which manipulates the UI.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._shell;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Application.prototype, "commands", {
	        /**
	         * Get the application command registry.
	         *
	         * #### Notes
	         * The command registry is a service, and is provided as a property
	         * for the convenience of application extension authors. A service
	         * provider may require the command registry as needed.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._commands;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Application.prototype, "palette", {
	        /**
	         * Get the application palette registry.
	         *
	         * #### Notes
	         * The palette registry is a service, and is provided as a property
	         * for the convenience of application extension authors. A service
	         * provider may require the palette registry as needed.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._palette;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Application.prototype, "shortcuts", {
	        /**
	         * Get the application shortcut registry.
	         *
	         * #### Notes
	         * The shortcut registry is a service, and is provided as a property
	         * for the convenience of application extension authors. A service
	         * provider may require the shortcut registry as needed.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._shortcuts;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Register a service provider with the application.
	     *
	     * @param provider - The service provider to register.
	     *
	     * #### Notes
	     * An error will be thrown if a provider with the same id is already
	     * registered, if a provider which provides the identical service is
	     * already registered, or if the provider has a circular dependency.
	     */
	    Application.prototype.registerProvider = function (provider) {
	        this._services.registerProvider(provider);
	    };
	    /**
	     * List the IDs of all service providers in the application.
	     *
	     * @returns A new array of all provider IDs in the application.
	     */
	    Application.prototype.listProviders = function () {
	        return this._services.listProviders();
	    };
	    /**
	     * Test whether the application has a registered service provider.
	     *
	     * @param id - The id of the provider of interest.
	     *
	     * @returns `true` if a service provider with the specified id is
	     *   registered, `false` otherwise.
	     */
	    Application.prototype.hasProvider = function (id) {
	        return this._services.hasProvider(id);
	    };
	    /**
	     * Test whether the application has a provider for a service type.
	     *
	     * @param kind - The type of the service of interest.
	     *
	     * @returns `true` if a service provider is registered for the
	     *   given service type, `false` otherwise.
	     */
	    Application.prototype.hasProviderFor = function (kind) {
	        return this._services.hasProviderFor(kind);
	    };
	    /**
	     * Resolve a service implementation for the given type.
	     *
	     * @param kind - The type of service object to resolve.
	     *
	     * @returns A promise which resolves the specified service type,
	     *   or rejects with an error if it cannot be satisfied.
	     *
	     * #### Notes
	     * Services are singletons. The same service instance will be
	     * returned each time a given service type is resolved.
	     *
	     * User code will not normally call this method directly. Instead
	     * the required services for the user's providers and extensions
	     * will be resolved automatically as needed.
	     */
	    Application.prototype.resolveService = function (kind) {
	        return this._services.resolveService(kind);
	    };
	    /**
	     * Register an extension with the application.
	     *
	     * @param extension - The application extension to register.
	     *
	     * #### Notes
	     * An error will be thrown if the extension id is already registered.
	     */
	    Application.prototype.registerExtension = function (extension) {
	        this._extensions.registerExtension(extension);
	    };
	    /**
	     * List the IDs of all extensions in the application.
	     *
	     * @returns A new array of all extension IDs in the application.
	     */
	    Application.prototype.listExtensions = function () {
	        return this._extensions.listExtensions();
	    };
	    /**
	     * Test whether the application has a registered extension.
	     *
	     * @param id - The id of the extension of interest.
	     *
	     * @returns `true` if an application extension with the specified
	     *   id is registered, `false` otherwise.
	     */
	    Application.prototype.hasExtension = function (id) {
	        return this._extensions.hasExtension(id);
	    };
	    /**
	     * Activate the application extension with the given id.
	     *
	     * @param id - The ID of the extension of interest.
	     *
	     * @returns A promise which resolves when the extension is fully
	     *   activated or rejects with an error if it cannot be activated.
	     */
	    Application.prototype.activateExtension = function (id) {
	        return this._extensions.activateExtension(id, this, this._services);
	    };
	    /**
	     * Run the bootstrapping process for the application.
	     *
	     * @param options - The options for bootstrapping the application.
	     *
	     * @returns A promise which resolves when all bootstrapping work
	     *   is complete and the shell is mounted to the DOM, or rejects
	     *   with an error if the bootstrapping process fails.
	     *
	     * #### Notes
	     * This should be called once by the application creator after all
	     * initial providers and extensions have been registered.
	     *
	     * Bootstrapping the application consists of the following steps:
	     * 1. Create the application shell
	     * 2. Register the default providers
	     * 3. Register the default extensions
	     * 4. Resolve the application services
	     * 5. Activate the initial extensions
	     * 6. Attach the shell widget to the DOM
	     * 7. Add the application event listeners
	     */
	    Application.prototype.run = function (options) {
	        var _this = this;
	        if (options === void 0) { options = {}; }
	        // Resolve immediately if the application is already started.
	        if (this._started) {
	            return Promise.resolve();
	        }
	        // Return the pending bootstrapping promise if it exists.
	        if (this._promise) {
	            return this._promise;
	        }
	        // Create the application shell.
	        this._shell = this.createApplicationShell();
	        // Register the default providers.
	        this.registerDefaultProviders();
	        // Register the default extensions.
	        this.registerDefaultExtensions();
	        // Resolve the application services.
	        var promises = [
	            this.resolveService(commandregistry_1.ABCCommandRegistry),
	            this.resolveService(paletteregistry_1.ABCPaletteRegistry),
	            this.resolveService(shortcutregistry_1.ABCShortcutRegistry)
	        ];
	        // Setup the promise for the rest of the bootstrapping.
	        this._promise = Promise.all(promises).then(function (results) {
	            // Store the resolved default services.
	            _this._commands = results[0];
	            _this._palette = results[1];
	            _this._shortcuts = results[2];
	            // Compute the extension ids to activate.
	            var extIDs;
	            var optVal = options.activateExtensions;
	            if (optVal === true) {
	                extIDs = _this.listExtensions();
	            }
	            else if (optVal === false) {
	                extIDs = [];
	            }
	            else if (optVal) {
	                extIDs = optVal;
	            }
	            else {
	                extIDs = _this.listExtensions();
	            }
	            // Activate the initial extensions.
	            return Promise.all(extIDs.map(function (id) { return _this.activateExtension(id); }));
	        }).then(function () {
	            // Mark the application as started and clear the stored promise.
	            _this._promise = null;
	            _this._started = true;
	            // Compute the id of the shell host node.
	            var shellHostID = options.shellHostID || '';
	            // Attach the application shell to the host node.
	            _this.attachApplicationShell(shellHostID);
	            // Add the application event listeners.
	            _this.addEventsListeners();
	        }).catch(function (error) {
	            // Clear the stored promise.
	            _this._promise = null;
	            // Rethrow the error to reject the promise.
	            throw error;
	        });
	        // Return the pending bootstrapping promise.
	        return this._promise;
	    };
	    /**
	     * Handle the DOM events for the application.
	     *
	     * @param event - The DOM event sent to the application.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events registered for the application. It
	     * should not be called directly by user code.
	     */
	    Application.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'resize':
	                this.evtResize(event);
	                break;
	            case 'keydown':
	                this.evtKeydown(event);
	                break;
	        }
	    };
	    /**
	     * Create the shell widget for the application.
	     *
	     * @returns An instance of an application shell.
	     *
	     * #### Notes
	     * A subclass may reimplement this this method for a custom shell.
	     */
	    Application.prototype.createApplicationShell = function () {
	        return new applicationshell_1.ApplicationShell();
	    };
	    /**
	     * Register the default service providers for the application.
	     *
	     * #### Notes
	     * The default implementation of this method registers default
	     * providers for the `ABCCommandRegistry`, `ABCPaletteRegistry`,
	     * and `ABCShortcutRegistry` services, unless providers for these
	     * services have already been registered.
	     *
	     * A subclass may reimplement this this method to register custom
	     * default providers, but it should ensure that providers for the
	     * default services are also registered.
	     */
	    Application.prototype.registerDefaultProviders = function () {
	        if (!this.hasProviderFor(commandregistry_1.ABCCommandRegistry)) {
	            this.registerProvider(commandregistry_1.commandRegistryProvider);
	        }
	        if (!this.hasProviderFor(shortcutregistry_1.ABCShortcutRegistry)) {
	            this.registerProvider(shortcutregistry_1.shortcutRegistryProvider);
	        }
	        if (!this.hasProviderFor(paletteregistry_1.ABCPaletteRegistry)) {
	            this.registerProvider(paletteregistry_1.paletteRegistryProvider);
	        }
	    };
	    /**
	     * Register the default extensions for the application.
	     *
	     * #### Notes
	     * The default implementation of this method is a no-op.
	     *
	     * A subclass may reimplement this method as needed.
	     */
	    Application.prototype.registerDefaultExtensions = function () { };
	    /**
	     * Attach the application shell to the DOM.
	     *
	     * @param id - The id of the host node for shell, or `''`.
	     *
	     * #### Notes
	     * If the id is not provided, the document body will be the host.
	     *
	     * A subclass may reimplement this method for custom attachment.
	     */
	    Application.prototype.attachApplicationShell = function (id) {
	        this._shell.attach(id ? document.getElementById(id) : document.body);
	    };
	    /**
	     * Add the application event listeners.
	     *
	     * #### Notes
	     * The default implementation of this method listens for `'resize'`
	     * and `'keydown'` events.
	     *
	     * A subclass may reimplement this method as needed.
	     */
	    Application.prototype.addEventsListeners = function () {
	        document.addEventListener('keydown', this);
	        window.addEventListener('resize', this);
	    };
	    /**
	     * A method invoked on a document `'resize'` event.
	     *
	     * #### Notes
	     * The default implementation of this method updates the shell.
	     *
	     * A subclass may reimplement this method as needed.
	     */
	    Application.prototype.evtResize = function (event) {
	        this._shell.update();
	    };
	    /**
	     * A method invoked on a document `'keydown'` event.
	     *
	     * #### Notes
	     * The default implementation of this method invokes the key-down
	     * processing method of the shortcut manager.
	     *
	     * A subclass may reimplement this method as needed.
	     */
	    Application.prototype.evtKeydown = function (event) {
	        this._shortcuts.processKeydownEvent(event);
	    };
	    return Application;
	}());
	exports.Application = Application;
	/**
	 * The namespace for the application private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Initialize an application with the given options object.
	     */
	    function initFrom(app, options) {
	        var providers = options.providers || [];
	        var extensions = options.extensions || [];
	        providers.forEach(function (p) { app.registerProvider(p); });
	        extensions.forEach(function (e) { app.registerExtension(e); });
	    }
	    Private.initFrom = initFrom;
	})(Private || (Private = {}));


/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var arrays = __webpack_require__(3);
	var phosphor_boxpanel_1 = __webpack_require__(4);
	var phosphor_dockpanel_1 = __webpack_require__(30);
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_splitpanel_1 = __webpack_require__(32);
	var phosphor_stackedpanel_1 = __webpack_require__(37);
	var phosphor_widget_1 = __webpack_require__(20);
	var sidebar_1 = __webpack_require__(47);
	/**
	 * The class name added to AppShell instances.
	 */
	var APPLICATION_SHELL_CLASS = 'p-ApplicationShell';
	/**
	 *
	 */
	var ApplicationShell = (function (_super) {
	    __extends(ApplicationShell, _super);
	    /**
	     * Construct a new application shell.
	     */
	    function ApplicationShell() {
	        _super.call(this);
	        this.addClass(APPLICATION_SHELL_CLASS);
	        var topPanel = new phosphor_panel_1.Panel();
	        var hboxPanel = new phosphor_boxpanel_1.BoxPanel();
	        var dockPanel = new phosphor_dockpanel_1.DockPanel();
	        var hsplitPanel = new phosphor_splitpanel_1.SplitPanel();
	        var leftHandler = new SideBarHandler('left');
	        var rightHandler = new SideBarHandler('right');
	        var rootLayout = new phosphor_boxpanel_1.BoxLayout();
	        this._topPanel = topPanel;
	        this._hboxPanel = hboxPanel;
	        this._dockPanel = dockPanel;
	        this._hsplitPanel = hsplitPanel;
	        this._leftHandler = leftHandler;
	        this._rightHandler = rightHandler;
	        // TODO fix these
	        hsplitPanel.id = 'p-main-split-panel';
	        leftHandler.sideBar.addClass('p-mod-left');
	        rightHandler.sideBar.addClass('p-mod-right');
	        leftHandler.stackedPanel.id = 'p-left-stack';
	        rightHandler.stackedPanel.id = 'p-right-stack';
	        dockPanel.id = 'p-main-dock-panel';
	        dockPanel.spacing = 8; // TODO make this configurable?
	        hsplitPanel.orientation = phosphor_splitpanel_1.SplitPanel.Horizontal;
	        hsplitPanel.spacing = 1; // TODO make this configurable?
	        phosphor_splitpanel_1.SplitPanel.setStretch(leftHandler.stackedPanel, 0);
	        phosphor_splitpanel_1.SplitPanel.setStretch(dockPanel, 1);
	        phosphor_splitpanel_1.SplitPanel.setStretch(rightHandler.stackedPanel, 0);
	        hsplitPanel.addChild(leftHandler.stackedPanel);
	        hsplitPanel.addChild(dockPanel);
	        hsplitPanel.addChild(rightHandler.stackedPanel);
	        hboxPanel.direction = phosphor_boxpanel_1.BoxPanel.LeftToRight;
	        hboxPanel.spacing = 0; // TODO make this configurable?
	        phosphor_boxpanel_1.BoxPanel.setStretch(leftHandler.sideBar, 0);
	        phosphor_boxpanel_1.BoxPanel.setStretch(hsplitPanel, 1);
	        phosphor_boxpanel_1.BoxPanel.setStretch(rightHandler.sideBar, 0);
	        hboxPanel.addChild(leftHandler.sideBar);
	        hboxPanel.addChild(hsplitPanel);
	        hboxPanel.addChild(rightHandler.sideBar);
	        rootLayout.direction = phosphor_boxpanel_1.BoxLayout.TopToBottom;
	        rootLayout.spacing = 0; // TODO make this configurable?
	        phosphor_boxpanel_1.BoxLayout.setStretch(topPanel, 0);
	        phosphor_boxpanel_1.BoxLayout.setStretch(hboxPanel, 1);
	        rootLayout.addChild(topPanel);
	        rootLayout.addChild(hboxPanel);
	        this.layout = rootLayout;
	    }
	    /**
	     * Add a widget to the top content area.
	     */
	    ApplicationShell.prototype.addToTopArea = function (widget, options) {
	        if (options === void 0) { options = {}; }
	        // TODO
	        if (!widget.id) {
	            console.error('widgets added to app shell must have unique id property');
	            return;
	        }
	    };
	    /**
	     * Add a widget to the left content area.
	     */
	    ApplicationShell.prototype.addToLeftArea = function (widget, options) {
	        if (options === void 0) { options = {}; }
	        if (!widget.id) {
	            console.error('widgets added to app shell must have unique id property');
	            return;
	        }
	        var rank = 'rank' in options ? options.rank : 100;
	        this._leftHandler.addWidget(widget, rank);
	    };
	    /**
	     * Add a widget to the right content area.
	     */
	    ApplicationShell.prototype.addToRightArea = function (widget, options) {
	        if (options === void 0) { options = {}; }
	        if (!widget.id) {
	            console.error('widgets added to app shell must have unique id property');
	            return;
	        }
	        var rank = 'rank' in options ? options.rank : 100;
	        this._rightHandler.addWidget(widget, rank);
	    };
	    /**
	     * Add a widget to the main content area.
	     */
	    ApplicationShell.prototype.addToMainArea = function (widget, options) {
	        if (options === void 0) { options = {}; }
	        // TODO
	        if (!widget.id) {
	            console.error('widgets added to app shell must have unique id property');
	            return;
	        }
	        this._dockPanel.insertTabAfter(widget);
	    };
	    /**
	     *
	     */
	    ApplicationShell.prototype.activateLeft = function (id) {
	        this._leftHandler.activate(id);
	    };
	    /**
	     *
	     */
	    ApplicationShell.prototype.activateRight = function (id) {
	        this._rightHandler.activate(id);
	    };
	    /**
	     *
	     */
	    ApplicationShell.prototype.activateMain = function (id) {
	        // TODO
	    };
	    /**
	     *
	     */
	    ApplicationShell.prototype.collapseLeft = function () {
	        this._leftHandler.collapse();
	    };
	    /**
	     *
	     */
	    ApplicationShell.prototype.collapseRight = function () {
	        this._rightHandler.collapse();
	    };
	    return ApplicationShell;
	}(phosphor_widget_1.Widget));
	exports.ApplicationShell = ApplicationShell;
	/**
	 * A class which manages a side bar and related stacked panel.
	 */
	var SideBarHandler = (function () {
	    /**
	     * Construct a new side bar handler.
	     */
	    function SideBarHandler(side) {
	        this._items = [];
	        this._side = side;
	        this._sideBar = new sidebar_1.SideBar();
	        this._stackedPanel = new phosphor_stackedpanel_1.StackedPanel();
	        this._sideBar.hide();
	        this._stackedPanel.hide();
	        this._sideBar.currentChanged.connect(this._onCurrentChanged, this);
	        this._stackedPanel.widgetRemoved.connect(this._onWidgetRemoved, this);
	    }
	    /**
	     * A less-than comparison function for side bar rank items.
	     */
	    SideBarHandler.itemCmp = function (first, second) {
	        return first.rank < second.rank;
	    };
	    Object.defineProperty(SideBarHandler.prototype, "sideBar", {
	        /**
	         * Get the side bar managed by the handler.
	         */
	        get: function () {
	            return this._sideBar;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SideBarHandler.prototype, "stackedPanel", {
	        /**
	         * Get the stacked panel managed by the handler
	         */
	        get: function () {
	            return this._stackedPanel;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Activate a widget residing in the side bar by ID.
	     *
	     * @param id - The widget's unique ID.
	     */
	    SideBarHandler.prototype.activate = function (id) {
	        var widget = this._findWidgetByID(id);
	        if (widget)
	            this._sideBar.currentTitle = widget.title;
	    };
	    /**
	     * Collapse the sidebar so no items are expanded.
	     */
	    SideBarHandler.prototype.collapse = function () {
	        this._sideBar.currentTitle = null;
	    };
	    /**
	     * Add a widget and its title to the stacked panel and side bar.
	     *
	     * If the widget is already added, it will be moved.
	     */
	    SideBarHandler.prototype.addWidget = function (widget, rank) {
	        widget.parent = null;
	        widget.hide();
	        var item = { widget: widget, rank: rank };
	        var index = this._findInsertIndex(item);
	        arrays.insert(this._items, index, item);
	        this._stackedPanel.insertChild(index, widget);
	        this._sideBar.insertTitle(index, widget.title);
	        this._refreshVisibility();
	    };
	    /**
	     * Find the insertion index for a rank item.
	     */
	    SideBarHandler.prototype._findInsertIndex = function (item) {
	        return arrays.upperBound(this._items, item, SideBarHandler.itemCmp);
	    };
	    /**
	     * Find the index of the item with the given widget, or `-1`.
	     */
	    SideBarHandler.prototype._findWidgetIndex = function (widget) {
	        return arrays.findIndex(this._items, function (item) { return item.widget === widget; });
	    };
	    /**
	     * Find the widget which owns the given title, or `null`.
	     */
	    SideBarHandler.prototype._findWidgetByTitle = function (title) {
	        var item = arrays.find(this._items, function (item) { return item.widget.title === title; });
	        return item ? item.widget : null;
	    };
	    /**
	     * Find the widget with the given id, or `null`.
	     */
	    SideBarHandler.prototype._findWidgetByID = function (id) {
	        var item = arrays.find(this._items, function (item) { return item.widget.id === id; });
	        return item ? item.widget : null;
	    };
	    /**
	     * Refresh the visibility of the side bar and stacked panel.
	     */
	    SideBarHandler.prototype._refreshVisibility = function () {
	        this._sideBar.setHidden(this._sideBar.titleCount() === 0);
	        this._stackedPanel.setHidden(this._sideBar.currentTitle === null);
	    };
	    /**
	     * Handle the `currentChanged` signal from the sidebar.
	     */
	    SideBarHandler.prototype._onCurrentChanged = function (sender, args) {
	        var oldWidget = this._findWidgetByTitle(args.oldValue);
	        var newWidget = this._findWidgetByTitle(args.newValue);
	        if (oldWidget)
	            oldWidget.hide();
	        if (newWidget)
	            newWidget.show();
	        if (newWidget) {
	            document.body.dataset[(this._side + "Area")] = newWidget.id;
	        }
	        else {
	            delete document.body.dataset[(this._side + "Area")];
	        }
	        this._refreshVisibility();
	    };
	    /*
	     * Handle the `widgetRemoved` signal from the stacked panel.
	     */
	    SideBarHandler.prototype._onWidgetRemoved = function (sender, widget) {
	        arrays.removeAt(this._items, this._findWidgetIndex(widget));
	        this._sideBar.removeTitle(widget.title);
	        this._refreshVisibility();
	    };
	    return SideBarHandler;
	}());


/***/ },
/* 3 */
/***/ function(module, exports) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	/**
	 * Execute a callback for each element in an array.
	 *
	 * @param array - The array of values to iterate.
	 *
	 * @param callback - The callback to invoke for the array elements.
	 *
	 * @param fromIndex - The starting index for iteration.
	 *
	 * @param wrap - Whether iteration wraps around at the end of the array.
	 *
	 * @returns The first value returned by `callback` which is not
	 *   equal to `undefined`, or `undefined` if the callback does
	 *   not return a value or if the start index is out of range.
	 *
	 * #### Notes
	 * It is not safe to modify the size of the array while iterating.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * function logger(value: number): void {
	 *   console.log(value);
	 * }
	 *
	 * let data = [1, 2, 3, 4];
	 * arrays.forEach(data, logger);           // logs 1, 2, 3, 4
	 * arrays.forEach(data, logger, 2);        // logs 3, 4
	 * arrays.forEach(data, logger, 2, true);  // logs 3, 4, 1, 2
	 * arrays.forEach(data, (v, i) => {        // 2
	 *   if (v === 3) return i;
	 * });
	 * ```
	 *
	 * **See also** [[rforEach]]
	 */
	function forEach(array, callback, fromIndex, wrap) {
	    if (fromIndex === void 0) { fromIndex = 0; }
	    if (wrap === void 0) { wrap = false; }
	    var start = fromIndex | 0;
	    if (start < 0 || start >= array.length) {
	        return void 0;
	    }
	    if (wrap) {
	        for (var i = 0, n = array.length; i < n; ++i) {
	            var j = (start + i) % n;
	            var result = callback(array[j], j);
	            if (result !== void 0)
	                return result;
	        }
	    }
	    else {
	        for (var i = start, n = array.length; i < n; ++i) {
	            var result = callback(array[i], i);
	            if (result !== void 0)
	                return result;
	        }
	    }
	    return void 0;
	}
	exports.forEach = forEach;
	/**
	 * Execute a callback for each element in an array, in reverse.
	 *
	 * @param array - The array of values to iterate.
	 *
	 * @param callback - The callback to invoke for the array elements.
	 *
	 * @param fromIndex - The starting index for iteration.
	 *
	 * @param wrap - Whether iteration wraps around at the end of the array.
	 *
	 * @returns The first value returned by `callback` which is not
	 *   equal to `undefined`, or `undefined` if the callback does
	 *   not return a value or if the start index is out of range.
	 *
	 * #### Notes
	 * It is not safe to modify the size of the array while iterating.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * function logger(value: number): void {
	 *   console.log(value);
	 * }
	 *
	 * let data = [1, 2, 3, 4];
	 * arrays.rforEach(data, logger);           // logs 4, 3, 2, 1
	 * arrays.rforEach(data, logger, 2);        // logs 3, 2, 1
	 * arrays.rforEach(data, logger, 2, true);  // logs 3, 2, 1, 4
	 * arrays.rforEach(data, (v, i) => {        // 2
	 *   if (v === 3) return i;
	 * });
	 * ```
	 * **See also** [[forEach]]
	 */
	function rforEach(array, callback, fromIndex, wrap) {
	    if (fromIndex === void 0) { fromIndex = array.length - 1; }
	    if (wrap === void 0) { wrap = false; }
	    var start = fromIndex | 0;
	    if (start < 0 || start >= array.length) {
	        return void 0;
	    }
	    if (wrap) {
	        for (var i = 0, n = array.length; i < n; ++i) {
	            var j = (start - i + n) % n;
	            var result = callback(array[j], j);
	            if (result !== void 0)
	                return result;
	        }
	    }
	    else {
	        for (var i = start; i >= 0; --i) {
	            var result = callback(array[i], i);
	            if (result !== void 0)
	                return result;
	        }
	    }
	    return void 0;
	}
	exports.rforEach = rforEach;
	/**
	 * Find the index of the first value which matches a predicate.
	 *
	 * @param array - The array of values to be searched.
	 *
	 * @param pred - The predicate function to apply to the values.
	 *
	 * @param fromIndex - The starting index of the search.
	 *
	 * @param wrap - Whether the search wraps around at the end of the array.
	 *
	 * @returns The index of the first matching value, or `-1` if no value
	 *   matches the predicate or if the start index is out of range.
	 *
	 * #### Notes
	 * It is not safe to modify the size of the array while iterating.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * function isEven(value: number): boolean {
	 *   return value % 2 === 0;
	 * }
	 *
	 * let data = [1, 2, 3, 4, 3, 2, 1];
	 * arrays.findIndex(data, isEven);           // 1
	 * arrays.findIndex(data, isEven, 4);        // 5
	 * arrays.findIndex(data, isEven, 6);        // -1
	 * arrays.findIndex(data, isEven, 6, true);  // 1
	 * ```
	 *
	 * **See also** [[rfindIndex]].
	 */
	function findIndex(array, pred, fromIndex, wrap) {
	    if (fromIndex === void 0) { fromIndex = 0; }
	    if (wrap === void 0) { wrap = false; }
	    var start = fromIndex | 0;
	    if (start < 0 || start >= array.length) {
	        return -1;
	    }
	    if (wrap) {
	        for (var i = 0, n = array.length; i < n; ++i) {
	            var j = (start + i) % n;
	            if (pred(array[j], j))
	                return j;
	        }
	    }
	    else {
	        for (var i = start, n = array.length; i < n; ++i) {
	            if (pred(array[i], i))
	                return i;
	        }
	    }
	    return -1;
	}
	exports.findIndex = findIndex;
	/**
	 * Find the index of the last value which matches a predicate.
	 *
	 * @param array - The array of values to be searched.
	 *
	 * @param pred - The predicate function to apply to the values.
	 *
	 * @param fromIndex - The starting index of the search.
	 *
	 * @param wrap - Whether the search wraps around at the front of the array.
	 *
	 * @returns The index of the last matching value, or `-1` if no value
	 *   matches the predicate or if the start index is out of range.
	 *
	 * #### Notes
	 * It is not safe to modify the size of the array while iterating.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * function isEven(value: number): boolean {
	 *   return value % 2 === 0;
	 * }
	 *
	 * let data = [1, 2, 3, 4, 3, 2, 1];
	 * arrays.rfindIndex(data, isEven);           // 5
	 * arrays.rfindIndex(data, isEven, 4);        // 3
	 * arrays.rfindIndex(data, isEven, 0);        // -1
	 * arrays.rfindIndex(data, isEven, 0, true);  // 5
	 * ```
	 *
	 * **See also** [[findIndex]].
	 */
	function rfindIndex(array, pred, fromIndex, wrap) {
	    if (fromIndex === void 0) { fromIndex = array.length - 1; }
	    if (wrap === void 0) { wrap = false; }
	    var start = fromIndex | 0;
	    if (start < 0 || start >= array.length) {
	        return -1;
	    }
	    if (wrap) {
	        for (var i = 0, n = array.length; i < n; ++i) {
	            var j = (start - i + n) % n;
	            if (pred(array[j], j))
	                return j;
	        }
	    }
	    else {
	        for (var i = start; i >= 0; --i) {
	            if (pred(array[i], i))
	                return i;
	        }
	    }
	    return -1;
	}
	exports.rfindIndex = rfindIndex;
	/**
	 * Find the first value which matches a predicate.
	 *
	 * @param array - The array of values to be searched.
	 *
	 * @param pred - The predicate function to apply to the values.
	 *
	 * @param fromIndex - The starting index of the search.
	 *
	 * @param wrap - Whether the search wraps around at the end of the array.
	 *
	 * @returns The first matching value, or `undefined` if no value matches
	 *   the predicate or if the start index is out of range.
	 *
	 * #### Notes
	 * It is not safe to modify the size of the array while iterating.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * function isEven(value: number): boolean {
	 *   return value % 2 === 0;
	 * }
	 *
	 * let data = [1, 2, 3, 4, 3, 2, 1];
	 * arrays.find(data, isEven);           // 2
	 * arrays.find(data, isEven, 4);        // 2
	 * arrays.find(data, isEven, 6);        // undefined
	 * arrays.find(data, isEven, 6, true);  // 2
	 * ```
	 *
	 * **See also** [[rfind]].
	 */
	function find(array, pred, fromIndex, wrap) {
	    var i = findIndex(array, pred, fromIndex, wrap);
	    return i !== -1 ? array[i] : void 0;
	}
	exports.find = find;
	/**
	 * Find the last value which matches a predicate.
	 *
	 * @param array - The array of values to be searched.
	 *
	 * @param pred - The predicate function to apply to the values.
	 *
	 * @param fromIndex - The starting index of the search.
	 *
	 * @param wrap - Whether the search wraps around at the front of the array.
	 *
	 * @returns The last matching value, or `undefined` if no value matches
	 *   the predicate or if the start index is out of range.
	 *
	 * #### Notes
	 * The range of visited indices is set before the first invocation of
	 * `pred`. It is not safe for `pred` to change the length of `array`.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * function isEven(value: number): boolean {
	 *   return value % 2 === 0;
	 * }
	 *
	 * let data = [1, 2, 3, 4, 3, 2, 1];
	 * arrays.rfind(data, isEven);           // 2
	 * arrays.rfind(data, isEven, 4);        // 4
	 * arrays.rfind(data, isEven, 0);        // undefined
	 * arrays.rfind(data, isEven, 0, true);  // 2
	 * ```
	 *
	 * **See also** [[find]].
	 */
	function rfind(array, pred, fromIndex, wrap) {
	    var i = rfindIndex(array, pred, fromIndex, wrap);
	    return i !== -1 ? array[i] : void 0;
	}
	exports.rfind = rfind;
	/**
	 * Insert an element into an array at a specified index.
	 *
	 * @param array - The array of values to modify.
	 *
	 * @param index - The index at which to insert the value. This value
	 *   is clamped to the bounds of the array.
	 *
	 * @param value - The value to insert into the array.
	 *
	 * @returns The index at which the value was inserted.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * let data = [0, 1, 2, 3, 4];
	 * arrays.insert(data, 0, 12);  // 0
	 * arrays.insert(data, 3, 42);  // 3
	 * arrays.insert(data, -9, 9);  // 0
	 * arrays.insert(data, 12, 8);  // 8
	 * console.log(data);           // [9, 12, 0, 1, 42, 2, 3, 4, 8]
	 * ```
	 *
	 * **See also** [[removeAt]] and [[remove]]
	 */
	function insert(array, index, value) {
	    var j = Math.max(0, Math.min(index | 0, array.length));
	    for (var i = array.length; i > j; --i) {
	        array[i] = array[i - 1];
	    }
	    array[j] = value;
	    return j;
	}
	exports.insert = insert;
	/**
	 * Move an element in an array from one index to another.
	 *
	 * @param array - The array of values to modify.
	 *
	 * @param fromIndex - The index of the element to move.
	 *
	 * @param toIndex - The target index of the element.
	 *
	 * @returns `true` if the element was moved, or `false` if either
	 *   index is out of range.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * let data = [0, 1, 2, 3, 4];
	 * arrays.move(data, 1, 2);   // true
	 * arrays.move(data, -1, 0);  // false
	 * arrays.move(data, 4, 2);   // true
	 * arrays.move(data, 10, 0);  // false
	 * console.log(data);         // [0, 2, 4, 1, 3]
	 * ```
	 */
	function move(array, fromIndex, toIndex) {
	    var j = fromIndex | 0;
	    if (j < 0 || j >= array.length) {
	        return false;
	    }
	    var k = toIndex | 0;
	    if (k < 0 || k >= array.length) {
	        return false;
	    }
	    var value = array[j];
	    if (j > k) {
	        for (var i = j; i > k; --i) {
	            array[i] = array[i - 1];
	        }
	    }
	    else if (j < k) {
	        for (var i = j; i < k; ++i) {
	            array[i] = array[i + 1];
	        }
	    }
	    array[k] = value;
	    return true;
	}
	exports.move = move;
	/**
	 * Remove an element from an array at a specified index.
	 *
	 * @param array - The array of values to modify.
	 *
	 * @param index - The index of the element to remove.
	 *
	 * @returns The removed value, or `undefined` if the index is out
	 *   of range.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * let data = [0, 1, 2, 3, 4];
	 * arrays.removeAt(data, 1);   // 1
	 * arrays.removeAt(data, 3);   // 4
	 * arrays.removeAt(data, 10);  // undefined
	 * console.log(data);          // [0, 2, 3]
	 * ```
	 *
	 * **See also** [[remove]] and [[insert]]
	 */
	function removeAt(array, index) {
	    var j = index | 0;
	    if (j < 0 || j >= array.length) {
	        return void 0;
	    }
	    var value = array[j];
	    for (var i = j + 1, n = array.length; i < n; ++i) {
	        array[i - 1] = array[i];
	    }
	    array.length -= 1;
	    return value;
	}
	exports.removeAt = removeAt;
	/**
	 * Remove the first occurrence of a value from an array.
	 *
	 * @param array - The array of values to modify.
	 *
	 * @param value - The value to remove from the array.
	 *
	 * @returns The index where the value was located, or `-1` if the
	 *   value is not the array.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * let data = [0, 1, 2, 3, 4];
	 * arrays.remove(data, 1);  // 1
	 * arrays.remove(data, 3);  // 2
	 * arrays.remove(data, 7);  // -1
	 * console.log(data);       // [0, 2, 4]
	 * ```
	 *
	 * **See also** [[removeAt]] and [[insert]]
	 */
	function remove(array, value) {
	    var j = -1;
	    for (var i = 0, n = array.length; i < n; ++i) {
	        if (array[i] === value) {
	            j = i;
	            break;
	        }
	    }
	    if (j === -1) {
	        return -1;
	    }
	    for (var i = j + 1, n = array.length; i < n; ++i) {
	        array[i - 1] = array[i];
	    }
	    array.length -= 1;
	    return j;
	}
	exports.remove = remove;
	/**
	 * Reverse an array in-place subject to an optional range.
	 *
	 * @param array - The array to reverse.
	 *
	 * @param fromIndex - The index of the first element of the range.
	 *   This value will be clamped to the array bounds.
	 *
	 * @param toIndex - The index of the last element of the range.
	 *   This value will be clamped to the array bounds.
	 *
	 * @returns A reference to the original array.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * let data = [0, 1, 2, 3, 4];
	 * arrays.reverse(data, 1, 3);    // [0, 3, 2, 1, 4]
	 * arrays.reverse(data, 3);       // [0, 3, 2, 4, 1]
	 * arrays.reverse(data);          // [1, 4, 2, 3, 0]
	 * ```
	 *
	 * **See also** [[rotate]]
	 */
	function reverse(array, fromIndex, toIndex) {
	    if (fromIndex === void 0) { fromIndex = 0; }
	    if (toIndex === void 0) { toIndex = array.length; }
	    var i = Math.max(0, Math.min(fromIndex | 0, array.length - 1));
	    var j = Math.max(0, Math.min(toIndex | 0, array.length - 1));
	    if (j < i)
	        i = j + (j = i, 0);
	    while (i < j) {
	        var tmpval = array[i];
	        array[i++] = array[j];
	        array[j--] = tmpval;
	    }
	    return array;
	}
	exports.reverse = reverse;
	/**
	 * Rotate the elements of an array by a positive or negative delta.
	 *
	 * @param array - The array to rotate.
	 *
	 * @param delta - The amount of rotation to apply to the elements. A
	 *   positive delta will shift the elements to the left. A negative
	 *   delta will shift the elements to the right.
	 *
	 * @returns A reference to the original array.
	 *
	 * #### Notes
	 * This executes in `O(n)` time and `O(1)` space.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * let data = [0, 1, 2, 3, 4];
	 * arrays.rotate(data, 2);    // [2, 3, 4, 0, 1]
	 * arrays.rotate(data, -2);   // [0, 1, 2, 3, 4]
	 * arrays.rotate(data, 10);   // [0, 1, 2, 3, 4]
	 * arrays.rotate(data, 9);    // [4, 0, 1, 2, 3]
	 * ```
	 *
	 * **See also** [[reverse]]
	 */
	function rotate(array, delta) {
	    var n = array.length;
	    if (n <= 1) {
	        return array;
	    }
	    var d = delta | 0;
	    if (d > 0) {
	        d = d % n;
	    }
	    else if (d < 0) {
	        d = ((d % n) + n) % n;
	    }
	    if (d === 0) {
	        return array;
	    }
	    reverse(array, 0, d - 1);
	    reverse(array, d, n - 1);
	    reverse(array, 0, n - 1);
	    return array;
	}
	exports.rotate = rotate;
	/**
	 * Using a binary search, find the index of the first element in an
	 * array which compares `>=` to a value.
	 *
	 * @param array - The array of values to be searched. It must be sorted
	 *   in ascending order.
	 *
	 * @param value - The value to locate in the array.
	 *
	 * @param cmp - The comparison function which returns `true` if an
	 *   array element is less than the given value.
	 *
	 * @returns The index of the first element in `array` which compares
	 *   `>=` to `value`, or `array.length` if there is no such element.
	 *
	 * #### Notes
	 * It is not safe for the comparison function to modify the array.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * function numberCmp(a: number, b: number): boolean {
	 *   return a < b;
	 * }
	 *
	 * let data = [0, 3, 4, 7, 7, 9];
	 * arrays.lowerBound(data, 0, numberCmp);   // 0
	 * arrays.lowerBound(data, 6, numberCmp);   // 3
	 * arrays.lowerBound(data, 7, numberCmp);   // 3
	 * arrays.lowerBound(data, -1, numberCmp);  // 0
	 * arrays.lowerBound(data, 10, numberCmp);  // 6
	 * ```
	 *
	 * **See also** [[upperBound]]
	 */
	function lowerBound(array, value, cmp) {
	    var begin = 0;
	    var half;
	    var middle;
	    var n = array.length;
	    while (n > 0) {
	        half = n >> 1;
	        middle = begin + half;
	        if (cmp(array[middle], value)) {
	            begin = middle + 1;
	            n -= half + 1;
	        }
	        else {
	            n = half;
	        }
	    }
	    return begin;
	}
	exports.lowerBound = lowerBound;
	/**
	 * Using a binary search, find the index of the first element in an
	 * array which compares `>` than a value.
	 *
	 * @param array - The array of values to be searched. It must be sorted
	 *   in ascending order.
	 *
	 * @param value - The value to locate in the array.
	 *
	 * @param cmp - The comparison function which returns `true` if the
	 *   the given value is less than an array element.
	 *
	 * @returns The index of the first element in `array` which compares
	 *   `>` than `value`, or `array.length` if there is no such element.
	 *
	 * #### Notes
	 * It is not safe for the comparison function to modify the array.
	 *
	 * #### Example
	 * ```typescript
	 * import * as arrays from 'phosphor-arrays';
	 *
	 * function numberCmp(a: number, b: number): number {
	 *   return a < b;
	 * }
	 *
	 * let data = [0, 3, 4, 7, 7, 9];
	 * arrays.upperBound(data, 0, numberCmp);   // 1
	 * arrays.upperBound(data, 6, numberCmp);   // 3
	 * arrays.upperBound(data, 7, numberCmp);   // 5
	 * arrays.upperBound(data, -1, numberCmp);  // 0
	 * arrays.upperBound(data, 10, numberCmp);  // 6
	 * ```
	 *
	 * **See also** [[lowerBound]]
	 */
	function upperBound(array, value, cmp) {
	    var begin = 0;
	    var half;
	    var middle;
	    var n = array.length;
	    while (n > 0) {
	        half = n >> 1;
	        middle = begin + half;
	        if (cmp(value, array[middle])) {
	            n = half;
	        }
	        else {
	            begin = middle + 1;
	            n -= half + 1;
	        }
	    }
	    return begin;
	}
	exports.upperBound = upperBound;
	//# sourceMappingURL=index.js.map

/***/ },
/* 4 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	__export(__webpack_require__(5));
	__export(__webpack_require__(29));


/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var arrays = __webpack_require__(3);
	var phosphor_boxengine_1 = __webpack_require__(6);
	var phosphor_domutil_1 = __webpack_require__(7);
	var phosphor_messaging_1 = __webpack_require__(13);
	var phosphor_properties_1 = __webpack_require__(17);
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * The class name added to left-to-right box layout parents.
	 */
	var LEFT_TO_RIGHT_CLASS = 'p-mod-left-to-right';
	/**
	 * The class name added to right-to-left box layout parents.
	 */
	var RIGHT_TO_LEFT_CLASS = 'p-mod-right-to-left';
	/**
	 * The class name added to top-to-bottom box layout parents.
	 */
	var TOP_TO_BOTTOM_CLASS = 'p-mod-top-to-bottom';
	/**
	 * The class name added to bottom-to-top box layout parents.
	 */
	var BOTTOM_TO_TOP_CLASS = 'p-mod-bottom-to-top';
	/**
	 * The layout direction of a box layout.
	 */
	(function (Direction) {
	    /**
	     * Left to right direction.
	     */
	    Direction[Direction["LeftToRight"] = 0] = "LeftToRight";
	    /**
	     * Right to left direction.
	     */
	    Direction[Direction["RightToLeft"] = 1] = "RightToLeft";
	    /**
	     * Top to bottom direction.
	     */
	    Direction[Direction["TopToBottom"] = 2] = "TopToBottom";
	    /**
	     * Bottom to top direction.
	     */
	    Direction[Direction["BottomToTop"] = 3] = "BottomToTop";
	})(exports.Direction || (exports.Direction = {}));
	var Direction = exports.Direction;
	/**
	 * A layout which arranges its children in a single row or column.
	 */
	var BoxLayout = (function (_super) {
	    __extends(BoxLayout, _super);
	    function BoxLayout() {
	        _super.apply(this, arguments);
	        this._fixed = 0;
	        this._spacing = 8;
	        this._box = null;
	        this._sizers = [];
	        this._direction = Direction.TopToBottom;
	    }
	    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;
	            }
	            BoxLayoutPrivate.toggleDirection(this.parent, value);
	            this.parent.fit();
	        },
	        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 = Math.max(0, value | 0);
	            if (this._spacing === value) {
	                return;
	            }
	            this._spacing = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.fit();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Initialize the children of the layout.
	     *
	     * #### Notes
	     * This method is called automatically when the layout is installed
	     * on its parent widget.
	     */
	    BoxLayout.prototype.initialize = function () {
	        BoxLayoutPrivate.toggleDirection(this.parent, this.direction);
	        _super.prototype.initialize.call(this);
	    };
	    /**
	     * Attach a child widget to the parent's DOM node.
	     *
	     * @param index - The current index of the child in the layout.
	     *
	     * @param child - The child widget to attach to the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    BoxLayout.prototype.attachChild = function (index, child) {
	        arrays.insert(this._sizers, index, new phosphor_boxengine_1.BoxSizer());
	        BoxLayoutPrivate.prepareGeometry(child);
	        this.parent.node.appendChild(child.node);
	        if (this.parent.isAttached)
	            phosphor_messaging_1.sendMessage(child, phosphor_widget_1.Widget.MsgAfterAttach);
	        this.parent.fit();
	    };
	    /**
	     * Move a child widget in the parent's DOM node.
	     *
	     * @param fromIndex - The previous index of the child in the layout.
	     *
	     * @param toIndex - The current index of the child in the layout.
	     *
	     * @param child - The child widget to move in the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    BoxLayout.prototype.moveChild = function (fromIndex, toIndex, child) {
	        arrays.move(this._sizers, fromIndex, toIndex);
	        this.parent.update();
	    };
	    /**
	     * Detach a child widget from the parent's DOM node.
	     *
	     * @param index - The previous index of the child in the layout.
	     *
	     * @param child - The child widget to detach from the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    BoxLayout.prototype.detachChild = function (index, child) {
	        arrays.removeAt(this._sizers, index);
	        if (this.parent.isAttached)
	            phosphor_messaging_1.sendMessage(child, phosphor_widget_1.Widget.MsgBeforeDetach);
	        this.parent.node.removeChild(child.node);
	        BoxLayoutPrivate.resetGeometry(child);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on an `'after-show'` message.
	     */
	    BoxLayout.prototype.onAfterShow = function (msg) {
	        _super.prototype.onAfterShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    BoxLayout.prototype.onAfterAttach = function (msg) {
	        _super.prototype.onAfterAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    BoxLayout.prototype.onChildShown = function (msg) {
	        if (BoxLayoutPrivate.IsIE) {
	            phosphor_messaging_1.sendMessage(this.parent, phosphor_widget_1.Widget.MsgFitRequest);
	        }
	        else {
	            this.parent.fit();
	        }
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    BoxLayout.prototype.onChildHidden = function (msg) {
	        if (BoxLayoutPrivate.IsIE) {
	            phosphor_messaging_1.sendMessage(this.parent, phosphor_widget_1.Widget.MsgFitRequest);
	        }
	        else {
	            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 child widgets.
	     */
	    BoxLayout.prototype._fit = function () {
	        // Compute the visible item count.
	        var nVisible = 0;
	        for (var i = 0, n = this.childCount(); i < n; ++i) {
	            if (!this.childAt(i).isHidden)
	                nVisible++;
	        }
	        // Update the fixed space for the visible items.
	        this._fixed = this._spacing * Math.max(0, nVisible - 1);
	        // Setup the initial size limits.
	        var minW = 0;
	        var minH = 0;
	        var maxW = Infinity;
	        var maxH = Infinity;
	        var horz = BoxLayoutPrivate.isHorizontal(this._direction);
	        if (horz) {
	            minW = this._fixed;
	            maxW = nVisible > 0 ? minW : maxW;
	        }
	        else {
	            minH = this._fixed;
	            maxH = nVisible > 0 ? minH : maxH;
	        }
	        // Update the sizers and computed size limits.
	        for (var i = 0, n = this.childCount(); i < n; ++i) {
	            var child = this.childAt(i);
	            var sizer = this._sizers[i];
	            if (child.isHidden) {
	                sizer.minSize = 0;
	                sizer.maxSize = 0;
	                continue;
	            }
	            var limits = phosphor_domutil_1.sizeLimits(child.node);
	            sizer.sizeHint = BoxLayout.getSizeBasis(child);
	            sizer.stretch = BoxLayout.getStretch(child);
	            if (horz) {
	                sizer.minSize = limits.minWidth;
	                sizer.maxSize = limits.maxWidth;
	                minW += limits.minWidth;
	                maxW += limits.maxWidth;
	                minH = Math.max(minH, limits.minHeight);
	                maxH = Math.min(maxH, limits.maxHeight);
	            }
	            else {
	                sizer.minSize = limits.minHeight;
	                sizer.maxSize = limits.maxHeight;
	                minH += limits.minHeight;
	                maxH += limits.maxHeight;
	                minW = Math.max(minW, limits.minWidth);
	                maxW = Math.min(maxW, limits.maxWidth);
	            }
	        }
	        // Update the box sizing and add it to the size constraints.
	        var box = this._box = phosphor_domutil_1.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        maxW += box.horizontalSum;
	        maxH += box.verticalSum;
	        // Update the parent's size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        style.maxWidth = maxW === Infinity ? 'none' : maxW + "px";
	        style.maxHeight = maxH === Infinity ? 'none' : maxH + "px";
	        // Notify the ancestor that it should fit immediately.
	        var ancestor = this.parent.parent;
	        if (ancestor)
	            phosphor_messaging_1.sendMessage(ancestor, phosphor_widget_1.Widget.MsgFitRequest);
	        // Notify the parent that it should update immediately.
	        phosphor_messaging_1.sendMessage(this.parent, phosphor_widget_1.Widget.MsgUpdateRequest);
	    };
	    /**
	     * Update the layout position and size of the child widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    BoxLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Bail early if there are no children to layout.
	        if (this.childCount() === 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.
	        var box = this._box || (this._box = phosphor_domutil_1.boxSizing(this.parent.node));
	        // Compute the layout area adjusted for border and padding.
	        var top = box.paddingTop;
	        var left = box.paddingLeft;
	        var width = offsetWidth - box.horizontalSum;
	        var height = offsetHeight - box.verticalSum;
	        // Distribute the layout space and adjust the start position.
	        switch (this._direction) {
	            case Direction.LeftToRight:
	                phosphor_boxengine_1.boxCalc(this._sizers, Math.max(0, width - this._fixed));
	                break;
	            case Direction.TopToBottom:
	                phosphor_boxengine_1.boxCalc(this._sizers, Math.max(0, height - this._fixed));
	                break;
	            case Direction.RightToLeft:
	                phosphor_boxengine_1.boxCalc(this._sizers, Math.max(0, width - this._fixed));
	                left += width;
	                break;
	            case Direction.BottomToTop:
	                phosphor_boxengine_1.boxCalc(this._sizers, Math.max(0, height - this._fixed));
	                top += height;
	                break;
	        }
	        // Layout the children using the computed box sizes.
	        for (var i = 0, n = this.childCount(); i < n; ++i) {
	            var child = this.childAt(i);
	            if (child.isHidden) {
	                continue;
	            }
	            var size = this._sizers[i].size;
	            switch (this._direction) {
	                case Direction.LeftToRight:
	                    BoxLayoutPrivate.setGeometry(child, left, top, size, height);
	                    left += size + this._spacing;
	                    break;
	                case Direction.TopToBottom:
	                    BoxLayoutPrivate.setGeometry(child, left, top, width, size);
	                    top += size + this._spacing;
	                    break;
	                case Direction.RightToLeft:
	                    BoxLayoutPrivate.setGeometry(child, left - size, top, size, height);
	                    left -= size + this._spacing;
	                    break;
	                case Direction.BottomToTop:
	                    BoxLayoutPrivate.setGeometry(child, left, top - size, width, size);
	                    top -= size + this._spacing;
	                    break;
	            }
	        }
	    };
	    return BoxLayout;
	})(phosphor_panel_1.PanelLayout);
	exports.BoxLayout = BoxLayout;
	/**
	 * The namespace for the `BoxLayout` class statics.
	 */
	var BoxLayout;
	(function (BoxLayout) {
	    /**
	     * A convenience alias of the `LeftToRight` [[Direction]].
	     */
	    BoxLayout.LeftToRight = Direction.LeftToRight;
	    /**
	     * A convenience alias of the `RightToLeft` [[Direction]].
	     */
	    BoxLayout.RightToLeft = Direction.RightToLeft;
	    /**
	     * A convenience alias of the `TopToBottom` [[Direction]].
	     */
	    BoxLayout.TopToBottom = Direction.TopToBottom;
	    /**
	     * A convenience alias of the `BottomToTop` [[Direction]].
	     */
	    BoxLayout.BottomToTop = Direction.BottomToTop;
	    /**
	     * 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 BoxLayoutPrivate.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) {
	        BoxLayoutPrivate.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 BoxLayoutPrivate.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) {
	        BoxLayoutPrivate.sizeBasisProperty.set(widget, value);
	    }
	    BoxLayout.setSizeBasis = setSizeBasis;
	})(BoxLayout = exports.BoxLayout || (exports.BoxLayout = {}));
	/**
	 * The namespace for the `BoxLayout` class private data.
	 */
	var BoxLayoutPrivate;
	(function (BoxLayoutPrivate) {
	    /**
	     * A flag indicating whether the browser is IE.
	     */
	    BoxLayoutPrivate.IsIE = /Trident/.test(navigator.userAgent);
	    /**
	     * The property descriptor for a widget stretch factor.
	     */
	    BoxLayoutPrivate.stretchProperty = new phosphor_properties_1.Property({
	        name: 'stretch',
	        value: 0,
	        coerce: function (owner, value) { return Math.max(0, value | 0); },
	        changed: onChildPropertyChanged,
	    });
	    /**
	     * The property descriptor for a widget size basis.
	     */
	    BoxLayoutPrivate.sizeBasisProperty = new phosphor_properties_1.Property({
	        name: 'sizeBasis',
	        value: 0,
	        coerce: function (owner, value) { return Math.max(0, value | 0); },
	        changed: onChildPropertyChanged,
	    });
	    /**
	     * Test whether a direction has horizontal orientation.
	     */
	    function isHorizontal(dir) {
	        return dir === Direction.LeftToRight || dir === Direction.RightToLeft;
	    }
	    BoxLayoutPrivate.isHorizontal = isHorizontal;
	    /**
	     * Toggle the CSS direction class for the given widget.
	     */
	    function toggleDirection(widget, dir) {
	        widget.toggleClass(LEFT_TO_RIGHT_CLASS, dir === Direction.LeftToRight);
	        widget.toggleClass(RIGHT_TO_LEFT_CLASS, dir === Direction.RightToLeft);
	        widget.toggleClass(TOP_TO_BOTTOM_CLASS, dir === Direction.TopToBottom);
	        widget.toggleClass(BOTTOM_TO_TOP_CLASS, dir === Direction.BottomToTop);
	    }
	    BoxLayoutPrivate.toggleDirection = toggleDirection;
	    /**
	     * Prepare a child widget for absolute layout geometry.
	     */
	    function prepareGeometry(widget) {
	        widget.node.style.position = 'absolute';
	    }
	    BoxLayoutPrivate.prepareGeometry = prepareGeometry;
	    /**
	     * Reset the layout geometry of a child widget.
	     */
	    function resetGeometry(widget) {
	        var rect = rectProperty.get(widget);
	        var style = widget.node.style;
	        rect.top = NaN;
	        rect.left = NaN;
	        rect.width = NaN;
	        rect.height = NaN;
	        style.position = '';
	        style.top = '';
	        style.left = '';
	        style.width = '';
	        style.height = '';
	    }
	    BoxLayoutPrivate.resetGeometry = resetGeometry;
	    /**
	     * Set the layout geometry of a child widget.
	     */
	    function setGeometry(widget, left, top, width, height) {
	        var resized = false;
	        var style = widget.node.style;
	        var rect = rectProperty.get(widget);
	        if (rect.top !== top) {
	            rect.top = top;
	            style.top = top + "px";
	        }
	        if (rect.left !== left) {
	            rect.left = left;
	            style.left = left + "px";
	        }
	        if (rect.width !== width) {
	            resized = true;
	            rect.width = width;
	            style.width = width + "px";
	        }
	        if (rect.height !== height) {
	            resized = true;
	            rect.height = height;
	            style.height = height + "px";
	        }
	        if (resized) {
	            phosphor_messaging_1.sendMessage(widget, new phosphor_widget_1.ResizeMessage(width, height));
	        }
	    }
	    BoxLayoutPrivate.setGeometry = setGeometry;
	    /**
	     * A property descriptor for a widget offset rect.
	     */
	    var rectProperty = new phosphor_properties_1.Property({
	        name: 'rect',
	        create: function () { return ({ top: NaN, left: NaN, width: NaN, height: NaN }); },
	    });
	    /**
	     * The change handler for the attached child properties.
	     */
	    function onChildPropertyChanged(child) {
	        var parent = child.parent;
	        var layout = parent && parent.layout;
	        if (layout instanceof BoxLayout)
	            parent.fit();
	    }
	})(BoxLayoutPrivate || (BoxLayoutPrivate = {}));


/***/ },
/* 6 */
/***/ function(module, exports) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	/**
	 * The sizer object for the [[boxCalc]] function.
	 *
	 * A box sizer holds the geometry information for an object along the
	 * layout orientation. An array of box sizers representing a line of
	 * objects is passed to [[boxCalc]] along with the amount of space
	 * available for layout. The algorithm will update the [[size]] of
	 * each box sizer with its computed size.
	 *
	 * #### Notes
	 * 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.
	         *
	         * 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.
	         *
	         * #### Notes
	         * 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.
	         *
	         * The sizer will never be sized less than this value, even if
	         * it means the sizer will overflow the available layout space.
	         *
	         * #### Notes
	         * 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.
	         *
	         * The sizer will never be sized greater than this value, even if
	         * it means the sizer will underflow the available layout space.
	         *
	         * #### Notes
	         * 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.
	         *
	         * 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.
	         *
	         * #### Notes
	         * 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.
	         *
	         * 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]`.
	         *
	         * #### Notes
	         * This value is output only. Changing the 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 the value will have no effect.
	         */
	        this.done = false;
	    }
	    return BoxSizer;
	})();
	exports.BoxSizer = BoxSizer;
	/**
	 * Compute the optimal layout sizes for an array 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.
	 *
	 * #### Notes
	 * This function can be called at any time to recompute the layout
	 * sizing for an existing array of sizers. The previously computed
	 * results will have no effect on the new output. It is therefore
	 * not necessary to create new sizers on each resize event.
	 */
	function boxCalc(sizers, space) {
	    // Bail early if there is nothing to do.
	    var count = sizers.length;
	    if (count === 0) {
	        return;
	    }
	    // 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];
	        initSizer(sizer);
	        totalSize += sizer.size;
	        totalMin += sizer.minSize;
	        totalMax += sizer.maxSize;
	        if (sizer.stretch > 0) {
	            totalStretch += sizer.stretch;
	            stretchCount++;
	        }
	    }
	    // If the space is equal to the total size, return.
	    if (space === totalSize) {
	        return;
	    }
	    // 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;
	    }
	    // 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;
	    }
	    // 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;
	                }
	            }
	        }
	    }
	}
	exports.boxCalc = boxCalc;
	/**
	 * (Re)initialize a box sizer's data for a layout pass.
	 */
	function initSizer(sizer) {
	    sizer.size = Math.max(sizer.minSize, Math.min(sizer.sizeHint, sizer.maxSize));
	    sizer.done = false;
	}
	//# sourceMappingURL=index.js.map

/***/ },
/* 7 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var phosphor_disposable_1 = __webpack_require__(8);
	__webpack_require__(9);
	/**
	 * The class name added to the document body during cursor override.
	 */
	var OVERRIDE_CURSOR_CLASS = 'p-mod-override-cursor';
	/**
	 * The id for the active cursor override.
	 */
	var overrideID = 0;
	/**
	 * Override the cursor 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 is a no-op and will not effect the current override.
	 *
	 * #### Example
	 * ```typescript
	 * import { overrideCursor } from 'phosphor-domutil';
	 *
	 * // force the cursor to be 'wait' for the entire document
	 * let override = overrideCursor('wait');
	 *
	 * // clear the override by disposing the return value
	 * override.dispose();
	 * ```
	 */
	function overrideCursor(cursor) {
	    var id = ++overrideID;
	    var body = document.body;
	    body.style.cursor = cursor;
	    body.classList.add(OVERRIDE_CURSOR_CLASS);
	    return new phosphor_disposable_1.DisposableDelegate(function () {
	        if (id === overrideID) {
	            body.style.cursor = '';
	            body.classList.remove(OVERRIDE_CURSOR_CLASS);
	        }
	    });
	}
	exports.overrideCursor = overrideCursor;
	/**
	 * Test whether a client position lies within a node.
	 *
	 * @param node - The DOM node of interest.
	 *
	 * @param clientX - The client X coordinate of interest.
	 *
	 * @param clientY - The client Y coordinate of interest.
	 *
	 * @returns `true` if the node covers the position, `false` otherwise.
	 *
	 * #### Example
	 * ```typescript
	 * import { hitTest } from 'phosphor-domutil';
	 *
	 * let div = document.createElement('div');
	 * div.style.position = 'absolute';
	 * div.style.left = '0px';
	 * div.style.top = '0px';
	 * div.style.width = '100px';
	 * div.style.height = '100px';
	 * document.body.appendChild(div);
	 *
	 * hitTest(div, 50, 50);   // true
	 * hitTest(div, 150, 150); // false
	 * ```
	 */
	function hitTest(node, clientX, clientY) {
	    var rect = node.getBoundingClientRect();
	    return (clientX >= rect.left &&
	        clientX < rect.right &&
	        clientY >= rect.top &&
	        clientY < rect.bottom);
	}
	exports.hitTest = hitTest;
	/**
	 * Compute the box sizing for a DOM node.
	 *
	 * @param node - The DOM node for which to compute the box sizing.
	 *
	 * @returns The box sizing data for the specified DOM node.
	 *
	 * #### Example
	 * ```typescript
	 * import { boxSizing } from 'phosphor-domutil';
	 *
	 * let div = document.createElement('div');
	 * div.style.borderTop = 'solid 10px black';
	 * document.body.appendChild(div);
	 *
	 * let sizing = boxSizing(div);
	 * sizing.borderTop;    // 10
	 * sizing.paddingLeft;  // 0
	 * // etc...
	 * ```
	 */
	function boxSizing(node) {
	    var cstyle = window.getComputedStyle(node);
	    var bt = parseInt(cstyle.borderTopWidth, 10) || 0;
	    var bl = parseInt(cstyle.borderLeftWidth, 10) || 0;
	    var br = parseInt(cstyle.borderRightWidth, 10) || 0;
	    var bb = parseInt(cstyle.borderBottomWidth, 10) || 0;
	    var pt = parseInt(cstyle.paddingTop, 10) || 0;
	    var pl = parseInt(cstyle.paddingLeft, 10) || 0;
	    var pr = parseInt(cstyle.paddingRight, 10) || 0;
	    var pb = parseInt(cstyle.paddingBottom, 10) || 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,
	    };
	}
	exports.boxSizing = boxSizing;
	/**
	 * Compute the size limits for a DOM node.
	 *
	 * @param node - The node for which to compute the size limits.
	 *
	 * @returns The size limit data for the specified DOM node.
	 *
	 * #### Example
	 * ```typescript
	 * import { sizeLimits } from 'phosphor-domutil';
	 *
	 * let div = document.createElement('div');
	 * div.style.minWidth = '90px';
	 * document.body.appendChild(div);
	 *
	 * let limits = sizeLimits(div);
	 * limits.minWidth;   // 90
	 * limits.maxHeight;  // Infinity
	 * // etc...
	 * ```
	 */
	function sizeLimits(node) {
	    var cstyle = window.getComputedStyle(node);
	    return {
	        minWidth: parseInt(cstyle.minWidth, 10) || 0,
	        minHeight: parseInt(cstyle.minHeight, 10) || 0,
	        maxWidth: parseInt(cstyle.maxWidth, 10) || Infinity,
	        maxHeight: parseInt(cstyle.maxHeight, 10) || Infinity,
	    };
	}
	exports.sizeLimits = sizeLimits;
	//# sourceMappingURL=index.js.map

/***/ },
/* 8 */
/***/ function(module, exports) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	/**
	 * A disposable object which delegates to a callback.
	 */
	var DisposableDelegate = (function () {
	    /**
	     * Construct a new disposable delegate.
	     *
	     * @param callback - The function to invoke when the delegate is
	     *   disposed.
	     */
	    function DisposableDelegate(callback) {
	        this._callback = callback || null;
	    }
	    Object.defineProperty(DisposableDelegate.prototype, "isDisposed", {
	        /**
	         * Test whether the delegate has been disposed.
	         *
	         * #### Notes
	         * This is a read-only property which is always safe to access.
	         */
	        get: function () {
	            return this._callback === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the delegate and invoke its callback.
	     *
	     * #### Notes
	     * If this method is called more than once, all calls made after the
	     * first will be a no-op.
	     */
	    DisposableDelegate.prototype.dispose = function () {
	        if (this._callback === null) {
	            return;
	        }
	        var callback = this._callback;
	        this._callback = null;
	        callback();
	    };
	    return DisposableDelegate;
	})();
	exports.DisposableDelegate = DisposableDelegate;
	/**
	 * An object which manages a collection of disposable items.
	 */
	var DisposableSet = (function () {
	    /**
	     * Construct a new disposable set.
	     *
	     * @param items - The initial disposable items for the set.
	     */
	    function DisposableSet(items) {
	        var _this = this;
	        this._set = new Set();
	        if (items)
	            items.forEach(function (item) { _this._set.add(item); });
	    }
	    Object.defineProperty(DisposableSet.prototype, "isDisposed", {
	        /**
	         * Test whether the set has been disposed.
	         *
	         * #### Notes
	         * This is a read-only property which is always safe to access.
	         */
	        get: function () {
	            return this._set === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the set and dispose the items it contains.
	     *
	     * #### Notes
	     * Items are disposed in the order they are added to the set.
	     *
	     * It is unsafe to use the set after it has been disposed.
	     *
	     * If this method is called more than once, all calls made after the
	     * first will be a no-op.
	     */
	    DisposableSet.prototype.dispose = function () {
	        if (this._set === null) {
	            return;
	        }
	        var set = this._set;
	        this._set = null;
	        set.forEach(function (item) { item.dispose(); });
	    };
	    /**
	     * Add a disposable item to the set.
	     *
	     * @param item - The disposable item to add to the set. If the item
	     *   is already contained in the set, this is a no-op.
	     *
	     * @throws Will throw an error if the set has been disposed.
	     */
	    DisposableSet.prototype.add = function (item) {
	        if (this._set === null) {
	            throw new Error('object is disposed');
	        }
	        this._set.add(item);
	    };
	    /**
	     * Remove a disposable item from the set.
	     *
	     * @param item - The disposable item to remove from the set. If the
	     *   item does not exist in the set, this is a no-op.
	     *
	     * @throws Will throw an error if the set has been disposed.
	     */
	    DisposableSet.prototype.remove = function (item) {
	        if (this._set === null) {
	            throw new Error('object is disposed');
	        }
	        this._set.delete(item);
	    };
	    /**
	     * Clear all disposable items from the set.
	     *
	     * @throws Will throw an error if the set has been disposed.
	     */
	    DisposableSet.prototype.clear = function () {
	        if (this._set === null) {
	            throw new Error('object is disposed');
	        }
	        this._set.clear();
	    };
	    return DisposableSet;
	})();
	exports.DisposableSet = DisposableSet;
	//# sourceMappingURL=index.js.map

/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(10);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../css-loader/index.js!./index.css", function() {
				var newContent = require("!!./../../css-loader/index.js!./index.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 10 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\r\n| Copyright (c) 2014-2015, PhosphorJS Contributors\r\n|\r\n| Distributed under the terms of the BSD 3-Clause License.\r\n|\r\n| The full license is in the file LICENSE, distributed with this software.\r\n|----------------------------------------------------------------------------*/\r\nbody.p-mod-override-cursor * {\r\n  cursor: inherit !important;\r\n}\r\n", ""]);
	
	// exports


/***/ },
/* 11 */
/***/ function(module, exports) {

	/*
		MIT License http://www.opensource.org/licenses/mit-license.php
		Author Tobias Koppers @sokra
	*/
	// css base code, injected by the css-loader
	module.exports = function() {
		var list = [];
	
		// return the list of modules as css string
		list.toString = function toString() {
			var result = [];
			for(var i = 0; i < this.length; i++) {
				var item = this[i];
				if(item[2]) {
					result.push("@media " + item[2] + "{" + item[1] + "}");
				} else {
					result.push(item[1]);
				}
			}
			return result.join("");
		};
	
		// import a list of modules into the list
		list.i = function(modules, mediaQuery) {
			if(typeof modules === "string")
				modules = [[null, modules, ""]];
			var alreadyImportedModules = {};
			for(var i = 0; i < this.length; i++) {
				var id = this[i][0];
				if(typeof id === "number")
					alreadyImportedModules[id] = true;
			}
			for(i = 0; i < modules.length; i++) {
				var item = modules[i];
				// skip already imported module
				// this implementation is not 100% perfect for weird media query combinations
				//  when a module is imported multiple times with different media queries.
				//  I hope this will never occur (Hey this way we have smaller bundles)
				if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
					if(mediaQuery && !item[2]) {
						item[2] = mediaQuery;
					} else if(mediaQuery) {
						item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
					}
					list.push(item);
				}
			}
		};
		return list;
	};


/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {

	/*
		MIT License http://www.opensource.org/licenses/mit-license.php
		Author Tobias Koppers @sokra
	*/
	var stylesInDom = {},
		memoize = function(fn) {
			var memo;
			return function () {
				if (typeof memo === "undefined") memo = fn.apply(this, arguments);
				return memo;
			};
		},
		isOldIE = memoize(function() {
			return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
		}),
		getHeadElement = memoize(function () {
			return document.head || document.getElementsByTagName("head")[0];
		}),
		singletonElement = null,
		singletonCounter = 0,
		styleElementsInsertedAtTop = [];
	
	module.exports = function(list, options) {
		if(true) {
			if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
		}
	
		options = options || {};
		// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
		// tags it will allow on a page
		if (typeof options.singleton === "undefined") options.singleton = isOldIE();
	
		// By default, add <style> tags to the bottom of <head>.
		if (typeof options.insertAt === "undefined") options.insertAt = "bottom";
	
		var styles = listToStyles(list);
		addStylesToDom(styles, options);
	
		return function update(newList) {
			var mayRemove = [];
			for(var i = 0; i < styles.length; i++) {
				var item = styles[i];
				var domStyle = stylesInDom[item.id];
				domStyle.refs--;
				mayRemove.push(domStyle);
			}
			if(newList) {
				var newStyles = listToStyles(newList);
				addStylesToDom(newStyles, options);
			}
			for(var i = 0; i < mayRemove.length; i++) {
				var domStyle = mayRemove[i];
				if(domStyle.refs === 0) {
					for(var j = 0; j < domStyle.parts.length; j++)
						domStyle.parts[j]();
					delete stylesInDom[domStyle.id];
				}
			}
		};
	}
	
	function addStylesToDom(styles, options) {
		for(var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];
			if(domStyle) {
				domStyle.refs++;
				for(var j = 0; j < domStyle.parts.length; j++) {
					domStyle.parts[j](item.parts[j]);
				}
				for(; j < item.parts.length; j++) {
					domStyle.parts.push(addStyle(item.parts[j], options));
				}
			} else {
				var parts = [];
				for(var j = 0; j < item.parts.length; j++) {
					parts.push(addStyle(item.parts[j], options));
				}
				stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
			}
		}
	}
	
	function listToStyles(list) {
		var styles = [];
		var newStyles = {};
		for(var i = 0; i < list.length; i++) {
			var item = list[i];
			var id = item[0];
			var css = item[1];
			var media = item[2];
			var sourceMap = item[3];
			var part = {css: css, media: media, sourceMap: sourceMap};
			if(!newStyles[id])
				styles.push(newStyles[id] = {id: id, parts: [part]});
			else
				newStyles[id].parts.push(part);
		}
		return styles;
	}
	
	function insertStyleElement(options, styleElement) {
		var head = getHeadElement();
		var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
		if (options.insertAt === "top") {
			if(!lastStyleElementInsertedAtTop) {
				head.insertBefore(styleElement, head.firstChild);
			} else if(lastStyleElementInsertedAtTop.nextSibling) {
				head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
			} else {
				head.appendChild(styleElement);
			}
			styleElementsInsertedAtTop.push(styleElement);
		} else if (options.insertAt === "bottom") {
			head.appendChild(styleElement);
		} else {
			throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
		}
	}
	
	function removeStyleElement(styleElement) {
		styleElement.parentNode.removeChild(styleElement);
		var idx = styleElementsInsertedAtTop.indexOf(styleElement);
		if(idx >= 0) {
			styleElementsInsertedAtTop.splice(idx, 1);
		}
	}
	
	function createStyleElement(options) {
		var styleElement = document.createElement("style");
		styleElement.type = "text/css";
		insertStyleElement(options, styleElement);
		return styleElement;
	}
	
	function createLinkElement(options) {
		var linkElement = document.createElement("link");
		linkElement.rel = "stylesheet";
		insertStyleElement(options, linkElement);
		return linkElement;
	}
	
	function addStyle(obj, options) {
		var styleElement, update, remove;
	
		if (options.singleton) {
			var styleIndex = singletonCounter++;
			styleElement = singletonElement || (singletonElement = createStyleElement(options));
			update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
			remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
		} else if(obj.sourceMap &&
			typeof URL === "function" &&
			typeof URL.createObjectURL === "function" &&
			typeof URL.revokeObjectURL === "function" &&
			typeof Blob === "function" &&
			typeof btoa === "function") {
			styleElement = createLinkElement(options);
			update = updateLink.bind(null, styleElement);
			remove = function() {
				removeStyleElement(styleElement);
				if(styleElement.href)
					URL.revokeObjectURL(styleElement.href);
			};
		} else {
			styleElement = createStyleElement(options);
			update = applyToTag.bind(null, styleElement);
			remove = function() {
				removeStyleElement(styleElement);
			};
		}
	
		update(obj);
	
		return function updateStyle(newObj) {
			if(newObj) {
				if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
					return;
				update(obj = newObj);
			} else {
				remove();
			}
		};
	}
	
	var replaceText = (function () {
		var textStore = [];
	
		return function (index, replacement) {
			textStore[index] = replacement;
			return textStore.filter(Boolean).join('\n');
		};
	})();
	
	function applyToSingletonTag(styleElement, index, remove, obj) {
		var css = remove ? "" : obj.css;
	
		if (styleElement.styleSheet) {
			styleElement.styleSheet.cssText = replaceText(index, css);
		} else {
			var cssNode = document.createTextNode(css);
			var childNodes = styleElement.childNodes;
			if (childNodes[index]) styleElement.removeChild(childNodes[index]);
			if (childNodes.length) {
				styleElement.insertBefore(cssNode, childNodes[index]);
			} else {
				styleElement.appendChild(cssNode);
			}
		}
	}
	
	function applyToTag(styleElement, obj) {
		var css = obj.css;
		var media = obj.media;
	
		if(media) {
			styleElement.setAttribute("media", media)
		}
	
		if(styleElement.styleSheet) {
			styleElement.styleSheet.cssText = css;
		} else {
			while(styleElement.firstChild) {
				styleElement.removeChild(styleElement.firstChild);
			}
			styleElement.appendChild(document.createTextNode(css));
		}
	}
	
	function updateLink(linkElement, obj) {
		var css = obj.css;
		var sourceMap = obj.sourceMap;
	
		if(sourceMap) {
			// http://stackoverflow.com/a/26603875
			css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
		}
	
		var blob = new Blob([css], { type: "text/css" });
	
		var oldSrc = linkElement.href;
	
		linkElement.href = URL.createObjectURL(blob);
	
		if(oldSrc)
			URL.revokeObjectURL(oldSrc);
	}


/***/ },
/* 13 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(setImmediate) {/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var phosphor_queue_1 = __webpack_require__(16);
	/**
	 * A message which can be sent or posted to a message handler.
	 *
	 * #### Notes
	 * This class may be subclassed to create complex message types.
	 *
	 * **See Also** [[postMessage]] and [[sendMessage]].
	 */
	var Message = (function () {
	    /**
	     * Construct a new message.
	     *
	     * @param type - The type of the message. Consumers of a message will
	     *   use this value to cast the message to the appropriately derived
	     *   message type.
	     */
	    function Message(type) {
	        this._type = type;
	    }
	    Object.defineProperty(Message.prototype, "type", {
	        /**
	         * Get the type of the message.
	         */
	        get: function () {
	            return this._type;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return Message;
	})();
	exports.Message = Message;
	/**
	 * Send a message to the message handler to process immediately.
	 *
	 * @param handler - The handler which should process the message.
	 *
	 * @param msg - The message to send to the handler.
	 *
	 * #### Notes
	 * Unlike [[postMessage]], [[sendMessage]] delivers the message to
	 * the handler immediately. The handler will not have the opportunity
	 * to compress the message, however the message will still be sent
	 * through any installed message filters.
	 *
	 * **See Also** [[postMessage]].
	 */
	function sendMessage(handler, msg) {
	    getDispatcher(handler).sendMessage(handler, msg);
	}
	exports.sendMessage = sendMessage;
	/**
	 * Post a message to the 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
	 * Unlike [[sendMessage]], [[postMessage]] will schedule the deliver of
	 * the message for the next cycle of the event loop. The handler will
	 * have the opportunity to compress the message in order to optimize
	 * its handling of similar messages. The message will be sent through
	 * any installed message filters before being delivered to the handler.
	 *
	 * **See Also** [[sendMessage]].
	 */
	function postMessage(handler, msg) {
	    getDispatcher(handler).postMessage(handler, msg);
	}
	exports.postMessage = postMessage;
	/**
	 * Test whether a message handler has posted messages pending delivery.
	 *
	 * @param handler - The message handler of interest.
	 *
	 * @returns `true` if the handler has pending posted messages, `false`
	 *   otherwise.
	 *
	 * **See Also** [[sendPendingMessage]].
	 */
	function hasPendingMessages(handler) {
	    return getDispatcher(handler).hasPendingMessages();
	}
	exports.hasPendingMessages = hasPendingMessages;
	/**
	 * Send the first pending posted message to the message handler.
	 *
	 * @param handler - The message handler of interest.
	 *
	 * #### Notes
	 * If the handler has no pending messages, this is a no-op.
	 *
	 * **See Also** [[hasPendingMessages]].
	 */
	function sendPendingMessage(handler) {
	    getDispatcher(handler).sendPendingMessage(handler);
	}
	exports.sendPendingMessage = sendPendingMessage;
	/**
	 * Install a message filter for a message handler.
	 *
	 * A message filter is invoked before the message handler processes a
	 * message. If the filter returns `true` from its [[filterMessage]] method,
	 * no other filters will be invoked, and the message will not be delivered.
	 *
	 * The most recently installed message filter is executed first.
	 *
	 * @param handler - The handler whose messages should be filtered.
	 *
	 * @param filter - The filter to install for the handler.
	 *
	 * #### Notes
	 * It is possible to install the same filter multiple times. If the
	 * filter should be unique, call [[removeMessageFilter]] first.
	 *
	 * **See Also** [[removeMessageFilter]].
	 */
	function installMessageFilter(handler, filter) {
	    getDispatcher(handler).installMessageFilter(filter);
	}
	exports.installMessageFilter = installMessageFilter;
	/**
	 * Remove a previously installed message filter for a message handler.
	 *
	 * @param handler - The handler for which the filter is installed.
	 *
	 * @param filter - The filter to remove.
	 *
	 * #### Notes
	 * This will remove **all** occurrences of the filter. If the filter is
	 * not installed, this is a no-op.
	 *
	 * It is safe to call this function while the filter is executing.
	 *
	 * **See Also** [[installMessageFilter]].
	 */
	function removeMessageFilter(handler, filter) {
	    getDispatcher(handler).removeMessageFilter(filter);
	}
	exports.removeMessageFilter = removeMessageFilter;
	/**
	 * Clear all message data associated with the message handler.
	 *
	 * @param handler - The message handler for which to clear the data.
	 *
	 * #### Notes
	 * This will remove all pending messages and filters for the handler.
	 */
	function clearMessageData(handler) {
	    var dispatcher = dispatcherMap.get(handler);
	    if (dispatcher)
	        dispatcher.clear();
	    dispatchQueue.removeAll(handler);
	}
	exports.clearMessageData = clearMessageData;
	/**
	 * The internal mapping of message handler to message dispatcher
	 */
	var dispatcherMap = new WeakMap();
	/**
	 * The internal queue of pending message handlers.
	 */
	var dispatchQueue = new phosphor_queue_1.Queue();
	/**
	 * The internal animation frame id for the message loop wake up call.
	 */
	var frameId = void 0;
	/**
	 * A local reference to an event loop hook.
	 */
	var raf;
	if (typeof requestAnimationFrame === 'function') {
	    raf = requestAnimationFrame;
	}
	else {
	    raf = setImmediate;
	}
	/**
	 * Get or create the message dispatcher for a message handler.
	 */
	function getDispatcher(handler) {
	    var dispatcher = dispatcherMap.get(handler);
	    if (dispatcher)
	        return dispatcher;
	    dispatcher = new MessageDispatcher();
	    dispatcherMap.set(handler, dispatcher);
	    return dispatcher;
	}
	/**
	 * Wake up the message loop to process any pending dispatchers.
	 *
	 * This is a no-op if a wake up is not needed or is already pending.
	 */
	function wakeUpMessageLoop() {
	    if (frameId === void 0 && !dispatchQueue.empty) {
	        frameId = raf(runMessageLoop);
	    }
	}
	/**
	 * Run an iteration of the message loop.
	 *
	 * This will process all pending dispatchers in the queue. Dispatchers
	 * which are added to the queue while the message loop is running will
	 * be processed on the next message loop cycle.
	 */
	function runMessageLoop() {
	    // Clear the frame id so the next wake up call can be scheduled.
	    frameId = void 0;
	    // If the queue is empty, there is nothing else to do.
	    if (dispatchQueue.empty) {
	        return;
	    }
	    // Add a null sentinel value to the end of the queue. The queue
	    // will only be processed up to the first null value. This means
	    // that messages posted during this cycle will execute on the next
	    // cycle of the loop.
	    dispatchQueue.push(null);
	    // The message dispatch loop. If the dispatcher is the null sentinel,
	    // the processing of the current block of messages is complete and
	    // another loop is scheduled. Otherwise, the pending message is
	    // dispatched to the message handler.
	    while (!dispatchQueue.empty) {
	        var handler = dispatchQueue.pop();
	        if (handler === null) {
	            wakeUpMessageLoop();
	            return;
	        }
	        getDispatcher(handler).sendPendingMessage(handler);
	    }
	}
	/**
	 * Safely process a message for a message handler.
	 *
	 * If the handler throws an exception, it will be caught and logged.
	 */
	function safeProcess(handler, msg) {
	    try {
	        handler.processMessage(msg);
	    }
	    catch (err) {
	        console.error(err);
	    }
	}
	/**
	 * Safely compress a message for a message handler.
	 *
	 * If the handler throws an exception, it will be caught and logged.
	 */
	function safeCompress(handler, msg, queue) {
	    var result = false;
	    try {
	        result = handler.compressMessage(msg, queue);
	    }
	    catch (err) {
	        console.error(err);
	    }
	    return result;
	}
	/**
	 * Safely filter a message for a message handler.
	 *
	 * If the filter throws an exception, it will be caught and logged.
	 */
	function safeFilter(filter, handler, msg) {
	    var result = false;
	    try {
	        result = filter.filterMessage(handler, msg);
	    }
	    catch (err) {
	        console.error(err);
	    }
	    return result;
	}
	/**
	 * An internal class which manages message dispatching for a handler.
	 */
	var MessageDispatcher = (function () {
	    function MessageDispatcher() {
	        this._filters = null;
	        this._messages = null;
	    }
	    /**
	     * Send a message to the handler immediately.
	     *
	     * The message will first be sent through installed filters.
	     */
	    MessageDispatcher.prototype.sendMessage = function (handler, msg) {
	        if (!this._filterMessage(handler, msg)) {
	            safeProcess(handler, msg);
	        }
	    };
	    /**
	     * Post a message for delivery in the future.
	     *
	     * The message will first be compressed if possible.
	     */
	    MessageDispatcher.prototype.postMessage = function (handler, msg) {
	        if (!this._compressMessage(handler, msg)) {
	            this._enqueueMessage(handler, msg);
	        }
	    };
	    /**
	     * Test whether the dispatcher has messages pending delivery.
	     */
	    MessageDispatcher.prototype.hasPendingMessages = function () {
	        return !!(this._messages && !this._messages.empty);
	    };
	    /**
	     * Send the first pending message to the message handler.
	     */
	    MessageDispatcher.prototype.sendPendingMessage = function (handler) {
	        if (this._messages && !this._messages.empty) {
	            this.sendMessage(handler, this._messages.pop());
	        }
	    };
	    /**
	     * Install a message filter for the dispatcher.
	     */
	    MessageDispatcher.prototype.installMessageFilter = function (filter) {
	        this._filters = { next: this._filters, filter: filter };
	    };
	    /**
	     * Remove all occurrences of a message filter from the dispatcher.
	     */
	    MessageDispatcher.prototype.removeMessageFilter = function (filter) {
	        var link = this._filters;
	        var prev = null;
	        while (link !== null) {
	            if (link.filter === filter) {
	                link.filter = null;
	            }
	            else if (prev === null) {
	                this._filters = link;
	                prev = link;
	            }
	            else {
	                prev.next = link;
	                prev = link;
	            }
	            link = link.next;
	        }
	        if (!prev) {
	            this._filters = null;
	        }
	        else {
	            prev.next = null;
	        }
	    };
	    /**
	     * Clear all messages and filters from the dispatcher.
	     */
	    MessageDispatcher.prototype.clear = function () {
	        if (this._messages) {
	            this._messages.clear();
	        }
	        for (var link = this._filters; link !== null; link = link.next) {
	            link.filter = null;
	        }
	        this._filters = null;
	    };
	    /**
	     * Run the installed message filters for the handler.
	     *
	     * Returns `true` if the message was filtered, `false` otherwise.
	     */
	    MessageDispatcher.prototype._filterMessage = function (handler, msg) {
	        for (var link = this._filters; link !== null; link = link.next) {
	            if (link.filter && safeFilter(link.filter, handler, msg)) {
	                return true;
	            }
	        }
	        return false;
	    };
	    /**
	     * Compress the mssage for the given handler.
	     *
	     * Returns `true` if the message was compressed, `false` otherwise.
	     */
	    MessageDispatcher.prototype._compressMessage = function (handler, msg) {
	        if (!handler.compressMessage) {
	            return false;
	        }
	        if (!this._messages || this._messages.empty) {
	            return false;
	        }
	        return safeCompress(handler, msg, this._messages);
	    };
	    /**
	     * Enqueue the message for future delivery to the handler.
	     */
	    MessageDispatcher.prototype._enqueueMessage = function (handler, msg) {
	        this._ensureMessages().push(msg);
	        dispatchQueue.push(handler);
	        wakeUpMessageLoop();
	    };
	    /**
	     * Get the internal message queue, creating it if needed.
	     */
	    MessageDispatcher.prototype._ensureMessages = function () {
	        return this._messages || (this._messages = new phosphor_queue_1.Queue());
	    };
	    return MessageDispatcher;
	})();
	//# sourceMappingURL=index.js.map
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(14).setImmediate))

/***/ },
/* 14 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(setImmediate, clearImmediate) {var nextTick = __webpack_require__(15).nextTick;
	var apply = Function.prototype.apply;
	var slice = Array.prototype.slice;
	var immediateIds = {};
	var nextImmediateId = 0;
	
	// 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) { 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);
	  }
	};
	
	// That's not how node.js implements it but the exposed api is the same.
	exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) {
	  var id = nextImmediateId++;
	  var args = arguments.length < 2 ? false : slice.call(arguments, 1);
	
	  immediateIds[id] = true;
	
	  nextTick(function onNextTick() {
	    if (immediateIds[id]) {
	      // fn.call() is faster so we optimize for the common use-case
	      // @see http://jsperf.com/call-apply-segu
	      if (args) {
	        fn.apply(null, args);
	      } else {
	        fn.call(null);
	      }
	      // Prevent ids from leaking
	      exports.clearImmediate(id);
	    }
	  });
	
	  return id;
	};
	
	exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) {
	  delete immediateIds[id];
	};
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(14).setImmediate, __webpack_require__(14).clearImmediate))

/***/ },
/* 15 */
/***/ function(module, exports) {

	// shim for using process in browser
	
	var process = module.exports = {};
	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 = setTimeout(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;
	    clearTimeout(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) {
	        setTimeout(drainQueue, 0);
	    }
	};
	
	// 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.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; };


/***/ },
/* 16 */
/***/ function(module, exports) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	/**
	 * A generic FIFO queue data structure.
	 *
	 * #### Notes
	 * This queue is implemented internally using a singly linked list and
	 * can grow to arbitrary size.
	 *
	 * #### Example
	 * ```typescript
	 * let q = new Queue<number>([0, 1, 2]);
	 * q.size;      // 3
	 * q.empty;     // false
	 * q.pop();     // 0
	 * q.pop();     // 1
	 * q.push(42);  // undefined
	 * q.size;      // 2
	 * q.pop();     // 2
	 * q.pop();     // 42
	 * q.pop();     // undefined
	 * q.size;      // 0
	 * q.empty;     // true
	 * ```
	 */
	var Queue = (function () {
	    /**
	     * Construct a new queue.
	     *
	     * @param items - The initial items for the queue.
	     */
	    function Queue(items) {
	        var _this = this;
	        this._size = 0;
	        this._front = null;
	        this._back = null;
	        if (items)
	            items.forEach(function (item) { return _this.push(item); });
	    }
	    Object.defineProperty(Queue.prototype, "size", {
	        /**
	         * Get the number of elements in the queue.
	         *
	         * #### Notes
	         * This has `O(1)` complexity.
	         */
	        get: function () {
	            return this._size;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Queue.prototype, "empty", {
	        /**
	         * Test whether the queue is empty.
	         *
	         * #### Notes
	         * This has `O(1)` complexity.
	         */
	        get: function () {
	            return this._size === 0;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Queue.prototype, "front", {
	        /**
	         * Get the value at the front of the queue.
	         *
	         * #### Notes
	         * This has `O(1)` complexity.
	         *
	         * If the queue is empty, this value will be `undefined`.
	         */
	        get: function () {
	            return this._front !== null ? this._front.value : void 0;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Queue.prototype, "back", {
	        /**
	         * Get the value at the back of the queue.
	         *
	         * #### Notes
	         * This has `O(1)` complexity.
	         *
	         * If the queue is empty, this value will be `undefined`.
	         */
	        get: function () {
	            return this._back !== null ? this._back.value : void 0;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Push a value onto the back of the queue.
	     *
	     * @param value - The value to add to the queue.
	     *
	     * #### Notes
	     * This has `O(1)` complexity.
	     */
	    Queue.prototype.push = function (value) {
	        var link = { next: null, value: value };
	        if (this._back === null) {
	            this._front = link;
	            this._back = link;
	        }
	        else {
	            this._back.next = link;
	            this._back = link;
	        }
	        this._size++;
	    };
	    /**
	     * Pop and return the value at the front of the queue.
	     *
	     * @returns The value at the front of the queue.
	     *
	     * #### Notes
	     * This has `O(1)` complexity.
	     *
	     * If the queue is empty, the return value will be `undefined`.
	     */
	    Queue.prototype.pop = function () {
	        var link = this._front;
	        if (link === null) {
	            return void 0;
	        }
	        if (link.next === null) {
	            this._front = null;
	            this._back = null;
	        }
	        else {
	            this._front = link.next;
	        }
	        this._size--;
	        return link.value;
	    };
	    /**
	     * Remove the first occurrence of a value from the queue.
	     *
	     * @param value - The value to remove from the queue.
	     *
	     * @returns `true` on success, `false` otherwise.
	     *
	     * #### Notes
	     * This has `O(N)` complexity.
	     */
	    Queue.prototype.remove = function (value) {
	        var link = this._front;
	        var prev = null;
	        while (link !== null) {
	            if (link.value === value) {
	                if (prev === null) {
	                    this._front = link.next;
	                }
	                else {
	                    prev.next = link.next;
	                }
	                if (link.next === null) {
	                    this._back = prev;
	                }
	                this._size--;
	                return true;
	            }
	            prev = link;
	            link = link.next;
	        }
	        return false;
	    };
	    /**
	     * Remove all occurrences of a value from the queue.
	     *
	     * @param value - The value to remove from the queue.
	     *
	     * @returns The number of occurrences removed.
	     *
	     * #### Notes
	     * This has `O(N)` complexity.
	     */
	    Queue.prototype.removeAll = function (value) {
	        var count = 0;
	        var link = this._front;
	        var prev = null;
	        while (link !== null) {
	            if (link.value === value) {
	                count++;
	                this._size--;
	            }
	            else if (prev === null) {
	                this._front = link;
	                prev = link;
	            }
	            else {
	                prev.next = link;
	                prev = link;
	            }
	            link = link.next;
	        }
	        if (!prev) {
	            this._front = null;
	            this._back = null;
	        }
	        else {
	            prev.next = null;
	            this._back = prev;
	        }
	        return count;
	    };
	    /**
	     * Remove all values from the queue.
	     *
	     * #### Notes
	     * This has `O(1)` complexity.
	     */
	    Queue.prototype.clear = function () {
	        this._size = 0;
	        this._front = null;
	        this._back = null;
	    };
	    /**
	     * Create an array from the values in the queue.
	     *
	     * @returns An array of all values in the queue.
	     *
	     * #### Notes
	     * This has `O(N)` complexity.
	     */
	    Queue.prototype.toArray = function () {
	        var result = new Array(this._size);
	        for (var i = 0, link = this._front; link !== null; link = link.next, ++i) {
	            result[i] = link.value;
	        }
	        return result;
	    };
	    /**
	     * Test whether any value in the queue passes a predicate function.
	     *
	     * @param pred - The predicate to apply to the values.
	     *
	     * @returns `true` if any value in the queue passes the predicate,
	     *   or `false` otherwise.
	     *
	     * #### Notes
	     * This has `O(N)` complexity.
	     *
	     * It is **not** safe for the predicate to modify the queue while
	     * iterating.
	     */
	    Queue.prototype.some = function (pred) {
	        for (var i = 0, link = this._front; link !== null; link = link.next, ++i) {
	            if (pred(link.value, i))
	                return true;
	        }
	        return false;
	    };
	    /**
	     * Test whether all values in the queue pass a predicate function.
	     *
	     * @param pred - The predicate to apply to the values.
	     *
	     * @returns `true` if all values in the queue pass the predicate,
	     *   or `false` otherwise.
	     *
	     * #### Notes
	     * This has `O(N)` complexity.
	     *
	     * It is **not** safe for the predicate to modify the queue while
	     * iterating.
	     */
	    Queue.prototype.every = function (pred) {
	        for (var i = 0, link = this._front; link !== null; link = link.next, ++i) {
	            if (!pred(link.value, i))
	                return false;
	        }
	        return true;
	    };
	    /**
	     * Create an array of the values which pass a predicate function.
	     *
	     * @param pred - The predicate to apply to the values.
	     *
	     * @returns The array of values which pass the predicate.
	     *
	     * #### Notes
	     * This has `O(N)` complexity.
	     *
	     * It is **not** safe for the predicate to modify the queue while
	     * iterating.
	     */
	    Queue.prototype.filter = function (pred) {
	        var result = [];
	        for (var i = 0, link = this._front; link !== null; link = link.next, ++i) {
	            if (pred(link.value, i))
	                result.push(link.value);
	        }
	        return result;
	    };
	    /**
	     * Create an array of mapped values for the values in the queue.
	     *
	     * @param callback - The map function to apply to the values.
	     *
	     * @returns The array of values returned by the map function.
	     *
	     * #### Notes
	     * This has `O(N)` complexity.
	     *
	     * It is **not** safe for the callback to modify the queue while
	     * iterating.
	     */
	    Queue.prototype.map = function (callback) {
	        var result = new Array(this._size);
	        for (var i = 0, link = this._front; link !== null; link = link.next, ++i) {
	            result[i] = callback(link.value, i);
	        }
	        return result;
	    };
	    /**
	     * Execute a callback for each value in the queue.
	     *
	     * @param callback - The function to apply to the values.
	     *
	     * @returns The first value returned by the callback which is not
	     *   `undefined`.
	     *
	     * #### Notes
	     * This has `O(N)` complexity.
	     *
	     * Iteration will terminate immediately if the callback returns any
	     * value other than `undefined`.
	     *
	     * It is **not** safe for the callback to modify the queue while
	     * iterating.
	     */
	    Queue.prototype.forEach = function (callback) {
	        for (var i = 0, link = this._front; link !== null; link = link.next, ++i) {
	            var result = callback(link.value, i);
	            if (result !== void 0)
	                return result;
	        }
	        return void 0;
	    };
	    return Queue;
	})();
	exports.Queue = Queue;
	//# sourceMappingURL=index.js.map

/***/ },
/* 17 */
/***/ function(module, exports) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	/**
	 * A property descriptor for a datum belonging to an object.
	 *
	 * Property descriptors can be used to expose a rich interface for an
	 * object which encapsulates value creation, coercion, and notification.
	 * They can also be used to extend the state of an object with semantic
	 * data from an unrelated class.
	 */
	var Property = (function () {
	    /**
	     * Construct a new property descriptor.
	     *
	     * @param options - The options for initializing the property.
	     */
	    function Property(options) {
	        this._pid = nextPID();
	        this._name = options.name;
	        this._value = options.value;
	        this._create = options.create;
	        this._coerce = options.coerce;
	        this._compare = options.compare;
	        this._changed = options.changed;
	        this._notify = options.notify;
	    }
	    Object.defineProperty(Property.prototype, "name", {
	        /**
	         * Get the human readable name for the property.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._name;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Property.prototype, "notify", {
	        /**
	         * Get the notify signal for the property.
	         *
	         * #### Notes
	         * This will be `undefined` if no notify signal was provided.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._notify;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * 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.
	     */
	    Property.prototype.get = function (owner) {
	        var value;
	        var hash = lookupHash(owner);
	        if (this._pid in hash) {
	            value = hash[this._pid];
	        }
	        else {
	            value = hash[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.
	     */
	    Property.prototype.set = function (owner, value) {
	        var oldValue;
	        var hash = lookupHash(owner);
	        if (this._pid in hash) {
	            oldValue = hash[this._pid];
	        }
	        else {
	            oldValue = hash[this._pid] = this._createValue(owner);
	        }
	        var newValue = this._coerceValue(owner, value);
	        this._maybeNotify(owner, oldValue, hash[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.
	     */
	    Property.prototype.coerce = function (owner) {
	        var oldValue;
	        var hash = lookupHash(owner);
	        if (this._pid in hash) {
	            oldValue = hash[this._pid];
	        }
	        else {
	            oldValue = hash[this._pid] = this._createValue(owner);
	        }
	        var newValue = this._coerceValue(owner, oldValue);
	        this._maybeNotify(owner, oldValue, hash[this._pid] = newValue);
	    };
	    /**
	     * Get or create the default value for the given owner.
	     */
	    Property.prototype._createValue = function (owner) {
	        var create = this._create;
	        return create ? create(owner) : this._value;
	    };
	    /**
	     * Coerce the value for the given owner.
	     */
	    Property.prototype._coerceValue = function (owner, value) {
	        var coerce = this._coerce;
	        return coerce ? coerce(owner, value) : value;
	    };
	    /**
	     * Compare the old value and new value for equality.
	     */
	    Property.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.
	     */
	    Property.prototype._maybeNotify = function (owner, oldValue, newValue) {
	        var changed = this._changed;
	        var notify = this._notify;
	        if (!changed && !notify) {
	            return;
	        }
	        if (this._compareValue(oldValue, newValue)) {
	            return;
	        }
	        if (changed) {
	            changed(owner, oldValue, newValue);
	        }
	        if (notify) {
	            notify.bind(owner).emit({ name: this._name, oldValue: oldValue, newValue: newValue });
	        }
	    };
	    return Property;
	})();
	exports.Property = Property;
	/**
	 * Clear the stored property data for the given property 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 clearPropertyData(owner) {
	    ownerData.delete(owner);
	}
	exports.clearPropertyData = clearPropertyData;
	/**
	 * A weak mapping of property owner to property hash.
	 */
	var ownerData = new WeakMap();
	/**
	 * A function which computes successive unique property ids.
	 */
	var nextPID = (function () { var id = 0; return function () { return 'pid-' + id++; }; })();
	/**
	 * Lookup the data hash for the property owner.
	 *
	 * This will create the hash if one does not already exist.
	 */
	function lookupHash(owner) {
	    var hash = ownerData.get(owner);
	    if (hash !== void 0)
	        return hash;
	    hash = Object.create(null);
	    ownerData.set(owner, hash);
	    return hash;
	}
	//# sourceMappingURL=index.js.map

/***/ },
/* 18 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	__export(__webpack_require__(19));
	__export(__webpack_require__(28));


/***/ },
/* 19 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var arrays = __webpack_require__(3);
	var phosphor_messaging_1 = __webpack_require__(13);
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * 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() {
	        _super.apply(this, arguments);
	        this._children = [];
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     *
	     * #### Notes
	     * This will dispose all current child widgets of the layout.
	     */
	    PanelLayout.prototype.dispose = function () {
	        while (this._children.length > 0) {
	            this._children.pop().dispose();
	        }
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Get the number of child widgets in the layout.
	     *
	     * @returns The number of child widgets in the layout.
	     */
	    PanelLayout.prototype.childCount = function () {
	        return this._children.length;
	    };
	    /**
	     * Get the child widget at the specified index.
	     *
	     * @param index - The index of the child widget of interest.
	     *
	     * @returns The child at the specified index, or `undefined`.
	     */
	    PanelLayout.prototype.childAt = function (index) {
	        return this._children[index];
	    };
	    /**
	     * Add a child widget to the end of the layout.
	     *
	     * @param child - The child widget to add to the layout.
	     *
	     * #### Notes
	     * If the child is already contained in the layout, it will be moved.
	     */
	    PanelLayout.prototype.addChild = function (child) {
	        this.insertChild(this.childCount(), child);
	    };
	    /**
	     * Insert a child widget into the layout at the specified index.
	     *
	     * @param index - The index at which to insert the child widget.
	     *
	     * @param child - The child widget to insert into the layout.
	     *
	     * #### Notes
	     * If the child is already contained in the layout, it will be moved.
	     */
	    PanelLayout.prototype.insertChild = function (index, child) {
	        child.parent = this.parent;
	        var n = this._children.length;
	        var i = this._children.indexOf(child);
	        var j = Math.max(0, Math.min(index | 0, n));
	        if (i !== -1) {
	            if (j === n)
	                j--;
	            if (i === j)
	                return;
	            arrays.move(this._children, i, j);
	            if (this.parent)
	                this.moveChild(i, j, child);
	        }
	        else {
	            arrays.insert(this._children, j, child);
	            if (this.parent)
	                this.attachChild(j, child);
	        }
	    };
	    /**
	     * Remove a child widget from the layout.
	     *
	     * @param child - The child widget to remove from the layout.
	     *
	     * #### Notes
	     * A child widget will be removed from the layout automatically 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`.
	     *
	     * If the child is not contained in the layout, this is a no-op.
	     */
	    PanelLayout.prototype.removeChild = function (child) {
	        var i = arrays.remove(this._children, child);
	        if (i !== -1 && this.parent)
	            this.detachChild(i, child);
	    };
	    /**
	     * Initialize the children of the layout.
	     *
	     * #### Notes
	     * This method is called automatically when the layout is installed
	     * on its parent widget.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    PanelLayout.prototype.initialize = function () {
	        for (var i = 0; i < this.childCount(); ++i) {
	            var child = this.childAt(i);
	            child.parent = this.parent;
	            this.attachChild(i, child);
	        }
	    };
	    /**
	     * Attach a child widget to the parent's DOM node.
	     *
	     * @param index - The current index of the child in the layout.
	     *
	     * @param child - The child 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 child's node to the parent's
	     * node at the proper location, and sends an `'after-attach'` message
	     * to the child if the parent is attached to the DOM.
	     *
	     * Subclasses may reimplement this method to control how the child's
	     * node is added to the parent's node, but the reimplementation must
	     * send an `'after-attach'` message to the child if the parent is
	     * attached to the DOM.
	     */
	    PanelLayout.prototype.attachChild = function (index, child) {
	        var ref = this.parent.node.children[index];
	        this.parent.node.insertBefore(child.node, ref);
	        if (this.parent.isAttached)
	            phosphor_messaging_1.sendMessage(child, phosphor_widget_1.Widget.MsgAfterAttach);
	    };
	    /**
	     * Move a child widget in the parent's DOM node.
	     *
	     * @param fromIndex - The previous index of the child in the layout.
	     *
	     * @param toIndex - The current index of the child in the layout.
	     *
	     * @param child - The child 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 child's node to the proper
	     * location in the parent's node and sends both a `'before-detach'`
	     * and an `'after-attach'` message to the child if the parent is
	     * attached to the DOM.
	     *
	     * Subclasses may reimplement this method to control how the child's
	     * node is moved in the parent's node, but the reimplementation must
	     * send both a `'before-detach'` and an `'after-attach'` message to
	     * the child if the parent is attached to the DOM.
	     */
	    PanelLayout.prototype.moveChild = function (fromIndex, toIndex, child) {
	        if (this.parent.isAttached)
	            phosphor_messaging_1.sendMessage(child, phosphor_widget_1.Widget.MsgBeforeDetach);
	        this.parent.node.removeChild(child.node);
	        var ref = this.parent.node.children[toIndex];
	        this.parent.node.insertBefore(child.node, ref);
	        if (this.parent.isAttached)
	            phosphor_messaging_1.sendMessage(child, phosphor_widget_1.Widget.MsgAfterAttach);
	    };
	    /**
	     * Detach a child widget from the parent's DOM node.
	     *
	     * @param index - The previous index of the child in the layout.
	     *
	     * @param child - The child 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 child's node from the
	     * parent's node, and sends a `'before-detach'` message to the child
	     * if the parent is attached to the DOM.
	     *
	     * Subclasses may reimplement this method to control how the child's
	     * node is removed from the parent's node, but the reimplementation
	     * must send a `'before-detach'` message to the child if the parent
	     * is attached to the DOM.
	     */
	    PanelLayout.prototype.detachChild = function (index, child) {
	        if (this.parent.isAttached)
	            phosphor_messaging_1.sendMessage(child, phosphor_widget_1.Widget.MsgBeforeDetach);
	        this.parent.node.removeChild(child.node);
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     *
	     * #### Notes
	     * This will remove the child from the layout.
	     *
	     * Subclasses should **not** typically reimplement this method.
	     */
	    PanelLayout.prototype.onChildRemoved = function (msg) {
	        this.removeChild(msg.child);
	    };
	    return PanelLayout;
	})(phosphor_widget_1.AbstractLayout);
	exports.PanelLayout = PanelLayout;


/***/ },
/* 20 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	__export(__webpack_require__(21));
	__export(__webpack_require__(25));
	__export(__webpack_require__(23));
	__webpack_require__(26);


/***/ },
/* 21 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_messaging_1 = __webpack_require__(13);
	var phosphor_properties_1 = __webpack_require__(17);
	var phosphor_signaling_1 = __webpack_require__(22);
	var widget_1 = __webpack_require__(23);
	/**
	 * The abstract base class of all Phosphor layouts.
	 *
	 * #### Notes
	 * A layout is used to add child widgets to a parent and to arrange
	 * those children within the parent's node.
	 *
	 * This class must be subclassed to make a fully functioning layout.
	 */
	var Layout = (function () {
	    function Layout() {
	        this._disposed = false;
	        this._parent = null;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     *
	     * #### Notes
	     * This method should be reimplemented by subclasses to dispose their
	     * children. All reimplementations should call the superclass method.
	     */
	    Layout.prototype.dispose = function () {
	        this._disposed = true;
	        this._parent = null;
	        phosphor_signaling_1.clearSignalData(this);
	        phosphor_properties_1.clearPropertyData(this);
	    };
	    Object.defineProperty(Layout.prototype, "isDisposed", {
	        /**
	         * Test whether the layout is disposed.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        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 layout parent should not be set directly by user code.
	         */
	        set: function (value) {
	            if (!value) {
	                throw new Error('Cannot set layout parent to null.');
	            }
	            if (this._parent === value) {
	                return;
	            }
	            if (this._parent) {
	                throw new Error('Cannot change layout parent.');
	            }
	            if (value.layout !== this) {
	                throw new Error('Invalid layout parent.');
	            }
	            this._parent = value;
	            this.initialize();
	        },
	        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 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 'after-attach':
	                this.onAfterAttach(msg);
	                break;
	            case 'before-detach':
	                this.onBeforeDetach(msg);
	                break;
	            case 'after-show':
	                this.onAfterShow(msg);
	                break;
	            case 'before-hide':
	                this.onBeforeHide(msg);
	                break;
	            case 'child-removed':
	                this.onChildRemoved(msg);
	                break;
	            case 'child-shown':
	                this.onChildShown(msg);
	                break;
	            case 'child-hidden':
	                this.onChildHidden(msg);
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     *
	     * The default implementation of this handler is a no-op.
	     */
	    Layout.prototype.onFitRequest = function (msg) { };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     *
	     * The default implementation of this handler is a no-op.
	     */
	    Layout.prototype.onChildShown = function (msg) { };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     *
	     * The default implementation of this handler is a no-op.
	     */
	    Layout.prototype.onChildHidden = function (msg) { };
	    return Layout;
	})();
	exports.Layout = Layout;
	/**
	 * An abstract base class for creating index-based layouts.
	 *
	 * #### Notes
	 * This class implements core functionality which is required by nearly
	 * all layouts. It is a good starting point for creating custom layouts
	 * which control the types of children that may be added to the layout.
	 *
	 * This class must be subclassed to make a fully functioning layout.
	 */
	var AbstractLayout = (function (_super) {
	    __extends(AbstractLayout, _super);
	    function AbstractLayout() {
	        _super.apply(this, arguments);
	    }
	    /**
	     * Get the index of the specified child widget.
	     *
	     * @param child - The child widget of interest.
	     *
	     * @returns The index of the specified child, or `-1`.
	     */
	    AbstractLayout.prototype.childIndex = function (child) {
	        for (var i = 0; i < this.childCount(); ++i) {
	            if (this.childAt(i) === child)
	                return i;
	        }
	        return -1;
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     *
	     * #### Notes
	     * The default implementation of this method sends an `UnknownSize`
	     * resize message to all children.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    AbstractLayout.prototype.onResize = function (msg) {
	        for (var i = 0; i < this.childCount(); ++i) {
	            phosphor_messaging_1.sendMessage(this.childAt(i), widget_1.ResizeMessage.UnknownSize);
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     *
	     * #### Notes
	     * The default implementation of this method sends an `UnknownSize`
	     * resize message to all children.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    AbstractLayout.prototype.onUpdateRequest = function (msg) {
	        for (var i = 0; i < this.childCount(); ++i) {
	            phosphor_messaging_1.sendMessage(this.childAt(i), widget_1.ResizeMessage.UnknownSize);
	        }
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message
	     * to all children.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    AbstractLayout.prototype.onAfterAttach = function (msg) {
	        for (var i = 0; i < this.childCount(); ++i) {
	            phosphor_messaging_1.sendMessage(this.childAt(i), msg);
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message
	     * to all children.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    AbstractLayout.prototype.onBeforeDetach = function (msg) {
	        for (var i = 0; i < this.childCount(); ++i) {
	            phosphor_messaging_1.sendMessage(this.childAt(i), msg);
	        }
	    };
	    /**
	     * A message handler invoked on an `'after-show'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message
	     * to all non-hidden children.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    AbstractLayout.prototype.onAfterShow = function (msg) {
	        for (var i = 0; i < this.childCount(); ++i) {
	            var child = this.childAt(i);
	            if (!child.isHidden)
	                phosphor_messaging_1.sendMessage(child, msg);
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-hide'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message
	     * to all non-hidden children.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    AbstractLayout.prototype.onBeforeHide = function (msg) {
	        for (var i = 0; i < this.childCount(); ++i) {
	            var child = this.childAt(i);
	            if (!child.isHidden)
	                phosphor_messaging_1.sendMessage(child, msg);
	        }
	    };
	    return AbstractLayout;
	})(Layout);
	exports.AbstractLayout = AbstractLayout;


/***/ },
/* 22 */
/***/ function(module, exports) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	/**
	 * An object used for type-safe inter-object communication.
	 *
	 * #### Notes
	 * Signals provide a type-safe implementation of the publish-subscribe
	 * pattern. An object (publisher) declares which signals it will emit,
	 * and consumers connect callbacks (subscribers) to those signals. The
	 * subscribers are invoked whenever the publisher emits the signal.
	 *
	 * A `Signal` object must be bound to a sender in order to be useful.
	 * A common pattern is to declare a `Signal` object as a static class
	 * member, along with a convenience getter which binds the signal to
	 * the `this` instance on-demand.
	 *
	 * #### Example
	 * ```typescript
	 * import { ISignal, Signal } from 'phosphor-signaling';
	 *
	 * class MyClass {
	 *
	 *   static valueChangedSignal = new Signal<MyClass, number>();
	 *
	 *   constructor(name: string) {
	 *     this._name = name;
	 *   }
	 *
	 *   get valueChanged(): ISignal<MyClass, number> {
	 *     return MyClass.valueChangedSignal.bind(this);
	 *   }
	 *
	 *   get name(): string {
	 *     return this._name;
	 *   }
	 *
	 *   get value(): number {
	 *     return this._value;
	 *   }
	 *
	 *   set value(value: number) {
	 *     if (value !== this._value) {
	 *       this._value = value;
	 *       this.valueChanged.emit(value);
	 *     }
	 *   }
	 *
	 *   private _name: string;
	 *   private _value = 0;
	 * }
	 *
	 * function logger(sender: MyClass, value: number): void {
	 *   console.log(sender.name, value);
	 * }
	 *
	 * let m1 = new MyClass('foo');
	 * let m2 = new MyClass('bar');
	 *
	 * m1.valueChanged.connect(logger);
	 * m2.valueChanged.connect(logger);
	 *
	 * m1.value = 42;  // logs: foo 42
	 * m2.value = 17;  // logs: bar 17
	 * ```
	 */
	var Signal = (function () {
	    function Signal() {
	    }
	    /**
	     * Bind the signal to a specific sender.
	     *
	     * @param sender - The sender object to bind to the signal.
	     *
	     * @returns The bound signal object which can be used for connecting,
	     *   disconnecting, and emitting the signal.
	     */
	    Signal.prototype.bind = function (sender) {
	        return new BoundSignal(this, sender);
	    };
	    return Signal;
	})();
	exports.Signal = Signal;
	/**
	 * Remove all connections where the given object is the sender.
	 *
	 * @param sender - The sender object of interest.
	 *
	 * #### Example
	 * ```typescript
	 * disconnectSender(someObject);
	 * ```
	 */
	function disconnectSender(sender) {
	    var list = senderMap.get(sender);
	    if (!list) {
	        return;
	    }
	    var conn = list.first;
	    while (conn !== null) {
	        removeFromSendersList(conn);
	        conn.callback = null;
	        conn.thisArg = null;
	        conn = conn.nextReceiver;
	    }
	    senderMap.delete(sender);
	}
	exports.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 `callback` is used as
	 * the receiver.
	 *
	 * #### Example
	 * ```typescript
	 * // disconnect a regular object receiver
	 * disconnectReceiver(myObject);
	 *
	 * // disconnect a plain callback receiver
	 * disconnectReceiver(myCallback);
	 * ```
	 */
	function disconnectReceiver(receiver) {
	    var conn = receiverMap.get(receiver);
	    if (!conn) {
	        return;
	    }
	    while (conn !== null) {
	        var next = conn.nextSender;
	        conn.callback = null;
	        conn.thisArg = null;
	        conn.prevSender = null;
	        conn.nextSender = null;
	        conn = next;
	    }
	    receiverMap.delete(receiver);
	}
	exports.disconnectReceiver = disconnectReceiver;
	/**
	 * Clear all signal data associated with the given object.
	 *
	 * @param obj - The object for which the signal data should be cleared.
	 *
	 * #### Notes
	 * This removes all signal connections where the object is used as
	 * either the sender or the receiver.
	 *
	 * #### Example
	 * ```typescript
	 * clearSignalData(someObject);
	 * ```
	 */
	function clearSignalData(obj) {
	    disconnectSender(obj);
	    disconnectReceiver(obj);
	}
	exports.clearSignalData = clearSignalData;
	/**
	 * A concrete implementation of ISignal.
	 */
	var BoundSignal = (function () {
	    /**
	     * Construct a new bound signal.
	     */
	    function BoundSignal(signal, sender) {
	        this._signal = signal;
	        this._sender = sender;
	    }
	    /**
	     * Connect a callback to the signal.
	     */
	    BoundSignal.prototype.connect = function (callback, thisArg) {
	        return connect(this._sender, this._signal, callback, thisArg);
	    };
	    /**
	     * Disconnect a callback from the signal.
	     */
	    BoundSignal.prototype.disconnect = function (callback, thisArg) {
	        return disconnect(this._sender, this._signal, callback, thisArg);
	    };
	    /**
	     * Emit the signal and invoke the connected callbacks.
	     */
	    BoundSignal.prototype.emit = function (args) {
	        emit(this._sender, this._signal, args);
	    };
	    return BoundSignal;
	})();
	/**
	 * A struct which holds connection data.
	 */
	var Connection = (function () {
	    function Connection() {
	        /**
	         * The signal for the connection.
	         */
	        this.signal = null;
	        /**
	         * The callback connected to the signal.
	         */
	        this.callback = null;
	        /**
	         * The `this` context for the callback.
	         */
	        this.thisArg = null;
	        /**
	         * The next connection in the singly linked receivers list.
	         */
	        this.nextReceiver = null;
	        /**
	         * The next connection in the doubly linked senders list.
	         */
	        this.nextSender = null;
	        /**
	         * The previous connection in the doubly linked senders list.
	         */
	        this.prevSender = null;
	    }
	    return Connection;
	})();
	/**
	 * The list of receiver connections for a specific sender.
	 */
	var ConnectionList = (function () {
	    function ConnectionList() {
	        /**
	         * The ref count for the list.
	         */
	        this.refs = 0;
	        /**
	         * The first connection in the list.
	         */
	        this.first = null;
	        /**
	         * The last connection in the list.
	         */
	        this.last = null;
	    }
	    return ConnectionList;
	})();
	/**
	 * A mapping of sender object to its receiver connection list.
	 */
	var senderMap = new WeakMap();
	/**
	 * A mapping of receiver object to its sender connection list.
	 */
	var receiverMap = new WeakMap();
	/**
	 * Create a connection between a sender, signal, and callback.
	 */
	function connect(sender, signal, callback, thisArg) {
	    // Coerce a `null` thisArg to `undefined`.
	    thisArg = thisArg || void 0;
	    // Search for an equivalent connection and bail if one exists.
	    var list = senderMap.get(sender);
	    if (list && findConnection(list, signal, callback, thisArg)) {
	        return false;
	    }
	    // Create a new connection.
	    var conn = new Connection();
	    conn.signal = signal;
	    conn.callback = callback;
	    conn.thisArg = thisArg;
	    // Add the connection to the receivers list.
	    if (!list) {
	        list = new ConnectionList();
	        list.first = conn;
	        list.last = conn;
	        senderMap.set(sender, list);
	    }
	    else if (list.last === null) {
	        list.first = conn;
	        list.last = conn;
	    }
	    else {
	        list.last.nextReceiver = conn;
	        list.last = conn;
	    }
	    // Add the connection to the senders list.
	    var receiver = thisArg || callback;
	    var head = receiverMap.get(receiver);
	    if (head) {
	        head.prevSender = conn;
	        conn.nextSender = head;
	    }
	    receiverMap.set(receiver, conn);
	    return true;
	}
	/**
	 * Break the connection between a sender, signal, and callback.
	 */
	function disconnect(sender, signal, callback, thisArg) {
	    // Coerce a `null` thisArg to `undefined`.
	    thisArg = thisArg || void 0;
	    // Search for an equivalent connection and bail if none exists.
	    var list = senderMap.get(sender);
	    if (!list) {
	        return false;
	    }
	    var conn = findConnection(list, signal, callback, thisArg);
	    if (!conn) {
	        return false;
	    }
	    // Remove the connection from the senders list. It will be removed
	    // from the receivers list the next time the signal is emitted.
	    removeFromSendersList(conn);
	    // Clear the connection data so it becomes a dead connection.
	    conn.callback = null;
	    conn.thisArg = null;
	    return true;
	}
	/**
	 * Emit a signal and invoke the connected callbacks.
	 */
	function emit(sender, signal, args) {
	    // If there is no connection list, there is nothing to do.
	    var list = senderMap.get(sender);
	    if (!list) {
	        return;
	    }
	    // Prepare to dispatch the callbacks. Increment the reference count
	    // on the list so that the list is cleaned only when the emit stack
	    // is fully unwound.
	    list.refs++;
	    var dirty = false;
	    var last = list.last;
	    var conn = list.first;
	    // Dispatch the callbacks. If a connection has a null callback, it
	    // indicates the list is dirty. Connections which match the signal
	    // are safely dispatched where all exceptions are logged. Dispatch
	    // is stopped at the last connection for the current stack frame.
	    while (conn !== null) {
	        if (!conn.callback) {
	            dirty = true;
	        }
	        else if (conn.signal === signal) {
	            safeInvoke(conn, sender, args);
	        }
	        if (conn === last) {
	            break;
	        }
	        conn = conn.nextReceiver;
	    }
	    // Decrement the reference count on the list.
	    list.refs--;
	    // Clean the list if it's dirty and the emit stack is fully unwound.
	    if (dirty && list.refs === 0) {
	        cleanList(list);
	    }
	}
	/**
	 * Safely invoke the callback for the given connection.
	 *
	 * Exceptions thrown by the callback will be caught and logged.
	 */
	function safeInvoke(conn, sender, args) {
	    try {
	        conn.callback.call(conn.thisArg, sender, args);
	    }
	    catch (err) {
	        console.error('Exception in signal handler:', err);
	    }
	}
	/**
	 * Find a matching connection in the given connection list.
	 *
	 * Returns `null` if no matching connection is found.
	 */
	function findConnection(list, signal, callback, thisArg) {
	    var conn = list.first;
	    while (conn !== null) {
	        if (conn.signal === signal &&
	            conn.callback === callback &&
	            conn.thisArg === thisArg) {
	            return conn;
	        }
	        conn = conn.nextReceiver;
	    }
	    return null;
	}
	/**
	 * Remove the dead connections from the given connection list.
	 */
	function cleanList(list) {
	    var prev;
	    var conn = list.first;
	    while (conn !== null) {
	        var next = conn.nextReceiver;
	        if (!conn.callback) {
	            conn.nextReceiver = null;
	        }
	        else if (!prev) {
	            list.first = conn;
	            prev = conn;
	        }
	        else {
	            prev.nextReceiver = conn;
	            prev = conn;
	        }
	        conn = next;
	    }
	    if (!prev) {
	        list.first = null;
	        list.last = null;
	    }
	    else {
	        prev.nextReceiver = null;
	        list.last = prev;
	    }
	}
	/**
	 * Remove a connection from the doubly linked list of senders.
	 */
	function removeFromSendersList(conn) {
	    var receiver = conn.thisArg || conn.callback;
	    if (!receiver) {
	        return;
	    }
	    var prev = conn.prevSender;
	    var next = conn.nextSender;
	    if (prev === null && next === null) {
	        receiverMap.delete(receiver);
	    }
	    else if (prev === null) {
	        receiverMap.set(receiver, next);
	        next.prevSender = null;
	    }
	    else if (next === null) {
	        prev.nextSender = null;
	    }
	    else {
	        prev.nextSender = next;
	        next.prevSender = prev;
	    }
	    conn.prevSender = null;
	    conn.nextSender = null;
	}
	//# sourceMappingURL=index.js.map

/***/ },
/* 23 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_messaging_1 = __webpack_require__(13);
	var phosphor_nodewrapper_1 = __webpack_require__(24);
	var phosphor_properties_1 = __webpack_require__(17);
	var phosphor_signaling_1 = __webpack_require__(22);
	var title_1 = __webpack_require__(25);
	/**
	 * The class name added to Widget instances.
	 */
	var WIDGET_CLASS = 'p-Widget';
	/**
	 * The class name added to hidden widgets.
	 */
	var HIDDEN_CLASS = 'p-mod-hidden';
	/**
	 * 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. Simply instantiate an empty widget and add the DOM content
	 * directly to the widget's `.node`.
	 */
	var Widget = (function (_super) {
	    __extends(Widget, _super);
	    /**
	     * Construct a new widget.
	     */
	    function Widget() {
	        _super.call(this);
	        this._flags = 0;
	        this._layout = null;
	        this._parent = null;
	        this.addClass(WIDGET_CLASS);
	    }
	    /**
	     * Dispose of the widget and its descendants.
	     *
	     * #### Notes
	     * It is generally unsafe to use the widget after it is 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(WidgetFlag.IsDisposed);
	        this.disposed.emit(void 0);
	        // Remove or detach the widget if necessary.
	        if (this.parent) {
	            this.parent = null;
	        }
	        else if (this.isAttached) {
	            this.detach();
	        }
	        // Dispose of the widget layout.
	        if (this._layout) {
	            this._layout.dispose();
	            this._layout = null;
	        }
	        // Clear the attached data associated with the widget.
	        phosphor_signaling_1.clearSignalData(this);
	        phosphor_messaging_1.clearMessageData(this);
	        phosphor_properties_1.clearPropertyData(this);
	    };
	    Object.defineProperty(Widget.prototype, "disposed", {
	        /**
	         * A signal emitted when the widget is disposed.
	         *
	         * **See also:** [[dispose]], [[disposed]]
	         */
	        get: function () {
	            return WidgetPrivate.disposedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "isDisposed", {
	        /**
	         * Test whether the widget has been disposed.
	         *
	         * #### Notes
	         * This is a read-only property.
	         *
	         * **See also:** [[dispose]], [[disposed]]
	         */
	        get: function () {
	            return this.testFlag(WidgetFlag.IsDisposed);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "isAttached", {
	        /**
	         * Test whether the widget's node is attached to the DOM.
	         *
	         * #### Notes
	         * This is a read-only property.
	         *
	         * **See also:** [[attach]], [[detach]]
	         */
	        get: function () {
	            return this.testFlag(WidgetFlag.IsAttached);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "isHidden", {
	        /**
	         * Test whether the widget is explicitly hidden.
	         *
	         * #### Notes
	         * This is a read-only property.
	         *
	         * **See also:** [[isVisible]], [[hide]], [[show]]
	         */
	        get: function () {
	            return this.testFlag(WidgetFlag.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.
	         *
	         * This is a read-only property.
	         *
	         * **See also:** [[isHidden]], [[hide]], [[show]]
	         */
	        get: function () {
	            return this.testFlag(WidgetFlag.IsVisible);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "title", {
	        /**
	         * Get the title data object for the widget.
	         *
	         * #### Notes
	         * The title data is used by some container widgets when displaying
	         * the widget along with a title, such as a tab panel or dock panel.
	         *
	         * Not all widgets will make use of the title data, so it is created
	         * on-demand the first time it is accessed.
	         */
	        get: function () {
	            return WidgetPrivate.titleProperty.get(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "parent", {
	        /**
	         * Get the parent of the widget.
	         *
	         * #### Notes
	         * This will be `null` if the widget does not have a parent.
	         */
	        get: function () {
	            return this._parent;
	        },
	        /**
	         * Set the parent of the widget.
	         *
	         * #### Notes
	         * The widget will be automatically removed from its current parent.
	         *
	         * This is a no-op if there is no effective parent change.
	         */
	        set: function (value) {
	            value = value || null;
	            if (this._parent === value) {
	                return;
	            }
	            if (value && this.contains(value)) {
	                throw new Error('Invalid parent widget.');
	            }
	            if (this._parent && !this._parent.isDisposed) {
	                phosphor_messaging_1.sendMessage(this._parent, new ChildMessage('child-removed', this));
	            }
	            this._parent = value;
	            if (this._parent && !this._parent.isDisposed) {
	                phosphor_messaging_1.sendMessage(this._parent, new ChildMessage('child-added', this));
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "layout", {
	        /**
	         * Get the layout for the widget.
	         *
	         * #### Notes
	         * This will be `null` if the widget does not have a layout.
	         */
	        get: function () {
	            return this._layout;
	        },
	        /**
	         * Set the layout for the widget.
	         *
	         * #### Notes
	         * The layout is single-use only. It cannot be set to `null` and it
	         * cannot be changed after the first assignment.
	         *
	         * The layout is disposed automatically when the widget is disposed.
	         */
	        set: function (value) {
	            if (!value) {
	                throw new Error('Cannot set widget layout to null.');
	            }
	            if (this._layout === value) {
	                return;
	            }
	            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
	    });
	    /**
	     * Test whether a widget is a descendant of this widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns `true` if the widget is a descendant, `false` otherwise.
	     */
	    Widget.prototype.contains = function (widget) {
	        while (widget) {
	            if (widget === this) {
	                return true;
	            }
	            widget = widget._parent;
	        }
	        return false;
	    };
	    /**
	     * Post an `'update-request'` message to the widget.
	     *
	     * **See also:** [[MsgUpdateRequest]]
	     */
	    Widget.prototype.update = function () {
	        phosphor_messaging_1.postMessage(this, Widget.MsgUpdateRequest);
	    };
	    /**
	     * Post a `'fit-request'` message to the widget.
	     *
	     * **See also:** [[MsgFitRequest]]
	     */
	    Widget.prototype.fit = function () {
	        phosphor_messaging_1.postMessage(this, Widget.MsgFitRequest);
	    };
	    /**
	     * Send a `'close-request'` message to the widget.
	     *
	     * **See also:** [[MsgCloseRequest]]
	     */
	    Widget.prototype.close = function () {
	        phosphor_messaging_1.sendMessage(this, Widget.MsgCloseRequest);
	    };
	    /**
	     * Show the widget and make it visible to its parent widget.
	     *
	     * #### Notes
	     * This causes the [[isHidden]] property to be `false`.
	     */
	    Widget.prototype.show = function () {
	        if (!this.testFlag(WidgetFlag.IsHidden)) {
	            return;
	        }
	        this.clearFlag(WidgetFlag.IsHidden);
	        this.removeClass(HIDDEN_CLASS);
	        if (this.isAttached && (!this.parent || this.parent.isVisible)) {
	            phosphor_messaging_1.sendMessage(this, Widget.MsgAfterShow);
	        }
	        if (this.parent) {
	            phosphor_messaging_1.sendMessage(this.parent, new ChildMessage('child-shown', this));
	        }
	    };
	    /**
	     * Hide the widget and make it hidden to its parent widget.
	     *
	     * #### Notes
	     * This causes the [[isHidden]] property to be `true`.
	     */
	    Widget.prototype.hide = function () {
	        if (this.testFlag(WidgetFlag.IsHidden)) {
	            return;
	        }
	        this.setFlag(WidgetFlag.IsHidden);
	        if (this.isAttached && (!this.parent || this.parent.isVisible)) {
	            phosphor_messaging_1.sendMessage(this, Widget.MsgBeforeHide);
	        }
	        this.addClass(HIDDEN_CLASS);
	        if (this.parent) {
	            phosphor_messaging_1.sendMessage(this.parent, new ChildMessage('child-hidden', this));
	        }
	    };
	    /**
	     * Set whether the widget is hidden.
	     *
	     * @param hidden - `true` to hide the widget, or `false` to show it.
	     *
	     * #### Notes
	     * `widget.setHidden(true)` is equivalent to `widget.hide()`, and
	     * `widget.setHidden(false)` is equivalent to `widget.show()`.
	     */
	    Widget.prototype.setHidden = function (hidden) {
	        if (hidden) {
	            this.hide();
	        }
	        else {
	            this.show();
	        }
	    };
	    /**
	     * Attach the widget to a host DOM node.
	     *
	     * @param host - The DOM node to use as the widget's host.
	     *
	     * @throws 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.
	     */
	    Widget.prototype.attach = function (host) {
	        if (this.parent) {
	            throw new Error('Cannot attach child widget.');
	        }
	        if (this.isAttached || document.body.contains(this.node)) {
	            throw new Error('Widget already attached.');
	        }
	        if (!document.body.contains(host)) {
	            throw new Error('Host not attached.');
	        }
	        host.appendChild(this.node);
	        phosphor_messaging_1.sendMessage(this, Widget.MsgAfterAttach);
	    };
	    /**
	     * Detach the widget from its host DOM node.
	     *
	     * @throws An error if the widget is not a root widget, or if the
	     *   widget is not attached.
	     */
	    Widget.prototype.detach = function () {
	        if (this.parent) {
	            throw new Error('Cannot detach child widget.');
	        }
	        if (!this.isAttached || !document.body.contains(this.node)) {
	            throw new Error('Widget not attached.');
	        }
	        phosphor_messaging_1.sendMessage(this, Widget.MsgBeforeDetach);
	        this.node.parentNode.removeChild(this.node);
	    };
	    /**
	     * Test whether the given widget flag is set.
	     *
	     * #### Notes
	     * This will not typically be consumed 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 consumed directly by user code.
	     */
	    Widget.prototype.setFlag = function (flag) {
	        this._flags |= flag;
	    };
	    /**
	     * Clear the given widget flag.
	     *
	     * #### Notes
	     * This will not typically be consumed directly by user code.
	     */
	    Widget.prototype.clearFlag = function (flag) {
	        this._flags &= ~flag;
	    };
	    /**
	     * Compress a message posted to the widget.
	     *
	     * @param msg - The message posted to the widget.
	     *
	     * @param pending - The queue of pending messages for the widget.
	     *
	     * @returns `true` if the message should be ignored, or `false` if
	     *   the message should be enqueued for delivery as normal.
	     *
	     * #### Notes
	     * Subclasses may reimplement this method as needed.
	     */
	    Widget.prototype.compressMessage = function (msg, pending) {
	        if (msg.type === 'update-request') {
	            return pending.some(function (other) { return other.type === 'update-request'; });
	        }
	        if (msg.type === 'fit-request') {
	            return pending.some(function (other) { return other.type === 'fit-request'; });
	        }
	        return false;
	    };
	    /**
	     * 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 'after-show':
	                this.setFlag(WidgetFlag.IsVisible);
	                this.notifyLayout(msg);
	                this.onAfterShow(msg);
	                break;
	            case 'before-hide':
	                this.notifyLayout(msg);
	                this.onBeforeHide(msg);
	                this.clearFlag(WidgetFlag.IsVisible);
	                break;
	            case 'after-attach':
	                var visible = !this.isHidden && (!this.parent || this.parent.isVisible);
	                if (visible)
	                    this.setFlag(WidgetFlag.IsVisible);
	                this.setFlag(WidgetFlag.IsAttached);
	                this.notifyLayout(msg);
	                this.onAfterAttach(msg);
	                break;
	            case 'before-detach':
	                this.notifyLayout(msg);
	                this.onBeforeDetach(msg);
	                this.clearFlag(WidgetFlag.IsVisible);
	                this.clearFlag(WidgetFlag.IsAttached);
	                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.
	     */
	    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 of this handler detaches the widget.
	     *
	     * **See also:** [[close]], [[MsgCloseRequest]]
	     */
	    Widget.prototype.onCloseRequest = function (msg) {
	        if (this.parent) {
	            this.parent = null;
	        }
	        else if (this.isAttached) {
	            this.detach();
	        }
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     *
	     * The default implementation of this handler is a no-op.
	     *
	     * **See also:** [[ResizeMessage]]
	     */
	    Widget.prototype.onResize = function (msg) { };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     *
	     * The default implementation of this handler is a no-op.
	     *
	     * **See also:** [[update]], [[MsgUpdateRequest]]
	     */
	    Widget.prototype.onUpdateRequest = function (msg) { };
	    /**
	     * A message handler invoked on an `'after-show'` message.
	     *
	     * The default implementation of this handler is a no-op.
	     *
	     * **See also:** [[MsgAfterShow]]
	     */
	    Widget.prototype.onAfterShow = function (msg) { };
	    /**
	     * A message handler invoked on a `'before-hide'` message.
	     *
	     * The default implementation of this handler is a no-op.
	     *
	     * **See also:** [[MsgBeforeHide]]
	     */
	    Widget.prototype.onBeforeHide = function (msg) { };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     *
	     * The default implementation of this handler is a no-op.
	     *
	     * **See also:** [[MsgAfterAttach]]
	     */
	    Widget.prototype.onAfterAttach = function (msg) { };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     *
	     * The default implementation of this handler is a no-op.
	     *
	     * **See also:** [[MsgBeforeDetach]]
	     */
	    Widget.prototype.onBeforeDetach = function (msg) { };
	    /**
	     * A message handler invoked on a `'child-added'` message.
	     *
	     * The default implementation of this handler is a no-op.
	     *
	     * **See also:** [[ChildMessage]]
	     */
	    Widget.prototype.onChildAdded = function (msg) { };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     *
	     * The default implementation of this handler is a no-op.
	     *
	     * **See also:** [[ChildMessage]]
	     */
	    Widget.prototype.onChildRemoved = function (msg) { };
	    return Widget;
	})(phosphor_nodewrapper_1.NodeWrapper);
	exports.Widget = Widget;
	/**
	 * The namespace for the `Widget` class statics.
	 */
	var Widget;
	(function (Widget) {
	    /**
	     * A singleton `'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.
	     *
	     * Messages of this type are compressed by default.
	     *
	     * **See also:** [[update]], [[onUpdateRequest]]
	     */
	    Widget.MsgUpdateRequest = new phosphor_messaging_1.Message('update-request');
	    /**
	     * A singleton `'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.
	     *
	     * Messages of this type are compressed by default.
	     *
	     * **See also:** [[fit]]
	     */
	    Widget.MsgFitRequest = new phosphor_messaging_1.Message('fit-request');
	    /**
	     * A singleton `'close-request'` message.
	     *
	     * #### Notes
	     * This message should be dispatched to a widget when it should close
	     * and remove itself from the widget hierarchy.
	     *
	     * Messages of this type are compressed by default.
	     *
	     * **See also:** [[close]], [[onCloseRequest]]
	     */
	    Widget.MsgCloseRequest = new phosphor_messaging_1.Message('close-request');
	    /**
	     * 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.
	     *
	     * **See also:** [[isVisible]], [[onAfterShow]]
	     */
	    Widget.MsgAfterShow = new phosphor_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.
	     *
	     * **See also:** [[isVisible]], [[onBeforeHide]]
	     */
	    Widget.MsgBeforeHide = new phosphor_messaging_1.Message('before-hide');
	    /**
	     * A singleton `'after-attach'` message.
	     *
	     * #### Notes
	     * This message is sent to a widget after it is attached.
	     *
	     * **See also:** [[isAttached]], [[onAfterAttach]]
	     */
	    Widget.MsgAfterAttach = new phosphor_messaging_1.Message('after-attach');
	    /**
	     * A singleton `'before-detach'` message.
	     *
	     * #### Notes
	     * This message is sent to a widget before it is detached.
	     *
	     * **See also:** [[isAttached]], [[onBeforeDetach]]
	     */
	    Widget.MsgBeforeDetach = new phosphor_messaging_1.Message('before-detach');
	})(Widget = exports.Widget || (exports.Widget = {}));
	/**
	 * An enum of widget bit flags.
	 */
	(function (WidgetFlag) {
	    /**
	     * The widget has been disposed.
	     */
	    WidgetFlag[WidgetFlag["IsDisposed"] = 1] = "IsDisposed";
	    /**
	     * The widget is attached to the DOM.
	     */
	    WidgetFlag[WidgetFlag["IsAttached"] = 2] = "IsAttached";
	    /**
	     * The widget is hidden.
	     */
	    WidgetFlag[WidgetFlag["IsHidden"] = 4] = "IsHidden";
	    /**
	     * The widget is visible.
	     */
	    WidgetFlag[WidgetFlag["IsVisible"] = 8] = "IsVisible";
	})(exports.WidgetFlag || (exports.WidgetFlag = {}));
	var WidgetFlag = exports.WidgetFlag;
	/**
	 * 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) {
	        _super.call(this, type);
	        this._child = child;
	    }
	    Object.defineProperty(ChildMessage.prototype, "child", {
	        /**
	         * The child widget for the message.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._child;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ChildMessage;
	})(phosphor_messaging_1.Message);
	exports.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) {
	        _super.call(this, 'resize');
	        this._width = width;
	        this._height = height;
	    }
	    Object.defineProperty(ResizeMessage.prototype, "width", {
	        /**
	         * The offset width of the widget.
	         *
	         * #### Notes
	         * This will be `-1` if the width is unknown.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._width;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ResizeMessage.prototype, "height", {
	        /**
	         * The offset height of the widget.
	         *
	         * #### Notes
	         * This will be `-1` if the height is unknown.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._height;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ResizeMessage;
	})(phosphor_messaging_1.Message);
	exports.ResizeMessage = ResizeMessage;
	/**
	 * The namespace for the `ResizeMessage` class statics.
	 */
	var ResizeMessage;
	(function (ResizeMessage) {
	    /**
	     * A singleton `'resize'` message with an unknown size.
	     */
	    ResizeMessage.UnknownSize = new ResizeMessage(-1, -1);
	})(ResizeMessage = exports.ResizeMessage || (exports.ResizeMessage = {}));
	/**
	 * The namespace for the widget private data.
	 */
	var WidgetPrivate;
	(function (WidgetPrivate) {
	    /**
	     * A signal emitted when the widget is disposed.
	     */
	    WidgetPrivate.disposedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A property for the title data for a widget.
	     */
	    WidgetPrivate.titleProperty = new phosphor_properties_1.Property({
	        name: 'title',
	        create: function () { return new title_1.Title(); },
	    });
	})(WidgetPrivate || (WidgetPrivate = {}));


/***/ },
/* 24 */
/***/ function(module, exports) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	/**
	 * A base class for creating objects which wrap a DOM node.
	 */
	var NodeWrapper = (function () {
	    /**
	     * Construct a new node wrapper.
	     */
	    function NodeWrapper() {
	        this._node = this.constructor.createNode();
	    }
	    /**
	     * Create the DOM node for a new node wrapper instance.
	     *
	     * @returns The DOM node to use with the node wrapper instance.
	     *
	     * #### Notes
	     * The default implementation creates an empty `<div>`.
	     *
	     * This may be reimplemented by a subclass to create a custom node.
	     */
	    NodeWrapper.createNode = function () {
	        return document.createElement('div');
	    };
	    Object.defineProperty(NodeWrapper.prototype, "node", {
	        /**
	         * Get the DOM node managed by the wrapper.
	         *
	         * #### Notes
	         * This property is read-only.
	         */
	        get: function () {
	            return this._node;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NodeWrapper.prototype, "id", {
	        /**
	         * Get the id of the wrapper's DOM node.
	         */
	        get: function () {
	            return this._node.id;
	        },
	        /**
	         * Set the id of the wrapper's DOM node.
	         */
	        set: function (value) {
	            this._node.id = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Test whether the wrapper'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.
	     */
	    NodeWrapper.prototype.hasClass = function (name) {
	        return this._node.classList.contains(name);
	    };
	    /**
	     * Add a class name to the wrapper'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.
	     */
	    NodeWrapper.prototype.addClass = function (name) {
	        this._node.classList.add(name);
	    };
	    /**
	     * Remove a class name from the wrapper'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.
	     */
	    NodeWrapper.prototype.removeClass = function (name) {
	        this._node.classList.remove(name);
	    };
	    /**
	     * Toggle a class name on the wrapper'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.
	     */
	    NodeWrapper.prototype.toggleClass = function (name, force) {
	        var present;
	        if (force === true) {
	            this.addClass(name);
	            present = true;
	        }
	        else if (force === false) {
	            this.removeClass(name);
	            present = false;
	        }
	        else if (this.hasClass(name)) {
	            this.removeClass(name);
	            present = false;
	        }
	        else {
	            this.addClass(name);
	            present = true;
	        }
	        return present;
	    };
	    return NodeWrapper;
	})();
	exports.NodeWrapper = NodeWrapper;


/***/ },
/* 25 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var phosphor_properties_1 = __webpack_require__(17);
	var phosphor_signaling_1 = __webpack_require__(22);
	/**
	 * An object which holds data related to a widget title.
	 *
	 * #### Notes
	 * A title object is intended to hold the data necessary to display a
	 * header for a particular widget. 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 a title.
	     */
	    function Title(options) {
	        if (options)
	            TitlePrivate.initFrom(this, options);
	    }
	    Object.defineProperty(Title.prototype, "changed", {
	        /**
	         * A signal emitted when the title state changes.
	         */
	        get: function () {
	            return TitlePrivate.changedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "text", {
	        /**
	         * Get the text for the title.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         */
	        get: function () {
	            return TitlePrivate.textProperty.get(this);
	        },
	        /**
	         * Set the text for the title.
	         */
	        set: function (value) {
	            TitlePrivate.textProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "icon", {
	        /**
	         * Get the icon class name for the title.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         */
	        get: function () {
	            return TitlePrivate.iconProperty.get(this);
	        },
	        /**
	         * Set the icon class name for the title.
	         *
	         * #### Notes
	         * Multiple class names can be separated with whitespace.
	         */
	        set: function (value) {
	            TitlePrivate.iconProperty.set(this, value);
	        },
	        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 TitlePrivate.closableProperty.get(this);
	        },
	        /**
	         * Set the closable state for the title.
	         *
	         * #### Notes
	         * This controls the presence of a close icon when applicable.
	         */
	        set: function (value) {
	            TitlePrivate.closableProperty.set(this, value);
	        },
	        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 TitlePrivate.classNameProperty.get(this);
	        },
	        /**
	         * Set the extra class name for the title.
	         *
	         * #### Notes
	         * Multiple class names can be separated with whitespace.
	         */
	        set: function (value) {
	            TitlePrivate.classNameProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return Title;
	})();
	exports.Title = Title;
	/**
	 * The namespace for the title private data.
	 */
	var TitlePrivate;
	(function (TitlePrivate) {
	    /**
	     * A signal emitted when the title state changes.
	     */
	    TitlePrivate.changedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * The property descriptor for the title text.
	     */
	    TitlePrivate.textProperty = new phosphor_properties_1.Property({
	        name: 'text',
	        value: '',
	        notify: TitlePrivate.changedSignal,
	    });
	    /**
	     * The property descriptor for the title icon class.
	     */
	    TitlePrivate.iconProperty = new phosphor_properties_1.Property({
	        name: 'icon',
	        value: '',
	        notify: TitlePrivate.changedSignal,
	    });
	    /**
	     * The property descriptor for the title closable state.
	     */
	    TitlePrivate.closableProperty = new phosphor_properties_1.Property({
	        name: 'closable',
	        value: false,
	        notify: TitlePrivate.changedSignal,
	    });
	    /**
	     * The property descriptor for the title extra class name.
	     */
	    TitlePrivate.classNameProperty = new phosphor_properties_1.Property({
	        name: 'className',
	        value: '',
	        notify: TitlePrivate.changedSignal,
	    });
	    /**
	     * Initialize a title from an options object.
	     */
	    function initFrom(title, options) {
	        if (options.text !== void 0) {
	            title.text = options.text;
	        }
	        if (options.icon !== void 0) {
	            title.icon = options.icon;
	        }
	        if (options.closable !== void 0) {
	            title.closable = options.closable;
	        }
	        if (options.className !== void 0) {
	            title.className = options.className;
	        }
	    }
	    TitlePrivate.initFrom = initFrom;
	})(TitlePrivate || (TitlePrivate = {}));


/***/ },
/* 26 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(27);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../css-loader/index.js!./index.css", function() {
				var newContent = require("!!./../../css-loader/index.js!./index.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 27 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\r\n| Copyright (c) 2014-2015, PhosphorJS Contributors\r\n|\r\n| Distributed under the terms of the BSD 3-Clause License.\r\n|\r\n| The full license is in the file LICENSE, distributed with this software.\r\n|----------------------------------------------------------------------------*/\r\n.p-Widget {\r\n  box-sizing: border-box;\r\n  position: relative;\r\n  overflow: hidden;\r\n  cursor: default;\r\n  -webkit-user-select: none;\r\n  -moz-user-select: none;\r\n  -ms-user-select: none;\r\n  user-select: none;\r\n}\r\n\r\n\r\n.p-Widget.p-mod-hidden {\r\n  display: none;\r\n}\r\n", ""]);
	
	// exports


/***/ },
/* 28 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_widget_1 = __webpack_require__(20);
	var layout_1 = __webpack_require__(19);
	/**
	 * The class name added to Panel instances.
	 */
	var PANEL_CLASS = 'p-Panel';
	/**
	 * A simple and convenient panel widget class.
	 *
	 * #### Notes
	 * This class is suitable as a base class for implementing a variety of
	 * convenience panels, but can also be used directly along 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.
	     */
	    function Panel() {
	        _super.call(this);
	        this.addClass(PANEL_CLASS);
	        this.layout = this.constructor.createLayout();
	    }
	    /**
	     * Create a panel layout to use with a panel.
	     *
	     * @returns A new panel layout to use with a panel.
	     *
	     * #### Notes
	     * This may be reimplemented by a subclass to create custom layouts.
	     */
	    Panel.createLayout = function () {
	        return new layout_1.PanelLayout();
	    };
	    /**
	     * Get the number of child widgets in the panel.
	     *
	     * @returns The number of child widgets in the panel.
	     */
	    Panel.prototype.childCount = function () {
	        return this.layout.childCount();
	    };
	    /**
	     * Get the child widget at the specified index.
	     *
	     * @param index - The index of the child widget of interest.
	     *
	     * @returns The child at the specified index, or `undefined`.
	     */
	    Panel.prototype.childAt = function (index) {
	        return this.layout.childAt(index);
	    };
	    /**
	     * Get the index of the specified child widget.
	     *
	     * @param child - The child widget of interest.
	     *
	     * @returns The index of the specified child, or `-1`.
	     */
	    Panel.prototype.childIndex = function (child) {
	        return this.layout.childIndex(child);
	    };
	    /**
	     * Add a child widget to the end of the panel.
	     *
	     * @param child - The child widget to add to the panel.
	     *
	     * #### Notes
	     * If the child is already contained in the panel, it will be moved.
	     */
	    Panel.prototype.addChild = function (child) {
	        this.layout.addChild(child);
	    };
	    /**
	     * Insert a child widget at the specified index.
	     *
	     * @param index - The index at which to insert the child.
	     *
	     * @param child - The child widget to insert into to the panel.
	     *
	     * #### Notes
	     * If the child is already contained in the panel, it will be moved.
	     */
	    Panel.prototype.insertChild = function (index, child) {
	        this.layout.insertChild(index, child);
	    };
	    return Panel;
	})(phosphor_widget_1.Widget);
	exports.Panel = Panel;


/***/ },
/* 29 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_panel_1 = __webpack_require__(18);
	var layout_1 = __webpack_require__(5);
	/**
	 * The class name added to BoxPanel instances.
	 */
	var BOX_PANEL_CLASS = 'p-BoxPanel';
	/**
	 * The class name added to a BoxPanel child.
	 */
	var CHILD_CLASS = 'p-BoxPanel-child';
	/**
	 * A panel which arranges its children 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.
	     */
	    function BoxPanel() {
	        _super.call(this);
	        this.addClass(BOX_PANEL_CLASS);
	    }
	    /**
	     * Create a box layout for a box panel.
	     */
	    BoxPanel.createLayout = function () {
	        return new layout_1.BoxLayout();
	    };
	    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, "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(CHILD_CLASS);
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    BoxPanel.prototype.onChildRemoved = function (msg) {
	        msg.child.removeClass(CHILD_CLASS);
	    };
	    return BoxPanel;
	})(phosphor_panel_1.Panel);
	exports.BoxPanel = BoxPanel;
	/**
	 * The namespace for the `BoxPanel` class statics.
	 */
	var BoxPanel;
	(function (BoxPanel) {
	    /**
	     * A convenience alias of the `LeftToRight` [[Direction]].
	     */
	    BoxPanel.LeftToRight = layout_1.Direction.LeftToRight;
	    /**
	     * A convenience alias of the `RightToLeft` [[Direction]].
	     */
	    BoxPanel.RightToLeft = layout_1.Direction.RightToLeft;
	    /**
	     * A convenience alias of the `TopToBottom` [[Direction]].
	     */
	    BoxPanel.TopToBottom = layout_1.Direction.TopToBottom;
	    /**
	     * A convenience alias of the `BottomToTop` [[Direction]].
	     */
	    BoxPanel.BottomToTop = layout_1.Direction.BottomToTop;
	    /**
	     * 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 layout_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) {
	        layout_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 layout_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) {
	        layout_1.BoxLayout.setSizeBasis(widget, value);
	    }
	    BoxPanel.setSizeBasis = setSizeBasis;
	})(BoxPanel = exports.BoxPanel || (exports.BoxPanel = {}));


/***/ },
/* 30 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var arrays = __webpack_require__(3);
	var phosphor_domutil_1 = __webpack_require__(7);
	var phosphor_dragdrop_1 = __webpack_require__(31);
	var phosphor_nodewrapper_1 = __webpack_require__(24);
	var phosphor_properties_1 = __webpack_require__(17);
	var phosphor_splitpanel_1 = __webpack_require__(32);
	var phosphor_stackedpanel_1 = __webpack_require__(37);
	var phosphor_tabs_1 = __webpack_require__(40);
	var phosphor_widget_1 = __webpack_require__(20);
	__webpack_require__(45);
	// TODO - need better solution for storing these class names
	/**
	 * The class name added to DockPanel instances.
	 */
	var DOCK_PANEL_CLASS = 'p-DockPanel';
	/**
	 * The class name added to dock tab panels.
	 */
	var TAB_PANEL_CLASS = 'p-DockTabPanel';
	/**
	 * The class name added to dock split panels.
	 */
	var SPLIT_PANEL_CLASS = 'p-DockSplitPanel';
	/**
	 * The class name added to dock panel overlays.
	 */
	var OVERLAY_CLASS = 'p-DockPanel-overlay';
	/**
	 * The class name added to hidden overlays and tabs.
	 */
	var HIDDEN_CLASS = 'p-mod-hidden';
	/**
	 * The class name added to top root dock overlays.
	 */
	var ROOT_TOP_CLASS = 'p-mod-root-top';
	/**
	 * The class name added to left root dock overlays.
	 */
	var ROOT_LEFT_CLASS = 'p-mod-root-left';
	/**
	 * The class name added to right root dock overlays.
	 */
	var ROOT_RIGHT_CLASS = 'p-mod-root-right';
	/**
	 * The class name added to bottom root dock overlays.
	 */
	var ROOT_BOTTOM_CLASS = 'p-mod-root-bottom';
	/**
	 * The class name added to center root dock overlays.
	 */
	var ROOT_CENTER_CLASS = 'p-mod-root-center';
	/**
	 * The class name added to top panel dock overlays.
	 */
	var PANEL_TOP_CLASS = 'p-mod-panel-top';
	/**
	 * The class name added to left panel dock overlays.
	 */
	var PANEL_LEFT_CLASS = 'p-mod-panel-left';
	/**
	 * The class name added to right panel dock overlays.
	 */
	var PANEL_RIGHT_CLASS = 'p-mod-panel-right';
	/**
	 * The class name added to bottom panel dock overlays.
	 */
	var PANEL_BOTTOM_CLASS = 'p-mod-panel-bottom';
	/**
	 * The class named added to center panel dock overlays.
	 */
	var PANEL_CENTER_CLASS = 'p-mod-panel-center';
	/**
	 * The factory MIME type supported by the dock panel.
	 */
	var FACTORY_MIME = 'application/x-phosphor-widget-factory';
	/**
	 * The size of the edge dock zone for the root panel.
	 */
	var EDGE_SIZE = 30;
	/**
	 * A widget which provides a flexible docking area for content widgets.
	 */
	var DockPanel = (function (_super) {
	    __extends(DockPanel, _super);
	    /**
	     * Construct a new dock panel.
	     */
	    function DockPanel() {
	        _super.call(this);
	        this.addClass(DOCK_PANEL_CLASS);
	        this.layout = new phosphor_stackedpanel_1.StackedLayout();
	    }
	    Object.defineProperty(DockPanel.prototype, "spacing", {
	        /**
	         * Get the spacing between the tab panels.
	         */
	        get: function () {
	            return DockPanelPrivate.spacingProperty.get(this);
	        },
	        /**
	         * Set the spacing between the tab panels.
	         */
	        set: function (value) {
	            DockPanelPrivate.spacingProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Insert a widget as a new panel above a reference widget.
	     *
	     * @param widget - The widget to insert into the dock panel.
	     *
	     * @param ref - The reference widget. If this is not provided, the
	     *   widget will be inserted at the top edge of the dock panel.
	     *
	     * @throws An error if either `widget` or `ref` is invalid.
	     */
	    DockPanel.prototype.insertTop = function (widget, ref) {
	        DockPanelPrivate.insertSplit(this, widget, ref, phosphor_splitpanel_1.Orientation.Vertical, false);
	    };
	    /**
	     * Insert a widget as a new panel to the left of a reference widget.
	     *
	     * @param widget - The widget to insert into the dock panel.
	     *
	     * @param ref - The reference widget. If this is not provided, the
	     *   widget will be inserted at the left edge of the dock panel.
	     *
	     * @throws An error if either `widget` or `ref` is invalid.
	     */
	    DockPanel.prototype.insertLeft = function (widget, ref) {
	        DockPanelPrivate.insertSplit(this, widget, ref, phosphor_splitpanel_1.Orientation.Horizontal, false);
	    };
	    /**
	     * Insert a widget as a new panel to the right of a reference widget.
	     *
	     * @param widget - The widget to insert into the dock panel.
	     *
	     * @param ref - The reference widget. If this is not provided, the
	     *   widget will be inserted at the right edge of the dock panel.
	     *
	     * @throws An error if either `widget` or `ref` is invalid.
	     */
	    DockPanel.prototype.insertRight = function (widget, ref) {
	        DockPanelPrivate.insertSplit(this, widget, ref, phosphor_splitpanel_1.Orientation.Horizontal, true);
	    };
	    /**
	     * Insert a widget as a new panel below a reference widget.
	     *
	     * @param widget - The widget to insert into the dock panel.
	     *
	     * @param ref - The reference widget. If this is not provided, the
	     *   widget will be inserted at the bottom edge of the dock panel.
	     *
	     * @throws An error if either `widget` or `ref` is invalid.
	     */
	    DockPanel.prototype.insertBottom = function (widget, ref) {
	        DockPanelPrivate.insertSplit(this, widget, ref, phosphor_splitpanel_1.Orientation.Vertical, true);
	    };
	    /**
	     * Insert a widget as a sibling tab before a reference widget.
	     *
	     * @param widget - The widget to insert into the dock panel.
	     *
	     * @param ref - The reference widget. If this is not provided, the
	     *   widget will be inserted as the first tab in the top-left panel.
	     *
	     * @throws An error if either `widget` or `ref` is invalid.
	     */
	    DockPanel.prototype.insertTabBefore = function (widget, ref) {
	        DockPanelPrivate.insertTab(this, widget, ref, false);
	    };
	    /**
	     * Insert a widget as a sibling tab after a reference widget.
	     *
	     * @param widget - The widget to insert into the dock panel.
	     *
	     * @param ref - The reference widget. If this is not provided, the
	     *   widget will be inserted as the last tab in the top-left panel.
	     *
	     * @throws An error if either `widget` or `ref` is invalid.
	     */
	    DockPanel.prototype.insertTabAfter = function (widget, ref) {
	        DockPanelPrivate.insertTab(this, widget, ref, true);
	    };
	    /**
	     * Ensure the tab for the specified content widget is selected.
	     *
	     * @param widget - The content widget of interest.
	     *
	     * #### Notes
	     * If the widget is not contained in the dock panel, or is already
	     * the selected tab in its respective tab panel, this is a no-op.
	     */
	    DockPanel.prototype.selectWidget = function (widget) {
	        DockPanelPrivate.selectWidget(this, widget);
	    };
	    /**
	     * Handle the DOM events for the dock panel.
	     *
	     * @param event - The DOM event sent to the dock panel.
	     *
	     * #### 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.
	     */
	    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;
	        }
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    DockPanel.prototype.onAfterAttach = function (msg) {
	        var node = this.node;
	        node.addEventListener('p-dragenter', this);
	        node.addEventListener('p-dragleave', this);
	        node.addEventListener('p-dragover', this);
	        node.addEventListener('p-drop', this);
	    };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     */
	    DockPanel.prototype.onBeforeDetach = function (msg) {
	        var node = this.node;
	        node.removeEventListener('p-dragenter', this);
	        node.removeEventListener('p-dragleave', this);
	        node.removeEventListener('p-dragover', this);
	        node.removeEventListener('p-drop', this);
	    };
	    /**
	     * Handle the `'p-dragenter'` event for the dock panel.
	     */
	    DockPanel.prototype._evtDragEnter = function (event) {
	        if (event.mimeData.hasData(FACTORY_MIME)) {
	            event.preventDefault();
	            event.stopPropagation();
	        }
	    };
	    /**
	     * Handle the `'p-dragleave'` event for the dock panel.
	     */
	    DockPanel.prototype._evtDragLeave = function (event) {
	        event.preventDefault();
	        event.stopPropagation();
	        var related = event.relatedTarget;
	        if (!related || !this.node.contains(related)) {
	            DockPanelPrivate.hideOverlay(this);
	        }
	    };
	    /**
	     * Handle the `'p-dragover'` event for the dock panel.
	     */
	    DockPanel.prototype._evtDragOver = function (event) {
	        event.preventDefault();
	        event.stopPropagation();
	        var x = event.clientX;
	        var y = event.clientY;
	        var zone = DockPanelPrivate.showOverlay(this, x, y);
	        if (zone === 10 /* Invalid */) {
	            event.dropAction = phosphor_dragdrop_1.DropAction.None;
	        }
	        else {
	            event.dropAction = event.proposedAction;
	        }
	    };
	    /**
	     * Handle the `'p-drop'` event for the dock panel.
	     */
	    DockPanel.prototype._evtDrop = function (event) {
	        event.preventDefault();
	        event.stopPropagation();
	        DockPanelPrivate.hideOverlay(this);
	        if (event.proposedAction === phosphor_dragdrop_1.DropAction.None) {
	            event.dropAction = phosphor_dragdrop_1.DropAction.None;
	            return;
	        }
	        var x = event.clientX;
	        var y = event.clientY;
	        var target = DockPanelPrivate.findDockTarget(this, x, y);
	        if (target.zone === 10 /* Invalid */) {
	            event.dropAction = phosphor_dragdrop_1.DropAction.None;
	            return;
	        }
	        var factory = event.mimeData.getData(FACTORY_MIME);
	        if (typeof factory !== 'function') {
	            event.dropAction = phosphor_dragdrop_1.DropAction.None;
	            return;
	        }
	        var widget = factory();
	        if (!(widget instanceof phosphor_widget_1.Widget)) {
	            event.dropAction = phosphor_dragdrop_1.DropAction.None;
	            return;
	        }
	        DockPanelPrivate.handleDrop(this, widget, target);
	        event.dropAction = event.proposedAction;
	    };
	    return DockPanel;
	})(phosphor_widget_1.Widget);
	exports.DockPanel = DockPanel;
	/**
	 * A custom tab panel used by a DockPanel.
	 */
	var DockTabPanel = (function (_super) {
	    __extends(DockTabPanel, _super);
	    /**
	     * Construct a new dock tab panel.
	     */
	    function DockTabPanel() {
	        _super.call(this);
	        this.addClass(TAB_PANEL_CLASS);
	        this.tabBar.tabsMovable = true;
	    }
	    return DockTabPanel;
	})(phosphor_tabs_1.TabPanel);
	/**
	 * A custom split panel used by a DockPanel.
	 */
	var DockSplitPanel = (function (_super) {
	    __extends(DockSplitPanel, _super);
	    /**
	     * Construct a new dock split panel.
	     */
	    function DockSplitPanel(orientation, spacing) {
	        _super.call(this);
	        this.addClass(SPLIT_PANEL_CLASS);
	        this.orientation = orientation;
	        this.spacing = spacing;
	    }
	    return DockSplitPanel;
	})(phosphor_splitpanel_1.SplitPanel);
	/**
	 * A node wrapper used as an overlay dock indicator for a dock panel.
	 */
	var DockPanelOverlay = (function (_super) {
	    __extends(DockPanelOverlay, _super);
	    /**
	     * Construct a new dock panel overlay.
	     */
	    function DockPanelOverlay() {
	        _super.call(this);
	        this._zone = 10 /* Invalid */;
	        this.addClass(OVERLAY_CLASS);
	        this.addClass(HIDDEN_CLASS);
	    }
	    /**
	     * Show the overlay with the given zone and geometry
	     */
	    DockPanelOverlay.prototype.show = function (zone, left, top, width, height) {
	        var style = this.node.style;
	        style.top = top + 'px';
	        style.left = left + 'px';
	        style.width = width + 'px';
	        style.height = height + 'px';
	        this.removeClass(HIDDEN_CLASS);
	        this._setZone(zone);
	    };
	    /**
	     * Hide the overlay and reset its zone.
	     */
	    DockPanelOverlay.prototype.hide = function () {
	        this.addClass(HIDDEN_CLASS);
	        this._setZone(10 /* Invalid */);
	    };
	    /**
	     * Set the dock zone for the overlay.
	     */
	    DockPanelOverlay.prototype._setZone = function (zone) {
	        if (zone === this._zone) {
	            return;
	        }
	        var oldClass = DockPanelOverlay.zoneMap[this._zone];
	        var newClass = DockPanelOverlay.zoneMap[zone];
	        if (oldClass)
	            this.removeClass(oldClass);
	        if (newClass)
	            this.addClass(newClass);
	        this._zone = zone;
	    };
	    /**
	     * A mapping of dock zone enum value to modifier class.
	     */
	    DockPanelOverlay.zoneMap = [
	        ROOT_TOP_CLASS,
	        ROOT_LEFT_CLASS,
	        ROOT_RIGHT_CLASS,
	        ROOT_BOTTOM_CLASS,
	        ROOT_CENTER_CLASS,
	        PANEL_TOP_CLASS,
	        PANEL_LEFT_CLASS,
	        PANEL_RIGHT_CLASS,
	        PANEL_BOTTOM_CLASS,
	        PANEL_CENTER_CLASS
	    ];
	    return DockPanelOverlay;
	})(phosphor_nodewrapper_1.NodeWrapper);
	/**
	 * The namespace for the `DockPanel` class private data.
	 */
	var DockPanelPrivate;
	(function (DockPanelPrivate) {
	    /**
	     * The property descriptor for the spacing between panels.
	     */
	    DockPanelPrivate.spacingProperty = new phosphor_properties_1.Property({
	        name: 'spacing',
	        value: 3,
	        coerce: function (owner, value) { return Math.max(0, value | 0); },
	        changed: onSpacingChanged,
	    });
	    /**
	     * Insert a widget as a new split panel in a dock panel.
	     */
	    function insertSplit(owner, widget, ref, orientation, after) {
	        // Ensure the insert args are valid.
	        validateInsertArgs(owner, widget, ref);
	        // If the widget is the same as the ref, there's nothing to do.
	        if (widget === ref) {
	            return;
	        }
	        // Unparent the widget before performing the insert. This ensures
	        // that structural changes to the dock panel occur before searching
	        // for the insert location.
	        widget.parent = null;
	        // Setup the new tab panel to host the widget.
	        var tabPanel = createTabPanel();
	        tabPanel.addChild(widget);
	        // If there is no root, add the new tab panel as the root.
	        if (!getRoot(owner)) {
	            setRoot(owner, tabPanel);
	            return;
	        }
	        // If the ref widget is null, split the root panel.
	        if (!ref) {
	            var root = ensureSplitRoot(owner, orientation);
	            var sizes_1 = root.sizes();
	            var count = sizes_1.length;
	            arrays.insert(sizes_1, after ? count : 0, 0.5);
	            root.insertChild(after ? count : 0, tabPanel);
	            root.setSizes(sizes_1);
	            return;
	        }
	        // Lookup the tab panel for the ref widget.
	        var refTabPanel = findTabPanel(ref);
	        // If the ref tab panel parent is the dock panel, split the root.
	        if (refTabPanel.parent === owner) {
	            var root = ensureSplitRoot(owner, orientation);
	            root.insertChild(after ? 1 : 0, tabPanel);
	            root.setSizes([1, 1]);
	            return;
	        }
	        // Assert the parent of the ref tab panel is a dock split panel.
	        if (!(refTabPanel.parent instanceof DockSplitPanel)) {
	            internalError();
	        }
	        // Cast the ref tab panel parent to a dock split panel.
	        var splitPanel = refTabPanel.parent;
	        // If the split panel is the correct orientation, the widget
	        // can be inserted directly and sized to 1/2 the ref space.
	        if (splitPanel.orientation === orientation) {
	            var i_1 = splitPanel.childIndex(refTabPanel);
	            var sizes_2 = splitPanel.sizes();
	            var size = sizes_2[i_1] = sizes_2[i_1] / 2;
	            arrays.insert(sizes_2, after ? i_1 + 1 : i_1, size);
	            splitPanel.insertChild(after ? i_1 + 1 : i_1, tabPanel);
	            splitPanel.setSizes(sizes_2);
	            return;
	        }
	        // If the split panel only has a single child, its orientation
	        // can be changed directly and its sizes set to a 1:1 ratio.
	        if (splitPanel.childCount() === 1) {
	            splitPanel.orientation = orientation;
	            splitPanel.insertChild(after ? 1 : 0, tabPanel);
	            splitPanel.setSizes([1, 1]);
	            return;
	        }
	        // Assert the split panel has more than one child.
	        if (splitPanel.childCount() === 0) {
	            internalError();
	        }
	        // Otherwise, a new split panel with the correct orientation needs
	        // to be created to hold the ref panel and tab panel, and inserted
	        // in the previous location of the ref panel.
	        var sizes = splitPanel.sizes();
	        var i = splitPanel.childIndex(refTabPanel);
	        var childSplit = new DockSplitPanel(orientation, owner.spacing);
	        childSplit.addChild(refTabPanel);
	        childSplit.insertChild(after ? 1 : 0, tabPanel);
	        splitPanel.insertChild(i, childSplit);
	        splitPanel.setSizes(sizes);
	        childSplit.setSizes([1, 1]);
	    }
	    DockPanelPrivate.insertSplit = insertSplit;
	    /**
	     * Insert a widget as a sibling tab in a dock panel.
	     */
	    function insertTab(owner, widget, ref, after) {
	        // Ensure the insert args are valid.
	        validateInsertArgs(owner, widget, ref);
	        // If the widget is the same as the ref, there's nothing to do.
	        if (widget === ref) {
	            return;
	        }
	        // Unparent the widget before performing the insert. This ensures
	        // that structural changes to the dock panel occur before searching
	        // for the insert location.
	        widget.parent = null;
	        // Find the index and tab panel for the insert operation.
	        var index;
	        var tabPanel;
	        if (ref) {
	            tabPanel = findTabPanel(ref);
	            index = tabPanel.childIndex(ref) + (after ? 1 : 0);
	        }
	        else {
	            tabPanel = ensureFirstTabPanel(owner);
	            index = after ? tabPanel.childCount() : 0;
	        }
	        // Insert the widget into the tab panel at the proper location.
	        tabPanel.insertChild(index, widget);
	    }
	    DockPanelPrivate.insertTab = insertTab;
	    /**
	     * Ensure the given widget is the current widget in its tab panel.
	     *
	     * This is a no-op if the widget is not contained in the dock panel.
	     */
	    function selectWidget(owner, widget) {
	        if (!dockPanelContains(owner, widget))
	            return;
	        widget.parent.parent.currentWidget = widget;
	    }
	    DockPanelPrivate.selectWidget = selectWidget;
	    /**
	     * Hide the dock panel overlay for the given dock panel.
	     */
	    function hideOverlay(owner) {
	        getOverlay(owner).hide();
	    }
	    DockPanelPrivate.hideOverlay = hideOverlay;
	    /**
	     * Show the dock panel overlay indicator at the given client position.
	     *
	     * If the position is not over a dock zone, the overlay is hidden.
	     *
	     * This returns the dock zone used to display the overlay.
	     */
	    function showOverlay(owner, clientX, clientY) {
	        // Find the dock target for the given client position.
	        var target = findDockTarget(owner, clientX, clientY);
	        // If the dock zone is invalid, hide the overlay and bail.
	        if (target.zone === 10 /* Invalid */) {
	            hideOverlay(owner);
	            return target.zone;
	        }
	        // Setup the variables needed to compute the overlay geometry.
	        var top;
	        var left;
	        var width;
	        var height;
	        var pcr;
	        var box = phosphor_domutil_1.boxSizing(owner.node); // TODO cache this?
	        var rect = owner.node.getBoundingClientRect();
	        // Compute the overlay geometry based on the dock zone.
	        switch (target.zone) {
	            case 0 /* RootTop */:
	                top = box.paddingTop;
	                left = box.paddingLeft;
	                width = rect.width - box.horizontalSum;
	                height = (rect.height - box.verticalSum) / 3;
	                break;
	            case 1 /* RootLeft */:
	                top = box.paddingTop;
	                left = box.paddingLeft;
	                width = (rect.width - box.horizontalSum) / 3;
	                height = rect.height - box.verticalSum;
	                break;
	            case 2 /* RootRight */:
	                top = box.paddingTop;
	                width = (rect.width - box.horizontalSum) / 3;
	                left = box.paddingLeft + 2 * width;
	                height = rect.height - box.verticalSum;
	                break;
	            case 3 /* RootBottom */:
	                height = (rect.height - box.verticalSum) / 3;
	                top = box.paddingTop + 2 * height;
	                left = box.paddingLeft;
	                width = rect.width - box.horizontalSum;
	                break;
	            case 4 /* RootCenter */:
	                top = box.paddingTop;
	                left = box.paddingLeft;
	                width = rect.width - box.horizontalSum;
	                height = rect.height - box.verticalSum;
	                break;
	            case 5 /* PanelTop */:
	                pcr = target.panel.node.getBoundingClientRect();
	                top = pcr.top - rect.top - box.borderTop;
	                left = pcr.left - rect.left - box.borderLeft;
	                width = pcr.width;
	                height = pcr.height / 2;
	                break;
	            case 6 /* PanelLeft */:
	                pcr = target.panel.node.getBoundingClientRect();
	                top = pcr.top - rect.top - box.borderTop;
	                left = pcr.left - rect.left - box.borderLeft;
	                width = pcr.width / 2;
	                height = pcr.height;
	                break;
	            case 7 /* PanelRight */:
	                pcr = target.panel.node.getBoundingClientRect();
	                top = pcr.top - rect.top - box.borderTop;
	                left = pcr.left - rect.left - box.borderLeft + pcr.width / 2;
	                width = pcr.width / 2;
	                height = pcr.height;
	                break;
	            case 8 /* PanelBottom */:
	                pcr = target.panel.node.getBoundingClientRect();
	                top = pcr.top - rect.top - box.borderTop + pcr.height / 2;
	                left = pcr.left - rect.left - box.borderLeft;
	                width = pcr.width;
	                height = pcr.height / 2;
	                break;
	            case 9 /* PanelCenter */:
	                pcr = target.panel.node.getBoundingClientRect();
	                top = pcr.top - rect.top - box.borderTop;
	                left = pcr.left - rect.left - box.borderLeft;
	                width = pcr.width;
	                height = pcr.height;
	                break;
	        }
	        // Show the overlay and return the dock zone.
	        getOverlay(owner).show(target.zone, left, top, width, height);
	        return target.zone;
	    }
	    DockPanelPrivate.showOverlay = showOverlay;
	    /**
	     * Find the dock target for the given client position.
	     */
	    function findDockTarget(owner, clientX, clientY) {
	        var root = getRoot(owner);
	        if (!root) {
	            return { zone: 4 /* RootCenter */, panel: null };
	        }
	        if (!phosphor_domutil_1.hitTest(root.node, clientX, clientY)) {
	            return { zone: 10 /* Invalid */, panel: null };
	        }
	        var edgeZone = getEdgeZone(root.node, clientX, clientY);
	        if (edgeZone !== 10 /* Invalid */) {
	            return { zone: edgeZone, panel: null };
	        }
	        var hitPanel = iterTabPanels(root, function (tabs) {
	            return phosphor_domutil_1.hitTest(tabs.node, clientX, clientY) ? tabs : void 0;
	        });
	        if (!hitPanel) {
	            return { zone: 10 /* Invalid */, panel: null };
	        }
	        var panelZone = getPanelZone(hitPanel.node, clientX, clientY);
	        return { zone: panelZone, panel: hitPanel };
	    }
	    DockPanelPrivate.findDockTarget = findDockTarget;
	    /**
	     * Drop a widget onto a dock panel using the given dock target.
	     */
	    function handleDrop(owner, widget, target) {
	        // Do nothing if the dock zone is invalid.
	        if (target.zone === 10 /* Invalid */) {
	            return;
	        }
	        // Handle the simple case of root drops first.
	        switch (target.zone) {
	            case 0 /* RootTop */:
	                owner.insertTop(widget);
	                return;
	            case 1 /* RootLeft */:
	                owner.insertLeft(widget);
	                return;
	            case 2 /* RootRight */:
	                owner.insertRight(widget);
	                return;
	            case 3 /* RootBottom */:
	                owner.insertBottom(widget);
	                return;
	            case 4 /* RootCenter */:
	                owner.insertLeft(widget);
	                return;
	        }
	        // Otherwise, it's a panel drop, and that requires more checks.
	        // Do nothing if the widget is dropped as a tab on its own panel.
	        if (target.zone === 9 /* PanelCenter */) {
	            if (target.panel.childIndex(widget) !== -1) {
	                return;
	            }
	        }
	        // Do nothing if the panel only contains the drop widget.
	        if (target.panel.childCount() === 1) {
	            if (target.panel.childAt(0) === widget) {
	                return;
	            }
	        }
	        // Find a suitable reference widget for the drop.
	        var n = target.panel.childCount();
	        var ref = target.panel.childAt(n - 1);
	        if (ref === widget) {
	            ref = target.panel.childAt(n - 2);
	        }
	        // Insert the widget based on the panel zone.
	        switch (target.zone) {
	            case 5 /* PanelTop */:
	                owner.insertTop(widget, ref);
	                return;
	            case 6 /* PanelLeft */:
	                owner.insertLeft(widget, ref);
	                return;
	            case 7 /* PanelRight */:
	                owner.insertRight(widget, ref);
	                return;
	            case 8 /* PanelBottom */:
	                owner.insertBottom(widget, ref);
	                return;
	            case 9 /* PanelCenter */:
	                owner.insertTabAfter(widget, ref);
	                selectWidget(owner, widget);
	                return;
	        }
	    }
	    DockPanelPrivate.handleDrop = handleDrop;
	    /**
	     * A private attached property for the dock panel root.
	     */
	    var rootProperty = new phosphor_properties_1.Property({
	        name: 'root',
	        value: null,
	        changed: onRootChanged,
	    });
	    /**
	     * A private attached property for the dock panel overlay.
	     */
	    var overlayProperty = new phosphor_properties_1.Property({
	        name: 'overlay',
	        create: createOverlay,
	    });
	    /**
	     * Get the root panel for a dock panel.
	     */
	    function getRoot(owner) {
	        return rootProperty.get(owner);
	    }
	    /**
	     * Set the root panel for a dock panel.
	     */
	    function setRoot(owner, root) {
	        rootProperty.set(owner, root);
	    }
	    /**
	     * Get the overlay for a dock panel.
	     */
	    function getOverlay(owner) {
	        return overlayProperty.get(owner);
	    }
	    /**
	     * The change handler for the dock panel `rootProperty`.
	     *
	     * This will re-parent the new root and set it as the current widget.
	     *
	     * The old root is not modified.
	     */
	    function onRootChanged(owner, old, root) {
	        if (!root)
	            return;
	        var layout = owner.layout;
	        layout.addChild(root);
	        root.show();
	    }
	    /**
	     * The creation handler for the dock panel `overlayProperty`.
	     *
	     * This will create and install the overlay for the panel.
	     */
	    function createOverlay(owner) {
	        var overlay = new DockPanelOverlay();
	        owner.node.appendChild(overlay.node);
	        return overlay;
	    }
	    /**
	     * The change handler for the `spacing` property of a dock panel.
	     */
	    function onSpacingChanged(owner, old, spacing) {
	        var root = getRoot(owner);
	        if (root instanceof DockSplitPanel) {
	            updateSpacing(root, spacing);
	        }
	    }
	    /**
	     * Recursively update the spacing of a dock split panel.
	     */
	    function updateSpacing(panel, spacing) {
	        for (var i = 0, n = panel.childCount(); i < n; ++i) {
	            var child = panel.childAt(i);
	            if (child instanceof DockSplitPanel) {
	                updateSpacing(child, spacing);
	            }
	        }
	        panel.spacing = spacing;
	    }
	    /**
	     * Throw an internal dock panel error.
	     */
	    function internalError() {
	        throw new Error('Internal DockPanel Error.');
	    }
	    /**
	     * Test whether a dock panel contains the given widget.
	     *
	     * For this condition to be `true`, the widget must be a logical child
	     * of a `DockTabPanel`, which itself must be a proper descendant of the
	     * given dock panel.
	     */
	    function dockPanelContains(owner, widget) {
	        var stack = widget.parent;
	        if (!stack) {
	            return false;
	        }
	        var tabs = stack.parent;
	        if (!(tabs instanceof DockTabPanel)) {
	            return false;
	        }
	        var parent = tabs.parent;
	        while (parent) {
	            if (parent === owner) {
	                return true;
	            }
	            if (!(parent instanceof DockSplitPanel)) {
	                return false;
	            }
	            parent = parent.parent;
	        }
	        return false;
	    }
	    /**
	     * Find the ancestor dock tab panel for the given widget.
	     *
	     * This assumes the widget already belongs to a dock panel, and will
	     * throw an error if that assumption does not hold.
	     */
	    function findTabPanel(widget) {
	        var stack = widget.parent;
	        if (!stack) {
	            internalError();
	        }
	        var tabs = stack.parent;
	        if (!(tabs instanceof DockTabPanel)) {
	            internalError();
	        }
	        return tabs;
	    }
	    /**
	     * Find the first dock tab panel for the given dock panel.
	     *
	     * This returns `null` if the dock panel has no content. It will throw
	     * an error if the structure of the dock panel is found to be invalid.
	     */
	    function findFirstTabPanel(owner) {
	        var root = getRoot(owner);
	        while (root) {
	            if (root instanceof DockTabPanel) {
	                return root;
	            }
	            if (!(root instanceof DockSplitPanel) || root.childCount() === 0) {
	                internalError();
	            }
	            root = root.childAt(0);
	        }
	        return null;
	    }
	    /**
	     * Get or create the first dock tab panel for the given dock panel.
	     *
	     * If dock panel has no root, a new tab panel will be created and
	     * added as the root. An error will be thrown if the structure of
	     * the dock panel is found to be invalid.
	     */
	    function ensureFirstTabPanel(owner) {
	        var tabs = findFirstTabPanel(owner);
	        if (!tabs) {
	            tabs = createTabPanel();
	            setRoot(owner, tabs);
	        }
	        return tabs;
	    }
	    /**
	     * Ensure the root panel is a splitter with the given orientation.
	     *
	     * This will throw an error if the panel does not have a current root,
	     * since that would violate the invariants of the dock panel structure.
	     */
	    function ensureSplitRoot(owner, orientation) {
	        var oldRoot = getRoot(owner);
	        if (!oldRoot) {
	            internalError();
	        }
	        if (oldRoot instanceof DockSplitPanel) {
	            if (oldRoot.orientation === orientation) {
	                return oldRoot;
	            }
	            if (oldRoot.childCount() <= 1) {
	                oldRoot.orientation = orientation;
	                return oldRoot;
	            }
	        }
	        var newRoot = new DockSplitPanel(orientation, owner.spacing);
	        newRoot.addChild(oldRoot);
	        setRoot(owner, newRoot);
	        return newRoot;
	    }
	    /**
	     * Validate the insert arguments for a dock panel.
	     *
	     * This will throw an error if the target widget is null, or if the
	     * reference widget is not null and not contained by the dock panel.
	     */
	    function validateInsertArgs(owner, widget, ref) {
	        if (!widget) {
	            throw new Error('Target widget is null.');
	        }
	        if (ref && !dockPanelContains(owner, ref)) {
	            throw new Error('Reference widget not contained by the dock panel.');
	        }
	    }
	    /**
	     * Recursively iterate over the dock tab panels of a root panel.
	     *
	     * Iteration stops if the callback returns anything but `undefined`.
	     */
	    function iterTabPanels(root, callback) {
	        if (root instanceof DockTabPanel) {
	            return callback(root);
	        }
	        if (!(root instanceof DockSplitPanel)) {
	            internalError();
	        }
	        for (var i = 0; i < root.childCount(); ++i) {
	            var child = root.childAt(i);
	            var result = iterTabPanels(child, callback);
	            if (result !== void 0)
	                return result;
	        }
	        return void 0;
	    }
	    /**
	     * Get the root edge zone for the given node and client position.
	     *
	     * This assumes the position lies within the node's client rect.
	     *
	     * Returns the `Invalid` zone if the position is not within an edge.
	     */
	    function getEdgeZone(node, x, y) {
	        var zone;
	        var rect = node.getBoundingClientRect();
	        if (x < rect.left + EDGE_SIZE) {
	            if (y - rect.top < x - rect.left) {
	                zone = 0 /* RootTop */;
	            }
	            else if (rect.bottom - y < x - rect.left) {
	                zone = 3 /* RootBottom */;
	            }
	            else {
	                zone = 1 /* RootLeft */;
	            }
	        }
	        else if (x >= rect.right - EDGE_SIZE) {
	            if (y - rect.top < rect.right - x) {
	                zone = 0 /* RootTop */;
	            }
	            else if (rect.bottom - y < rect.right - x) {
	                zone = 3 /* RootBottom */;
	            }
	            else {
	                zone = 2 /* RootRight */;
	            }
	        }
	        else if (y < rect.top + EDGE_SIZE) {
	            zone = 0 /* RootTop */;
	        }
	        else if (y >= rect.bottom - EDGE_SIZE) {
	            zone = 3 /* RootBottom */;
	        }
	        else {
	            zone = 10 /* Invalid */;
	        }
	        return zone;
	    }
	    /**
	     * Get the panel zone for the given node and position.
	     *
	     * This assumes the position lies within the node's client rect.
	     *
	     * This always returns a valid zone.
	     */
	    function getPanelZone(node, x, y) {
	        var zone;
	        var rect = node.getBoundingClientRect();
	        var fracX = (x - rect.left) / rect.width;
	        var fracY = (y - rect.top) / rect.height;
	        if (fracX < 1 / 3) {
	            if (fracY < fracX) {
	                zone = 5 /* PanelTop */;
	            }
	            else if (1 - fracY < fracX) {
	                zone = 8 /* PanelBottom */;
	            }
	            else {
	                zone = 6 /* PanelLeft */;
	            }
	        }
	        else if (fracX < 2 / 3) {
	            if (fracY < 1 / 3) {
	                zone = 5 /* PanelTop */;
	            }
	            else if (fracY < 2 / 3) {
	                zone = 9 /* PanelCenter */;
	            }
	            else {
	                zone = 8 /* PanelBottom */;
	            }
	        }
	        else {
	            if (fracY < 1 - fracX) {
	                zone = 5 /* PanelTop */;
	            }
	            else if (fracY > fracX) {
	                zone = 8 /* PanelBottom */;
	            }
	            else {
	                zone = 7 /* PanelRight */;
	            }
	        }
	        return zone;
	    }
	    /**
	     * The current tab drag object.
	     */
	    var currentDrag = null;
	    /**
	     * Create a new tab panel for a dock panel.
	     */
	    function createTabPanel() {
	        var panel = new DockTabPanel();
	        panel.tabBar.tabDetachRequested.connect(onTabDetachRequested);
	        panel.stackedPanel.widgetRemoved.connect(onWidgetRemoved);
	        return panel;
	    }
	    /**
	     * Remove an empty dock tab panel from the hierarchy.
	     *
	     * This ensures that the hierarchy is kept consistent by merging an
	     * ancestor split panel when it contains only a single child widget.
	     */
	    function removeTabPanel(tabPanel) {
	        // Assert the tab panel is empty.
	        if (tabPanel.childCount() !== 0) {
	            internalError();
	        }
	        // If the parent of the tab panel is a dock panel, just remove it.
	        if (tabPanel.parent instanceof DockPanel) {
	            setRoot(tabPanel.parent, null);
	            tabPanel.dispose();
	            return;
	        }
	        // Assert the tab panel parent is a dock split panel.
	        if (!(tabPanel.parent instanceof DockSplitPanel)) {
	            internalError();
	        }
	        // Cast the tab panel parent to a dock split panel.
	        var splitPanel = tabPanel.parent;
	        // Assert the split panel has at least two children.
	        if (splitPanel.childCount() < 2) {
	            internalError();
	        }
	        // Dispose the tab panel to ensure its resources are released.
	        tabPanel.dispose();
	        // If the split panel still has multiple children, there is
	        // nothing more to do.
	        if (splitPanel.childCount() > 1) {
	            return;
	        }
	        // Extract the remaining child from the split panel.
	        var child = splitPanel.childAt(0);
	        // Assert the remaining child is a proper panel type.
	        if (!(child instanceof DockTabPanel) && !(child instanceof DockSplitPanel)) {
	            internalError();
	        }
	        // If the parent of the split panel is a dock panel, replace it.
	        if (splitPanel.parent instanceof DockPanel) {
	            setRoot(splitPanel.parent, child);
	            splitPanel.dispose();
	            return;
	        }
	        // Assert the split panel parent is a dock split panel.
	        if (!(splitPanel.parent instanceof DockSplitPanel)) {
	            internalError();
	        }
	        // Cast the split panel parent to a dock split panel.
	        var grandPanel = splitPanel.parent;
	        // If the child is a dock tab panel, replace the split panel.
	        if (child instanceof DockTabPanel) {
	            var sizes = grandPanel.sizes();
	            var index_1 = grandPanel.childIndex(splitPanel);
	            splitPanel.parent = null;
	            grandPanel.insertChild(index_1, child);
	            grandPanel.setSizes(sizes);
	            splitPanel.dispose();
	            return;
	        }
	        // Cast the child to a dock split panel.
	        var childSplit = child;
	        // Child splitters have an orthogonal orientation to their parent.
	        // Assert the orientation of the child matches the grand parent.
	        if (childSplit.orientation !== grandPanel.orientation) {
	            internalError();
	        }
	        // The grand children can now be merged with their grand parent.
	        // Start by fetching the relevant current sizes and insert index.
	        var index = grandPanel.childIndex(splitPanel);
	        var childSizes = childSplit.sizes();
	        var grandSizes = grandPanel.sizes();
	        // Remove the split panel and store its share of the size.
	        splitPanel.parent = null;
	        var sizeShare = arrays.removeAt(grandSizes, index);
	        // Merge the grand children and maintain their relative size.
	        for (var i = 0; childSplit.childCount() !== 0; ++i) {
	            grandPanel.insertChild(index + i, childSplit.childAt(0));
	            arrays.insert(grandSizes, index + i, sizeShare * childSizes[i]);
	        }
	        // Update the grand parent sizes and dispose the removed panel.
	        grandPanel.setSizes(grandSizes);
	        splitPanel.dispose();
	    }
	    /**
	     * Handle the `tabDetachRequested` signal from a dock tab bar.
	     */
	    function onTabDetachRequested(sender, args) {
	        // Do nothing if a drag is already in progress.
	        if (currentDrag) {
	            return;
	        }
	        // Release the tab bar's hold on the mouse.
	        sender.releaseMouse();
	        // Setup the mime data for the drag operation.
	        var mimeData = new phosphor_dragdrop_1.MimeData();
	        var widget = args.item;
	        mimeData.setData(FACTORY_MIME, function () { return widget; });
	        // Create the drag image for the drag operation.
	        var tab = sender.tabAt(args.index);
	        var dragImage = tab.cloneNode(true);
	        // Create the drag object to manage the drag-drop operation.
	        currentDrag = new phosphor_dragdrop_1.Drag({
	            mimeData: mimeData,
	            dragImage: dragImage,
	            proposedAction: phosphor_dragdrop_1.DropAction.Move,
	            supportedActions: phosphor_dragdrop_1.DropActions.Move,
	        });
	        // Start the drag operation and cleanup when done.
	        tab.classList.add(HIDDEN_CLASS);
	        currentDrag.start(args.clientX, args.clientY).then(function () {
	            currentDrag = null;
	            tab.classList.remove(HIDDEN_CLASS);
	        });
	    }
	    /**
	     * Handle the `widgetRemvoed` signal for a dock stacked panel.
	     */
	    function onWidgetRemoved(sender, widget) {
	        if (sender.childCount() === 0) {
	            removeTabPanel(sender.parent);
	        }
	    }
	})(DockPanelPrivate || (DockPanelPrivate = {}));


/***/ },
/* 31 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var phosphor_domutil_1 = __webpack_require__(7);
	/**
	 * The class name added to drag image nodes.
	 */
	var DRAG_IMAGE_CLASS = 'p-mod-drag-image';
	/**
	 * An enum which defines the possible independent drop actions.
	 */
	(function (DropAction) {
	    /**
	     * No item may be dropped.
	     */
	    DropAction[DropAction["None"] = 0] = "None";
	    /**
	     * The item is copied into its new location.
	     */
	    DropAction[DropAction["Copy"] = 1] = "Copy";
	    /**
	     * The item is linked to its new location.
	     */
	    DropAction[DropAction["Link"] = 2] = "Link";
	    /**
	     * The item is moved to its new location.
	     */
	    DropAction[DropAction["Move"] = 4] = "Move";
	})(exports.DropAction || (exports.DropAction = {}));
	var DropAction = exports.DropAction;
	/**
	 * An enum which defines the combinations of possible drop actions.
	 */
	(function (DropActions) {
	    /**
	     * No drop action is supported.
	     */
	    DropActions[DropActions["None"] = 0] = "None";
	    /**
	     * The item may be copied to its new location.
	     */
	    DropActions[DropActions["Copy"] = 1] = "Copy";
	    /**
	     * The item may be linked to its new location.
	     */
	    DropActions[DropActions["Link"] = 2] = "Link";
	    /**
	     * The item may be moved to its new location.
	     */
	    DropActions[DropActions["Move"] = 4] = "Move";
	    /**
	     * The item may be copied or linked to its new location.
	     */
	    DropActions[DropActions["CopyLink"] = 3] = "CopyLink";
	    /**
	     * The item may be copied or moved to its new location.
	     */
	    DropActions[DropActions["CopyMove"] = 5] = "CopyMove";
	    /**
	     * The item may be linked or moved to its new location.
	     */
	    DropActions[DropActions["LinkMove"] = 6] = "LinkMove";
	    /**
	     * The item may be copied, linked, or moved to its new location.
	     */
	    DropActions[DropActions["All"] = 7] = "All";
	})(exports.DropActions || (exports.DropActions = {}));
	var DropActions = exports.DropActions;
	/**
	 * An object which stores MIME data for drag-drop operations.
	 *
	 * #### Notes
	 * This class does not attempt to enforce "correctness" of MIME types
	 * and their associated data. Since this drag-drop system 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 contains 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] : void 0;
	    };
	    /**
	     * 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)
	            return;
	        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;
	/**
	 * 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 canceled at any time by pressing `Escape`
	 * or by disposing the drag object.
	 *
	 * #### 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; two features which are
	 * not possible with the native drag-drop APIs.
	 */
	var Drag = (function () {
	    /**
	     * Construct a new drag object.
	     *
	     * @param options - The options for initializing the drag.
	     */
	    function Drag(options) {
	        this._disposed = false;
	        this._source = null;
	        this._mimeData = null;
	        this._dragImage = null;
	        this._dropAction = DropAction.None;
	        this._proposedAction = DropAction.Copy;
	        this._supportedActions = DropActions.Copy;
	        this._override = null;
	        this._currentTarget = null;
	        this._currentElement = null;
	        this._promise = null;
	        this._resolve = null;
	        this._mimeData = options.mimeData;
	        if (options.dragImage !== void 0) {
	            this._dragImage = options.dragImage;
	        }
	        if (options.proposedAction !== void 0) {
	            this._proposedAction = options.proposedAction;
	        }
	        if (options.supportedActions !== void 0) {
	            this._supportedActions = options.supportedActions;
	        }
	        if (options.source !== void 0) {
	            this._source = options.source;
	        }
	    }
	    /**
	     * Dispose of the resources held by the drag object.
	     *
	     * #### Notes
	     * This will cancel the drag operation if it is active.
	     *
	     * All calls made after the first call to this method are a no-op.
	     */
	    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 = createMouseEvent('mouseup', -1, -1);
	            dispatchDragLeave(this, this._currentTarget, null, event_1);
	        }
	        // Finalize the drag object with `None`.
	        this._finalize(DropAction.None);
	    };
	    Object.defineProperty(Drag.prototype, "isDisposed", {
	        /**
	         * Test whether the drag object is disposed.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Drag.prototype, "mimeData", {
	        /**
	         * Get the mime data for the drag object.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._mimeData;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Drag.prototype, "dragImage", {
	        /**
	         * Get the drag image element for the drag object.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._dragImage;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Drag.prototype, "proposedAction", {
	        /**
	         * Get the proposed drop action for the drag object.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._proposedAction;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Drag.prototype, "supportedActions", {
	        /**
	         * Get the supported drop actions for the drag object.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._supportedActions;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Drag.prototype, "source", {
	        /**
	         * Get the drag source for the drag object.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._source;
	        },
	        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 `DropAction.None`.
	     *
	     * The drag object will be automatically disposed when drag operation
	     * completes. This makes `Drag` objects suitable 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(DropAction.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 = 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);
	        // 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(DropAction.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 === DropAction.None) {
	            dispatchDragLeave(this, this._currentTarget, null, event);
	            this._finalize(DropAction.None);
	            return;
	        }
	        // Dispatch the drop event at the current target and finalize
	        // with the resulting drop action.
	        var action = 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 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;
	        // Note: drag enter fires *before* drag leave according to spec.
	        // https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model
	        // If the indicated element changes from the previous iteration,
	        // and is different from the current target, dispatch the enter
	        // events and compute the new target element.
	        if (currElem !== prevElem && currElem !== currTarget) {
	            currTarget = 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;
	            dispatchDragLeave(this, prevTarget, currTarget, event);
	        }
	        // Dispatch the drag over event and update the drop action.
	        var action = 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(DRAG_IMAGE_CLASS);
	        var style = this._dragImage.style;
	        style.pointerEvents = 'none';
	        style.position = 'absolute';
	        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) {
	        if ((action & this._supportedActions) === 0) {
	            action = DropAction.None;
	        }
	        if (this._override && this._dropAction === action) {
	            return;
	        }
	        switch (action) {
	            case DropAction.None:
	                this._dropAction = action;
	                this._override = phosphor_domutil_1.overrideCursor('no-drop');
	                break;
	            case DropAction.Copy:
	                this._dropAction = action;
	                this._override = phosphor_domutil_1.overrideCursor('copy');
	                break;
	            case DropAction.Link:
	                this._dropAction = action;
	                this._override = phosphor_domutil_1.overrideCursor('alias');
	                break;
	            case DropAction.Move:
	                this._dropAction = action;
	                this._override = phosphor_domutil_1.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();
	        // Clear the mime data.
	        if (this._mimeData)
	            this._mimeData.clear();
	        // Clear the internal drag state.
	        this._disposed = true;
	        this._source = null;
	        this._mimeData = null;
	        this._dragImage = null;
	        this._dropAction = DropAction.None;
	        this._proposedAction = DropAction.None;
	        this._supportedActions = DropActions.None;
	        this._override = null;
	        this._currentTarget = null;
	        this._currentElement = null;
	        this._promise = null;
	        this._resolve = null;
	        // Resolve the promise to the given drop action, if possible.
	        if (resolve)
	            resolve(action);
	    };
	    return Drag;
	}());
	exports.Drag = Drag;
	/**
	 * 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;
	}
	/**
	 * 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 and cast to a custom drag event.
	    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);
	    // Add the custom drag event data.
	    dragEvent.mimeData = drag.mimeData;
	    dragEvent.dropAction = DropAction.None;
	    dragEvent.proposedAction = drag.proposedAction;
	    dragEvent.supportedActions = drag.supportedActions;
	    dragEvent.source = drag.source;
	    // Return the fully initialized drag event.
	    return dragEvent;
	}
	/**
	 * 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;
	}
	/**
	 * 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);
	}
	/**
	 * 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 DropAction.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 DropAction.None;
	}
	/**
	 * 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 DropAction.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 DropAction.None;
	}


/***/ },
/* 32 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	__export(__webpack_require__(33));
	__export(__webpack_require__(34));
	__webpack_require__(35);


/***/ },
/* 33 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var arrays = __webpack_require__(3);
	var phosphor_boxengine_1 = __webpack_require__(6);
	var phosphor_domutil_1 = __webpack_require__(7);
	var phosphor_messaging_1 = __webpack_require__(13);
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_properties_1 = __webpack_require__(17);
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * The class name added to hidden split handles.
	 */
	var HIDDEN_CLASS = 'p-mod-hidden';
	/**
	 * The class name added to horizontal split panels.
	 */
	var HORIZONTAL_CLASS = 'p-mod-horizontal';
	/**
	 * The class name added to vertical split panels.
	 */
	var VERTICAL_CLASS = 'p-mod-vertical';
	/**
	 * The orientation of a split layout.
	 */
	(function (Orientation) {
	    /**
	     * Left-to-right horizontal orientation.
	     */
	    Orientation[Orientation["Horizontal"] = 0] = "Horizontal";
	    /**
	     * Top-to-bottom vertical orientation.
	     */
	    Orientation[Orientation["Vertical"] = 1] = "Vertical";
	})(exports.Orientation || (exports.Orientation = {}));
	var Orientation = exports.Orientation;
	/**
	 * A layout which arranges its children into resizable sections.
	 */
	var SplitLayout = (function (_super) {
	    __extends(SplitLayout, _super);
	    /**
	     * Construct a new split layout.
	     *
	     * @param factory - The handle factory for creating split handles.
	     */
	    function SplitLayout(factory) {
	        _super.call(this);
	        this._fixed = 0;
	        this._spacing = 3;
	        this._normed = false;
	        this._box = null;
	        this._sizers = [];
	        this._handles = [];
	        this._orientation = Orientation.Horizontal;
	        this._factory = factory;
	    }
	    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;
	            }
	            SplitLayoutPrivate.toggleOrientation(this.parent, value);
	            this.parent.fit();
	        },
	        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 = Math.max(0, value | 0);
	            if (this._spacing === value) {
	                return;
	            }
	            this._spacing = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.fit();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the normalized sizes of the widgets in the layout.
	     *
	     * @returns The normalized sizes of the widgets in the layout.
	     */
	    SplitLayout.prototype.sizes = function () {
	        return SplitLayoutPrivate.normalize(this._sizers.map(function (s) { return s.size; }));
	    };
	    /**
	     * Set the relative sizes for the child widgets in the layout.
	     *
	     * @param sizes - The relative sizes for the children in the layout.
	     *   These values will be normalized to the available layout space.
	     *
	     * #### Notes
	     * Extra values are ignored, too few will yield an undefined layout.
	     */
	    SplitLayout.prototype.setSizes = function (sizes) {
	        var normed = SplitLayoutPrivate.normalize(sizes);
	        for (var i = 0, n = this._sizers.length; i < n; ++i) {
	            var hint = Math.max(0, normed[i] || 0);
	            var sizer = this._sizers[i];
	            sizer.sizeHint = hint;
	            sizer.size = hint;
	        }
	        this._normed = true;
	        if (this.parent)
	            this.parent.update();
	    };
	    /**
	     * Get the handle for the widget at the given index.
	     *
	     * @param index - The index of the handle of interest.
	     *
	     * @returns The handle for the given index, or `undefined`.
	     */
	    SplitLayout.prototype.handleAt = function (index) {
	        return this._handles[index];
	    };
	    /**
	     * Move a split handle to the specified offset position.
	     *
	     * @param index - The index of the handle of the interest.
	     *
	     * @param position - The desired offset position of the handle. This
	     *   is the absolute position relative to the origin of the parent.
	     *
	     * #### Notes
	     * This will move the handle as close as possible to the desired
	     * position. The sibling children 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(HIDDEN_CLASS)) {
	            return;
	        }
	        // Compute the delta movement for the handle.
	        var delta;
	        if (this._orientation === Orientation.Horizontal) {
	            delta = position - handle.offsetLeft;
	        }
	        else {
	            delta = position - handle.offsetTop;
	        }
	        // Bail if there is no handle movement.
	        if (delta === 0) {
	            return;
	        }
	        // Prevent item 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 movement.
	        if (delta > 0) {
	            SplitLayoutPrivate.growSizer(this._sizers, index, delta);
	        }
	        else {
	            SplitLayoutPrivate.shrinkSizer(this._sizers, index, -delta);
	        }
	        // Update the layout of the child widgets.
	        if (this.parent)
	            this.parent.update();
	    };
	    /**
	     * Initialize the children of the layout.
	     *
	     * #### Notes
	     * This method is called automatically when the layout is installed
	     * on its parent widget.
	     */
	    SplitLayout.prototype.initialize = function () {
	        SplitLayoutPrivate.toggleOrientation(this.parent, this.orientation);
	        _super.prototype.initialize.call(this);
	    };
	    /**
	     * Attach a child widget to the parent's DOM node.
	     *
	     * @param index - The current index of the child in the layout.
	     *
	     * @param child - The child widget to attach to the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    SplitLayout.prototype.attachChild = function (index, child) {
	        var handle = SplitLayoutPrivate.createHandle(this._factory);
	        var average = SplitLayoutPrivate.averageSize(this._sizers);
	        var sizer = SplitLayoutPrivate.createSizer(average);
	        arrays.insert(this._sizers, index, sizer);
	        arrays.insert(this._handles, index, handle);
	        SplitLayoutPrivate.prepareGeometry(child);
	        this.parent.node.appendChild(child.node);
	        this.parent.node.appendChild(handle);
	        if (this.parent.isAttached)
	            phosphor_messaging_1.sendMessage(child, phosphor_widget_1.Widget.MsgAfterAttach);
	        this.parent.fit();
	    };
	    /**
	     * Move a child widget in the parent's DOM node.
	     *
	     * @param fromIndex - The previous index of the child in the layout.
	     *
	     * @param toIndex - The current index of the child in the layout.
	     *
	     * @param child - The child widget to move in the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    SplitLayout.prototype.moveChild = function (fromIndex, toIndex, child) {
	        arrays.move(this._sizers, fromIndex, toIndex);
	        arrays.move(this._handles, fromIndex, toIndex);
	        this.parent.fit(); // fit instead of update to show/hide handles
	    };
	    /**
	     * Detach a child widget from the parent's DOM node.
	     *
	     * @param index - The previous index of the child in the layout.
	     *
	     * @param child - The child widget to detach from the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    SplitLayout.prototype.detachChild = function (index, child) {
	        var sizer = arrays.removeAt(this._sizers, index);
	        var handle = arrays.removeAt(this._handles, index);
	        if (this.parent.isAttached)
	            phosphor_messaging_1.sendMessage(child, phosphor_widget_1.Widget.MsgBeforeDetach);
	        this.parent.node.removeChild(child.node);
	        this.parent.node.removeChild(handle);
	        SplitLayoutPrivate.resetGeometry(child);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on an `'after-show'` message.
	     */
	    SplitLayout.prototype.onAfterShow = function (msg) {
	        _super.prototype.onAfterShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    SplitLayout.prototype.onAfterAttach = function (msg) {
	        _super.prototype.onAfterAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    SplitLayout.prototype.onChildShown = function (msg) {
	        if (SplitLayoutPrivate.IsIE) {
	            phosphor_messaging_1.sendMessage(this.parent, phosphor_widget_1.Widget.MsgFitRequest);
	        }
	        else {
	            this.parent.fit();
	        }
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    SplitLayout.prototype.onChildHidden = function (msg) {
	        if (SplitLayoutPrivate.IsIE) {
	            phosphor_messaging_1.sendMessage(this.parent, phosphor_widget_1.Widget.MsgFitRequest);
	        }
	        else {
	            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 child widgets.
	     */
	    SplitLayout.prototype._fit = function () {
	        // Update the handles and track the visible widget count.
	        var nVisible = 0;
	        var lastHandle = null;
	        for (var i = 0, n = this.childCount(); i < n; ++i) {
	            var handle = this._handles[i];
	            if (this.childAt(i).isHidden) {
	                handle.classList.add(HIDDEN_CLASS);
	            }
	            else {
	                handle.classList.remove(HIDDEN_CLASS);
	                lastHandle = handle;
	                nVisible++;
	            }
	        }
	        // Hide the handle for the last visible child.
	        if (lastHandle)
	            lastHandle.classList.add(HIDDEN_CLASS);
	        // Update the fixed space for the visible items.
	        this._fixed = this._spacing * Math.max(0, nVisible - 1);
	        // Setup the initial size limits.
	        var minW = 0;
	        var minH = 0;
	        var maxW = Infinity;
	        var maxH = Infinity;
	        var horz = this._orientation === Orientation.Horizontal;
	        if (horz) {
	            minW = this._fixed;
	            maxW = nVisible > 0 ? minW : maxW;
	        }
	        else {
	            minH = this._fixed;
	            maxH = nVisible > 0 ? minH : maxH;
	        }
	        // Update the sizers and computed size limits.
	        for (var i = 0, n = this.childCount(); i < n; ++i) {
	            var child = this.childAt(i);
	            var sizer = this._sizers[i];
	            if (sizer.size > 0) {
	                sizer.sizeHint = sizer.size;
	            }
	            if (child.isHidden) {
	                sizer.minSize = 0;
	                sizer.maxSize = 0;
	                continue;
	            }
	            var limits = phosphor_domutil_1.sizeLimits(child.node);
	            sizer.stretch = SplitLayout.getStretch(child);
	            if (horz) {
	                sizer.minSize = limits.minWidth;
	                sizer.maxSize = limits.maxWidth;
	                minW += limits.minWidth;
	                maxW += limits.maxWidth;
	                minH = Math.max(minH, limits.minHeight);
	                maxH = Math.min(maxH, limits.maxHeight);
	            }
	            else {
	                sizer.minSize = limits.minHeight;
	                sizer.maxSize = limits.maxHeight;
	                minH += limits.minHeight;
	                maxH += limits.maxHeight;
	                minW = Math.max(minW, limits.minWidth);
	                maxW = Math.min(maxW, limits.maxWidth);
	            }
	        }
	        // Update the box sizing and add it to the size constraints.
	        var box = this._box = phosphor_domutil_1.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        maxW += box.horizontalSum;
	        maxH += box.verticalSum;
	        // Update the parent's size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        style.maxWidth = maxW === Infinity ? 'none' : maxW + "px";
	        style.maxHeight = maxH === Infinity ? 'none' : maxH + "px";
	        // Notify the ancestor that it should fit immediately.
	        var ancestor = this.parent.parent;
	        if (ancestor)
	            phosphor_messaging_1.sendMessage(ancestor, phosphor_widget_1.Widget.MsgFitRequest);
	        // Notify the parent that it should update immediately.
	        phosphor_messaging_1.sendMessage(this.parent, phosphor_widget_1.Widget.MsgUpdateRequest);
	    };
	    /**
	     * Update the layout position and size of the child widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    SplitLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Bail early if there are no children to layout.
	        if (this.childCount() === 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.
	        var box = this._box || (this._box = phosphor_domutil_1.boxSizing(this.parent.node));
	        // Compute the actual layout bounds adjusted for border and padding.
	        var top = box.paddingTop;
	        var left = box.paddingLeft;
	        var width = offsetWidth - box.horizontalSum;
	        var height = offsetHeight - box.verticalSum;
	        // Compute the adjusted layout space.
	        var space;
	        var horz = this._orientation === 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._normed) {
	            for (var _i = 0, _a = this._sizers; _i < _a.length; _i++) {
	                var sizer = _a[_i];
	                sizer.sizeHint *= space;
	            }
	            this._normed = false;
	        }
	        // Distribute the layout space to the box sizers.
	        phosphor_boxengine_1.boxCalc(this._sizers, space);
	        // Layout the children using the computed box sizes.
	        var spacing = this._spacing;
	        for (var i = 0, n = this.childCount(); i < n; ++i) {
	            var child = this.childAt(i);
	            if (child.isHidden) {
	                continue;
	            }
	            var handle = this._handles[i];
	            var size = this._sizers[i].size;
	            if (horz) {
	                SplitLayoutPrivate.setGeometry(child, left, top, size, height);
	                left += size;
	                SplitLayoutPrivate.setHandleGeo(handle, left, top, spacing, height);
	                left += spacing;
	            }
	            else {
	                SplitLayoutPrivate.setGeometry(child, left, top, width, size);
	                top += size;
	                SplitLayoutPrivate.setHandleGeo(handle, left, top, width, spacing);
	                top += spacing;
	            }
	        }
	    };
	    return SplitLayout;
	})(phosphor_panel_1.PanelLayout);
	exports.SplitLayout = SplitLayout;
	/**
	 * The namespace for the `SplitLayout` class statics.
	 */
	var SplitLayout;
	(function (SplitLayout) {
	    /**
	     * A convenience alias of the `Horizontal` [[Orientation]].
	     */
	    SplitLayout.Horizontal = Orientation.Horizontal;
	    /**
	     * A convenience alias of the `Vertical` [[Orientation]].
	     */
	    SplitLayout.Vertical = Orientation.Vertical;
	    /**
	     * 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 SplitLayoutPrivate.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) {
	        SplitLayoutPrivate.stretchProperty.set(widget, value);
	    }
	    SplitLayout.setStretch = setStretch;
	})(SplitLayout = exports.SplitLayout || (exports.SplitLayout = {}));
	/**
	 * The namespace for the `SplitLayout` class private data.
	 */
	var SplitLayoutPrivate;
	(function (SplitLayoutPrivate) {
	    /**
	     * A flag indicating whether the browser is IE.
	     */
	    SplitLayoutPrivate.IsIE = /Trident/.test(navigator.userAgent);
	    /**
	     * The property descriptor for a widget stretch factor.
	     */
	    SplitLayoutPrivate.stretchProperty = new phosphor_properties_1.Property({
	        name: 'stretch',
	        value: 0,
	        coerce: function (owner, value) { return Math.max(0, value | 0); },
	        changed: onChildPropertyChanged,
	    });
	    /**
	     * Create a new box sizer with the given size hint.
	     */
	    function createSizer(size) {
	        var sizer = new phosphor_boxengine_1.BoxSizer();
	        sizer.sizeHint = size | 0;
	        return sizer;
	    }
	    SplitLayoutPrivate.createSizer = createSizer;
	    /**
	     * Create a new split handle using the given factory.
	     */
	    function createHandle(factory) {
	        var handle = factory.createHandle();
	        handle.style.position = 'absolute';
	        return handle;
	    }
	    SplitLayoutPrivate.createHandle = createHandle;
	    /**
	     * Toggle the CSS orientation class for the given widget.
	     */
	    function toggleOrientation(widget, orient) {
	        widget.toggleClass(HORIZONTAL_CLASS, orient === Orientation.Horizontal);
	        widget.toggleClass(VERTICAL_CLASS, orient === Orientation.Vertical);
	    }
	    SplitLayoutPrivate.toggleOrientation = toggleOrientation;
	    /**
	     * Prepare the layout geometry for the given child widget.
	     */
	    function prepareGeometry(widget) {
	        widget.node.style.position = 'absolute';
	    }
	    SplitLayoutPrivate.prepareGeometry = prepareGeometry;
	    /**
	     * Reset the layout geometry for the given child widget.
	     */
	    function resetGeometry(widget) {
	        var rect = rectProperty.get(widget);
	        var style = widget.node.style;
	        rect.top = NaN;
	        rect.left = NaN;
	        rect.width = NaN;
	        rect.height = NaN;
	        style.position = '';
	        style.top = '';
	        style.left = '';
	        style.width = '';
	        style.height = '';
	    }
	    SplitLayoutPrivate.resetGeometry = resetGeometry;
	    /**
	     * Set the layout geometry of a child widget.
	     */
	    function setGeometry(widget, left, top, width, height) {
	        var resized = false;
	        var style = widget.node.style;
	        var rect = rectProperty.get(widget);
	        if (rect.top !== top) {
	            rect.top = top;
	            style.top = top + "px";
	        }
	        if (rect.left !== left) {
	            rect.left = left;
	            style.left = left + "px";
	        }
	        if (rect.width !== width) {
	            resized = true;
	            rect.width = width;
	            style.width = width + "px";
	        }
	        if (rect.height !== height) {
	            resized = true;
	            rect.height = height;
	            style.height = height + "px";
	        }
	        if (resized) {
	            phosphor_messaging_1.sendMessage(widget, new phosphor_widget_1.ResizeMessage(width, height));
	        }
	    }
	    SplitLayoutPrivate.setGeometry = setGeometry;
	    /**
	     * Set the layout geometry of a split handle.
	     */
	    function setHandleGeo(handle, left, top, width, height) {
	        var style = handle.style;
	        style.top = top + "px";
	        style.left = left + "px";
	        style.width = width + "px";
	        style.height = height + "px";
	    }
	    SplitLayoutPrivate.setHandleGeo = setHandleGeo;
	    /**
	     * Compute the average size of the given box sizers.
	     */
	    function averageSize(sizers) {
	        if (sizers.length === 0)
	            return 0;
	        return sizers.reduce(function (v, s) { return v + s.size; }, 0) / sizers.length;
	    }
	    SplitLayoutPrivate.averageSize = averageSize;
	    /**
	     * Normalize an array of positive values.
	     */
	    function normalize(values) {
	        var n = values.length;
	        if (n === 0) {
	            return [];
	        }
	        var sum = 0;
	        for (var i = 0; i < n; ++i) {
	            sum += values[i];
	        }
	        var result = new Array(n);
	        if (sum === 0) {
	            for (var i = 0; i < n; ++i) {
	                result[i] = 1 / n;
	            }
	        }
	        else {
	            for (var i = 0; i < n; ++i) {
	                result[i] = values[i] / sum;
	            }
	        }
	        return result;
	    }
	    SplitLayoutPrivate.normalize = normalize;
	    /**
	     * Grow a sizer to the right by a positive delta and adjust neighbors.
	     */
	    function growSizer(sizers, index, delta) {
	        var growLimit = 0;
	        for (var i = 0; i <= index; ++i) {
	            var sizer = sizers[i];
	            growLimit += sizer.maxSize - sizer.size;
	        }
	        var shrinkLimit = 0;
	        for (var i = index + 1, n = sizers.length; i < n; ++i) {
	            var sizer = sizers[i];
	            shrinkLimit += sizer.size - sizer.minSize;
	        }
	        delta = Math.min(delta, growLimit, shrinkLimit);
	        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;
	            }
	        }
	        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;
	            }
	        }
	    }
	    SplitLayoutPrivate.growSizer = growSizer;
	    /**
	     * Shrink a sizer to the left by a positive delta and adjust neighbors.
	     */
	    function shrinkSizer(sizers, index, delta) {
	        var growLimit = 0;
	        for (var i = index + 1, n = sizers.length; i < n; ++i) {
	            var sizer = sizers[i];
	            growLimit += sizer.maxSize - sizer.size;
	        }
	        var shrinkLimit = 0;
	        for (var i = 0; i <= index; ++i) {
	            var sizer = sizers[i];
	            shrinkLimit += sizer.size - sizer.minSize;
	        }
	        delta = Math.min(delta, growLimit, shrinkLimit);
	        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;
	            }
	        }
	        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;
	            }
	        }
	    }
	    SplitLayoutPrivate.shrinkSizer = shrinkSizer;
	    /**
	     * A property descriptor for a widget offset rect.
	     */
	    var rectProperty = new phosphor_properties_1.Property({
	        name: 'rect',
	        create: function () { return ({ top: NaN, left: NaN, width: NaN, height: NaN }); },
	    });
	    /**
	     * The change handler for the attached child properties.
	     */
	    function onChildPropertyChanged(child) {
	        var parent = child.parent;
	        var layout = parent && parent.layout;
	        if (layout instanceof SplitLayout)
	            parent.fit();
	    }
	})(SplitLayoutPrivate || (SplitLayoutPrivate = {}));


/***/ },
/* 34 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_domutil_1 = __webpack_require__(7);
	var phosphor_panel_1 = __webpack_require__(18);
	var layout_1 = __webpack_require__(33);
	/**
	 * The class name added to SplitPanel instances.
	 */
	var SPLIT_PANEL_CLASS = 'p-SplitPanel';
	/**
	 * The class name added to split panel children.
	 */
	var CHILD_CLASS = 'p-SplitPanel-child';
	/**
	 * The class name added to split panel handles.
	 */
	var HANDLE_CLASS = 'p-SplitPanel-handle';
	/**
	 * A panel which arranges its children 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.
	     */
	    function SplitPanel() {
	        _super.call(this);
	        this._pressData = null;
	        this.addClass(SPLIT_PANEL_CLASS);
	    }
	    /**
	     * Create a split layout for a split panel.
	     */
	    SplitPanel.createLayout = function () {
	        return new layout_1.SplitLayout(this);
	    };
	    /**
	     * Create a split handle for use in a split panel.
	     *
	     * #### Notes
	     * This may be reimplemented to create custom split handles.
	     */
	    SplitPanel.createHandle = function () {
	        var handle = document.createElement('div');
	        handle.className = HANDLE_CLASS;
	        return handle;
	    };
	    /**
	     * 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, "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
	    });
	    /**
	     * Get the normalized sizes of the widgets in the panel.
	     *
	     * @returns The normalized sizes of the widgets in the panel.
	     */
	    SplitPanel.prototype.sizes = function () {
	        return this.layout.sizes();
	    };
	    /**
	     * Set the relative sizes for the child widgets in the panel.
	     *
	     * @param sizes - The relative sizes for the children in the panel.
	     *   These values will be normalized to the available layout space.
	     *
	     * #### Notes
	     * Extra values are ignored, too few will yield an undefined layout.
	     */
	    SplitPanel.prototype.setSizes = function (sizes) {
	        this.layout.setSizes(sizes);
	    };
	    /**
	     * Get the split handle for the widget at the given index.
	     *
	     * @param index - The index of the widget of interest.
	     *
	     * @returns The split handle for the widget, or `undefined`.
	     */
	    SplitPanel.prototype.handleAt = function (index) {
	        return this.layout.handleAt(index);
	    };
	    /**
	     * 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 'keyup':
	            case 'keypress':
	            case 'contextmenu':
	                // Stop all input events during drag.
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    SplitPanel.prototype.onAfterAttach = function (msg) {
	        this.node.addEventListener('mousedown', this);
	    };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     */
	    SplitPanel.prototype.onBeforeDetach = 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(CHILD_CLASS);
	        this._releaseMouse();
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    SplitPanel.prototype.onChildRemoved = function (msg) {
	        msg.child.removeClass(CHILD_CLASS);
	        this._releaseMouse();
	    };
	    /**
	     * Handle the `'keydown'` event for the split panel.
	     */
	    SplitPanel.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 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 target, if any.
	        var layout = this.layout;
	        var target = event.target;
	        var _a = SplitPanelPrivate.findHandle(layout, target), index = _a.index, handle = _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('keyup', this, true);
	        document.addEventListener('keypress', this, true);
	        document.addEventListener('contextmenu', this, true);
	        // Compute the offset delta for the handle press.
	        var delta;
	        var rect = handle.getBoundingClientRect();
	        if (layout.orientation === layout_1.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 = phosphor_domutil_1.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 === layout_1.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('keyup', this, true);
	        document.removeEventListener('keypress', this, true);
	        document.removeEventListener('contextmenu', this, true);
	    };
	    return SplitPanel;
	})(phosphor_panel_1.Panel);
	exports.SplitPanel = SplitPanel;
	/**
	 * The namespace for the `SplitPanel` class statics.
	 */
	var SplitPanel;
	(function (SplitPanel) {
	    /**
	     * A convenience alias of the `Horizontal` [[Orientation]].
	     */
	    SplitPanel.Horizontal = layout_1.Orientation.Horizontal;
	    /**
	     * A convenience alias of the `Vertical` [[Orientation]].
	     */
	    SplitPanel.Vertical = layout_1.Orientation.Vertical;
	    /**
	     * 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 layout_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) {
	        layout_1.SplitLayout.setStretch(widget, value);
	    }
	    SplitPanel.setStretch = setStretch;
	})(SplitPanel = exports.SplitPanel || (exports.SplitPanel = {}));
	/**
	 * The namespace for the `SplitPanel` class private data.
	 */
	var SplitPanelPrivate;
	(function (SplitPanelPrivate) {
	    /**
	     * Find the split handle which contains the given target element.
	     */
	    function findHandle(layout, target) {
	        for (var i = 0, n = layout.childCount(); i < n; ++i) {
	            var handle = layout.handleAt(i);
	            if (handle.contains(target)) {
	                return { index: i, handle: handle };
	            }
	        }
	        return { index: -1, handle: null };
	    }
	    SplitPanelPrivate.findHandle = findHandle;
	})(SplitPanelPrivate || (SplitPanelPrivate = {}));


/***/ },
/* 35 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(36);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../css-loader/index.js!./index.css", function() {
				var newContent = require("!!./../../css-loader/index.js!./index.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 36 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2015, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n.p-SplitPanel {\n  z-index: 0;\n}\n\n\n.p-SplitPanel-child {\n  z-index: 0;\n}\n\n\n.p-SplitPanel-handle {\n  z-index: 1;\n}\n\n\n.p-SplitPanel-handle.p-mod-hidden {\n  display: none;\n}\n\n\n.p-SplitPanel-handle:after {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  content: '';\n}\n\n\n.p-SplitPanel.p-mod-horizontal > .p-SplitPanel-handle {\n  cursor: ew-resize;\n}\n\n\n.p-SplitPanel.p-mod-vertical > .p-SplitPanel-handle {\n  cursor: ns-resize;\n}\n\n\n.p-SplitPanel.p-mod-horizontal > .p-SplitPanel-handle:after {\n  left: 50%;\n  min-width: 7px;\n  transform: translateX(-50%);\n}\n\n\n.p-SplitPanel.p-mod-vertical > .p-SplitPanel-handle:after {\n  top: 50%;\n  min-height: 7px;\n  transform: translateY(-50%);\n}\n", ""]);
	
	// exports


/***/ },
/* 37 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	__export(__webpack_require__(38));
	__export(__webpack_require__(39));


/***/ },
/* 38 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_domutil_1 = __webpack_require__(7);
	var phosphor_messaging_1 = __webpack_require__(13);
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_properties_1 = __webpack_require__(17);
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * A layout where visible children are stacked atop one another.
	 *
	 * #### Notes
	 * The Z-order of the visible children follows their layout order.
	 */
	var StackedLayout = (function (_super) {
	    __extends(StackedLayout, _super);
	    function StackedLayout() {
	        _super.apply(this, arguments);
	        this._box = null;
	    }
	    /**
	     * Attach a child widget to the parent's DOM node.
	     *
	     * @param index - The current index of the child in the layout.
	     *
	     * @param child - The child widget to attach to the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    StackedLayout.prototype.attachChild = function (index, child) {
	        StackedLayoutPrivate.prepareGeometry(child);
	        this.parent.node.appendChild(child.node);
	        if (this.parent.isAttached)
	            phosphor_messaging_1.sendMessage(child, phosphor_widget_1.Widget.MsgAfterAttach);
	        this.parent.fit();
	    };
	    /**
	     * Move a child widget in the parent's DOM node.
	     *
	     * @param fromIndex - The previous index of the child in the layout.
	     *
	     * @param toIndex - The current index of the child in the layout.
	     *
	     * @param child - The child widget to move in the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    StackedLayout.prototype.moveChild = function (fromIndex, toIndex, child) {
	        this.parent.update();
	    };
	    /**
	     * Detach a child widget from the parent's DOM node.
	     *
	     * @param index - The previous index of the child in the layout.
	     *
	     * @param child - The child widget to detach from the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    StackedLayout.prototype.detachChild = function (index, child) {
	        if (this.parent.isAttached)
	            phosphor_messaging_1.sendMessage(child, phosphor_widget_1.Widget.MsgBeforeDetach);
	        this.parent.node.removeChild(child.node);
	        StackedLayoutPrivate.resetGeometry(child);
	        child.node.style.zIndex = '';
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on an `'after-show'` message.
	     */
	    StackedLayout.prototype.onAfterShow = function (msg) {
	        _super.prototype.onAfterShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    StackedLayout.prototype.onAfterAttach = function (msg) {
	        _super.prototype.onAfterAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    StackedLayout.prototype.onChildShown = function (msg) {
	        if (StackedLayoutPrivate.IsIE) {
	            phosphor_messaging_1.sendMessage(this.parent, phosphor_widget_1.Widget.MsgFitRequest);
	        }
	        else {
	            this.parent.fit();
	        }
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    StackedLayout.prototype.onChildHidden = function (msg) {
	        if (StackedLayoutPrivate.IsIE) {
	            phosphor_messaging_1.sendMessage(this.parent, phosphor_widget_1.Widget.MsgFitRequest);
	        }
	        else {
	            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 child widgets.
	     */
	    StackedLayout.prototype._fit = function () {
	        // Setup the initial size limits.
	        var minW = 0;
	        var minH = 0;
	        var maxW = Infinity;
	        var maxH = Infinity;
	        // Update the computed size limits.
	        for (var i = 0, n = this.childCount(); i < n; ++i) {
	            var child = this.childAt(i);
	            if (child.isHidden) {
	                continue;
	            }
	            var limits = phosphor_domutil_1.sizeLimits(child.node);
	            minW = Math.max(minW, limits.minWidth);
	            minH = Math.max(minH, limits.minHeight);
	            maxW = Math.min(maxW, limits.maxWidth);
	            maxH = Math.min(maxH, limits.maxHeight);
	        }
	        // Ensure max limits >= min limits.
	        maxW = Math.max(minW, maxW);
	        maxH = Math.max(minH, maxH);
	        // Update the box sizing and add it to the size constraints.
	        var box = this._box = phosphor_domutil_1.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        maxW += box.horizontalSum;
	        maxH += box.verticalSum;
	        // Update the parent's size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        style.maxWidth = maxW === Infinity ? 'none' : maxW + "px";
	        style.maxHeight = maxH === Infinity ? 'none' : maxH + "px";
	        // Notify the ancestor that it should fit immediately.
	        var ancestor = this.parent.parent;
	        if (ancestor)
	            phosphor_messaging_1.sendMessage(ancestor, phosphor_widget_1.Widget.MsgFitRequest);
	        // Notify the parent that it should update immediately.
	        phosphor_messaging_1.sendMessage(this.parent, phosphor_widget_1.Widget.MsgUpdateRequest);
	    };
	    /**
	     * Update the layout position and size of the child widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    StackedLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Bail early if there are no children to layout.
	        if (this.childCount() === 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.
	        var box = this._box || (this._box = phosphor_domutil_1.boxSizing(this.parent.node));
	        // Compute the actual layout bounds adjusted for border and padding.
	        var top = box.paddingTop;
	        var left = box.paddingLeft;
	        var width = offsetWidth - box.horizontalSum;
	        var height = offsetHeight - box.verticalSum;
	        // Update the child stacking order and layout geometry.
	        for (var i = 0, n = this.childCount(); i < n; ++i) {
	            var child = this.childAt(i);
	            if (child.isHidden) {
	                continue;
	            }
	            child.node.style.zIndex = "" + i;
	            StackedLayoutPrivate.setGeometry(child, left, top, width, height);
	        }
	    };
	    return StackedLayout;
	})(phosphor_panel_1.PanelLayout);
	exports.StackedLayout = StackedLayout;
	/**
	 * The namespace for the `StackedLayout` class private data.
	 */
	var StackedLayoutPrivate;
	(function (StackedLayoutPrivate) {
	    /**
	     * A flag indicating whether the browser is IE.
	     */
	    StackedLayoutPrivate.IsIE = /Trident/.test(navigator.userAgent);
	    /**
	     * Prepare a child widget for absolute layout geometry.
	     */
	    function prepareGeometry(widget) {
	        widget.node.style.position = 'absolute';
	    }
	    StackedLayoutPrivate.prepareGeometry = prepareGeometry;
	    /**
	     * Reset the layout geometry for the given child widget.
	     */
	    function resetGeometry(widget) {
	        var rect = rectProperty.get(widget);
	        var style = widget.node.style;
	        rect.top = NaN;
	        rect.left = NaN;
	        rect.width = NaN;
	        rect.height = NaN;
	        style.position = '';
	        style.top = '';
	        style.left = '';
	        style.width = '';
	        style.height = '';
	    }
	    StackedLayoutPrivate.resetGeometry = resetGeometry;
	    /**
	     * Set the layout geometry for the given child widget.
	     */
	    function setGeometry(widget, left, top, width, height) {
	        var resized = false;
	        var style = widget.node.style;
	        var rect = rectProperty.get(widget);
	        if (rect.top !== top) {
	            rect.top = top;
	            style.top = top + "px";
	        }
	        if (rect.left !== left) {
	            rect.left = left;
	            style.left = left + "px";
	        }
	        if (rect.width !== width) {
	            resized = true;
	            rect.width = width;
	            style.width = width + "px";
	        }
	        if (rect.height !== height) {
	            resized = true;
	            rect.height = height;
	            style.height = height + "px";
	        }
	        if (resized) {
	            phosphor_messaging_1.sendMessage(widget, new phosphor_widget_1.ResizeMessage(width, height));
	        }
	    }
	    StackedLayoutPrivate.setGeometry = setGeometry;
	    /**
	     * A property descriptor for a widget offset rect.
	     */
	    var rectProperty = new phosphor_properties_1.Property({
	        name: 'rect',
	        create: function () { return ({ top: NaN, left: NaN, width: NaN, height: NaN }); },
	    });
	})(StackedLayoutPrivate || (StackedLayoutPrivate = {}));


/***/ },
/* 39 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_signaling_1 = __webpack_require__(22);
	var layout_1 = __webpack_require__(38);
	/**
	 * The class name added to StackedPanel instances.
	 */
	var STACKED_PANEL_CLASS = 'p-StackedPanel';
	/**
	 * The class name added to a StackedPanel child.
	 */
	var CHILD_CLASS = 'p-StackedPanel-child';
	/**
	 * A panel where visible children 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.
	     */
	    function StackedPanel() {
	        _super.call(this);
	        this.addClass(STACKED_PANEL_CLASS);
	    }
	    /**
	     * Create a stacked layout for a stacked panel.
	     */
	    StackedPanel.createLayout = function () {
	        return new layout_1.StackedLayout();
	    };
	    Object.defineProperty(StackedPanel.prototype, "widgetRemoved", {
	        /**
	         * A signal emitted when a widget is removed from the panel.
	         */
	        get: function () {
	            return StackedPanelPrivate.widgetRemovedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * A message handler invoked on a `'child-added'` message.
	     */
	    StackedPanel.prototype.onChildAdded = function (msg) {
	        msg.child.addClass(CHILD_CLASS);
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    StackedPanel.prototype.onChildRemoved = function (msg) {
	        msg.child.removeClass(CHILD_CLASS);
	        this.widgetRemoved.emit(msg.child);
	    };
	    return StackedPanel;
	})(phosphor_panel_1.Panel);
	exports.StackedPanel = StackedPanel;
	/**
	 * The namespace for the `StackedPanel` class private data.
	 */
	var StackedPanelPrivate;
	(function (StackedPanelPrivate) {
	    /**
	     * A signal emitted when a widget is removed from the panel.
	     */
	    StackedPanelPrivate.widgetRemovedSignal = new phosphor_signaling_1.Signal();
	})(StackedPanelPrivate || (StackedPanelPrivate = {}));


/***/ },
/* 40 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	__export(__webpack_require__(41));
	__export(__webpack_require__(42));
	__webpack_require__(43);


/***/ },
/* 41 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var arrays = __webpack_require__(3);
	var phosphor_domutil_1 = __webpack_require__(7);
	var phosphor_signaling_1 = __webpack_require__(22);
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * The class name added to TabBar instances.
	 */
	var TAB_BAR_CLASS = 'p-TabBar';
	/**
	 * The class name added to a tab bar body node.
	 */
	var BODY_CLASS = 'p-TabBar-body';
	/**
	 * The class name added to a tab bar header node.
	 */
	var HEADER_CLASS = 'p-TabBar-header';
	/**
	 * The class name added to a tab bar content node.
	 */
	var CONTENT_CLASS = 'p-TabBar-content';
	/**
	 * The class name added to a tab bar footer node.
	 */
	var FOOTER_CLASS = 'p-TabBar-footer';
	/**
	 * The class name added to a tab bar tab.
	 */
	var TAB_CLASS = 'p-TabBar-tab';
	/**
	 * The class name added to a tab text node.
	 */
	var TEXT_CLASS = 'p-TabBar-tabText';
	/**
	 * The class name added to a tab icon node.
	 */
	var ICON_CLASS = 'p-TabBar-tabIcon';
	/**
	 * The class name added to a tab close icon node.
	 */
	var CLOSE_CLASS = 'p-TabBar-tabCloseIcon';
	/**
	 * The class name added to a tab bar and tab when dragging.
	 */
	var DRAGGING_CLASS = 'p-mod-dragging';
	/**
	 * The class name added to the current tab.
	 */
	var CURRENT_CLASS = 'p-mod-current';
	/**
	 * The class name added to a closable tab.
	 */
	var CLOSABLE_CLASS = 'p-mod-closable';
	/**
	 * The start drag distance threshold.
	 */
	var DRAG_THRESHOLD = 5;
	/**
	 * The detach distance threshold.
	 */
	var DETACH_THRESHOLD = 20;
	/**
	 * The tab transition duration.
	 */
	var TRANSITION_DURATION = 150; // Keep in sync with CSS.
	/**
	 * A widget which displays tab items as a row of tabs.
	 */
	var TabBar = (function (_super) {
	    __extends(TabBar, _super);
	    /**
	     * Construct a new tab bar.
	     */
	    function TabBar() {
	        _super.call(this);
	        this._tabsMovable = false;
	        this._items = [];
	        this._tabs = [];
	        this._dirtySet = new Set();
	        this._currentItem = null;
	        this._dragData = null;
	        this.addClass(TAB_BAR_CLASS);
	    }
	    /**
	     * Create the DOM node for a tab bar.
	     */
	    TabBar.createNode = function () {
	        var node = document.createElement('div');
	        var header = document.createElement('div');
	        var body = document.createElement('div');
	        var footer = document.createElement('div');
	        var content = document.createElement('ul');
	        header.className = HEADER_CLASS;
	        body.className = BODY_CLASS;
	        footer.className = FOOTER_CLASS;
	        content.className = CONTENT_CLASS;
	        body.appendChild(content);
	        node.appendChild(header);
	        node.appendChild(body);
	        node.appendChild(footer);
	        return node;
	    };
	    /**
	     * Create and initialize a tab node for a tab bar.
	     *
	     * @param title - The title to use for the initial tab state.
	     *
	     * @returns A new DOM node to use as a tab in a tab bar.
	     *
	     * #### Notes
	     * It is not necessary to subscribe to the `changed` signal of the
	     * title. The tab bar subscribes to that signal and will call the
	     * [[updateTab]] static method automatically as needed.
	     *
	     * This method may be reimplemented to create custom tabs.
	     */
	    TabBar.createTab = function (title) {
	        var node = document.createElement('li');
	        var icon = document.createElement('span');
	        var text = document.createElement('span');
	        var close = document.createElement('span');
	        node.className = TAB_CLASS;
	        icon.className = ICON_CLASS;
	        text.className = TEXT_CLASS;
	        close.className = CLOSE_CLASS;
	        node.appendChild(icon);
	        node.appendChild(text);
	        node.appendChild(close);
	        this.updateTab(node, title);
	        return node;
	    };
	    /**
	     * Update a tab node to reflect the current state of a title.
	     *
	     * @param tab - A tab node created by a call to [[createTab]].
	     *
	     * @param title - The title object to use for the tab state.
	     *
	     * #### Notes
	     * This is called automatically when the title state changes.
	     *
	     * If the [[createTab]] method is reimplemented, this method should
	     * also be reimplemented so that the tab state is properly updated.
	     */
	    TabBar.updateTab = function (tab, title) {
	        var tabInfix = title.className ? ' ' + title.className : '';
	        var tabSuffix = title.closable ? ' ' + CLOSABLE_CLASS : '';
	        var iconSuffix = title.icon ? ' ' + title.icon : '';
	        var icon = tab.firstChild;
	        var text = icon.nextSibling;
	        tab.className = TAB_CLASS + tabInfix + tabSuffix;
	        icon.className = ICON_CLASS + iconSuffix;
	        text.textContent = title.text;
	    };
	    /**
	     * Get the close icon node for a given tab node.
	     *
	     * @param tab - A tab node created by a call to [[createTab]].
	     *
	     * @returns The close icon node for the tab node.
	     *
	     * #### Notes
	     * The close icon node is used to correctly process click events.
	     *
	     * If the [[createTab]] method is reimplemented, this method should
	     * also be reimplemented so that the correct icon node is returned.
	     */
	    TabBar.tabCloseIcon = function (tab) {
	        return tab.lastChild;
	    };
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    TabBar.prototype.dispose = function () {
	        this._releaseMouse();
	        this._tabs.length = 0;
	        this._items.length = 0;
	        this._dirtySet.clear();
	        this._currentItem = null;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(TabBar.prototype, "currentChanged", {
	        /**
	         * A signal emitted when the current tab is changed.
	         */
	        get: function () {
	            return TabBarPrivate.currentChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "tabMoved", {
	        /**
	         * A signal emitted when a tab is moved by the user.
	         */
	        get: function () {
	            return TabBarPrivate.tabMovedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "tabCloseRequested", {
	        /**
	         * A signal emitted when the user clicks a tab's close icon.
	         */
	        get: function () {
	            return TabBarPrivate.tabCloseRequestedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "tabDetachRequested", {
	        /**
	         * A signal emitted when a tab is dragged beyond the detach threshold.
	         */
	        get: function () {
	            return TabBarPrivate.tabDetachRequestedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "currentItem", {
	        /**
	         * Get the currently selected tab item.
	         */
	        get: function () {
	            return this._currentItem;
	        },
	        /**
	         * Set the currently selected tab item.
	         */
	        set: function (value) {
	            var item = value || null;
	            if (this._currentItem === item) {
	                return;
	            }
	            var index = item ? this._items.indexOf(item) : -1;
	            if (item && index === -1) {
	                console.warn('Tab item not contained in tab bar.');
	                return;
	            }
	            this._currentItem = item;
	            this.currentChanged.emit({ index: index, item: item });
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "tabsMovable", {
	        /**
	         * Get whether the tabs are movable by the user.
	         */
	        get: function () {
	            return this._tabsMovable;
	        },
	        /**
	         * Set whether the tabs are movable by the user.
	         */
	        set: function (value) {
	            this._tabsMovable = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "headerNode", {
	        /**
	         * Get the tab bar header node.
	         *
	         * #### Notes
	         * This node can be used to add extra content to the tab bar header.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this.node.getElementsByClassName(HEADER_CLASS)[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "bodyNode", {
	        /**
	         * Get the tab bar body node.
	         *
	         * #### Notes
	         * This node can be used to add extra content to the tab bar.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this.node.getElementsByClassName(BODY_CLASS)[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "footerNode", {
	        /**
	         * Get the tab bar footer node.
	         *
	         * #### Notes
	         * This node can be used to add extra content to the tab bar footer.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this.node.getElementsByClassName(FOOTER_CLASS)[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "contentNode", {
	        /**
	         * Get the tab bar content node.
	         *
	         * #### Notes
	         * This is the node which holds the tab nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this.node.getElementsByClassName(CONTENT_CLASS)[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the number of tab items in the tab bar.
	     *
	     * @returns The number of tab items in the tab bar.
	     */
	    TabBar.prototype.itemCount = function () {
	        return this._items.length;
	    };
	    /**
	     * Get the tab item at the specified index.
	     *
	     * @param index - The index of the tab item of interest.
	     *
	     * @returns The tab item at the specified index, or `undefined`.
	     */
	    TabBar.prototype.itemAt = function (index) {
	        return this._items[index];
	    };
	    /**
	     * Get the index of the specified tab item.
	     *
	     * @param item - The tab item of interest.
	     *
	     * @returns The index of the specified item, or `-1`.
	     */
	    TabBar.prototype.itemIndex = function (item) {
	        return this._items.indexOf(item);
	    };
	    /**
	     * Add a tab item to the end of the tab bar.
	     *
	     * @param item - The tab item to add to the tab bar.
	     *
	     * #### Notes
	     * If the item is already added to the tab bar, it will be moved.
	     */
	    TabBar.prototype.addItem = function (item) {
	        this.insertItem(this.itemCount(), item);
	    };
	    /**
	     * Insert a tab item at the specified index.
	     *
	     * @param index - The index at which to insert the item.
	     *
	     * @param item - The tab item to insert into the tab bar.
	     *
	     * #### Notes
	     * If the item is already added to the tab bar, it will be moved.
	     */
	    TabBar.prototype.insertItem = function (index, item) {
	        this._releaseMouse();
	        var n = this._items.length;
	        var i = this._items.indexOf(item);
	        var j = Math.max(0, Math.min(index | 0, n));
	        if (i !== -1) {
	            if (j === n)
	                j--;
	            if (i === j)
	                return;
	            arrays.move(this._tabs, i, j);
	            arrays.move(this._items, i, j);
	            this.contentNode.insertBefore(this._tabs[j], this._tabs[j + 1]);
	        }
	        else {
	            var tab = this.constructor.createTab(item.title);
	            arrays.insert(this._tabs, j, tab);
	            arrays.insert(this._items, j, item);
	            this.contentNode.insertBefore(tab, this._tabs[j + 1]);
	            item.title.changed.connect(this._onTitleChanged, this);
	            if (!this.currentItem)
	                this.currentItem = item;
	        }
	        this.update();
	    };
	    /**
	     * Remove a tab item from the tab bar.
	     *
	     * @param item - The tab item to remove from the tab bar.
	     *
	     * #### Notes
	     * If the item is not in the tab bar, this is a no-op.
	     */
	    TabBar.prototype.removeItem = function (item) {
	        this._releaseMouse();
	        var i = arrays.remove(this._items, item);
	        if (i === -1) {
	            return;
	        }
	        this._dirtySet.delete(item.title);
	        item.title.changed.disconnect(this._onTitleChanged, this);
	        this.contentNode.removeChild(arrays.removeAt(this._tabs, i));
	        if (this.currentItem === item) {
	            var next = this._items[i];
	            var prev = this._items[i - 1];
	            this.currentItem = next || prev;
	        }
	        this.update();
	    };
	    /**
	     * Get the tab node for the item at the given index.
	     *
	     * @param index - The index of the tab item of interest.
	     *
	     * @returns The tab node for the item, or `undefined`.
	     */
	    TabBar.prototype.tabAt = function (index) {
	        return this._tabs[index];
	    };
	    /**
	     * 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. It should
	     * not be called directly by user code.
	     */
	    TabBar.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'click':
	                this._evtClick(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 an `'after-attach'` message.
	     */
	    TabBar.prototype.onAfterAttach = function (msg) {
	        this.node.addEventListener('click', this);
	        this.node.addEventListener('mousedown', this);
	    };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     */
	    TabBar.prototype.onBeforeDetach = function (msg) {
	        this.node.removeEventListener('click', this);
	        this.node.removeEventListener('mousedown', this);
	        this._releaseMouse();
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    TabBar.prototype.onUpdateRequest = function (msg) {
	        var tabs = this._tabs;
	        var items = this._items;
	        var dirty = this._dirtySet;
	        var current = this._currentItem;
	        var constructor = this.constructor;
	        for (var i = 0, n = tabs.length; i < n; ++i) {
	            var tab = tabs[i];
	            var item = items[i];
	            if (dirty.has(item.title)) {
	                constructor.updateTab(tab, item.title);
	            }
	            if (item === current) {
	                tab.classList.add(CURRENT_CLASS);
	                tab.style.zIndex = "" + n;
	            }
	            else {
	                tab.classList.remove(CURRENT_CLASS);
	                tab.style.zIndex = "" + (n - i - 1);
	            }
	        }
	        dirty.clear();
	    };
	    /**
	     * 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 `'click'` event for the tab bar.
	     */
	    TabBar.prototype._evtClick = function (event) {
	        // Do nothing if it's not a left click.
	        if (event.button !== 0) {
	            return;
	        }
	        // Do nothing if a drag is in progress.
	        if (this._dragData) {
	            return;
	        }
	        // Do nothing if the click is not on a tab.
	        var x = event.clientX;
	        var y = event.clientY;
	        var i = arrays.findIndex(this._tabs, function (tab) { return phosphor_domutil_1.hitTest(tab, x, y); });
	        if (i < 0) {
	            return;
	        }
	        // Clicking on a tab stops the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Ignore the click if the title is not closable.
	        var item = this._items[i];
	        if (!item.title.closable) {
	            return;
	        }
	        // Ignore the click if it was not on a close icon.
	        var constructor = this.constructor;
	        var icon = constructor.tabCloseIcon(this._tabs[i]);
	        if (!icon.contains(event.target)) {
	            return;
	        }
	        // Emit the tab close requested signal.
	        this.tabCloseRequested.emit({ index: i, item: item });
	    };
	    /**
	     * Handle the `'mousedown'` event for the tab bar.
	     */
	    TabBar.prototype._evtMouseDown = function (event) {
	        // Do nothing if it's not a left mouse press.
	        if (event.button !== 0) {
	            return;
	        }
	        // Do nothing if a drag is in progress.
	        if (this._dragData) {
	            return;
	        }
	        // Do nothing if the press is not on a tab.
	        var x = event.clientX;
	        var y = event.clientY;
	        var i = arrays.findIndex(this._tabs, function (tab) { return phosphor_domutil_1.hitTest(tab, x, y); });
	        if (i < 0) {
	            return;
	        }
	        // Pressing on a tab stops the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Ignore the press if it was on a close icon.
	        var constructor = this.constructor;
	        var icon = constructor.tabCloseIcon(this._tabs[i]);
	        if (icon.contains(event.target)) {
	            return;
	        }
	        // Setup the drag data if the tabs are movable.
	        if (this._tabsMovable) {
	            this._dragData = new TabBarPrivate.DragData();
	            this._dragData.index = i;
	            this._dragData.tab = this._tabs[i];
	            this._dragData.pressX = event.clientX;
	            this._dragData.pressY = event.clientY;
	            document.addEventListener('mousemove', this, true);
	            document.addEventListener('mouseup', this, true);
	            document.addEventListener('keydown', this, true);
	            document.addEventListener('contextmenu', this, true);
	        }
	        // Update the current item to the pressed item.
	        this.currentItem = this._items[i];
	    };
	    /**
	     * Handle the `'mousemove'` event for the tab bar.
	     */
	    TabBar.prototype._evtMouseMove = function (event) {
	        // Do nothing if no drag is in progress.
	        if (!this._dragData) {
	            return;
	        }
	        // Suppress the event during a drag.
	        event.preventDefault();
	        event.stopPropagation();
	        // Ensure the drag threshold is exceeded before moving the tab.
	        var data = this._dragData;
	        if (!data.dragActive) {
	            var dx = Math.abs(event.clientX - data.pressX);
	            var dy = Math.abs(event.clientY - data.pressY);
	            if (dx < DRAG_THRESHOLD && dy < DRAG_THRESHOLD) {
	                return;
	            }
	            // Fill in the rest of the drag data measurements.
	            var tabRect = data.tab.getBoundingClientRect();
	            data.tabLeft = data.tab.offsetLeft;
	            data.tabWidth = tabRect.width;
	            data.tabPressX = data.pressX - tabRect.left;
	            data.tabLayout = TabBarPrivate.snapTabLayout(this._tabs);
	            data.contentRect = this.contentNode.getBoundingClientRect();
	            data.override = phosphor_domutil_1.overrideCursor('default');
	            // Add the dragging classes and mark the drag as active.
	            data.tab.classList.add(DRAGGING_CLASS);
	            this.addClass(DRAGGING_CLASS);
	            data.dragActive = true;
	        }
	        // Emit the detach request signal if the threshold is exceeded.
	        if (!data.detachRequested && TabBarPrivate.detachExceeded(data, event)) {
	            data.detachRequested = true;
	            var index = data.index;
	            var item = this._items[index];
	            var clientX = event.clientX;
	            var clientY = event.clientY;
	            this.tabDetachRequested.emit({ index: index, item: item, clientX: clientX, clientY: clientY });
	            if (data.dragAborted) {
	                return;
	            }
	        }
	        // Update the tab layout and computed target index.
	        TabBarPrivate.layoutTabs(this._tabs, data, event);
	    };
	    /**
	     * Handle the `'mouseup'` event for the tab bar.
	     */
	    TabBar.prototype._evtMouseUp = function (event) {
	        var _this = this;
	        // Do nothing if it's not a left mouse release.
	        if (event.button !== 0) {
	            return;
	        }
	        // Do nothing if no drag is in progress.
	        if (!this._dragData) {
	            return;
	        }
	        // Suppress the event during a drag operation.
	        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);
	        // Bail early if the drag is not active.
	        var data = this._dragData;
	        if (!data.dragActive) {
	            this._dragData = null;
	            return;
	        }
	        // Position the tab at its final resting position.
	        TabBarPrivate.finalizeTabPosition(data);
	        // Remove the dragging class from the tab so it can be transitioned.
	        data.tab.classList.remove(DRAGGING_CLASS);
	        // 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.
	            TabBarPrivate.resetTabPositions(_this._tabs);
	            // Clear the cursor grab and drag styles.
	            data.override.dispose();
	            _this.removeClass(DRAGGING_CLASS);
	            // 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 tab and related tab item to the new location.
	            arrays.move(_this._tabs, i, j);
	            arrays.move(_this._items, i, j);
	            _this.contentNode.insertBefore(_this._tabs[j], _this._tabs[j + 1]);
	            // Emit the tab moved signal and schedule a render update.
	            _this.tabMoved.emit({ fromIndex: i, toIndex: j, item: _this._items[j] });
	            _this.update();
	        }, TRANSITION_DURATION);
	    };
	    /**
	     * Release the mouse and restore the non-dragged tab positions.
	     */
	    TabBar.prototype._releaseMouse = function () {
	        // Do nothing if no drag is in progress.
	        if (!this._dragData) {
	            return;
	        }
	        // 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);
	        // Clear the drag data reference.
	        var data = this._dragData;
	        this._dragData = null;
	        // 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.
	        TabBarPrivate.resetTabPositions(this._tabs);
	        // Clear the cursor override and extra styling classes.
	        data.override.dispose();
	        data.tab.classList.remove(DRAGGING_CLASS);
	        this.removeClass(DRAGGING_CLASS);
	    };
	    /**
	     * Handle the `changed` signal of a title object.
	     */
	    TabBar.prototype._onTitleChanged = function (sender) {
	        this._dirtySet.add(sender);
	        this.update();
	    };
	    return TabBar;
	})(phosphor_widget_1.Widget);
	exports.TabBar = TabBar;
	/**
	 * The namespace for the `TabBar` class private data.
	 */
	var TabBarPrivate;
	(function (TabBarPrivate) {
	    /**
	     * A signal emitted when the current tab item is changed.
	     */
	    TabBarPrivate.currentChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when a tab is moved by the user.
	     */
	    TabBarPrivate.tabMovedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when the user clicks a tab's close icon.
	     */
	    TabBarPrivate.tabCloseRequestedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when a tab is dragged beyond the detach threshold.
	     */
	    TabBarPrivate.tabDetachRequestedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A struct which holds the drag data for a tab bar.
	     */
	    var DragData = (function () {
	        function DragData() {
	            /**
	             * The tab node being dragged.
	             */
	            this.tab = null;
	            /**
	             * The index of the tab being dragged.
	             */
	            this.index = -1;
	            /**
	             * The offset left of the tab being dragged.
	             */
	            this.tabLeft = -1;
	            /**
	             * The offset width of the tab being dragged.
	             */
	            this.tabWidth = -1;
	            /**
	             * The original mouse X position in tab coordinates.
	             */
	            this.tabPressX = -1;
	            /**
	             * The tab target index upon mouse release.
	             */
	            this.targetIndex = -1;
	            /**
	             * The array of tab layout objects snapped at drag start.
	             */
	            this.tabLayout = null;
	            /**
	             * The mouse press client X position.
	             */
	            this.pressX = -1;
	            /**
	             * The mouse press client Y position.
	             */
	            this.pressY = -1;
	            /**
	             * The bounding client rect of the tab bar content node.
	             */
	            this.contentRect = null;
	            /**
	             * The disposable to clean up the cursor override.
	             */
	            this.override = null;
	            /**
	             * Whether the drag is currently active.
	             */
	            this.dragActive = false;
	            /**
	             * Whether the drag has been aborted.
	             */
	            this.dragAborted = false;
	            /**
	             * Whether a detach request as been made.
	             */
	            this.detachRequested = false;
	        }
	        return DragData;
	    })();
	    TabBarPrivate.DragData = DragData;
	    /**
	     * Get a snapshot of the current tab layout values.
	     */
	    function snapTabLayout(tabs) {
	        var layout = new Array(tabs.length);
	        for (var i = 0, n = tabs.length; i < n; ++i) {
	            var node = tabs[i];
	            var left = node.offsetLeft;
	            var width = node.offsetWidth;
	            var cstyle = window.getComputedStyle(node);
	            var margin = parseInt(cstyle.marginLeft, 10) || 0;
	            layout[i] = { margin: margin, left: left, width: width };
	        }
	        return layout;
	    }
	    TabBarPrivate.snapTabLayout = snapTabLayout;
	    /**
	     * Test if the event exceeds the drag detach threshold.
	     */
	    function detachExceeded(data, event) {
	        var rect = data.contentRect;
	        return ((event.clientX < rect.left - DETACH_THRESHOLD) ||
	            (event.clientX >= rect.right + DETACH_THRESHOLD) ||
	            (event.clientY < rect.top - DETACH_THRESHOLD) ||
	            (event.clientY >= rect.bottom + DETACH_THRESHOLD));
	    }
	    TabBarPrivate.detachExceeded = detachExceeded;
	    /**
	     * Update the relative tab positions and computed target index.
	     */
	    function layoutTabs(tabs, data, event) {
	        var targetIndex = data.index;
	        var targetLeft = event.clientX - data.contentRect.left - data.tabPressX;
	        var targetRight = targetLeft + data.tabWidth;
	        for (var i = 0, n = tabs.length; i < n; ++i) {
	            var style = tabs[i].style;
	            var layout = data.tabLayout[i];
	            var threshold = layout.left + (layout.width >> 1);
	            if (i < data.index && targetLeft < threshold) {
	                style.left = data.tabWidth + data.tabLayout[i + 1].margin + 'px';
	                targetIndex = Math.min(targetIndex, i);
	            }
	            else if (i > data.index && targetRight > threshold) {
	                style.left = -data.tabWidth - layout.margin + 'px';
	                targetIndex = Math.max(targetIndex, i);
	            }
	            else if (i === data.index) {
	                var ideal = event.clientX - data.pressX;
	                var limit = data.contentRect.width - (data.tabLeft + data.tabWidth);
	                style.left = Math.max(-data.tabLeft, Math.min(ideal, limit)) + 'px';
	            }
	            else {
	                style.left = '';
	            }
	        }
	        data.targetIndex = targetIndex;
	    }
	    TabBarPrivate.layoutTabs = layoutTabs;
	    /**
	     * Position the drag tab at its final resting relative position.
	     */
	    function finalizeTabPosition(data) {
	        var ideal;
	        if (data.targetIndex === data.index) {
	            ideal = 0;
	        }
	        else if (data.targetIndex > data.index) {
	            var tgt = data.tabLayout[data.targetIndex];
	            ideal = tgt.left + tgt.width - data.tabWidth - data.tabLeft;
	        }
	        else {
	            var tgt = data.tabLayout[data.targetIndex];
	            ideal = tgt.left - data.tabLeft;
	        }
	        var style = data.tab.style;
	        var limit = data.contentRect.width - (data.tabLeft + data.tabWidth);
	        style.left = Math.max(-data.tabLeft, Math.min(ideal, limit)) + 'px';
	    }
	    TabBarPrivate.finalizeTabPosition = finalizeTabPosition;
	    /**
	     * Reset the relative positions of the given tabs.
	     */
	    function resetTabPositions(tabs) {
	        for (var i = 0, n = tabs.length; i < n; ++i) {
	            tabs[i].style.left = '';
	        }
	    }
	    TabBarPrivate.resetTabPositions = resetTabPositions;
	})(TabBarPrivate || (TabBarPrivate = {}));


/***/ },
/* 42 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_boxpanel_1 = __webpack_require__(4);
	var phosphor_stackedpanel_1 = __webpack_require__(37);
	var phosphor_widget_1 = __webpack_require__(20);
	var tabbar_1 = __webpack_require__(41);
	/**
	 * The class name added to TabPanel instances.
	 */
	var TAB_PANEL_CLASS = 'p-TabPanel';
	/**
	 * The class name added to a TabPanel's tab bar.
	 */
	var TAB_BAR_CLASS = 'p-TabPanel-tabBar';
	/**
	 * The class name added to a TabPanel's stacked panel.
	 */
	var STACKED_PANEL_CLASS = 'p-TabPanel-stackedPanel';
	/**
	 * 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 above 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.
	     */
	    function TabPanel() {
	        _super.call(this);
	        this._currentWidget = null;
	        this.addClass(TAB_PANEL_CLASS);
	        var constructor = this.constructor;
	        this._tabBar = constructor.createTabBar();
	        this._stackedPanel = constructor.createStackedPanel();
	        this._tabBar.tabMoved.connect(this._onTabMoved, this);
	        this._tabBar.currentChanged.connect(this._onCurrentChanged, this);
	        this._tabBar.tabCloseRequested.connect(this._onTabCloseRequested, this);
	        this._stackedPanel.widgetRemoved.connect(this._onWidgetRemoved, this);
	        var layout = new phosphor_boxpanel_1.BoxLayout();
	        layout.direction = phosphor_boxpanel_1.BoxLayout.TopToBottom;
	        layout.spacing = 0;
	        phosphor_boxpanel_1.BoxLayout.setStretch(this._tabBar, 0);
	        phosphor_boxpanel_1.BoxLayout.setStretch(this._stackedPanel, 1);
	        layout.addChild(this._tabBar);
	        layout.addChild(this._stackedPanel);
	        this.layout = layout;
	    }
	    /**
	     * Create a `TabBar` for a tab panel.
	     *
	     * @returns A new tab bar to use with a tab panel.
	     *
	     * #### Notes
	     * This may be reimplemented by subclasses for custom tab bars.
	     */
	    TabPanel.createTabBar = function () {
	        var tabBar = new tabbar_1.TabBar();
	        tabBar.addClass(TAB_BAR_CLASS);
	        return tabBar;
	    };
	    /**
	     * Create a `StackedPanel` for a tab panel.
	     *
	     * @returns A new stacked panel to use with a tab panel.
	     *
	     * #### Notes
	     * This may be reimplemented by subclasses for custom stacks.
	     */
	    TabPanel.createStackedPanel = function () {
	        var stackedPanel = new phosphor_stackedpanel_1.StackedPanel();
	        stackedPanel.addClass(STACKED_PANEL_CLASS);
	        return stackedPanel;
	    };
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    TabPanel.prototype.dispose = function () {
	        this._tabBar = null;
	        this._stackedPanel = null;
	        this._currentWidget = null;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(TabPanel.prototype, "currentWidget", {
	        /**
	         * Get the currently selected widget.
	         */
	        get: function () {
	            return this._tabBar.currentItem;
	        },
	        /**
	         * Set the currently selected widget.
	         */
	        set: function (value) {
	            this._tabBar.currentItem = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "tabsMovable", {
	        /**
	         * Get whether the tabs are movable by the user.
	         */
	        get: function () {
	            return this._tabBar.tabsMovable;
	        },
	        /**
	         * Set whether the tabs are movable by the user.
	         */
	        set: function (value) {
	            this._tabBar.tabsMovable = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "tabBar", {
	        /**
	         * Get the tab bar associated with the tab panel.
	         *
	         * #### Notes
	         * Modifying the tab bar directly can lead to undefined behavior.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._tabBar;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "stackedPanel", {
	        /**
	         * Get the stacked panel associated with the tab panel.
	         *
	         * #### Notes
	         * Modifying the stack directly can lead to undefined behavior.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._stackedPanel;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the number of child widgets in the tab panel.
	     *
	     * @returns The number of child widgets in the tab panel.
	     *
	     * #### Notes
	     * This delegates to the `childCount` method of the stacked panel.
	     */
	    TabPanel.prototype.childCount = function () {
	        return this._stackedPanel.childCount();
	    };
	    /**
	     * Get the child widget at the specified index.
	     *
	     * @param index - The index of the child widget of interest.
	     *
	     * @returns The child at the specified index, or `undefined`.
	     *
	     * #### Notes
	     * This delegates to the `childAt` method of the stacked panel.
	     */
	    TabPanel.prototype.childAt = function (index) {
	        return this._stackedPanel.childAt(index);
	    };
	    /**
	     * Get the index of the specified child widget.
	     *
	     * @param child - The child widget of interest.
	     *
	     * @returns The index of the specified child, or `-1`.
	     *
	     * #### Notes
	     * This delegates to the `childIndex` method of the stacked panel.
	     */
	    TabPanel.prototype.childIndex = function (child) {
	        return this._stackedPanel.childIndex(child);
	    };
	    /**
	     * Add a child widget to the end of the tab panel.
	     *
	     * @param child - The child widget to add to the tab panel.
	     *
	     * #### Notes
	     * If the child is already contained in the panel, it will be moved.
	     */
	    TabPanel.prototype.addChild = function (child) {
	        this.insertChild(this.childCount(), child);
	    };
	    /**
	     * Insert a child widget at the specified index.
	     *
	     * @param index - The index at which to insert the child.
	     *
	     * @param child - The child widget to insert into to the tab panel.
	     *
	     * #### Notes
	     * If the child is already contained in the panel, it will be moved.
	     */
	    TabPanel.prototype.insertChild = function (index, child) {
	        if (child !== this._currentWidget)
	            child.hide();
	        this._stackedPanel.insertChild(index, child);
	        this._tabBar.insertItem(index, child);
	    };
	    /**
	     * Handle the `currentChanged` signal from the tab bar.
	     */
	    TabPanel.prototype._onCurrentChanged = function (sender, args) {
	        var oldWidget = this._currentWidget;
	        var newWidget = args.item;
	        if (oldWidget === newWidget)
	            return;
	        this._currentWidget = newWidget;
	        if (oldWidget)
	            oldWidget.hide();
	        if (newWidget)
	            newWidget.show();
	    };
	    /**
	     * Handle the `tabCloseRequested` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabCloseRequested = function (sender, args) {
	        args.item.close();
	    };
	    /**
	     * Handle the `tabMoved` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabMoved = function (sender, args) {
	        this._stackedPanel.insertChild(args.toIndex, args.item);
	    };
	    /**
	     * Handle the `widgetRemoved` signal from the stacked panel.
	     */
	    TabPanel.prototype._onWidgetRemoved = function (sender, widget) {
	        if (this._currentWidget === widget)
	            this._currentWidget = null;
	        this._tabBar.removeItem(widget);
	    };
	    return TabPanel;
	})(phosphor_widget_1.Widget);
	exports.TabPanel = TabPanel;


/***/ },
/* 43 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(44);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../css-loader/index.js!./index.css", function() {
				var newContent = require("!!./../../css-loader/index.js!./index.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 44 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\r\n| Copyright (c) 2014-2015, PhosphorJS Contributors\r\n|\r\n| Distributed under the terms of the BSD 3-Clause License.\r\n|\r\n| The full license is in the file LICENSE, distributed with this software.\r\n|----------------------------------------------------------------------------*/\r\n.p-TabBar {\r\n  display: flex;\r\n  flex-direction: column;\r\n}\r\n\r\n\r\n.p-TabBar-header,\r\n.p-TabBar-footer {\r\n  flex: 0 0 auto;\r\n}\r\n\r\n\r\n.p-TabBar-body {\r\n  display: flex;\r\n  flex-direction: row;\r\n  flex: 1 1 auto;\r\n}\r\n\r\n\r\n.p-TabBar-content {\r\n  display: flex;\r\n  flex-direction: row;\r\n  flex: 1 1 auto;\r\n  margin: 0;\r\n  padding: 0;\r\n  list-style-type: none;\r\n}\r\n\r\n\r\n.p-TabBar-tab {\r\n  display: flex;\r\n  flex-direction: row;\r\n  box-sizing: border-box;\r\n  overflow: hidden;\r\n}\r\n\r\n\r\n.p-TabBar-tabIcon,\r\n.p-TabBar-tabCloseIcon {\r\n  flex: 0 0 auto;\r\n}\r\n\r\n\r\n.p-TabBar-tabText {\r\n  flex: 1 1 auto;\r\n  overflow: hidden;\r\n  white-space: nowrap;\r\n}\r\n\r\n\r\n.p-TabBar.p-mod-dragging .p-TabBar-tab {\r\n  position: relative;\r\n  left: 0;\r\n  transition: left 150ms ease; /* keep in sync with JS */\r\n}\r\n\r\n\r\n.p-TabBar.p-mod-dragging .p-TabBar-tab.p-mod-dragging {\r\n  transition: none;\r\n}\r\n\r\n\r\n.p-TabPanel-tabBar {\r\n  z-index: 1;\r\n}\r\n\r\n\r\n.p-TabPanel-stackedPanel {\r\n  z-index: 0;\r\n}\r\n", ""]);
	
	// exports


/***/ },
/* 45 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(46);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../css-loader/index.js!./index.css", function() {
				var newContent = require("!!./../../css-loader/index.js!./index.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 46 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\r\n| Copyright (c) 2014-2015, PhosphorJS Contributors\r\n|\r\n| Distributed under the terms of the BSD 3-Clause License.\r\n|\r\n| The full license is in the file LICENSE, distributed with this software.\r\n|----------------------------------------------------------------------------*/\r\n.p-DockPanel {\r\n  position: relative;\r\n  z-index: 0;\r\n}\r\n\r\n\r\n.p-DockPanel > .p-Widget {\r\n  position: absolute;\r\n  z-index: 0;\r\n}\r\n\r\n\r\n.p-DockPanel-overlay {\r\n  box-sizing: border-box;\r\n  position: absolute;\r\n  top: 0;\r\n  left: 0;\r\n  width: 0;\r\n  height: 0;\r\n  z-index: 1;\r\n  pointer-events: none;\r\n}\r\n\r\n\r\n.p-TabBar-tab.p-mod-hidden,\r\n.p-DockPanel-overlay.p-mod-hidden {\r\n  display: none;\r\n}\r\n", ""]);
	
	// exports


/***/ },
/* 47 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var arrays = __webpack_require__(3);
	var phosphor_domutil_1 = __webpack_require__(7);
	var phosphor_properties_1 = __webpack_require__(17);
	var phosphor_signaling_1 = __webpack_require__(22);
	var phosphor_widget_1 = __webpack_require__(20);
	__webpack_require__(48);
	/**
	 * The class name added to SideBar instances.
	 */
	var SIDE_BAR_CLASS = 'p-SideBar';
	/**
	 * The class name added to the side bar content node.
	 */
	var CONTENT_CLASS = 'p-SideBar-content';
	/**
	 * The class name added to side bar button nodes.
	 */
	var BUTTON_CLASS = 'p-SideBar-button';
	/**
	 * The class name added to a side bar button text node.
	 */
	var TEXT_CLASS = 'p-SideBar-button-text';
	/**
	 * The class name added to a side bar button icon node.
	 */
	var ICON_CLASS = 'p-SideBar-button-icon';
	/**
	 * The class name added to the current side bar button.
	 */
	var CURRENT_CLASS = 'p-mod-current';
	/**
	 * A widget which displays titles as a row of exclusive buttons.
	 */
	var SideBar = (function (_super) {
	    __extends(SideBar, _super);
	    /**
	     * Construct a new side bar.
	     */
	    function SideBar() {
	        _super.call(this);
	        this._dirty = false;
	        this._titles = [];
	        this.addClass(SIDE_BAR_CLASS);
	    }
	    /**
	     * Create the DOM node for a side bar.
	     */
	    SideBar.createNode = function () {
	        var node = document.createElement('div');
	        var content = document.createElement('ul');
	        content.className = CONTENT_CLASS;
	        node.appendChild(content);
	        return node;
	    };
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    SideBar.prototype.dispose = function () {
	        this._titles.length = 0;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(SideBar.prototype, "currentChanged", {
	        /**
	         * A signal emitted when the current side bar title is changed.
	         */
	        get: function () {
	            return SideBarPrivate.currentChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SideBar.prototype, "currentTitle", {
	        /**
	         * Get the currently selected side bar title.
	         */
	        get: function () {
	            return SideBarPrivate.currentTitleProperty.get(this);
	        },
	        /**
	         * Set the currently selected side bar title.
	         */
	        set: function (value) {
	            SideBarPrivate.currentTitleProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SideBar.prototype, "contentNode", {
	        /**
	         * Get the content node which holds the side bar buttons.
	         *
	         * #### Notes
	         * Modifying this node can lead to undefined behavior.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this.node.getElementsByClassName(CONTENT_CLASS)[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the number of title objects in the side bar.
	     *
	     * @returns The number of title objects in the side bar.
	     */
	    SideBar.prototype.titleCount = function () {
	        return this._titles.length;
	    };
	    /**
	     * Get the title object at the specified index.
	     *
	     * @param index - The index of the title object of interest.
	     *
	     * @returns The title at the specified index, or `undefined`.
	     */
	    SideBar.prototype.titleAt = function (index) {
	        return this._titles[index];
	    };
	    /**
	     * Get the index of the specified title object.
	     *
	     * @param title - The title object of interest.
	     *
	     * @returns The index of the specified title, or `-1`.
	     */
	    SideBar.prototype.titleIndex = function (title) {
	        return this._titles.indexOf(title);
	    };
	    /**
	     * Add a title object to the end of the side bar.
	     *
	     * @param title - The title object to add to the side bar.
	     *
	     * #### Notes
	     * If the title is already added to the side bar, it will be moved.
	     */
	    SideBar.prototype.addTitle = function (title) {
	        this.insertTitle(this.titleCount(), title);
	    };
	    /**
	     * Insert a title object at the specified index.
	     *
	     * @param index - The index at which to insert the title.
	     *
	     * @param title - The title object to insert into to the side bar.
	     *
	     * #### Notes
	     * If the title is already added to the side bar, it will be moved.
	     */
	    SideBar.prototype.insertTitle = function (index, title) {
	        var n = this.titleCount();
	        var i = this.titleIndex(title);
	        var j = Math.max(0, Math.min(index | 0, n));
	        if (i !== -1) {
	            if (j === n)
	                j--;
	            if (i === j)
	                return;
	            arrays.move(this._titles, i, j);
	        }
	        else {
	            arrays.insert(this._titles, j, title);
	            title.changed.connect(this._onTitleChanged, this);
	        }
	        this._dirty = true;
	        this.update();
	    };
	    /**
	     * Remove a title object from the side bar.
	     *
	     * @param title - The title object to remove from the side bar.
	     *
	     * #### Notes
	     * If the title is not in the side bar, this is a no-op.
	     */
	    SideBar.prototype.removeTitle = function (title) {
	        var i = arrays.remove(this._titles, title);
	        if (i === -1) {
	            return;
	        }
	        title.changed.disconnect(this._onTitleChanged, this);
	        if (this.currentTitle === title)
	            this.currentTitle = null;
	        this._dirty = true;
	        this.update();
	    };
	    /**
	     * Handle the DOM events for the side bar.
	     *
	     * @param event - The DOM event sent to the side bar.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the side bar's DOM node. It should
	     * not be called directly by user code.
	     */
	    SideBar.prototype.handleEvent = function (event) {
	        if (event.type === 'mousedown') {
	            this._evtMouseDown(event);
	        }
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    SideBar.prototype.onAfterAttach = function (msg) {
	        this.node.addEventListener('mousedown', this);
	    };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     */
	    SideBar.prototype.onBeforeDetach = function (msg) {
	        this.node.removeEventListener('mousedown', this);
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    SideBar.prototype.onUpdateRequest = function (msg) {
	        if (this._dirty) {
	            this._dirty = false;
	            SideBarPrivate.updateButtons(this);
	        }
	        else {
	            SideBarPrivate.updateCurrent(this);
	        }
	    };
	    /**
	     * Handle the `'mousedown'` event for the side bar.
	     */
	    SideBar.prototype._evtMouseDown = function (event) {
	        // Do nothing if it's not a left mouse press.
	        if (event.button !== 0) {
	            return;
	        }
	        // Do nothing if the press is not on a button.
	        var i = SideBarPrivate.hitTestButtons(this, event.clientX, event.clientY);
	        if (i < 0) {
	            return;
	        }
	        // Pressing on a button stops the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Update the current title.
	        var title = this._titles[i];
	        if (title !== this.currentTitle) {
	            this.currentTitle = title;
	        }
	        else {
	            this.currentTitle = null;
	        }
	    };
	    /**
	     * Handle the `changed` signal of a title object.
	     */
	    SideBar.prototype._onTitleChanged = function () {
	        this._dirty = true;
	        this.update();
	    };
	    return SideBar;
	}(phosphor_widget_1.Widget));
	exports.SideBar = SideBar;
	/**
	 * The namespace for the `SideBar` class private data.
	 */
	var SideBarPrivate;
	(function (SideBarPrivate) {
	    /**
	     * A signal emitted when the current title is changed.
	     */
	    SideBarPrivate.currentChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * The property descriptor for the current side bar title.
	     */
	    SideBarPrivate.currentTitleProperty = new phosphor_properties_1.Property({
	        name: 'currentTitle',
	        value: null,
	        coerce: coerceCurrentTitle,
	        changed: onCurrentTitleChanged,
	        notify: SideBarPrivate.currentChangedSignal,
	    });
	    /**
	     * Update the side bar buttons to match the current titles.
	     *
	     * This is a full update which also updates the currrent state.
	     */
	    function updateButtons(owner) {
	        var count = owner.titleCount();
	        var content = owner.contentNode;
	        var children = content.children;
	        while (children.length > count) {
	            content.removeChild(content.lastChild);
	        }
	        while (children.length < count) {
	            content.appendChild(createButtonNode());
	        }
	        for (var i = 0; i < count; ++i) {
	            var node = children[i];
	            updateButtonNode(node, owner.titleAt(i));
	        }
	        updateCurrent(owner);
	    }
	    SideBarPrivate.updateButtons = updateButtons;
	    /**
	     * Update the current state of the buttons to match the side bar.
	     *
	     * This is a partial update which only updates the current button
	     * class. It assumes the button count is the same as the title count.
	     */
	    function updateCurrent(owner) {
	        var count = owner.titleCount();
	        var content = owner.contentNode;
	        var children = content.children;
	        var current = owner.currentTitle;
	        for (var i = 0; i < count; ++i) {
	            var node = children[i];
	            if (owner.titleAt(i) === current) {
	                node.classList.add(CURRENT_CLASS);
	            }
	            else {
	                node.classList.remove(CURRENT_CLASS);
	            }
	        }
	    }
	    SideBarPrivate.updateCurrent = updateCurrent;
	    /**
	     * Get the index of the button node at a client position, or `-1`.
	     */
	    function hitTestButtons(owner, x, y) {
	        var nodes = owner.contentNode.children;
	        for (var i = 0, n = nodes.length; i < n; ++i) {
	            if (phosphor_domutil_1.hitTest(nodes[i], x, y))
	                return i;
	        }
	        return -1;
	    }
	    SideBarPrivate.hitTestButtons = hitTestButtons;
	    /**
	     * The coerce handler for the `currentTitle` property.
	     */
	    function coerceCurrentTitle(owner, value) {
	        return (value && owner.titleIndex(value) !== -1) ? value : null;
	    }
	    /**
	     * The change handler for the `currentTitle` property.
	     */
	    function onCurrentTitleChanged(owner) {
	        owner.update();
	    }
	    /**
	     * Create an uninitialized DOM node for a side bar button.
	     */
	    function createButtonNode() {
	        var node = document.createElement('li');
	        var icon = document.createElement('span');
	        var text = document.createElement('span');
	        text.className = TEXT_CLASS;
	        node.appendChild(icon);
	        node.appendChild(text);
	        return node;
	    }
	    /**
	     * Update a button node to reflect the state of a title.
	     */
	    function updateButtonNode(node, title) {
	        var icon = node.firstChild;
	        var text = node.lastChild;
	        if (title.className) {
	            node.className = BUTTON_CLASS + ' ' + title.className;
	        }
	        else {
	            node.className = BUTTON_CLASS;
	        }
	        if (title.icon) {
	            icon.className = ICON_CLASS + ' ' + title.icon;
	        }
	        else {
	            icon.className = ICON_CLASS;
	        }
	        text.textContent = title.text;
	    }
	})(SideBarPrivate || (SideBarPrivate = {}));


/***/ },
/* 48 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(49);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../../css-loader/index.js!./sidebar.css", function() {
				var newContent = require("!!./../../../css-loader/index.js!./sidebar.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 49 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2016, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n.p-SideBar-content {\n  margin: 0;\n  padding: 0;\n  display: flex;\n  align-items: stretch;\n  list-style-type: none;\n}\n", ""]);
	
	// exports


/***/ },
/* 50 */
/***/ function(module, exports) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	/**
	 * A class which manages a registry of extensions.
	 *
	 * #### Notes
	 * A service registry is used by populating it with extension objects,
	 * then calling the `activate` method to activate a specific extension.
	 *
	 * This class is used internally by the `Application` class. It will
	 * not typically be used directly by user code.
	 */
	var ExtensionRegistry = (function () {
	    /**
	     * Construct a new extension registry.
	     */
	    function ExtensionRegistry() {
	        this._extensionsByID = Private.createExtensionIDMap();
	    }
	    /**
	     * Register an extension with the registry.
	     *
	     * @param extension - The extension to add to the registry.
	     *
	     * #### Notes
	     * An error will be thrown if the extension id is already registered.
	     */
	    ExtensionRegistry.prototype.registerExtension = function (extension) {
	        // Throw an error if the extension id is already registered.
	        if (extension.id in this._extensionsByID) {
	            throw new Error("extension '" + extension.id + "' already registered");
	        }
	        // Create the extended extension and add it to the registry.
	        var ext = Private.createExtensionEx(extension);
	        this._extensionsByID[ext.id] = ext;
	    };
	    /**
	     * List the IDs of all extensions in the registry.
	     *
	     * @returns A new array of all extension IDs in the registry.
	     */
	    ExtensionRegistry.prototype.listExtensions = function () {
	        return Object.keys(this._extensionsByID);
	    };
	    /**
	     * Test whether the registry has an extension with the given id.
	     *
	     * @param id - The id of the extension of interest.
	     *
	     * @returns `true` if an extension with the specified id is
	     *   registered, `false` otherwise.
	     */
	    ExtensionRegistry.prototype.hasExtension = function (id) {
	        return id in this._extensionsByID;
	    };
	    /**
	     * Activate the extension with the given id.
	     *
	     * @param id - The ID of the extension of interest.
	     *
	     * @param context - The context object to pass as the first argument
	     *   to the extension's `activate` function.
	     *
	     * @param services - The service registry for resolving the services
	     *   required by the extension.
	     *
	     * @returns A promise which resolves when the extension is fully
	     *   activated or rejects with an error if it cannot be activated.
	     */
	    ExtensionRegistry.prototype.activateExtension = function (id, context, services) {
	        // Reject the promise if the extension is not registered.
	        var ext = this._extensionsByID[id];
	        if (!ext) {
	            return Promise.reject(new Error("extension '" + id + "' not registered"));
	        }
	        // Resolve immediately if the extension is already activated.
	        if (ext.activated) {
	            return Promise.resolve();
	        }
	        // Return the pending resolver promise if it exists.
	        if (ext.promise) {
	            return ext.promise;
	        }
	        // Resolve the services required by the extension.
	        var promises = ext.requires.map(function (req) { return services.resolveService(req); });
	        // Setup the resolver promise for the extension.
	        ext.promise = Promise.all(promises).then(function (deps) {
	            deps.unshift(context);
	            return ext.activate.apply(void 0, deps);
	        }).then(function () {
	            ext.promise = null;
	            ext.activated = true;
	        }).catch(function (error) {
	            ext.promise = null;
	            throw error;
	        });
	        // Return the pending resolver promise.
	        return ext.promise;
	    };
	    return ExtensionRegistry;
	}());
	exports.ExtensionRegistry = ExtensionRegistry;
	/**
	 * The namespace for the private extension registry functionality.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create new extension id map.
	     */
	    function createExtensionIDMap() {
	        return Object.create(null);
	    }
	    Private.createExtensionIDMap = createExtensionIDMap;
	    /**
	     * Create a new extended extension.
	     *
	     * @param extension - The extension source object.
	     *
	     * @returns A new extended extension initialized with the data
	     *   from the given extension.
	     *
	     * #### Notes
	     * The `requires` property of the extended extension will always be
	     * specified. If the original extension does not have dependencies,
	     * the `requires` array will be empty.
	     */
	    function createExtensionEx(extension) {
	        var id = extension.id, requires = extension.requires, activate = extension.activate;
	        requires = requires ? requires.slice() : [];
	        return { id: id, requires: requires, activate: activate, activated: false, promise: null };
	    }
	    Private.createExtensionEx = createExtensionEx;
	})(Private || (Private = {}));


/***/ },
/* 51 */
/***/ function(module, exports) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	/**
	 * A class which manages a registry of service providers.
	 *
	 * #### Notes
	 * A service registry is used by populating it with service providers,
	 * then calling the `resolve` method to get the singleton instance of
	 * a specified service type.
	 *
	 * This class is used internally by the `Application` class. It will
	 * not typically be used directly by user code.
	 */
	var ServiceRegistry = (function () {
	    /**
	     * Construct a new service registry.
	     */
	    function ServiceRegistry() {
	        this._providersByID = Private.createProviderIDMap();
	        this._providersByType = Private.createProviderTypeMap();
	    }
	    /**
	     * Register a service provider with the registry.
	     *
	     * @param provider - The service provider to add to the registry.
	     *
	     * #### Notes
	     * An error will be thrown if a provider with the same id is already
	     * registered, if a provider which provides the identical service is
	     * already registered, or if the provider has a circular dependency.
	     */
	    ServiceRegistry.prototype.registerProvider = function (provider) {
	        // Throw an error if the provider id is already registered.
	        var pid = provider.id;
	        if (pid in this._providersByID) {
	            throw new Error("provider '" + pid + "' already registered");
	        }
	        // Throw an error if the service type is already registered.
	        var other = this._providersByType.get(provider.provides);
	        if (other) {
	            throw new Error("'" + pid + "' service already provided by '" + other.id + "'");
	        }
	        // Throw an error if the provider has a circular dependency.
	        var cycle = Private.findCycle(provider, this._providersByType);
	        if (cycle) {
	            throw new Error("provider cycle detected: " + cycle.join(' -> '));
	        }
	        // Create the extended provider and add it to the registry.
	        var pex = Private.createProviderEx(provider);
	        this._providersByType.set(pex.provides, pex);
	        this._providersByID[pex.id] = pex;
	    };
	    /**
	     * List the IDs of all service providers in the registry.
	     *
	     * @returns A new array of all provider IDs in the registry.
	     */
	    ServiceRegistry.prototype.listProviders = function () {
	        return Object.keys(this._providersByID);
	    };
	    /**
	     * Test whether the registry has a provider with the given id.
	     *
	     * @param id - The id of the provider of interest.
	     *
	     * @returns `true` if a service provider with the specified id is
	     *   registered, `false` otherwise.
	     */
	    ServiceRegistry.prototype.hasProvider = function (id) {
	        return id in this._providersByID;
	    };
	    /**
	     * Test whether the registry has a provider for the given service.
	     *
	     * @param kind - The type of the service of interest.
	     *
	     * @returns `true` if a service provider is registered for the
	     *   specified service type, `false` otherwise.
	     */
	    ServiceRegistry.prototype.hasProviderFor = function (kind) {
	        return this._providersByType.has(kind);
	    };
	    /**
	     * Resolve a service implementation for the given type.
	     *
	     * @param kind - The type of service object to resolve.
	     *
	     * @returns A promise which resolves the specified service type,
	     *   or rejects with an error if it cannot be satisfied.
	     *
	     * #### Notes
	     * Services are singletons. The same service instance will be
	     * returned each time a given service type is resolved.
	     */
	    ServiceRegistry.prototype.resolveService = function (kind) {
	        return Private.resolveService(kind, this._providersByType, []);
	    };
	    return ServiceRegistry;
	}());
	exports.ServiceRegistry = ServiceRegistry;
	/**
	 * The namespace for the private service registry functionality.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create new provider id map.
	     */
	    function createProviderIDMap() {
	        return Object.create(null);
	    }
	    Private.createProviderIDMap = createProviderIDMap;
	    /**
	     * Create a new provider type map.
	     */
	    function createProviderTypeMap() {
	        return new Map();
	    }
	    Private.createProviderTypeMap = createProviderTypeMap;
	    /**
	     * Create a new extended provider.
	     *
	     * @param provider - The service provider source object.
	     *
	     * @returns A new extended provider initialized with the data
	     *   from the given service provider.
	     *
	     * #### Notes
	     * The `requires` property of the extended provider will always be
	     * specified. If the original provider does not have dependencies,
	     * the `requires` array will be empty.
	     */
	    function createProviderEx(provider) {
	        var id = provider.id, provides = provider.provides, requires = provider.requires, resolve = provider.resolve;
	        requires = requires ? requires.slice() : [];
	        return { id: id, provides: provides, requires: requires, resolve: resolve, value: null, resolved: false, promise: null };
	    }
	    Private.createProviderEx = createProviderEx;
	    /**
	     * Find a cycle with the given service provider, if one exists.
	     *
	     * @param provider - The service provider to test for a cycle.
	     *
	     * @param map - The mapping of type to extended provider.
	     *
	     * @returns The ordered IDs of the cyclic providers, or null if
	     *   no cycle is present.
	     */
	    function findCycle(provider, map) {
	        if (!provider.requires)
	            return null;
	        var trace = [provider.id];
	        var root = provider.provides;
	        return provider.requires.some(visit) ? trace : null;
	        function visit(kind) {
	            if (kind === root) {
	                return true;
	            }
	            var pex = map.get(kind);
	            if (!pex) {
	                return false;
	            }
	            trace.push(pex.id);
	            if (pex.requires.some(visit)) {
	                return true;
	            }
	            trace.pop();
	            return false;
	        }
	    }
	    Private.findCycle = findCycle;
	    /**
	     * Resolve the instance of the specified service type.
	     *
	     * @param kind - The service type to resolve.
	     *
	     * @param map - The mapping of type to extended provider.
	     *
	     * @param path - An array of provider ids representing the current
	     *   path of the resolver graph. This should be an empty array for
	     *   the first call to this function.
	     *
	     * @returns A promise which resolves to an instance of the requested
	     *   type, or rejects if the instance cannot be created.
	     */
	    function resolveService(kind, map, path) {
	        // Reject the promise if there is no provider for the type.
	        var pex = map.get(kind);
	        if (!pex) {
	            return Promise.reject(missingProviderError(kind, path));
	        }
	        // Resolve immediately if the provider is already resolved.
	        if (pex.resolved) {
	            return Promise.resolve(pex.value);
	        }
	        // Return the pending resolver promise if it exists.
	        if (pex.promise) {
	            return pex.promise;
	        }
	        // Setup the resolver promise for the provider.
	        pex.promise = resolveImpl(pex, map, path).then(function (value) {
	            pex.value = value;
	            pex.promise = null;
	            pex.resolved = true;
	            return value;
	        }, function (error) {
	            pex.promise = null;
	            throw error;
	        });
	        // Return the pending resolver promise.
	        return pex.promise;
	    }
	    Private.resolveService = resolveService;
	    /**
	     * Resolve the service instance for the given provider.
	     */
	    function resolveImpl(pex, map, path) {
	        // Push the current provider id onto the path stack.
	        path.push(pex.id);
	        // Generate the resolver promises from the provider dependencies.
	        var reqs = pex.requires.map(function (kind) { return resolveService(kind, map, path); });
	        // Pop the provider id from the path stack.
	        path.pop();
	        // Return the promise which resolves the type for the provider.
	        return Promise.all(reqs).then(function (deps) { return pex.resolve.apply(void 0, deps); });
	    }
	    /**
	     * Create a formatted error for a missing provider.
	     *
	     * @param kind - The service type which cannot be fulfilled.
	     *
	     * @param path - The resolver path at the point of failure.
	     *
	     * @returns An error with a formatted message.
	     */
	    function missingProviderError(kind, path) {
	        // The `any` cast is needed due to no `Function.name` on IE.
	        var name = kind.name || '';
	        var head = "No registered provider for type: " + name + ".";
	        var tail = "Provider resolution path: " + path.join(' -> ') + ".";
	        return new Error(head + " " + tail);
	    }
	})(Private || (Private = {}));


/***/ },
/* 52 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_disposable_1 = __webpack_require__(8);
	var phosphor_signaling_1 = __webpack_require__(22);
	/**
	 * An abstract base class which defines a command registry.
	 */
	var ABCCommandRegistry = (function () {
	    function ABCCommandRegistry() {
	    }
	    Object.defineProperty(ABCCommandRegistry.prototype, "commandsAdded", {
	        /**
	         * A signal emitted when commands are added to the registry.
	         */
	        get: function () {
	            return Private.commandsAddedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ABCCommandRegistry.prototype, "commandsRemoved", {
	        /**
	         * A signal emitted when commands are removed from the registry.
	         */
	        get: function () {
	            return Private.commandsRemovedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ABCCommandRegistry.prototype, "commandExecuted", {
	        /**
	         * A signal emitted when a command is executed.
	         */
	        get: function () {
	            return Private.commandExecutedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ABCCommandRegistry;
	}());
	exports.ABCCommandRegistry = ABCCommandRegistry;
	/**
	 * A concrete implementation of ABCCommandRegistry.
	 */
	var CommandRegistry = (function (_super) {
	    __extends(CommandRegistry, _super);
	    function CommandRegistry() {
	        _super.apply(this, arguments);
	        this._commands = Private.createCommandMap();
	    }
	    /**
	     * List the ids of the currently registered commands.
	     *
	     * @returns A new array of the registered command ids.
	     */
	    CommandRegistry.prototype.list = function () {
	        return Object.keys(this._commands);
	    };
	    /**
	     * Test whether the registry contains a command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @returns `true` if the command is registered, `false` otherwise.
	     */
	    CommandRegistry.prototype.has = function (id) {
	        return id in this._commands;
	    };
	    /**
	     * Add commands to the registry.
	     *
	     * @param items - The command items to add to the registry.
	     *
	     * @returns A disposable which will remove the added commands.
	     *
	     * #### Notes
	     * If the `id` for a command is already registered, a warning will be
	     * logged to the console and that specific command will be ignored.
	     */
	    CommandRegistry.prototype.add = function (items) {
	        var _this = this;
	        // Setup the array for the new unique ids.
	        var added = [];
	        // Add the new commands to the map and warn for duplicates.
	        for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
	            var _a = items_1[_i], id = _a.id, handler = _a.handler;
	            if (id in this._commands) {
	                console.warn("Command '" + id + "' is already registered.");
	            }
	            else {
	                this._commands[id] = handler;
	                added.push(id);
	            }
	        }
	        // If no items are added, return an empty delegate.
	        if (added.length === 0) {
	            return new phosphor_disposable_1.DisposableDelegate(null);
	        }
	        // Notify for the added commands using a safe shallow copy.
	        this.commandsAdded.emit(added.slice());
	        // Return a delegate which will remove the added commands.
	        return new phosphor_disposable_1.DisposableDelegate(function () {
	            for (var _i = 0, added_1 = added; _i < added_1.length; _i++) {
	                var id = added_1[_i];
	                delete _this._commands[id];
	            }
	            _this.commandsRemoved.emit(added.slice());
	        });
	    };
	    /**
	     * Execute a registered command.
	     *
	     * @param id - The id of the command to execute.
	     *
	     * #### Notes
	     * If the command id is not registered, a warning will be logged.
	     *
	     * If the handler throws an exception, it will be caught and logged.
	     */
	    CommandRegistry.prototype.execute = function (id) {
	        var handler = this._commands[id];
	        if (!handler) {
	            console.warn("command '" + id + "' not registered");
	            return;
	        }
	        try {
	            handler();
	        }
	        catch (err) {
	            console.error("error in command '" + id + "'", err);
	        }
	        this.commandExecuted.emit(id);
	    };
	    return CommandRegistry;
	}(ABCCommandRegistry));
	exports.CommandRegistry = CommandRegistry;
	/**
	 * The default command registry service provider.
	 */
	exports.commandRegistryProvider = {
	    id: 'phosphide.services.commandRegistry',
	    provides: ABCCommandRegistry,
	    resolve: function () { return new CommandRegistry(); },
	};
	/**
	 * The namespace for the private command registry functionality.
	 */
	var Private;
	(function (Private) {
	    /**
	     *
	     */
	    Private.commandsAddedSignal = new phosphor_signaling_1.Signal();
	    /**
	     *
	     */
	    Private.commandsRemovedSignal = new phosphor_signaling_1.Signal();
	    /**
	     *
	     */
	    Private.commandExecutedSignal = new phosphor_signaling_1.Signal();
	    /**
	     *
	     */
	    function createCommandMap() {
	        return Object.create(null);
	    }
	    Private.createCommandMap = createCommandMap;
	})(Private || (Private = {}));


/***/ },
/* 53 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_commandpalette_1 = __webpack_require__(54);
	var phosphor_disposable_1 = __webpack_require__(8);
	var phosphor_signaling_1 = __webpack_require__(22);
	var commandregistry_1 = __webpack_require__(52);
	var shortcutregistry_1 = __webpack_require__(61);
	/**
	 *
	 */
	var ABCPaletteRegistry = (function () {
	    function ABCPaletteRegistry() {
	    }
	    Object.defineProperty(ABCPaletteRegistry.prototype, "commandTriggered", {
	        /**
	         * A signal emitted when a command is triggered by the palette.
	         */
	        get: function () {
	            return Private.commandTriggeredSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ABCPaletteRegistry.prototype, "model", {
	        /**
	         *
	         */
	        get: function () {
	            return this.getModel();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ABCPaletteRegistry;
	}());
	exports.ABCPaletteRegistry = ABCPaletteRegistry;
	/**
	 *
	 */
	var PaletteRegistry = (function (_super) {
	    __extends(PaletteRegistry, _super);
	    /**
	     *
	     */
	    function PaletteRegistry(commands, shortcuts) {
	        var _this = this;
	        _super.call(this);
	        /**
	         * The private command handler function.
	         */
	        this._executeCommand = function (id) {
	            _this.commandTriggered.emit(id);
	            _this._commands.execute(id);
	        };
	        this._model = new phosphor_commandpalette_1.StandardPaletteModel();
	        this._boxes = [];
	        this._commands = commands;
	        this._shortcuts = shortcuts;
	        this._shortcuts.shortcutsAdded.connect(this._onShortcutsChanged, this);
	        this._shortcuts.shortcutsRemoved.connect(this._onShortcutsChanged, this);
	    }
	    /**
	     * Add command palette items to the palette registry.
	     *
	     * @param items - The array of items to add to the registry.
	     *
	     * @returns A disposable which will remove the added items.
	     */
	    PaletteRegistry.prototype.add = function (items) {
	        var _this = this;
	        var optionsArray = items.map(function (item) {
	            // let commandExists = this._commandRegistry.has(item.id);
	            // if (!commandExists) return null;
	            var seq = _this._shortcuts.sequenceFor(item.command);
	            var shortcut = seq ? Private.formatSequence(seq) : '';
	            var options = {
	                handler: _this._executeCommand,
	                args: item.command,
	                text: item.text,
	                shortcut: shortcut,
	                icon: item.icon || '',
	                caption: item.caption || '',
	                category: item.category || ''
	            };
	            return options;
	        });
	        if (optionsArray.length === 0) {
	            return new phosphor_disposable_1.DisposableDelegate(null);
	        }
	        var boxes = this._model.addItems(optionsArray).map(function (item) { return ({ item: item }); });
	        Array.prototype.push.apply(this._boxes, boxes);
	        return new phosphor_disposable_1.DisposableDelegate(function () {
	            _this._model.removeItems(boxes.map(function (box) { return box.item; }));
	            _this._boxes = _this._boxes.filter(function (box) { return boxes.indexOf(box) === -1; });
	        });
	    };
	    /**
	     *
	     */
	    PaletteRegistry.prototype.getModel = function () {
	        return this._model;
	    };
	    /**
	     * Update the shortcut for the given item pair.
	     */
	    PaletteRegistry.prototype._updateShortcut = function (box) {
	        var seq = this._shortcuts.sequenceFor(box.item.args);
	        var shortcut = seq ? Private.formatSequence(seq) : '';
	        var options = {
	            handler: this._executeCommand,
	            args: box.item.args,
	            text: box.item.text,
	            shortcut: shortcut,
	            icon: box.item.icon,
	            caption: box.item.caption,
	            category: box.item.category
	        };
	        this._model.removeItem(box.item);
	        box.item = this._model.addItem(options);
	    };
	    /**
	     * A handler for shortcut registry signals.
	     */
	    PaletteRegistry.prototype._onShortcutsChanged = function (sender, commands) {
	        var changed = Object.create(null);
	        commands.forEach(function (id) { changed[id] = true; });
	        for (var _i = 0, _a = this._boxes; _i < _a.length; _i++) {
	            var box = _a[_i];
	            var relevant = box.item.args in changed;
	            if (relevant)
	                this._updateShortcut(box);
	        }
	    };
	    return PaletteRegistry;
	}(ABCPaletteRegistry));
	exports.PaletteRegistry = PaletteRegistry;
	/**
	 * The default palette registry service provider.
	 */
	exports.paletteRegistryProvider = {
	    id: 'phosphide.services.paletteRegistry',
	    provides: ABCPaletteRegistry,
	    requires: [commandregistry_1.ABCCommandRegistry, shortcutregistry_1.ABCShortcutRegistry],
	    resolve: function (commands, shortcuts) {
	        return new PaletteRegistry(commands, shortcuts);
	    },
	};
	/**
	 *
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when a command is triggered by the palette.
	     */
	    Private.commandTriggeredSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A flag indicating whether the platform is Mac.
	     */
	    var IS_MAC = !!navigator.platform.match(/Mac/i);
	    /**
	     * How to format Accel (Cmd on Mac, Ctrl elsewhere)
	     */
	    var ACCEL = IS_MAC ? 'Cmd' : 'Ctrl';
	    /**
	     *
	     */
	    function formatSequence(seq) {
	        return seq.map(function (s) { return s.trim().replace(/\s+/g, '-').replace('Accel', ACCEL); }).join(' ');
	    }
	    Private.formatSequence = formatSequence;
	})(Private || (Private = {}));


/***/ },
/* 54 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	__export(__webpack_require__(55));
	__export(__webpack_require__(56));
	__export(__webpack_require__(57));
	__export(__webpack_require__(58));
	__webpack_require__(59);


/***/ },
/* 55 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var phosphor_signaling_1 = __webpack_require__(22);
	/**
	 * An enum of the support search result types.
	 */
	(function (SearchResultType) {
	    /**
	     * The search result represents a section header.
	     */
	    SearchResultType[SearchResultType["Header"] = 0] = "Header";
	    /**
	     * The search result represents a command.
	     */
	    SearchResultType[SearchResultType["Command"] = 1] = "Command";
	})(exports.SearchResultType || (exports.SearchResultType = {}));
	var SearchResultType = exports.SearchResultType;
	/**
	 * An abstract base class for creating command palette models.
	 */
	var AbstractPaletteModel = (function () {
	    function AbstractPaletteModel() {
	    }
	    Object.defineProperty(AbstractPaletteModel.prototype, "changed", {
	        /**
	         * A signal emitted when the potential search results change.
	         *
	         * #### Notes
	         * A subclass should emit this signal when its contents change in
	         * a way which may invalidate previously computed search results.
	         */
	        get: function () {
	            return AbstractPaletteModelPrivate.changedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return AbstractPaletteModel;
	})();
	exports.AbstractPaletteModel = AbstractPaletteModel;
	/**
	 * The namespace for the `AbstractPaletteModel` private data.
	 */
	var AbstractPaletteModelPrivate;
	(function (AbstractPaletteModelPrivate) {
	    /**
	     * A signal emitted when a palette model's search results change.
	     */
	    AbstractPaletteModelPrivate.changedSignal = new phosphor_signaling_1.Signal();
	})(AbstractPaletteModelPrivate || (AbstractPaletteModelPrivate = {}));


/***/ },
/* 56 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var arrays = __webpack_require__(3);
	var phosphor_widget_1 = __webpack_require__(20);
	var abstractmodel_1 = __webpack_require__(55);
	/**
	 * The class name added to `CommandPalette` instances.
	 */
	var PALETTE_CLASS = 'p-CommandPalette';
	/**
	 * The class name added to the search section of the palette.
	 */
	var SEARCH_CLASS = 'p-CommandPalette-search';
	/**
	 * The class name added to the input wrapper in the search section.
	 */
	var WRAPPER_CLASS = 'p-CommandPalette-inputWrapper';
	/**
	 * The class name added to the input node in the search section.
	 */
	var INPUT_CLASS = 'p-CommandPalette-input';
	/**
	 * The class name added to the content section of the palette.
	 */
	var CONTENT_CLASS = 'p-CommandPalette-content';
	/**
	 * The class name added to a palette section header.
	 */
	var HEADER_CLASS = 'p-CommandPalette-header';
	/**
	 * The class name added to a palette command.
	 */
	var COMMAND_CLASS = 'p-CommandPalette-command';
	/**
	 * The class name added to the command content node.
	 */
	var COMMAND_CONTENT_CLASS = 'p-CommandPalette-commandContent';
	/**
	 * The class name added to a command icon node.
	 */
	var COMMAND_ICON_CLASS = 'p-CommandPalette-commandIcon';
	/**
	 * The class name added to a command text node.
	 */
	var COMMAND_TEXT_CLASS = 'p-CommandPalette-commandText';
	/**
	 * The class name added to a command shortcut node.
	 */
	var COMMAND_SHORTCUT_CLASS = 'p-CommandPalette-commandShortcut';
	/**
	 * The class name added to a command caption node.
	 */
	var COMMAND_CAPTION_CLASS = 'p-CommandPalette-commandCaption';
	/**
	 * The class name added to the active palette header or command.
	 */
	var ACTIVE_CLASS = 'p-mod-active';
	/**
	 * An enum of command palette activation targets.
	 */
	(function (ActivationTarget) {
	    /**
	     * The activation target is a header item.
	     */
	    ActivationTarget[ActivationTarget["Header"] = 0] = "Header";
	    /**
	     * The activation target is a command item.
	     */
	    ActivationTarget[ActivationTarget["Command"] = 1] = "Command";
	    /**
	     * The activate target is any item.
	     */
	    ActivationTarget[ActivationTarget["Any"] = 2] = "Any";
	})(exports.ActivationTarget || (exports.ActivationTarget = {}));
	var ActivationTarget = exports.ActivationTarget;
	/**
	 * A widget which displays commands from a command source.
	 */
	var CommandPalette = (function (_super) {
	    __extends(CommandPalette, _super);
	    /**
	     * Construct a new command palette.
	     */
	    function CommandPalette() {
	        _super.call(this);
	        this._activeIndex = -1;
	        this._results = [];
	        this._headerPool = [];
	        this._commandPool = [];
	        this._model = null;
	        this.addClass(PALETTE_CLASS);
	    }
	    /**
	     * Create the DOM node for a command palette.
	     */
	    CommandPalette.createNode = function () {
	        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 = SEARCH_CLASS;
	        wrapper.className = WRAPPER_CLASS;
	        input.className = INPUT_CLASS;
	        content.className = CONTENT_CLASS;
	        input.spellcheck = false;
	        wrapper.appendChild(input);
	        search.appendChild(wrapper);
	        node.appendChild(search);
	        node.appendChild(content);
	        return node;
	    };
	    /**
	     * Create a new header node for a command palette.
	     *
	     * @returns A new DOM node for a palette section header.
	     *
	     * #### Notes
	     * This method may be reimplemented to create custom headers.
	     */
	    CommandPalette.createHeaderNode = function () {
	        var node = document.createElement('li');
	        node.className = HEADER_CLASS;
	        return node;
	    };
	    /**
	     * Create a new command node for a command palette.
	     *
	     * @returns A new DOM node for a palette section command.
	     *
	     * #### Notes
	     * This method may be reimplemented to create custom items.
	     */
	    CommandPalette.createCommandNode = function () {
	        var node = document.createElement('li');
	        var content = document.createElement('div');
	        var icon = document.createElement('span');
	        var text = document.createElement('span');
	        var caption = document.createElement('span');
	        var shortcut = document.createElement('span');
	        node.className = COMMAND_CLASS;
	        content.className = COMMAND_CONTENT_CLASS;
	        icon.className = COMMAND_ICON_CLASS;
	        text.className = COMMAND_TEXT_CLASS;
	        caption.className = COMMAND_CAPTION_CLASS;
	        shortcut.className = COMMAND_SHORTCUT_CLASS;
	        content.appendChild(shortcut);
	        content.appendChild(text);
	        content.appendChild(caption);
	        node.appendChild(icon);
	        node.appendChild(content);
	        return node;
	    };
	    /**
	     * Update a header node to reflect the given data.
	     *
	     * @param node - The header node which should be updated.
	     *
	     * @param data - The data object to use for the node state.
	     *
	     * #### Notes
	     * This is called automatically when the node should be updated.
	     *
	     * If the [[createHeaderNode]] method is reimplemented, this method
	     * should also be reimplemented so that the node state is properly
	     * updated.
	     */
	    CommandPalette.updateHeaderNode = function (node, data) {
	        node.className = HEADER_CLASS;
	        node.innerHTML = data.text;
	    };
	    /**
	     * Update a command node to reflect the given data.
	     *
	     * @param node - The command node which should be updated.
	     *
	     * @param data - The data object to use for the node state.
	     *
	     * #### Notes
	     * This is called automatically when the node should be updated.
	     *
	     * If the [[createHeaderNode]] method is reimplemented, this method
	     * should also be reimplemented so that the node state is properly
	     * updated.
	     */
	    CommandPalette.updateCommandNode = function (node, data) {
	        var icon = node.firstChild;
	        var content = icon.nextSibling;
	        var shortcut = content.firstChild;
	        var text = shortcut.nextSibling;
	        var caption = text.nextSibling;
	        var itemClass = COMMAND_CLASS;
	        if (data.className)
	            itemClass += ' ' + data.className;
	        node.className = itemClass;
	        var iconClass = COMMAND_ICON_CLASS;
	        if (data.icon)
	            iconClass += ' ' + data.icon;
	        icon.className = iconClass;
	        text.innerHTML = data.text;
	        caption.innerHTML = data.caption;
	        shortcut.innerHTML = data.shortcut;
	    };
	    /**
	     * Dispose of the resources held by the command palette.
	     */
	    CommandPalette.prototype.dispose = function () {
	        this._model = null;
	        this._results.length = 0;
	        this._headerPool.length = 0;
	        this._commandPool.length = 0;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(CommandPalette.prototype, "model", {
	        /**
	         * Get the model for the command palette.
	         */
	        get: function () {
	            return this._model;
	        },
	        /**
	         * Set the model for the command palette.
	         */
	        set: function (value) {
	            value = value || null;
	            if (this._model === value) {
	                return;
	            }
	            if (this._model) {
	                this._model.changed.disconnect(this._onModelChanged, this);
	            }
	            if (value) {
	                value.changed.connect(this._onModelChanged, this);
	            }
	            this._model = value;
	            this._results.length = 0;
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandPalette.prototype, "contentNode", {
	        /**
	         * Get the command palette content node.
	         *
	         * #### Notes
	         * This is the node which holds the command palette item nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this.node.getElementsByClassName(CONTENT_CLASS)[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandPalette.prototype, "inputNode", {
	        /**
	         * Get the command palette input node.
	         *
	         * #### Notes
	         * This node can be used to trigger manual updates of the command
	         * palette. Simply set the input node `value` to the desired text
	         * and call `palette.update()`.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this.node.getElementsByTagName('input')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Activate the first matching target item in the palette.
	     *
	     * @param target - The activation target. The default is `Any`.
	     *
	     * #### Notes
	     * This automatically scrolls the item into view.
	     *
	     * If no matching item is found, no item is activated.
	     */
	    CommandPalette.prototype.activateFirst = function (target) {
	        if (target === void 0) { target = ActivationTarget.Any; }
	        var i;
	        if (target === ActivationTarget.Header) {
	            var type = abstractmodel_1.SearchResultType.Header;
	            i = arrays.findIndex(this._results, function (r) { return r.type === type; });
	        }
	        else if (target === ActivationTarget.Command) {
	            var type = abstractmodel_1.SearchResultType.Command;
	            i = arrays.findIndex(this._results, function (r) { return r.type === type; });
	        }
	        else {
	            i = 0;
	        }
	        this._activate(i);
	    };
	    /**
	     * Activate the last matching target item in the palette.
	     *
	     * @param target - The activation target. The default is `Any`.
	     *
	     * #### Notes
	     * This automatically scrolls the item into view.
	     *
	     * If no matching item is found, no item is activated.
	     */
	    CommandPalette.prototype.activateLast = function (target) {
	        if (target === void 0) { target = ActivationTarget.Any; }
	        var i;
	        if (target === ActivationTarget.Header) {
	            var type = abstractmodel_1.SearchResultType.Header;
	            i = arrays.rfindIndex(this._results, function (r) { return r.type === type; });
	        }
	        else if (target === ActivationTarget.Command) {
	            var type = abstractmodel_1.SearchResultType.Command;
	            i = arrays.rfindIndex(this._results, function (r) { return r.type === type; });
	        }
	        else {
	            i = this._results.length - 1;
	        }
	        this._activate(i);
	    };
	    /**
	     * Activate the next matching target item in the palette.
	     *
	     * @param target - The activation target. The default is `Any`.
	     *
	     * #### Notes
	     * This automatically scrolls the item into view.
	     *
	     * The search will wrap around at the end of the palette.
	     *
	     * If no matching item is found, no item is activated.
	     */
	    CommandPalette.prototype.activateNext = function (target) {
	        if (target === void 0) { target = ActivationTarget.Any; }
	        var i;
	        var k = this._activeIndex + 1;
	        var j = k >= this._results.length ? 0 : k;
	        if (target === ActivationTarget.Header) {
	            var type = abstractmodel_1.SearchResultType.Header;
	            i = arrays.findIndex(this._results, function (r) { return r.type === type; }, j, true);
	        }
	        else if (target === ActivationTarget.Command) {
	            var type = abstractmodel_1.SearchResultType.Command;
	            i = arrays.findIndex(this._results, function (r) { return r.type === type; }, j, true);
	        }
	        else {
	            i = j;
	        }
	        this._activate(i);
	    };
	    /**
	     * Activate the previous matching target item in the palette.
	     *
	     * @param target - The activation target. The default is `Any`.
	     *
	     * #### Notes
	     * This automatically scrolls the item into view.
	     *
	     * The search will wrap around at the end of the palette.
	     *
	     * If no matching item is found, no item is activated.
	     */
	    CommandPalette.prototype.activatePrevious = function (target) {
	        if (target === void 0) { target = ActivationTarget.Any; }
	        var i;
	        var k = this._activeIndex;
	        var j = k <= 0 ? this._results.length - 1 : k - 1;
	        if (target === ActivationTarget.Header) {
	            var type = abstractmodel_1.SearchResultType.Header;
	            i = arrays.rfindIndex(this._results, function (r) { return r.type === type; }, j, true);
	        }
	        else if (target === ActivationTarget.Command) {
	            var type = abstractmodel_1.SearchResultType.Command;
	            i = arrays.rfindIndex(this._results, function (r) { return r.type === type; }, j, true);
	        }
	        else {
	            i = j;
	        }
	        this._activate(i);
	    };
	    /**
	     * Trigger the currently active item in the palette.
	     *
	     * #### Notes
	     * If the active item is a header, the search results are refined
	     * using the category of the header. If the current category is
	     * the same as the header category, the category will be removed.
	     *
	     * If the active item is a command, the command handler will be
	     * invoked and the current query text will be selected.
	     *
	     * If there is no active item, this is a no-op.
	     */
	    CommandPalette.prototype.triggerActive = function () {
	        var result = this._results[this._activeIndex];
	        if (!result) {
	            return;
	        }
	        if (result.type === abstractmodel_1.SearchResultType.Header) {
	            var input = this.inputNode;
	            var _a = CommandPalette.splitQuery(input.value), category = _a.category, text = _a.text;
	            var desired = result.value.category.trim();
	            var computed = desired === category ? '' : desired;
	            var query = CommandPalette.joinQuery(computed, text);
	            input.value = query;
	            input.focus();
	            this.update();
	        }
	        else if (result.type === abstractmodel_1.SearchResultType.Command) {
	            var _b = result.value, handler = _b.handler, args = _b.args;
	            this.inputNode.select();
	            handler(args);
	        }
	    };
	    /**
	     * 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.update();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'after-attach'` message.
	     */
	    CommandPalette.prototype.onAfterAttach = function (msg) {
	        this.node.addEventListener('click', this);
	        this.node.addEventListener('keydown', this);
	        this.node.addEventListener('input', this);
	    };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     */
	    CommandPalette.prototype.onBeforeDetach = function (msg) {
	        this.node.removeEventListener('click', this);
	        this.node.removeEventListener('keydown', this);
	        this.node.removeEventListener('input', this);
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    CommandPalette.prototype.onUpdateRequest = function (msg) {
	        // Clear the current content.
	        var content = this.contentNode;
	        content.textContent = '';
	        // Reset the active index.
	        this._activeIndex = -1;
	        // Bail early if there is no model.
	        if (!this._model) {
	            return;
	        }
	        // Split the query text into its category and text parts.
	        var _a = CommandPalette.splitQuery(this.inputNode.value), category = _a.category, text = _a.text;
	        // Search for query matches and store the results for later use.
	        var results = this._results = this._model.search(category, text);
	        // If the results are empty, there is nothing left to do.
	        if (results.length === 0) {
	            return;
	        }
	        // Grab the derived class type for access to the render methods.
	        var ctor = this.constructor;
	        // Setup the header node render function.
	        var headerPoolIndex = 0;
	        var headerPool = this._headerPool;
	        var renderHeader = function (data) {
	            var node = headerPool[headerPoolIndex++];
	            if (!node) {
	                node = ctor.createHeaderNode();
	                headerPool.push(node);
	            }
	            ctor.updateHeaderNode(node, data);
	            return node;
	        };
	        // Setup the command node render function.
	        var commandPoolIndex = 0;
	        var commandPool = this._commandPool;
	        var renderCommand = function (data) {
	            var node = commandPool[commandPoolIndex++];
	            if (!node) {
	                node = ctor.createCommandNode();
	                commandPool.push(node);
	            }
	            ctor.updateCommandNode(node, data);
	            return node;
	        };
	        // Loop over the search results and render the nodes.
	        var fragment = document.createDocumentFragment();
	        for (var _i = 0; _i < results.length; _i++) {
	            var _b = results[_i], type = _b.type, value = _b.value;
	            if (type === abstractmodel_1.SearchResultType.Header) {
	                fragment.appendChild(renderHeader(value));
	            }
	            else if (type === abstractmodel_1.SearchResultType.Command) {
	                fragment.appendChild(renderCommand(value));
	            }
	            else {
	                throw new Error('invalid search result type');
	            }
	        }
	        // Update the content node with the rendered search results.
	        content.appendChild(fragment);
	        // If there is query text, highlight the first command item.
	        // Otherwise, reset the content scroll position to the top.
	        if (category || text) {
	            this.activateFirst(ActivationTarget.Command);
	        }
	        else {
	            requestAnimationFrame(function () { content.scrollTop = 0; });
	        }
	    };
	    /**
	     * Activate the node at the given index.
	     *
	     * If the node is scrolled out of view, it will be scrolled into
	     * view and aligned according to the `alignTop` parameter.
	     */
	    CommandPalette.prototype._activate = function (index) {
	        var content = this.contentNode;
	        var children = content.children;
	        if (index < 0 || index >= children.length) {
	            index = -1;
	        }
	        if (this._activeIndex === index) {
	            return;
	        }
	        var oldNode = children[this._activeIndex];
	        var newNode = children[index];
	        this._activeIndex = index;
	        if (oldNode)
	            oldNode.classList.remove(ACTIVE_CLASS);
	        if (newNode)
	            newNode.classList.add(ACTIVE_CLASS);
	        if (newNode)
	            requestAnimationFrame(function () {
	                Private.scrollIfNeeded(content, newNode);
	            });
	    };
	    /**
	     * Handle the `'click'` event for the command palette.
	     */
	    CommandPalette.prototype._evtClick = function (event) {
	        if (event.button !== 0) {
	            return;
	        }
	        event.preventDefault();
	        event.stopPropagation();
	        var root = this.node;
	        var content = this.contentNode;
	        var target = event.target;
	        while (true) {
	            if (target === root)
	                return;
	            var parent_1 = target.parentNode;
	            if (parent_1 === content)
	                break;
	            target = parent_1;
	        }
	        var index = Array.prototype.indexOf.call(content.children, target);
	        this._activate(index);
	        this.triggerActive();
	    };
	    /**
	     * 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.triggerActive();
	                break;
	            case 38:
	                event.preventDefault();
	                event.stopPropagation();
	                this.activatePrevious();
	                break;
	            case 40:
	                event.preventDefault();
	                event.stopPropagation();
	                this.activateNext();
	                break;
	        }
	    };
	    /**
	     * Handle the `changed` signal for the palette model.
	     */
	    CommandPalette.prototype._onModelChanged = function () {
	        this.update();
	    };
	    return CommandPalette;
	})(phosphor_widget_1.Widget);
	exports.CommandPalette = CommandPalette;
	/**
	 * The namespace for the `CommandPalette` class statics.
	 */
	var CommandPalette;
	(function (CommandPalette) {
	    /**
	     * Split a query string into its category and text components.
	     *
	     * @param query - A query string of the form `(:<category>:)?<text>`.
	     *
	     * @returns The `category` and `text` components of the query with
	     *   leading and trailing whitespace removed.
	     */
	    function splitQuery(query) {
	        query = query.trim();
	        if (query[0] !== ':') {
	            return { category: '', text: query };
	        }
	        var i = query.indexOf(':', 1);
	        if (i === -1) {
	            return { category: query.slice(1).trim(), text: '' };
	        }
	        var category = query.slice(1, i).trim();
	        var text = query.slice(i + 1).trim();
	        return { category: category, text: text };
	    }
	    CommandPalette.splitQuery = splitQuery;
	    /**
	     * Join category and text components into a query string.
	     *
	     * @param category - The category for the query or an empty string.
	     *
	     * @param text - The text for the query or an empty string.
	     *
	     * @returns The joined query string for the components.
	     */
	    function joinQuery(category, text) {
	        var query;
	        if (category && text) {
	            query = ":" + category.trim() + ": " + text.trim();
	        }
	        else if (category) {
	            query = ":" + category.trim() + ": ";
	        }
	        else if (text) {
	            query = text.trim();
	        }
	        else {
	            query = '';
	        }
	        return query;
	    }
	    CommandPalette.joinQuery = joinQuery;
	})(CommandPalette = exports.CommandPalette || (exports.CommandPalette = {}));
	/**
	 * The namespace for the `CommandPalette` private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Scroll an element into view if needed.
	     *
	     * @param area - The scroll area element.
	     *
	     * @param elem - The element of interest.
	     */
	    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;
	        }
	    }
	    Private.scrollIfNeeded = scrollIfNeeded;
	})(Private || (Private = {}));


/***/ },
/* 57 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var arrays = __webpack_require__(3);
	var abstractmodel_1 = __webpack_require__(55);
	var stringsearch_1 = __webpack_require__(58);
	/**
	 * An object for use with a standard palette model.
	 *
	 * #### Notes
	 * Instances of this class will not typically be created directly by
	 * the user. A palette model will create and return instances of the
	 * class from its adder methods.
	 */
	var StandardPaletteItem = (function () {
	    /**
	     * Construct a new standard palette item.
	     *
	     * @param options - The options for initializing the item.
	     */
	    function StandardPaletteItem(options) {
	        this._text = options.text;
	        this._args = options.args;
	        this._handler = options.handler;
	        this._icon = options.icon || '';
	        this._caption = options.caption || '';
	        this._shortcut = options.shortcut || '';
	        this._className = options.className || '';
	        this._category = Private.normalizeCategory(options.category || '');
	    }
	    Object.defineProperty(StandardPaletteItem.prototype, "text", {
	        /**
	         * Get the primary text for the item.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._text;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(StandardPaletteItem.prototype, "icon", {
	        /**
	         * Get the icon class name(s) for the item.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._icon;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(StandardPaletteItem.prototype, "caption", {
	        /**
	         * Get the descriptive caption for the item.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._caption;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(StandardPaletteItem.prototype, "shortcut", {
	        /**
	         * Get the keyboard shortcut for the item.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._shortcut;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(StandardPaletteItem.prototype, "category", {
	        /**
	         * Get the category name for the item.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._category;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(StandardPaletteItem.prototype, "className", {
	        /**
	         * Get the extra class name(s) for the item.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._className;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(StandardPaletteItem.prototype, "handler", {
	        /**
	         * Get the handler function for the item.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._handler;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(StandardPaletteItem.prototype, "args", {
	        /**
	         * Get the arguments for the handler.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._args;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return StandardPaletteItem;
	})();
	exports.StandardPaletteItem = StandardPaletteItem;
	/**
	 * A concrete palette model which holds a collection of palette items.
	 *
	 * #### Notes
	 * This class is a reasonable option for populating command palettes
	 * when the number of items is reasonable, and when the items can be
	 * created ahead of time. If lazy searching of a large data set is
	 * required, then a custom palette model should be used instead.
	 */
	var StandardPaletteModel = (function (_super) {
	    __extends(StandardPaletteModel, _super);
	    function StandardPaletteModel() {
	        _super.apply(this, arguments);
	        this._items = [];
	    }
	    /**
	     * Get the items contained in the palette model.
	     *
	     * @returns A new array of the current items in the model.
	     */
	    StandardPaletteModel.prototype.items = function () {
	        return this._items.slice();
	    };
	    /**
	     * Add a new palette item to the model.
	     *
	     * @param options - The options for initializing the item.
	     *
	     * @returns The palette item which was added to the model.
	     */
	    StandardPaletteModel.prototype.addItem = function (options) {
	        var item = new StandardPaletteItem(options);
	        this._items.push(item);
	        this.changed.emit(void 0);
	        return item;
	    };
	    /**
	     * Add several new palette items to the model.
	     *
	     * @param options - The options for initializing the items.
	     *
	     * @returns The new palette items where were added to the model.
	     */
	    StandardPaletteModel.prototype.addItems = function (options) {
	        var items = options.map(function (opts) { return new StandardPaletteItem(opts); });
	        Array.prototype.push.apply(this._items, items);
	        this.changed.emit(void 0);
	        return items;
	    };
	    /**
	     * Remove a palette item from the model.
	     *
	     * @param item - The item to remove from the model.
	     *
	     * #### Notes
	     * If the item is not contained in the model, this is a no-op.
	     */
	    StandardPaletteModel.prototype.removeItem = function (item) {
	        var i = arrays.remove(this._items, item);
	        if (i !== -1)
	            this.changed.emit(void 0);
	    };
	    /**
	     * Remove several items from the model.
	     *
	     * @param items - The items to remove from the model.
	     *
	     * #### Notes
	     * Items which are no contained in the model are ignored.
	     */
	    StandardPaletteModel.prototype.removeItems = function (items) {
	        var rest = this._items.filter(function (other) { return items.indexOf(other) === -1; });
	        if (rest.length === this._items.length) {
	            return;
	        }
	        this._items = rest;
	        this.changed.emit(void 0);
	    };
	    /**
	     * Remove all items from the model.
	     */
	    StandardPaletteModel.prototype.clearItems = function () {
	        if (this._items.length === 0) {
	            return;
	        }
	        this._items.length = 0;
	        this.changed.emit(void 0);
	    };
	    /**
	     * Search the palette model for matching commands.
	     *
	     * @param category - The category match against the model items. If
	     *   this is an empty string, all item categories will be matched.
	     *
	     * @param text - The text to match against the model items. If this
	     *   is an empty string, all items will be matched.
	     *
	     * @returns An array of new search results for the query.
	     */
	    StandardPaletteModel.prototype.search = function (category, text) {
	        // Collect a mapping of the matching categories. The mapping will
	        // only contain categories which match the provided query text.
	        // If the category is an empty string, all categories will be
	        // matched with a score of `0` and a `null` indices array.
	        var catmap = Private.matchCategory(this._items, category);
	        // Filter the items for matching text. Only items which have a
	        // category in the given map are considered. The category score
	        // is added to the text score to create the final item score.
	        // If the text is an empty string, all items will be matched
	        // will a text score of `0` and `null` indices array.
	        var scores = Private.matchText(this._items, text, catmap);
	        // Sort the items based on their total item score. Ties are
	        // broken by locale ordering the category followed by the text.
	        scores.sort(Private.scoreCmp);
	        // Group the item scores by category. The categories are added
	        // to the map in the order they appear in the scores array.
	        var groups = Private.groupScores(scores);
	        // Return the results for the search. The headers are created in
	        // the order of key iteration of the map. On major browsers, this
	        // is insertion order. This means that headers are created in the
	        // order of first appearance in the sorted scores array.
	        return Private.createSearchResults(groups, catmap);
	    };
	    return StandardPaletteModel;
	})(abstractmodel_1.AbstractPaletteModel);
	exports.StandardPaletteModel = StandardPaletteModel;
	/**
	 * The namespace for the `StandardPaletteModel` private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Normalize a category for a palette item.
	     *
	     * @param category - The item category to normalize.
	     *
	     * @returns The normalized category text.
	     *
	     * #### Notes
	     * This converts the category to lower case and removes any
	     * extraneous whitespace.
	     */
	    function normalizeCategory(category) {
	        return category.trim().replace(/\s+/g, ' ').toLowerCase();
	    }
	    Private.normalizeCategory = normalizeCategory;
	    /**
	     * Collect a mapping of the categories which match the given query.
	     *
	     * @param items - The palette items to search.
	     *
	     * @param query - The category portion of the palette model query.
	     *
	     * @returns A mapping of matched category to match score.
	     *
	     * #### Notes
	     * The query string will be normalized by lower casing and removing
	     * all whitespace. If the normalized query is an empty string, all
	     * categories will be matched with a `0` score and `null` indices.
	     */
	    function matchCategory(items, query) {
	        // Normalize the query text to lower case with no whitespace.
	        query = normalizeQueryText(query);
	        // Create the maps needed to track the match state.
	        var seen = Object.create(null);
	        var matched = Object.create(null);
	        // Iterate over the items and match the categories.
	        for (var _i = 0; _i < items.length; _i++) {
	            var category = items[_i].category;
	            // If a category has already been seen, no more work is needed.
	            if (category in seen) {
	                continue;
	            }
	            // Mark the category as seen so it is only processed once.
	            seen[category] = true;
	            // If the query is empty, all categories match by default.
	            if (!query) {
	                matched[category] = { score: 0, indices: null };
	                continue;
	            }
	            // Run the matcher for the query and skip if no match.
	            var match = stringsearch_1.StringSearch.sumOfSquares(category, query);
	            if (!match) {
	                continue;
	            }
	            // Store the match score in the results.
	            matched[category] = match;
	        }
	        // Return the final mapping of matched categories.
	        return matched;
	    }
	    Private.matchCategory = matchCategory;
	    /**
	     * Filter palette items for those with matching text and category.
	     *
	     * @param items - The palette items to search.
	     *
	     * @param query - The text portion of the palette model query.
	     *
	     * @param categories - A mapping of the valid item categories.
	     *
	     * @returns An array of item scores for the matching items.
	     *
	     * #### Notes
	     * The query string will be normalized by lower casing and removing
	     * all whitespace. If the normalized query is an empty string, all
	     * items will be matched with a `0` text score and `null` indices.
	     *
	     * Items which have a category which is not present in the category
	     * map will be ignored.
	     *
	     * The final item score is the sum of the item text score and the
	     * relevant category score.
	     *
	     * This function does not sort the results.
	     */
	    function matchText(items, query, categories) {
	        // Normalize the query text to lower case with no whitespace.
	        query = normalizeQueryText(query);
	        // Create the array to hold the resulting scores.
	        var scores = [];
	        // Iterate over the items and match the text with the query.
	        for (var _i = 0; _i < items.length; _i++) {
	            var item = items[_i];
	            // Lookup the category score for the item category.
	            var cs = categories[item.category];
	            // If the category was not matched, the item is skipped.
	            if (!cs) {
	                continue;
	            }
	            // If the query is empty, all items are matched by default.
	            if (!query) {
	                scores.push({ score: cs.score, indices: null, item: item });
	                continue;
	            }
	            // Run the matcher for the query and skip if no match.
	            var match = stringsearch_1.StringSearch.sumOfSquares(item.text.toLowerCase(), query);
	            if (!match) {
	                continue;
	            }
	            // Create the match score for the item.
	            var score = cs.score + match.score;
	            scores.push({ score: score, indices: match.indices, item: item });
	        }
	        // Return the final array of matched item scores.
	        return scores;
	    }
	    Private.matchText = matchText;
	    /**
	     * A sort comparison function for a palette item match score.
	     *
	     * #### Notes
	     * This orders the items first based on score (lower is better), then
	     * by locale order of the item category followed by the item text.
	     */
	    function scoreCmp(a, b) {
	        var d1 = a.score - b.score;
	        if (d1 !== 0) {
	            return d1;
	        }
	        var d2 = a.item.category.localeCompare(b.item.category);
	        if (d2 !== 0) {
	            return d2;
	        }
	        return a.item.text.localeCompare(b.item.text);
	    }
	    Private.scoreCmp = scoreCmp;
	    /**
	     * Group item scores by item category.
	     *
	     * @param scores - The items to group by category.
	     *
	     * @returns A mapping of category name to group of items.
	     *
	     * #### Notes
	     * The categories are added to the map in the order of first
	     * appearance in the `scores` array.
	     */
	    function groupScores(scores) {
	        var result = Object.create(null);
	        for (var _i = 0; _i < scores.length; _i++) {
	            var score = scores[_i];
	            var cat = score.item.category;
	            (result[cat] || (result[cat] = [])).push(score);
	        }
	        return result;
	    }
	    Private.groupScores = groupScores;
	    /**
	     * Create the search results for a collection of item scores.
	     *
	     * @param groups - The item scores, grouped by category.
	     *
	     * @param categories - A mapping of category scores.
	     *
	     * @returns A flat array of search results for the groups.
	     *
	     * #### Notes
	     * This function renders the groups in iteration order, which on all
	     * major browsers is order of insertion (a de facto standard).
	     */
	    function createSearchResults(groups, categories) {
	        var results = [];
	        for (var cat in groups) {
	            results.push(createHeaderResult(cat, categories[cat]));
	            for (var _i = 0, _a = groups[cat]; _i < _a.length; _i++) {
	                var score = _a[_i];
	                results.push(createCommandResult(score));
	            }
	        }
	        return results;
	    }
	    Private.createSearchResults = createSearchResults;
	    /**
	     * Normalize the query text for a palette item.
	     *
	     * @param text - The category or text portion of a palette query.
	     *
	     * @returns The normalized query text.
	     *
	     * #### Notes
	     * The text is normalized by converting to lower case and removing
	     * all whitespace.
	     */
	    function normalizeQueryText(text) {
	        return text.replace(/\s+/g, '').toLowerCase();
	    }
	    /**
	     * Create a header search result for the given data.
	     *
	     * @param category - The category name for the header.
	     *
	     * @param score - The score for the category match.
	     *
	     * @returns A header search result for the given data.
	     */
	    function createHeaderResult(category, score) {
	        var text = highlightText(category, score.indices);
	        return { type: abstractmodel_1.SearchResultType.Header, value: { text: text, category: category } };
	    }
	    /**
	     * Create a command search result for the given data.
	     *
	     * @param score - The score for the item match.
	     *
	     * @returns A command search result for the given data.
	     */
	    function createCommandResult(score) {
	        var text = highlightText(score.item.text, score.indices);
	        var _a = score.item, icon = _a.icon, caption = _a.caption, shortcut = _a.shortcut, className = _a.className, handler = _a.handler, args = _a.args;
	        var value = { text: text, icon: icon, caption: caption, shortcut: shortcut, className: className, handler: handler, args: args };
	        return { type: abstractmodel_1.SearchResultType.Command, value: value };
	    }
	    /**
	     * Highlight the matching character of the given text.
	     *
	     * @param text - The text to highlight.
	     *
	     * @param indices - The character indices to highlight, or `null`.
	     *
	     * @returns The text interpolated with `<mark>` tags as needed.
	     */
	    function highlightText(text, indices) {
	        return indices ? stringsearch_1.StringSearch.highlight(text, indices) : text;
	    }
	})(Private || (Private = {}));


/***/ },
/* 58 */
/***/ function(module, exports) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	/**
	 * A namespace which holds string searching functionality.
	 */
	var StringSearch;
	(function (StringSearch) {
	    /**
	     * Compute the sum-of-squares match for the given search text.
	     *
	     * @param sourceText - The text which should be searched.
	     *
	     * @param queryText - The query text to locate in the source text.
	     *
	     * @returns The match result object, or `null` if there is no match.
	     *
	     * #### 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 `queryText` **must** appear in `sourceText` 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.
	     *
	     * The character match is performed with strict equality. It is case
	     * sensitive and does not ignore whitespace. If those behaviors are
	     * required, the text should be transformed before scoring.
	     *
	     * This has a runtime complexity of `O(n)` on `sourceText`.
	     */
	    function sumOfSquares(sourceText, queryText) {
	        var score = 0;
	        var indices = new Array(queryText.length);
	        for (var i = 0, j = 0, n = queryText.length; i < n; ++i, ++j) {
	            j = sourceText.indexOf(queryText[i], j);
	            if (j === -1)
	                return null;
	            indices[i] = j;
	            score += j * j;
	        }
	        return { score: score, indices: indices };
	    }
	    StringSearch.sumOfSquares = sumOfSquares;
	    /**
	     * Highlight the matched characters of a source string.
	     *
	     * @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.
	     *
	     * @returns A string with interpolated `<mark>` tags.
	     */
	    function highlight(sourceText, indices) {
	        var k = 0;
	        var last = 0;
	        var result = '';
	        var n = indices.length;
	        while (k < n) {
	            var i = indices[k];
	            var j = indices[k];
	            while (++k < n && indices[k] === j + 1)
	                j++;
	            var head = sourceText.slice(last, i);
	            var chunk = sourceText.slice(i, j + 1);
	            result += head + "<mark>" + chunk + "</mark>";
	            last = j + 1;
	        }
	        return result + sourceText.slice(last);
	    }
	    StringSearch.highlight = highlight;
	})(StringSearch = exports.StringSearch || (exports.StringSearch = {}));


/***/ },
/* 59 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(60);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../css-loader/index.js!./index.css", function() {
				var newContent = require("!!./../../css-loader/index.js!./index.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 60 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\r\n| Copyright (c) 2014-2016, PhosphorJS Contributors\r\n|\r\n| Distributed under the terms of the BSD 3-Clause License.\r\n|\r\n| The full license is in the file LICENSE, distributed with this software.\r\n|----------------------------------------------------------------------------*/\r\n.p-CommandPalette {\r\n  display: flex;\r\n  flex-direction: column;\r\n}\r\n\r\n\r\n.p-CommandPalette-search {\r\n  flex: 0 0 auto;\r\n}\r\n\r\n\r\n.p-CommandPalette-content {\r\n  flex: 1 1 auto;\r\n  margin: 0;\r\n  padding: 0;\r\n  min-height: 0;\r\n  overflow: auto;\r\n  list-style-type: none;\r\n}\r\n\r\n\r\n.p-CommandPalette-header {\r\n  overflow: hidden;\r\n  white-space: nowrap;\r\n  text-overflow: ellipsis;\r\n}\r\n\r\n\r\n.p-CommandPalette-command {\r\n  display: flex;\r\n  flex-direction: row;\r\n}\r\n\r\n\r\n.p-CommandPalette-commandIcon {\r\n  flex: 0 0 auto;\r\n}\r\n\r\n\r\n.p-CommandPalette-commandContent {\r\n  flex: 1 1 auto;\r\n}\r\n\r\n\r\n.p-CommandPalette-commandShortcut {\r\n  float: right;\r\n}\r\n\r\n\r\n.p-CommandPalette-commandText {\r\n  display: block;\r\n  overflow: hidden;\r\n  white-space: nowrap;\r\n  text-overflow: ellipsis;\r\n}\r\n\r\n\r\n.p-CommandPalette-commandCaption {\r\n  display: block;\r\n}\r\n", ""]);
	
	// exports


/***/ },
/* 61 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_disposable_1 = __webpack_require__(8);
	var phosphor_keymap_1 = __webpack_require__(62);
	var phosphor_signaling_1 = __webpack_require__(22);
	var commandregistry_1 = __webpack_require__(52);
	/**
	 * An abstract base class which defines a shortcut registry.
	 *
	 * TODO - allow multiple shortcuts for a single command?
	 */
	var ABCShortcutRegistry = (function () {
	    function ABCShortcutRegistry() {
	    }
	    Object.defineProperty(ABCShortcutRegistry.prototype, "shortcutsAdded", {
	        /**
	         * A signal emitted when shortcuts are added to the manager.
	         */
	        get: function () {
	            return Private.shortcutsAddedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ABCShortcutRegistry.prototype, "shortcutsRemoved", {
	        /**
	         * A signal emitted when shortcuts are removed from the manager.
	         */
	        get: function () {
	            return Private.shortcutsRemovedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ABCShortcutRegistry;
	}());
	exports.ABCShortcutRegistry = ABCShortcutRegistry;
	/**
	 * A concrete implementation of ABCShortcutRegistry.
	 *
	 * TODO - Support configurable keyboard layout.
	 */
	var ShortcutRegistry = (function (_super) {
	    __extends(ShortcutRegistry, _super);
	    /**
	     * Construct a shortcut manager.
	     *
	     * @param commands - The command registry for executing commands.
	     */
	    function ShortcutRegistry(commands) {
	        var _this = this;
	        _super.call(this);
	        /**
	         * The private key binding handler function.
	         */
	        this._executeCommand = function (id) {
	            _this._commands.execute(id);
	            return true;
	        };
	        this._keymap = new phosphor_keymap_1.KeymapManager();
	        this._commands = null;
	        this._sequences = Private.createSequenceMap();
	        this._commands = commands;
	    }
	    /**
	     * List the currently registered command ids.
	     *
	     * @returns A new array of the registered command ids.
	     */
	    ShortcutRegistry.prototype.list = function () {
	        return Object.keys(this._sequences);
	    };
	    /**
	     * Test whether the registry contains a sequence for a command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @returns `true` if a sequence is registered, `false` otherwise.
	     */
	    ShortcutRegistry.prototype.has = function (command) {
	        return command in this._sequences;
	    };
	    /**
	     * Get the key sequence for the given command id.
	     *
	     * @param command - The id of the command of interest.
	     *
	     * @returns The key sequence for the specified command, or null.
	     */
	    ShortcutRegistry.prototype.sequenceFor = function (command) {
	        var sequence = this._sequences[command];
	        return sequence ? sequence.slice() : null;
	    };
	    /**
	     * Add key bindings to the shortcut manager.
	     *
	     * @param bindings - The key bindings to add to the manager.
	     *
	     * @returns A disposable which removes the added key bindings.
	     *
	     * #### Notes
	     * If a shortcut for a specific command is already registered,
	     * a warning will be logged and that specific shortcut will be
	     * ignored.
	     */
	    ShortcutRegistry.prototype.add = function (items) {
	        var _this = this;
	        // Setup the added ids and keybinding arrays.
	        var added = [];
	        var bindings = [];
	        // Convert the shortcut items into key bindings.
	        for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
	            var _a = items_1[_i], sequence = _a.sequence, selector = _a.selector, command = _a.command;
	            // Log a warning if the command already has a shortcut.
	            if (command in this._sequences) {
	                console.warn("shortcut already registered for '" + command + "'");
	                continue;
	            }
	            // Register a safe shallow copy of the sequence.
	            sequence = sequence.slice();
	            this._sequences[command] = sequence;
	            // Add the command to the tracking array.
	            added.push(command);
	            // Add a keybinding to the tracking array.
	            var handler = this._executeCommand;
	            bindings.push({ sequence: sequence, selector: selector, handler: handler, args: command });
	        }
	        // If no items are added, return an empty delegate.
	        if (added.length === 0) {
	            return new phosphor_disposable_1.DisposableDelegate(null);
	        }
	        // Add the keybindings to the keymap manager.
	        // TODO - if any keybinding is invalid, we'll be out-of-sync.
	        var addedResult = this._keymap.add(bindings);
	        // Notify for the added shortcuts using a safe shallow copy.
	        this.shortcutsAdded.emit(added.slice());
	        // Return a delegate which will remove the added shortcuts.
	        return new phosphor_disposable_1.DisposableDelegate(function () {
	            addedResult.dispose();
	            for (var _i = 0, added_1 = added; _i < added_1.length; _i++) {
	                var id = added_1[_i];
	                delete _this._sequences[id];
	            }
	            _this.shortcutsRemoved.emit(added.slice());
	        });
	    };
	    /**
	     * Process a `'keydown'` event dispatching a matching shortcut.
	     *
	     * @param event - The event object for the `'keydown'` event.
	     *
	     * #### Notes
	     * This will typically be called automatically by the application.
	     */
	    ShortcutRegistry.prototype.processKeydownEvent = function (event) {
	        this._keymap.processKeydownEvent(event);
	    };
	    return ShortcutRegistry;
	}(ABCShortcutRegistry));
	exports.ShortcutRegistry = ShortcutRegistry;
	/**
	 * The default shortcut registry service provider.
	 */
	exports.shortcutRegistryProvider = {
	    id: 'phosphide.services.shortcutRegistry',
	    provides: ABCShortcutRegistry,
	    requires: [commandregistry_1.ABCCommandRegistry],
	    resolve: function (commands) { return new ShortcutRegistry(commands); },
	};
	/**
	 * The namespace for the private shortcut registry functionality.
	 */
	var Private;
	(function (Private) {
	    /**
	     *
	     */
	    Private.shortcutsAddedSignal = new phosphor_signaling_1.Signal();
	    /**
	     *
	     */
	    Private.shortcutsRemovedSignal = new phosphor_signaling_1.Signal();
	    /**
	     *
	     */
	    function createSequenceMap() {
	        return Object.create(null);
	    }
	    Private.createSequenceMap = createSequenceMap;
	})(Private || (Private = {}));


/***/ },
/* 62 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	__export(__webpack_require__(63));
	__export(__webpack_require__(64));


/***/ },
/* 63 */
/***/ function(module, exports) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	/**
	 * Create a normalized keystroke for a `'keydown'` event.
	 *
	 * @param event - The event object for a `'keydown'` event.
	 *
	 * @param layout - The keyboard layout for computing the keycap.
	 *
	 * @returns A normalized keystroke, or an empty string if the event
	 *   does not represent a valid shortcut keystroke.
	 */
	function keystrokeForKeydownEvent(event, layout) {
	    var keycap = layout.keycapForKeydownEvent(event);
	    if (!keycap) {
	        return '';
	    }
	    var mods = '';
	    if (event.metaKey && IS_MAC) {
	        mods += 'Cmd ';
	    }
	    if (event.ctrlKey) {
	        mods += 'Ctrl ';
	    }
	    if (event.altKey) {
	        mods += 'Alt ';
	    }
	    if (event.shiftKey) {
	        mods += 'Shift ';
	    }
	    return mods + keycap;
	}
	exports.keystrokeForKeydownEvent = keystrokeForKeydownEvent;
	/**
	 * Normalize and validate a keystroke.
	 *
	 * @param keystroke - The keystroke to normalize.
	 *
	 * @param layout - The keyboard layout for validating the keycap.
	 *
	 * @returns The normalized keystroke.
	 *
	 * @throws An error if the keystroke is invalid.
	 *
	 * #### Notes
	 * The keystroke must adhere to the format:
	 *
	 *   `[<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 keystroke must conform to the following:
	 *   - Modifiers and the primary key are case senstive.
	 *   - The primary key must be a valid key for the layout.
	 *   - Whitespace is used to separate modifiers and primary key.
	 *   - Modifiers may appear in any order before the primary key.
	 *   - Modifiers cannot appear in duplicate.
	 *   - The `Cmd` modifier is only valid on Mac.
	 *
	 * If a keystroke is nonconforming, an error will be thrown.
	 */
	function normalizeKeystroke(keystroke, layout) {
	    var keycap = '';
	    var alt = false;
	    var cmd = false;
	    var ctrl = false;
	    var shift = false;
	    for (var _i = 0, _a = keystroke.trim().split(/\s+/); _i < _a.length; _i++) {
	        var token = _a[_i];
	        if (token === 'Accel') {
	            token = IS_MAC ? 'Cmd' : 'Ctrl';
	        }
	        if (token === 'Alt') {
	            if (alt) {
	                throwKeystrokeError(keystroke, '`Alt` appears in duplicate');
	            }
	            if (keycap) {
	                throwKeystrokeError(keystroke, '`Alt` follows primary key');
	            }
	            alt = true;
	        }
	        else if (token === 'Cmd') {
	            if (cmd) {
	                throwKeystrokeError(keystroke, '`Cmd` appears in duplicate');
	            }
	            if (keycap) {
	                throwKeystrokeError(keystroke, '`Cmd` follows primary key');
	            }
	            if (!IS_MAC) {
	                throwKeystrokeError(keystroke, '`Cmd` used on non-Mac platform');
	            }
	            cmd = true;
	        }
	        else if (token === 'Ctrl') {
	            if (ctrl) {
	                throwKeystrokeError(keystroke, '`Ctrl` appears in duplicate');
	            }
	            if (keycap) {
	                throwKeystrokeError(keystroke, '`Ctrl` follows primary key');
	            }
	            ctrl = true;
	        }
	        else if (token === 'Shift') {
	            if (shift) {
	                throwKeystrokeError(keystroke, '`Shift` appears in duplicate');
	            }
	            if (keycap) {
	                throwKeystrokeError(keystroke, '`Shift` follows primary key');
	            }
	            shift = true;
	        }
	        else {
	            if (keycap) {
	                throwKeystrokeError(keystroke, 'primary key appears in duplicate');
	            }
	            if (!layout.isValidKeycap(token)) {
	                throwKeystrokeError(keystroke, 'primary key invalid for layout');
	            }
	            keycap = token;
	        }
	    }
	    if (!keycap) {
	        throwKeystrokeError(keystroke, 'primary key not specified');
	    }
	    var mods = '';
	    if (cmd) {
	        mods += 'Cmd ';
	    }
	    if (ctrl) {
	        mods += 'Ctrl ';
	    }
	    if (alt) {
	        mods += 'Alt ';
	    }
	    if (shift) {
	        mods += 'Shift ';
	    }
	    return mods + keycap;
	}
	exports.normalizeKeystroke = normalizeKeystroke;
	/**
	 * 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 keycodes to keycaps
	 * (the letter(s) printed on a physical keyboard key) which allows
	 * for reliable keyboard 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 keycap value.
	     */
	    function KeycodeLayout(name, codes) {
	        this._name = name;
	        this._codes = codes;
	        this._keys = extractKeys(codes);
	    }
	    Object.defineProperty(KeycodeLayout.prototype, "name", {
	        /**
	         * The human readable read-only name of the layout.
	         */
	        get: function () {
	            return this._name;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get an array of all keycap values supported by the layout.
	     *
	     * @returns A new array of the supported keycap values.
	     */
	    KeycodeLayout.prototype.keycaps = function () {
	        return Object.keys(this._keys);
	    };
	    /**
	     * Test whether the given keycap is a valid value for the layout.
	     *
	     * @param keycap - The user provided keycap to test for validity.
	     *
	     * @returns `true` if the keycap is valid, `false` otherwise.
	     */
	    KeycodeLayout.prototype.isValidKeycap = function (keycap) {
	        return keycap in this._keys;
	    };
	    /**
	     * Get the keycap for a `'keydown'` event.
	     *
	     * @param event - The event object for a `'keydown'` event.
	     *
	     * @returns The associated keycap value, or an empty string if
	     *   the event does not represent a valid primary shortcut key.
	     */
	    KeycodeLayout.prototype.keycapForKeydownEvent = function (event) {
	        return this._codes[event.keyCode] || '';
	    };
	    return 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: '\'',
	});
	/**
	 * A flag indicating whether the platform is Mac.
	 */
	var IS_MAC = !!navigator.platform.match(/Mac/i);
	/**
	 * Throw an error with the give invalid keystroke.
	 */
	function throwKeystrokeError(keystroke, message) {
	    throw new Error("invalid keystroke: " + keystroke + " (" + message + ")");
	}
	/**
	 * Extract the key set from a code map.
	 */
	function extractKeys(codes) {
	    var keys = Object.create(null);
	    for (var c in codes) {
	        keys[codes[c]] = true;
	    }
	    return keys;
	}


/***/ },
/* 64 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var clear_cut_1 = __webpack_require__(65);
	var phosphor_disposable_1 = __webpack_require__(8);
	var keyboard_1 = __webpack_require__(63);
	/**
	 * A class which manages a collection of key bindings.
	 */
	var KeymapManager = (function () {
	    /**
	     * Construct a new key map manager.
	     *
	     * @param layout - The keyboard layout to use with the manager.
	     *   The default layout is US English.
	     */
	    function KeymapManager(layout) {
	        if (layout === void 0) { layout = keyboard_1.EN_US; }
	        this._timer = 0;
	        this._replaying = false;
	        this._sequence = [];
	        this._exact = null;
	        this._bindings = [];
	        this._events = [];
	        this._layout = layout;
	    }
	    Object.defineProperty(KeymapManager.prototype, "layout", {
	        /**
	         * Get the keyboard layout used by the manager.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._layout;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add key bindings to the key map manager.
	     *
	     * @param bindings - The key bindings to add to the manager.
	     *
	     * @returns A disposable which removes the added key bindings.
	     *
	     * #### Notes
	     * If a key binding is invalid, a warning will be logged to the
	     * console and the offending key binding will be ignored.
	     *
	     * If multiple key bindings are registered for the same sequence,
	     * the binding with the highest CSS specificity is executed first.
	     *
	     * Ambiguous key bindings are resolved with a timeout.
	     */
	    KeymapManager.prototype.add = function (bindings) {
	        var _this = this;
	        var exbArray = [];
	        for (var _i = 0; _i < bindings.length; _i++) {
	            var kb = bindings[_i];
	            var exb = createExBinding(kb, this._layout);
	            if (exb !== null)
	                exbArray.push(exb);
	        }
	        Array.prototype.push.apply(this._bindings, exbArray);
	        return new phosphor_disposable_1.DisposableDelegate(function () { return _this._removeBindings(exbArray); });
	    };
	    /**
	     * 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 handler function of the best matching key binding.
	     *
	     * The manager **does not** install its own key event listeners. This
	     * allows user code full control over the nodes for which the manager
	     * processes `'keydown'` events.
	     */
	    KeymapManager.prototype.processKeydownEvent = function (event) {
	        // Bail immediately if playing back keystrokes.
	        if (this._replaying) {
	            return;
	        }
	        // Get the canonical keystroke for the event. An empty string
	        // indicates a keystroke which cannot be a valid key shortcut.
	        var keystroke = keyboard_1.keystrokeForKeydownEvent(event, this._layout);
	        if (!keystroke) {
	            return;
	        }
	        // Add the keystroke to the current key sequence.
	        this._sequence.push(keystroke);
	        // Find the exact and partial matches for the key sequence.
	        var _a = findMatch(this._bindings, this._sequence, event), exact = _a.exact, partial = _a.partial;
	        // If there is no exact or partial match, replay any suppressed
	        // events and clear the pending state so that the next key press
	        // starts from a fresh default state.
	        if (!exact && !partial) {
	            this._replayEvents();
	            this._clearPendingState();
	            return;
	        }
	        // Stop propagation of the event. If there is only a partial match,
	        // the event will be replayed if a final match is never triggered.
	        event.preventDefault();
	        event.stopPropagation();
	        // If there is an exact match but no partial, the exact match can
	        // be dispatched immediately. The pending state is cleared so the
	        // next key press starts from a fresh default state.
	        if (!partial) {
	            safeInvoke(exact);
	            this._clearPendingState();
	            return;
	        }
	        // If there is both an exact match and a partial, the exact match
	        // is stored for future dispatch in case the timer expires before
	        // a more specific match is triggered.
	        if (exact)
	            this._exact = exact;
	        // Store the event for possible playback in the future.
	        this._events.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();
	    };
	    /**
	     * Remove an array of extended bindings from the key map.
	     */
	    KeymapManager.prototype._removeBindings = function (exbArray) {
	        var count = 0;
	        for (var i = 0, n = this._bindings.length; i < n; ++i) {
	            var exb = this._bindings[i];
	            if (exbArray.indexOf(exb) !== -1) {
	                count++;
	            }
	            else {
	                this._bindings[i - count] = exb;
	            }
	        }
	        this._bindings.length -= count;
	    };
	    /**
	     * Start or restart the pending timer for the key map.
	     */
	    KeymapManager.prototype._startTimer = function () {
	        var _this = this;
	        this._clearTimer();
	        this._timer = setTimeout(function () {
	            _this._onPendingTimeout();
	        }, 1000);
	    };
	    /**
	     * Clear the pending timer for the key map.
	     */
	    KeymapManager.prototype._clearTimer = function () {
	        if (this._timer !== 0) {
	            clearTimeout(this._timer);
	            this._timer = 0;
	        }
	    };
	    /**
	     * Replay the events which were suppressed.
	     */
	    KeymapManager.prototype._replayEvents = function () {
	        if (this._events.length === 0) {
	            return;
	        }
	        this._replaying = true;
	        for (var _i = 0, _a = this._events; _i < _a.length; _i++) {
	            var evt = _a[_i];
	            var clone = cloneKeyboardEvent(evt);
	            evt.target.dispatchEvent(clone);
	        }
	        this._replaying = false;
	    };
	    /**
	     * Clear the pending state for the keymap.
	     */
	    KeymapManager.prototype._clearPendingState = function () {
	        this._clearTimer();
	        this._exact = null;
	        this._events.length = 0;
	        this._sequence.length = 0;
	    };
	    /**
	     * Handle the partial match timeout.
	     */
	    KeymapManager.prototype._onPendingTimeout = function () {
	        this._timer = 0;
	        if (this._exact) {
	            safeInvoke(this._exact);
	        }
	        else {
	            this._replayEvents();
	        }
	        this._clearPendingState();
	    };
	    return KeymapManager;
	})();
	exports.KeymapManager = KeymapManager;
	/**
	 * Create an extended key binding from a user key binding.
	 *
	 * Warns and returns `null` if the key binding is invalid.
	 */
	function createExBinding(binding, layout) {
	    if (!clear_cut_1.isSelectorValid(binding.selector)) {
	        console.warn("invalid key binding selector: " + binding.selector);
	        return null;
	    }
	    if (binding.sequence.length === 0) {
	        console.warn('empty key sequence for key binding');
	        return null;
	    }
	    try {
	        var sequence = binding.sequence.map(function (ks) { return keyboard_1.normalizeKeystroke(ks, layout); });
	    }
	    catch (e) {
	        console.warn(e.message);
	        return null;
	    }
	    return {
	        sequence: sequence,
	        args: binding.args,
	        handler: binding.handler,
	        selector: binding.selector,
	        specificity: clear_cut_1.calculateSpecificity(binding.selector),
	    };
	}
	;
	/**
	 * Test whether a binding sequence matches a key sequence.
	 *
	 * Returns a `SequenceMatch` value indicating the type of match.
	 */
	function matchSequence(exbSeq, keySeq) {
	    if (exbSeq.length < keySeq.length) {
	        return 0 /* None */;
	    }
	    for (var i = 0, n = keySeq.length; i < n; ++i) {
	        if (exbSeq[i] !== keySeq[i]) {
	            return 0 /* None */;
	        }
	    }
	    if (exbSeq.length > keySeq.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 distance = 0;
	    var target = event.target;
	    var current = event.currentTarget;
	    for (; target !== null; target = target.parentElement, ++distance) {
	        if (matchesSelector(target, selector)) {
	            return distance;
	        }
	        if (target === current) {
	            return -1;
	        }
	    }
	    return -1;
	}
	/**
	 * Find the 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 findMatch(bindings, sequence, event) {
	    // Whether a partial match has been found.
	    var partial = false;
	    // The current best exact match.
	    var exact = null;
	    // The match distance for the exact match.
	    var distance = Infinity;
	    // Iterate the bindings and search for the best match.
	    for (var i = 0, n = bindings.length; i < n; ++i) {
	        // Lookup the current binding.
	        var exb = bindings[i];
	        // Check whether the binding sequence is a match.
	        var match = matchSequence(exb.sequence, sequence);
	        // If there is no match, the binding is ignored.
	        if (match === 0 /* None */) {
	            continue;
	        }
	        // If it is a partial match and no other partial match has been
	        // found, ensure the selector matches and mark the partial flag.
	        if (match === 2 /* Partial */) {
	            if (!partial && targetDistance(exb.selector, event) !== -1) {
	                partial = true;
	            }
	            continue;
	        }
	        // Otherwise, it's an exact match. Update the best match if the
	        // binding is a stronger match than the current best exact match.
	        var td = targetDistance(exb.selector, event);
	        if (td !== -1 && td <= distance) {
	            if (exact === null || exb.specificity > exact.specificity) {
	                exact = exb;
	                distance = td;
	            }
	        }
	    }
	    // Return the match result.
	    return { exact: exact, partial: partial };
	}
	/**
	 * Safely invoke the handler for the key binding.
	 *
	 * Exceptions in the handler will be caught and logged.
	 */
	function safeInvoke(binding) {
	    try {
	        binding.handler.call(void 0, binding.args);
	    }
	    catch (err) {
	        console.error(err);
	    }
	}
	/**
	 * A cross-browser CSS selector matching prototype function.
	 *
	 * This function must be called with an element as `this` context.
	 */
	var 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;
	        }));
	})();
	/**
	 * Test whether an element matches a CSS selector.
	 */
	function matchesSelector(elem, selector) {
	    return protoMatchFunc.call(elem, selector);
	}
	/**
	 * Clone a keyboard event.
	 *
	 * #### Notes
	 * A custom event is required because Chrome nulls out the `keyCode`
	 * field in user-generated `KeyboardEvent` types.
	 */
	function cloneKeyboardEvent(event) {
	    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;
	}


/***/ },
/* 65 */
/***/ function(module, exports) {

	/* WEBPACK VAR INJECTION */(function(global) {/**
	 * Originally ported from https://github.com/keeganstreet/specificity/blob/866bf7ab4e7f62a7179c15b13a95af4e1c7b1afa/specificity.js
	 *
	 * Calculates the specificity of CSS selectors
	 * http://www.w3.org/TR/css3-selectors/#specificity
	 *
	 * Returns a selector integer value
	 */
	
	// The following regular expressions assume that selectors matching the preceding regular expressions have been removed
	var attributeRegex = /(\[[^\]]+\])/g;
	var idRegex = /(#[^\s\+>~\.\[:]+)/g;
	var classRegex = /(\.[^\s\+>~\.\[:]+)/g;
	var pseudoElementRegex = /(::[^\s\+>~\.\[:]+|:first-line|:first-letter|:before|:after)/g;
	var pseudoClassRegex = /(:[^\s\+>~\.\[:]+)/g;
	var elementRegex = /([^\s\+>~\.\[:]+)/g;
	var notRegex = /:not\(([^\)]*)\)/g;
	var ruleRegex = /\{[^]*/gm;
	var separatorRegex = /[\*\s\+>~]/g;
	var straysRegex = /[#\.]/g;
	
	// Find matches for a regular expression in a string and push their details to parts
	// Type is "a" for IDs, "b" for classes, attributes and pseudo-classes and "c" for elements and pseudo-elements
	var findMatch = function(regex, type, types, selector) {
	  var matches = selector.match(regex);
	  if (matches) {
	    for (var i = 0; i < matches.length; i++) {
	      types[type]++;
	      // Replace this simple selector with whitespace so it won't be counted in further simple selectors
	      selector = selector.replace(matches[i], ' ');
	    }
	  }
	
	  return selector;
	}
	
	// Calculate the specificity for a selector by dividing it into simple selectors and counting them
	var calculate = function(selector) {
	  var commaIndex = selector.indexOf(',');
	  if (commaIndex !== -1) {
	    selector = selector.substring(0, commaIndex);
	  }
	
	  var  types = {
	    a: 0,
	    b: 0,
	    c: 0
	  };
	
	  // Remove the negation psuedo-class (:not) but leave its argument because specificity is calculated on its argument
	  selector = selector.replace(notRegex, ' $1 ');
	
	  // Remove anything after a left brace in case a user has pasted in a rule, not just a selector
	  selector = selector.replace(ruleRegex, ' ');
	
	  // Add attribute selectors to parts collection (type b)
	  selector = findMatch(attributeRegex, 'b', types, selector);
	
	  // Add ID selectors to parts collection (type a)
	  selector = findMatch(idRegex, 'a', types, selector);
	
	  // Add class selectors to parts collection (type b)
	  selector = findMatch(classRegex, 'b', types, selector);
	
	  // Add pseudo-element selectors to parts collection (type c)
	  selector = findMatch(pseudoElementRegex, 'c', types, selector);
	
	  // Add pseudo-class selectors to parts collection (type b)
	  selector = findMatch(pseudoClassRegex, 'b', types, selector);
	
	  // Remove universal selector and separator characters
	  selector = selector.replace(separatorRegex, ' ');
	
	  // Remove any stray dots or hashes which aren't attached to words
	  // These may be present if the user is live-editing this selector
	  selector = selector.replace(straysRegex, ' ');
	
	  // The only things left should be element selectors (type c)
	  findMatch(elementRegex, 'c', types, selector);
	
	  return (types.a * 100) + (types.b * 10) + (types.c * 1);
	}
	
	var specificityCache = {};
	
	exports.calculateSpecificity = function(selector) {
	  var specificity = specificityCache[selector];
	  if (specificity === undefined) {
	    specificity = calculate(selector);
	    specificityCache[selector] = specificity;
	  }
	  return specificity;
	}
	
	if (global.document) {
	  var validSelectorCache = {};
	  var testSelectorElement = global.document.createElement('div');
	
	  exports.isSelectorValid = function(selector) {
	    var valid = validSelectorCache[selector];
	    if (valid === undefined) {
	      try {
	        testSelectorElement.querySelector(selector);
	        valid = true;
	      } catch (error) {
	        valid = false;
	      }
	      validSelectorCache[selector] = valid;
	    }
	    return valid;
	  }
	
	  exports.validateSelector = function(selector) {
	    if (!exports.isSelectorValid(selector)) {
	      var error = new SyntaxError(selector + ' is not a valid selector');
	      error.code = 'EBADSELECTOR';
	      throw error;
	    }
	  }
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

/***/ },
/* 66 */
/***/ function(module, exports, __webpack_require__) {

	var require;var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(process, global, module) {/*!
	 * @overview es6-promise - a tiny implementation of Promises/A+.
	 * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
	 * @license   Licensed under MIT license
	 *            See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE
	 * @version   3.2.1
	 */
	
	(function() {
	    "use strict";
	    function lib$es6$promise$utils$$objectOrFunction(x) {
	      return typeof x === 'function' || (typeof x === 'object' && x !== null);
	    }
	
	    function lib$es6$promise$utils$$isFunction(x) {
	      return typeof x === 'function';
	    }
	
	    function lib$es6$promise$utils$$isMaybeThenable(x) {
	      return typeof x === 'object' && x !== null;
	    }
	
	    var lib$es6$promise$utils$$_isArray;
	    if (!Array.isArray) {
	      lib$es6$promise$utils$$_isArray = function (x) {
	        return Object.prototype.toString.call(x) === '[object Array]';
	      };
	    } else {
	      lib$es6$promise$utils$$_isArray = Array.isArray;
	    }
	
	    var lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray;
	    var lib$es6$promise$asap$$len = 0;
	    var lib$es6$promise$asap$$vertxNext;
	    var lib$es6$promise$asap$$customSchedulerFn;
	
	    var lib$es6$promise$asap$$asap = function asap(callback, arg) {
	      lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len] = callback;
	      lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len + 1] = arg;
	      lib$es6$promise$asap$$len += 2;
	      if (lib$es6$promise$asap$$len === 2) {
	        // If len is 2, that means that we need to schedule an async flush.
	        // If additional callbacks are queued before the queue is flushed, they
	        // will be processed by this flush that we are scheduling.
	        if (lib$es6$promise$asap$$customSchedulerFn) {
	          lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush);
	        } else {
	          lib$es6$promise$asap$$scheduleFlush();
	        }
	      }
	    }
	
	    function lib$es6$promise$asap$$setScheduler(scheduleFn) {
	      lib$es6$promise$asap$$customSchedulerFn = scheduleFn;
	    }
	
	    function lib$es6$promise$asap$$setAsap(asapFn) {
	      lib$es6$promise$asap$$asap = asapFn;
	    }
	
	    var lib$es6$promise$asap$$browserWindow = (typeof window !== 'undefined') ? window : undefined;
	    var lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {};
	    var lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver;
	    var lib$es6$promise$asap$$isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
	
	    // test for web worker but not in IE10
	    var lib$es6$promise$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' &&
	      typeof importScripts !== 'undefined' &&
	      typeof MessageChannel !== 'undefined';
	
	    // node
	    function lib$es6$promise$asap$$useNextTick() {
	      // node version 0.10.x displays a deprecation warning when nextTick is used recursively
	      // see https://github.com/cujojs/when/issues/410 for details
	      return function() {
	        process.nextTick(lib$es6$promise$asap$$flush);
	      };
	    }
	
	    // vertx
	    function lib$es6$promise$asap$$useVertxTimer() {
	      return function() {
	        lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush);
	      };
	    }
	
	    function lib$es6$promise$asap$$useMutationObserver() {
	      var iterations = 0;
	      var observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush);
	      var node = document.createTextNode('');
	      observer.observe(node, { characterData: true });
	
	      return function() {
	        node.data = (iterations = ++iterations % 2);
	      };
	    }
	
	    // web worker
	    function lib$es6$promise$asap$$useMessageChannel() {
	      var channel = new MessageChannel();
	      channel.port1.onmessage = lib$es6$promise$asap$$flush;
	      return function () {
	        channel.port2.postMessage(0);
	      };
	    }
	
	    function lib$es6$promise$asap$$useSetTimeout() {
	      return function() {
	        setTimeout(lib$es6$promise$asap$$flush, 1);
	      };
	    }
	
	    var lib$es6$promise$asap$$queue = new Array(1000);
	    function lib$es6$promise$asap$$flush() {
	      for (var i = 0; i < lib$es6$promise$asap$$len; i+=2) {
	        var callback = lib$es6$promise$asap$$queue[i];
	        var arg = lib$es6$promise$asap$$queue[i+1];
	
	        callback(arg);
	
	        lib$es6$promise$asap$$queue[i] = undefined;
	        lib$es6$promise$asap$$queue[i+1] = undefined;
	      }
	
	      lib$es6$promise$asap$$len = 0;
	    }
	
	    function lib$es6$promise$asap$$attemptVertx() {
	      try {
	        var r = require;
	        var vertx = __webpack_require__(68);
	        lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext;
	        return lib$es6$promise$asap$$useVertxTimer();
	      } catch(e) {
	        return lib$es6$promise$asap$$useSetTimeout();
	      }
	    }
	
	    var lib$es6$promise$asap$$scheduleFlush;
	    // Decide what async method to use to triggering processing of queued callbacks:
	    if (lib$es6$promise$asap$$isNode) {
	      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useNextTick();
	    } else if (lib$es6$promise$asap$$BrowserMutationObserver) {
	      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMutationObserver();
	    } else if (lib$es6$promise$asap$$isWorker) {
	      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMessageChannel();
	    } else if (lib$es6$promise$asap$$browserWindow === undefined && "function" === 'function') {
	      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$attemptVertx();
	    } else {
	      lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useSetTimeout();
	    }
	    function lib$es6$promise$then$$then(onFulfillment, onRejection) {
	      var parent = this;
	
	      var child = new this.constructor(lib$es6$promise$$internal$$noop);
	
	      if (child[lib$es6$promise$$internal$$PROMISE_ID] === undefined) {
	        lib$es6$promise$$internal$$makePromise(child);
	      }
	
	      var state = parent._state;
	
	      if (state) {
	        var callback = arguments[state - 1];
	        lib$es6$promise$asap$$asap(function(){
	          lib$es6$promise$$internal$$invokeCallback(state, child, callback, parent._result);
	        });
	      } else {
	        lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection);
	      }
	
	      return child;
	    }
	    var lib$es6$promise$then$$default = lib$es6$promise$then$$then;
	    function lib$es6$promise$promise$resolve$$resolve(object) {
	      /*jshint validthis:true */
	      var Constructor = this;
	
	      if (object && typeof object === 'object' && object.constructor === Constructor) {
	        return object;
	      }
	
	      var promise = new Constructor(lib$es6$promise$$internal$$noop);
	      lib$es6$promise$$internal$$resolve(promise, object);
	      return promise;
	    }
	    var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve;
	    var lib$es6$promise$$internal$$PROMISE_ID = Math.random().toString(36).substring(16);
	
	    function lib$es6$promise$$internal$$noop() {}
	
	    var lib$es6$promise$$internal$$PENDING   = void 0;
	    var lib$es6$promise$$internal$$FULFILLED = 1;
	    var lib$es6$promise$$internal$$REJECTED  = 2;
	
	    var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject();
	
	    function lib$es6$promise$$internal$$selfFulfillment() {
	      return new TypeError("You cannot resolve a promise with itself");
	    }
	
	    function lib$es6$promise$$internal$$cannotReturnOwn() {
	      return new TypeError('A promises callback cannot return that same promise.');
	    }
	
	    function lib$es6$promise$$internal$$getThen(promise) {
	      try {
	        return promise.then;
	      } catch(error) {
	        lib$es6$promise$$internal$$GET_THEN_ERROR.error = error;
	        return lib$es6$promise$$internal$$GET_THEN_ERROR;
	      }
	    }
	
	    function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {
	      try {
	        then.call(value, fulfillmentHandler, rejectionHandler);
	      } catch(e) {
	        return e;
	      }
	    }
	
	    function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) {
	       lib$es6$promise$asap$$asap(function(promise) {
	        var sealed = false;
	        var error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) {
	          if (sealed) { return; }
	          sealed = true;
	          if (thenable !== value) {
	            lib$es6$promise$$internal$$resolve(promise, value);
	          } else {
	            lib$es6$promise$$internal$$fulfill(promise, value);
	          }
	        }, function(reason) {
	          if (sealed) { return; }
	          sealed = true;
	
	          lib$es6$promise$$internal$$reject(promise, reason);
	        }, 'Settle: ' + (promise._label || ' unknown promise'));
	
	        if (!sealed && error) {
	          sealed = true;
	          lib$es6$promise$$internal$$reject(promise, error);
	        }
	      }, promise);
	    }
	
	    function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) {
	      if (thenable._state === lib$es6$promise$$internal$$FULFILLED) {
	        lib$es6$promise$$internal$$fulfill(promise, thenable._result);
	      } else if (thenable._state === lib$es6$promise$$internal$$REJECTED) {
	        lib$es6$promise$$internal$$reject(promise, thenable._result);
	      } else {
	        lib$es6$promise$$internal$$subscribe(thenable, undefined, function(value) {
	          lib$es6$promise$$internal$$resolve(promise, value);
	        }, function(reason) {
	          lib$es6$promise$$internal$$reject(promise, reason);
	        });
	      }
	    }
	
	    function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable, then) {
	      if (maybeThenable.constructor === promise.constructor &&
	          then === lib$es6$promise$then$$default &&
	          constructor.resolve === lib$es6$promise$promise$resolve$$default) {
	        lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable);
	      } else {
	        if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) {
	          lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error);
	        } else if (then === undefined) {
	          lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
	        } else if (lib$es6$promise$utils$$isFunction(then)) {
	          lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then);
	        } else {
	          lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
	        }
	      }
	    }
	
	    function lib$es6$promise$$internal$$resolve(promise, value) {
	      if (promise === value) {
	        lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFulfillment());
	      } else if (lib$es6$promise$utils$$objectOrFunction(value)) {
	        lib$es6$promise$$internal$$handleMaybeThenable(promise, value, lib$es6$promise$$internal$$getThen(value));
	      } else {
	        lib$es6$promise$$internal$$fulfill(promise, value);
	      }
	    }
	
	    function lib$es6$promise$$internal$$publishRejection(promise) {
	      if (promise._onerror) {
	        promise._onerror(promise._result);
	      }
	
	      lib$es6$promise$$internal$$publish(promise);
	    }
	
	    function lib$es6$promise$$internal$$fulfill(promise, value) {
	      if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }
	
	      promise._result = value;
	      promise._state = lib$es6$promise$$internal$$FULFILLED;
	
	      if (promise._subscribers.length !== 0) {
	        lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise);
	      }
	    }
	
	    function lib$es6$promise$$internal$$reject(promise, reason) {
	      if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }
	      promise._state = lib$es6$promise$$internal$$REJECTED;
	      promise._result = reason;
	
	      lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise);
	    }
	
	    function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) {
	      var subscribers = parent._subscribers;
	      var length = subscribers.length;
	
	      parent._onerror = null;
	
	      subscribers[length] = child;
	      subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment;
	      subscribers[length + lib$es6$promise$$internal$$REJECTED]  = onRejection;
	
	      if (length === 0 && parent._state) {
	        lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent);
	      }
	    }
	
	    function lib$es6$promise$$internal$$publish(promise) {
	      var subscribers = promise._subscribers;
	      var settled = promise._state;
	
	      if (subscribers.length === 0) { return; }
	
	      var child, callback, detail = promise._result;
	
	      for (var i = 0; i < subscribers.length; i += 3) {
	        child = subscribers[i];
	        callback = subscribers[i + settled];
	
	        if (child) {
	          lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail);
	        } else {
	          callback(detail);
	        }
	      }
	
	      promise._subscribers.length = 0;
	    }
	
	    function lib$es6$promise$$internal$$ErrorObject() {
	      this.error = null;
	    }
	
	    var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject();
	
	    function lib$es6$promise$$internal$$tryCatch(callback, detail) {
	      try {
	        return callback(detail);
	      } catch(e) {
	        lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e;
	        return lib$es6$promise$$internal$$TRY_CATCH_ERROR;
	      }
	    }
	
	    function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) {
	      var hasCallback = lib$es6$promise$utils$$isFunction(callback),
	          value, error, succeeded, failed;
	
	      if (hasCallback) {
	        value = lib$es6$promise$$internal$$tryCatch(callback, detail);
	
	        if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) {
	          failed = true;
	          error = value.error;
	          value = null;
	        } else {
	          succeeded = true;
	        }
	
	        if (promise === value) {
	          lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn());
	          return;
	        }
	
	      } else {
	        value = detail;
	        succeeded = true;
	      }
	
	      if (promise._state !== lib$es6$promise$$internal$$PENDING) {
	        // noop
	      } else if (hasCallback && succeeded) {
	        lib$es6$promise$$internal$$resolve(promise, value);
	      } else if (failed) {
	        lib$es6$promise$$internal$$reject(promise, error);
	      } else if (settled === lib$es6$promise$$internal$$FULFILLED) {
	        lib$es6$promise$$internal$$fulfill(promise, value);
	      } else if (settled === lib$es6$promise$$internal$$REJECTED) {
	        lib$es6$promise$$internal$$reject(promise, value);
	      }
	    }
	
	    function lib$es6$promise$$internal$$initializePromise(promise, resolver) {
	      try {
	        resolver(function resolvePromise(value){
	          lib$es6$promise$$internal$$resolve(promise, value);
	        }, function rejectPromise(reason) {
	          lib$es6$promise$$internal$$reject(promise, reason);
	        });
	      } catch(e) {
	        lib$es6$promise$$internal$$reject(promise, e);
	      }
	    }
	
	    var lib$es6$promise$$internal$$id = 0;
	    function lib$es6$promise$$internal$$nextId() {
	      return lib$es6$promise$$internal$$id++;
	    }
	
	    function lib$es6$promise$$internal$$makePromise(promise) {
	      promise[lib$es6$promise$$internal$$PROMISE_ID] = lib$es6$promise$$internal$$id++;
	      promise._state = undefined;
	      promise._result = undefined;
	      promise._subscribers = [];
	    }
	
	    function lib$es6$promise$promise$all$$all(entries) {
	      return new lib$es6$promise$enumerator$$default(this, entries).promise;
	    }
	    var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all;
	    function lib$es6$promise$promise$race$$race(entries) {
	      /*jshint validthis:true */
	      var Constructor = this;
	
	      if (!lib$es6$promise$utils$$isArray(entries)) {
	        return new Constructor(function(resolve, reject) {
	          reject(new TypeError('You must pass an array to race.'));
	        });
	      } else {
	        return new Constructor(function(resolve, reject) {
	          var length = entries.length;
	          for (var i = 0; i < length; i++) {
	            Constructor.resolve(entries[i]).then(resolve, reject);
	          }
	        });
	      }
	    }
	    var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race;
	    function lib$es6$promise$promise$reject$$reject(reason) {
	      /*jshint validthis:true */
	      var Constructor = this;
	      var promise = new Constructor(lib$es6$promise$$internal$$noop);
	      lib$es6$promise$$internal$$reject(promise, reason);
	      return promise;
	    }
	    var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject;
	
	
	    function lib$es6$promise$promise$$needsResolver() {
	      throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
	    }
	
	    function lib$es6$promise$promise$$needsNew() {
	      throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
	    }
	
	    var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise;
	    /**
	      Promise objects represent the eventual result of an asynchronous operation. The
	      primary way of interacting with a promise is through its `then` method, which
	      registers callbacks to receive either a promise's eventual value or the reason
	      why the promise cannot be fulfilled.
	
	      Terminology
	      -----------
	
	      - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
	      - `thenable` is an object or function that defines a `then` method.
	      - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
	      - `exception` is a value that is thrown using the throw statement.
	      - `reason` is a value that indicates why a promise was rejected.
	      - `settled` the final resting state of a promise, fulfilled or rejected.
	
	      A promise can be in one of three states: pending, fulfilled, or rejected.
	
	      Promises that are fulfilled have a fulfillment value and are in the fulfilled
	      state.  Promises that are rejected have a rejection reason and are in the
	      rejected state.  A fulfillment value is never a thenable.
	
	      Promises can also be said to *resolve* a value.  If this value is also a
	      promise, then the original promise's settled state will match the value's
	      settled state.  So a promise that *resolves* a promise that rejects will
	      itself reject, and a promise that *resolves* a promise that fulfills will
	      itself fulfill.
	
	
	      Basic Usage:
	      ------------
	
	      ```js
	      var promise = new Promise(function(resolve, reject) {
	        // on success
	        resolve(value);
	
	        // on failure
	        reject(reason);
	      });
	
	      promise.then(function(value) {
	        // on fulfillment
	      }, function(reason) {
	        // on rejection
	      });
	      ```
	
	      Advanced Usage:
	      ---------------
	
	      Promises shine when abstracting away asynchronous interactions such as
	      `XMLHttpRequest`s.
	
	      ```js
	      function getJSON(url) {
	        return new Promise(function(resolve, reject){
	          var xhr = new XMLHttpRequest();
	
	          xhr.open('GET', url);
	          xhr.onreadystatechange = handler;
	          xhr.responseType = 'json';
	          xhr.setRequestHeader('Accept', 'application/json');
	          xhr.send();
	
	          function handler() {
	            if (this.readyState === this.DONE) {
	              if (this.status === 200) {
	                resolve(this.response);
	              } else {
	                reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
	              }
	            }
	          };
	        });
	      }
	
	      getJSON('/posts.json').then(function(json) {
	        // on fulfillment
	      }, function(reason) {
	        // on rejection
	      });
	      ```
	
	      Unlike callbacks, promises are great composable primitives.
	
	      ```js
	      Promise.all([
	        getJSON('/posts'),
	        getJSON('/comments')
	      ]).then(function(values){
	        values[0] // => postsJSON
	        values[1] // => commentsJSON
	
	        return values;
	      });
	      ```
	
	      @class Promise
	      @param {function} resolver
	      Useful for tooling.
	      @constructor
	    */
	    function lib$es6$promise$promise$$Promise(resolver) {
	      this[lib$es6$promise$$internal$$PROMISE_ID] = lib$es6$promise$$internal$$nextId();
	      this._result = this._state = undefined;
	      this._subscribers = [];
	
	      if (lib$es6$promise$$internal$$noop !== resolver) {
	        typeof resolver !== 'function' && lib$es6$promise$promise$$needsResolver();
	        this instanceof lib$es6$promise$promise$$Promise ? lib$es6$promise$$internal$$initializePromise(this, resolver) : lib$es6$promise$promise$$needsNew();
	      }
	    }
	
	    lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default;
	    lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default;
	    lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default;
	    lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default;
	    lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler;
	    lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap;
	    lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap;
	
	    lib$es6$promise$promise$$Promise.prototype = {
	      constructor: lib$es6$promise$promise$$Promise,
	
	    /**
	      The primary way of interacting with a promise is through its `then` method,
	      which registers callbacks to receive either a promise's eventual value or the
	      reason why the promise cannot be fulfilled.
	
	      ```js
	      findUser().then(function(user){
	        // user is available
	      }, function(reason){
	        // user is unavailable, and you are given the reason why
	      });
	      ```
	
	      Chaining
	      --------
	
	      The return value of `then` is itself a promise.  This second, 'downstream'
	      promise is resolved with the return value of the first promise's fulfillment
	      or rejection handler, or rejected if the handler throws an exception.
	
	      ```js
	      findUser().then(function (user) {
	        return user.name;
	      }, function (reason) {
	        return 'default name';
	      }).then(function (userName) {
	        // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
	        // will be `'default name'`
	      });
	
	      findUser().then(function (user) {
	        throw new Error('Found user, but still unhappy');
	      }, function (reason) {
	        throw new Error('`findUser` rejected and we're unhappy');
	      }).then(function (value) {
	        // never reached
	      }, function (reason) {
	        // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
	        // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
	      });
	      ```
	      If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
	
	      ```js
	      findUser().then(function (user) {
	        throw new PedagogicalException('Upstream error');
	      }).then(function (value) {
	        // never reached
	      }).then(function (value) {
	        // never reached
	      }, function (reason) {
	        // The `PedgagocialException` is propagated all the way down to here
	      });
	      ```
	
	      Assimilation
	      ------------
	
	      Sometimes the value you want to propagate to a downstream promise can only be
	      retrieved asynchronously. This can be achieved by returning a promise in the
	      fulfillment or rejection handler. The downstream promise will then be pending
	      until the returned promise is settled. This is called *assimilation*.
	
	      ```js
	      findUser().then(function (user) {
	        return findCommentsByAuthor(user);
	      }).then(function (comments) {
	        // The user's comments are now available
	      });
	      ```
	
	      If the assimliated promise rejects, then the downstream promise will also reject.
	
	      ```js
	      findUser().then(function (user) {
	        return findCommentsByAuthor(user);
	      }).then(function (comments) {
	        // If `findCommentsByAuthor` fulfills, we'll have the value here
	      }, function (reason) {
	        // If `findCommentsByAuthor` rejects, we'll have the reason here
	      });
	      ```
	
	      Simple Example
	      --------------
	
	      Synchronous Example
	
	      ```javascript
	      var result;
	
	      try {
	        result = findResult();
	        // success
	      } catch(reason) {
	        // failure
	      }
	      ```
	
	      Errback Example
	
	      ```js
	      findResult(function(result, err){
	        if (err) {
	          // failure
	        } else {
	          // success
	        }
	      });
	      ```
	
	      Promise Example;
	
	      ```javascript
	      findResult().then(function(result){
	        // success
	      }, function(reason){
	        // failure
	      });
	      ```
	
	      Advanced Example
	      --------------
	
	      Synchronous Example
	
	      ```javascript
	      var author, books;
	
	      try {
	        author = findAuthor();
	        books  = findBooksByAuthor(author);
	        // success
	      } catch(reason) {
	        // failure
	      }
	      ```
	
	      Errback Example
	
	      ```js
	
	      function foundBooks(books) {
	
	      }
	
	      function failure(reason) {
	
	      }
	
	      findAuthor(function(author, err){
	        if (err) {
	          failure(err);
	          // failure
	        } else {
	          try {
	            findBoooksByAuthor(author, function(books, err) {
	              if (err) {
	                failure(err);
	              } else {
	                try {
	                  foundBooks(books);
	                } catch(reason) {
	                  failure(reason);
	                }
	              }
	            });
	          } catch(error) {
	            failure(err);
	          }
	          // success
	        }
	      });
	      ```
	
	      Promise Example;
	
	      ```javascript
	      findAuthor().
	        then(findBooksByAuthor).
	        then(function(books){
	          // found books
	      }).catch(function(reason){
	        // something went wrong
	      });
	      ```
	
	      @method then
	      @param {Function} onFulfilled
	      @param {Function} onRejected
	      Useful for tooling.
	      @return {Promise}
	    */
	      then: lib$es6$promise$then$$default,
	
	    /**
	      `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
	      as the catch block of a try/catch statement.
	
	      ```js
	      function findAuthor(){
	        throw new Error('couldn't find that author');
	      }
	
	      // synchronous
	      try {
	        findAuthor();
	      } catch(reason) {
	        // something went wrong
	      }
	
	      // async with promises
	      findAuthor().catch(function(reason){
	        // something went wrong
	      });
	      ```
	
	      @method catch
	      @param {Function} onRejection
	      Useful for tooling.
	      @return {Promise}
	    */
	      'catch': function(onRejection) {
	        return this.then(null, onRejection);
	      }
	    };
	    var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator;
	    function lib$es6$promise$enumerator$$Enumerator(Constructor, input) {
	      this._instanceConstructor = Constructor;
	      this.promise = new Constructor(lib$es6$promise$$internal$$noop);
	
	      if (!this.promise[lib$es6$promise$$internal$$PROMISE_ID]) {
	        lib$es6$promise$$internal$$makePromise(this.promise);
	      }
	
	      if (lib$es6$promise$utils$$isArray(input)) {
	        this._input     = input;
	        this.length     = input.length;
	        this._remaining = input.length;
	
	        this._result = new Array(this.length);
	
	        if (this.length === 0) {
	          lib$es6$promise$$internal$$fulfill(this.promise, this._result);
	        } else {
	          this.length = this.length || 0;
	          this._enumerate();
	          if (this._remaining === 0) {
	            lib$es6$promise$$internal$$fulfill(this.promise, this._result);
	          }
	        }
	      } else {
	        lib$es6$promise$$internal$$reject(this.promise, lib$es6$promise$enumerator$$validationError());
	      }
	    }
	
	    function lib$es6$promise$enumerator$$validationError() {
	      return new Error('Array Methods must be provided an Array');
	    }
	
	    lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function() {
	      var length  = this.length;
	      var input   = this._input;
	
	      for (var i = 0; this._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
	        this._eachEntry(input[i], i);
	      }
	    };
	
	    lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) {
	      var c = this._instanceConstructor;
	      var resolve = c.resolve;
	
	      if (resolve === lib$es6$promise$promise$resolve$$default) {
	        var then = lib$es6$promise$$internal$$getThen(entry);
	
	        if (then === lib$es6$promise$then$$default &&
	            entry._state !== lib$es6$promise$$internal$$PENDING) {
	          this._settledAt(entry._state, i, entry._result);
	        } else if (typeof then !== 'function') {
	          this._remaining--;
	          this._result[i] = entry;
	        } else if (c === lib$es6$promise$promise$$default) {
	          var promise = new c(lib$es6$promise$$internal$$noop);
	          lib$es6$promise$$internal$$handleMaybeThenable(promise, entry, then);
	          this._willSettleAt(promise, i);
	        } else {
	          this._willSettleAt(new c(function(resolve) { resolve(entry); }), i);
	        }
	      } else {
	        this._willSettleAt(resolve(entry), i);
	      }
	    };
	
	    lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) {
	      var promise = this.promise;
	
	      if (promise._state === lib$es6$promise$$internal$$PENDING) {
	        this._remaining--;
	
	        if (state === lib$es6$promise$$internal$$REJECTED) {
	          lib$es6$promise$$internal$$reject(promise, value);
	        } else {
	          this._result[i] = value;
	        }
	      }
	
	      if (this._remaining === 0) {
	        lib$es6$promise$$internal$$fulfill(promise, this._result);
	      }
	    };
	
	    lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) {
	      var enumerator = this;
	
	      lib$es6$promise$$internal$$subscribe(promise, undefined, function(value) {
	        enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value);
	      }, function(reason) {
	        enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason);
	      });
	    };
	    function lib$es6$promise$polyfill$$polyfill() {
	      var local;
	
	      if (typeof global !== 'undefined') {
	          local = global;
	      } else if (typeof self !== 'undefined') {
	          local = self;
	      } else {
	          try {
	              local = Function('return this')();
	          } catch (e) {
	              throw new Error('polyfill failed because global object is unavailable in this environment');
	          }
	      }
	
	      var P = local.Promise;
	
	      if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) {
	        return;
	      }
	
	      local.Promise = lib$es6$promise$promise$$default;
	    }
	    var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill;
	
	    var lib$es6$promise$umd$$ES6Promise = {
	      'Promise': lib$es6$promise$promise$$default,
	      'polyfill': lib$es6$promise$polyfill$$default
	    };
	
	    /* global define:true module:true window: true */
	    if ("function" === 'function' && __webpack_require__(69)['amd']) {
	      !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { return lib$es6$promise$umd$$ES6Promise; }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	    } else if (typeof module !== 'undefined' && module['exports']) {
	      module['exports'] = lib$es6$promise$umd$$ES6Promise;
	    } else if (typeof this !== 'undefined') {
	      this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise;
	    }
	
	    lib$es6$promise$polyfill$$default();
	}).call(this);
	
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(15), (function() { return this; }()), __webpack_require__(67)(module)))

/***/ },
/* 67 */
/***/ function(module, exports) {

	module.exports = function(module) {
		if(!module.webpackPolyfill) {
			module.deprecate = function() {};
			module.paths = [];
			// module.parent = undefined by default
			module.children = [];
			module.webpackPolyfill = 1;
		}
		return module;
	}


/***/ },
/* 68 */
/***/ function(module, exports) {

	/* (ignored) */

/***/ },
/* 69 */
/***/ function(module, exports) {

	module.exports = function() { throw new Error("define cannot be used indirect"); };


/***/ },
/* 70 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(71);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../css-loader/index.js!./font-awesome.min.css", function() {
				var newContent = require("!!./../../css-loader/index.js!./font-awesome.min.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 71 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*!\n *  Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */@font-face{font-family:'FontAwesome';src:url(" + __webpack_require__(72) + ");src:url(" + __webpack_require__(73) + "?#iefix&v=4.6.3) format('embedded-opentype'),url(" + __webpack_require__(74) + ") format('woff2'),url(" + __webpack_require__(75) + ") format('woff'),url(" + __webpack_require__(76) + ") format('truetype'),url(" + __webpack_require__(77) + "#fontawesomeregular) format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:\"\\F000\"}.fa-music:before{content:\"\\F001\"}.fa-search:before{content:\"\\F002\"}.fa-envelope-o:before{content:\"\\F003\"}.fa-heart:before{content:\"\\F004\"}.fa-star:before{content:\"\\F005\"}.fa-star-o:before{content:\"\\F006\"}.fa-user:before{content:\"\\F007\"}.fa-film:before{content:\"\\F008\"}.fa-th-large:before{content:\"\\F009\"}.fa-th:before{content:\"\\F00A\"}.fa-th-list:before{content:\"\\F00B\"}.fa-check:before{content:\"\\F00C\"}.fa-remove:before,.fa-close:before,.fa-times:before{content:\"\\F00D\"}.fa-search-plus:before{content:\"\\F00E\"}.fa-search-minus:before{content:\"\\F010\"}.fa-power-off:before{content:\"\\F011\"}.fa-signal:before{content:\"\\F012\"}.fa-gear:before,.fa-cog:before{content:\"\\F013\"}.fa-trash-o:before{content:\"\\F014\"}.fa-home:before{content:\"\\F015\"}.fa-file-o:before{content:\"\\F016\"}.fa-clock-o:before{content:\"\\F017\"}.fa-road:before{content:\"\\F018\"}.fa-download:before{content:\"\\F019\"}.fa-arrow-circle-o-down:before{content:\"\\F01A\"}.fa-arrow-circle-o-up:before{content:\"\\F01B\"}.fa-inbox:before{content:\"\\F01C\"}.fa-play-circle-o:before{content:\"\\F01D\"}.fa-rotate-right:before,.fa-repeat:before{content:\"\\F01E\"}.fa-refresh:before{content:\"\\F021\"}.fa-list-alt:before{content:\"\\F022\"}.fa-lock:before{content:\"\\F023\"}.fa-flag:before{content:\"\\F024\"}.fa-headphones:before{content:\"\\F025\"}.fa-volume-off:before{content:\"\\F026\"}.fa-volume-down:before{content:\"\\F027\"}.fa-volume-up:before{content:\"\\F028\"}.fa-qrcode:before{content:\"\\F029\"}.fa-barcode:before{content:\"\\F02A\"}.fa-tag:before{content:\"\\F02B\"}.fa-tags:before{content:\"\\F02C\"}.fa-book:before{content:\"\\F02D\"}.fa-bookmark:before{content:\"\\F02E\"}.fa-print:before{content:\"\\F02F\"}.fa-camera:before{content:\"\\F030\"}.fa-font:before{content:\"\\F031\"}.fa-bold:before{content:\"\\F032\"}.fa-italic:before{content:\"\\F033\"}.fa-text-height:before{content:\"\\F034\"}.fa-text-width:before{content:\"\\F035\"}.fa-align-left:before{content:\"\\F036\"}.fa-align-center:before{content:\"\\F037\"}.fa-align-right:before{content:\"\\F038\"}.fa-align-justify:before{content:\"\\F039\"}.fa-list:before{content:\"\\F03A\"}.fa-dedent:before,.fa-outdent:before{content:\"\\F03B\"}.fa-indent:before{content:\"\\F03C\"}.fa-video-camera:before{content:\"\\F03D\"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:\"\\F03E\"}.fa-pencil:before{content:\"\\F040\"}.fa-map-marker:before{content:\"\\F041\"}.fa-adjust:before{content:\"\\F042\"}.fa-tint:before{content:\"\\F043\"}.fa-edit:before,.fa-pencil-square-o:before{content:\"\\F044\"}.fa-share-square-o:before{content:\"\\F045\"}.fa-check-square-o:before{content:\"\\F046\"}.fa-arrows:before{content:\"\\F047\"}.fa-step-backward:before{content:\"\\F048\"}.fa-fast-backward:before{content:\"\\F049\"}.fa-backward:before{content:\"\\F04A\"}.fa-play:before{content:\"\\F04B\"}.fa-pause:before{content:\"\\F04C\"}.fa-stop:before{content:\"\\F04D\"}.fa-forward:before{content:\"\\F04E\"}.fa-fast-forward:before{content:\"\\F050\"}.fa-step-forward:before{content:\"\\F051\"}.fa-eject:before{content:\"\\F052\"}.fa-chevron-left:before{content:\"\\F053\"}.fa-chevron-right:before{content:\"\\F054\"}.fa-plus-circle:before{content:\"\\F055\"}.fa-minus-circle:before{content:\"\\F056\"}.fa-times-circle:before{content:\"\\F057\"}.fa-check-circle:before{content:\"\\F058\"}.fa-question-circle:before{content:\"\\F059\"}.fa-info-circle:before{content:\"\\F05A\"}.fa-crosshairs:before{content:\"\\F05B\"}.fa-times-circle-o:before{content:\"\\F05C\"}.fa-check-circle-o:before{content:\"\\F05D\"}.fa-ban:before{content:\"\\F05E\"}.fa-arrow-left:before{content:\"\\F060\"}.fa-arrow-right:before{content:\"\\F061\"}.fa-arrow-up:before{content:\"\\F062\"}.fa-arrow-down:before{content:\"\\F063\"}.fa-mail-forward:before,.fa-share:before{content:\"\\F064\"}.fa-expand:before{content:\"\\F065\"}.fa-compress:before{content:\"\\F066\"}.fa-plus:before{content:\"\\F067\"}.fa-minus:before{content:\"\\F068\"}.fa-asterisk:before{content:\"\\F069\"}.fa-exclamation-circle:before{content:\"\\F06A\"}.fa-gift:before{content:\"\\F06B\"}.fa-leaf:before{content:\"\\F06C\"}.fa-fire:before{content:\"\\F06D\"}.fa-eye:before{content:\"\\F06E\"}.fa-eye-slash:before{content:\"\\F070\"}.fa-warning:before,.fa-exclamation-triangle:before{content:\"\\F071\"}.fa-plane:before{content:\"\\F072\"}.fa-calendar:before{content:\"\\F073\"}.fa-random:before{content:\"\\F074\"}.fa-comment:before{content:\"\\F075\"}.fa-magnet:before{content:\"\\F076\"}.fa-chevron-up:before{content:\"\\F077\"}.fa-chevron-down:before{content:\"\\F078\"}.fa-retweet:before{content:\"\\F079\"}.fa-shopping-cart:before{content:\"\\F07A\"}.fa-folder:before{content:\"\\F07B\"}.fa-folder-open:before{content:\"\\F07C\"}.fa-arrows-v:before{content:\"\\F07D\"}.fa-arrows-h:before{content:\"\\F07E\"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:\"\\F080\"}.fa-twitter-square:before{content:\"\\F081\"}.fa-facebook-square:before{content:\"\\F082\"}.fa-camera-retro:before{content:\"\\F083\"}.fa-key:before{content:\"\\F084\"}.fa-gears:before,.fa-cogs:before{content:\"\\F085\"}.fa-comments:before{content:\"\\F086\"}.fa-thumbs-o-up:before{content:\"\\F087\"}.fa-thumbs-o-down:before{content:\"\\F088\"}.fa-star-half:before{content:\"\\F089\"}.fa-heart-o:before{content:\"\\F08A\"}.fa-sign-out:before{content:\"\\F08B\"}.fa-linkedin-square:before{content:\"\\F08C\"}.fa-thumb-tack:before{content:\"\\F08D\"}.fa-external-link:before{content:\"\\F08E\"}.fa-sign-in:before{content:\"\\F090\"}.fa-trophy:before{content:\"\\F091\"}.fa-github-square:before{content:\"\\F092\"}.fa-upload:before{content:\"\\F093\"}.fa-lemon-o:before{content:\"\\F094\"}.fa-phone:before{content:\"\\F095\"}.fa-square-o:before{content:\"\\F096\"}.fa-bookmark-o:before{content:\"\\F097\"}.fa-phone-square:before{content:\"\\F098\"}.fa-twitter:before{content:\"\\F099\"}.fa-facebook-f:before,.fa-facebook:before{content:\"\\F09A\"}.fa-github:before{content:\"\\F09B\"}.fa-unlock:before{content:\"\\F09C\"}.fa-credit-card:before{content:\"\\F09D\"}.fa-feed:before,.fa-rss:before{content:\"\\F09E\"}.fa-hdd-o:before{content:\"\\F0A0\"}.fa-bullhorn:before{content:\"\\F0A1\"}.fa-bell:before{content:\"\\F0F3\"}.fa-certificate:before{content:\"\\F0A3\"}.fa-hand-o-right:before{content:\"\\F0A4\"}.fa-hand-o-left:before{content:\"\\F0A5\"}.fa-hand-o-up:before{content:\"\\F0A6\"}.fa-hand-o-down:before{content:\"\\F0A7\"}.fa-arrow-circle-left:before{content:\"\\F0A8\"}.fa-arrow-circle-right:before{content:\"\\F0A9\"}.fa-arrow-circle-up:before{content:\"\\F0AA\"}.fa-arrow-circle-down:before{content:\"\\F0AB\"}.fa-globe:before{content:\"\\F0AC\"}.fa-wrench:before{content:\"\\F0AD\"}.fa-tasks:before{content:\"\\F0AE\"}.fa-filter:before{content:\"\\F0B0\"}.fa-briefcase:before{content:\"\\F0B1\"}.fa-arrows-alt:before{content:\"\\F0B2\"}.fa-group:before,.fa-users:before{content:\"\\F0C0\"}.fa-chain:before,.fa-link:before{content:\"\\F0C1\"}.fa-cloud:before{content:\"\\F0C2\"}.fa-flask:before{content:\"\\F0C3\"}.fa-cut:before,.fa-scissors:before{content:\"\\F0C4\"}.fa-copy:before,.fa-files-o:before{content:\"\\F0C5\"}.fa-paperclip:before{content:\"\\F0C6\"}.fa-save:before,.fa-floppy-o:before{content:\"\\F0C7\"}.fa-square:before{content:\"\\F0C8\"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:\"\\F0C9\"}.fa-list-ul:before{content:\"\\F0CA\"}.fa-list-ol:before{content:\"\\F0CB\"}.fa-strikethrough:before{content:\"\\F0CC\"}.fa-underline:before{content:\"\\F0CD\"}.fa-table:before{content:\"\\F0CE\"}.fa-magic:before{content:\"\\F0D0\"}.fa-truck:before{content:\"\\F0D1\"}.fa-pinterest:before{content:\"\\F0D2\"}.fa-pinterest-square:before{content:\"\\F0D3\"}.fa-google-plus-square:before{content:\"\\F0D4\"}.fa-google-plus:before{content:\"\\F0D5\"}.fa-money:before{content:\"\\F0D6\"}.fa-caret-down:before{content:\"\\F0D7\"}.fa-caret-up:before{content:\"\\F0D8\"}.fa-caret-left:before{content:\"\\F0D9\"}.fa-caret-right:before{content:\"\\F0DA\"}.fa-columns:before{content:\"\\F0DB\"}.fa-unsorted:before,.fa-sort:before{content:\"\\F0DC\"}.fa-sort-down:before,.fa-sort-desc:before{content:\"\\F0DD\"}.fa-sort-up:before,.fa-sort-asc:before{content:\"\\F0DE\"}.fa-envelope:before{content:\"\\F0E0\"}.fa-linkedin:before{content:\"\\F0E1\"}.fa-rotate-left:before,.fa-undo:before{content:\"\\F0E2\"}.fa-legal:before,.fa-gavel:before{content:\"\\F0E3\"}.fa-dashboard:before,.fa-tachometer:before{content:\"\\F0E4\"}.fa-comment-o:before{content:\"\\F0E5\"}.fa-comments-o:before{content:\"\\F0E6\"}.fa-flash:before,.fa-bolt:before{content:\"\\F0E7\"}.fa-sitemap:before{content:\"\\F0E8\"}.fa-umbrella:before{content:\"\\F0E9\"}.fa-paste:before,.fa-clipboard:before{content:\"\\F0EA\"}.fa-lightbulb-o:before{content:\"\\F0EB\"}.fa-exchange:before{content:\"\\F0EC\"}.fa-cloud-download:before{content:\"\\F0ED\"}.fa-cloud-upload:before{content:\"\\F0EE\"}.fa-user-md:before{content:\"\\F0F0\"}.fa-stethoscope:before{content:\"\\F0F1\"}.fa-suitcase:before{content:\"\\F0F2\"}.fa-bell-o:before{content:\"\\F0A2\"}.fa-coffee:before{content:\"\\F0F4\"}.fa-cutlery:before{content:\"\\F0F5\"}.fa-file-text-o:before{content:\"\\F0F6\"}.fa-building-o:before{content:\"\\F0F7\"}.fa-hospital-o:before{content:\"\\F0F8\"}.fa-ambulance:before{content:\"\\F0F9\"}.fa-medkit:before{content:\"\\F0FA\"}.fa-fighter-jet:before{content:\"\\F0FB\"}.fa-beer:before{content:\"\\F0FC\"}.fa-h-square:before{content:\"\\F0FD\"}.fa-plus-square:before{content:\"\\F0FE\"}.fa-angle-double-left:before{content:\"\\F100\"}.fa-angle-double-right:before{content:\"\\F101\"}.fa-angle-double-up:before{content:\"\\F102\"}.fa-angle-double-down:before{content:\"\\F103\"}.fa-angle-left:before{content:\"\\F104\"}.fa-angle-right:before{content:\"\\F105\"}.fa-angle-up:before{content:\"\\F106\"}.fa-angle-down:before{content:\"\\F107\"}.fa-desktop:before{content:\"\\F108\"}.fa-laptop:before{content:\"\\F109\"}.fa-tablet:before{content:\"\\F10A\"}.fa-mobile-phone:before,.fa-mobile:before{content:\"\\F10B\"}.fa-circle-o:before{content:\"\\F10C\"}.fa-quote-left:before{content:\"\\F10D\"}.fa-quote-right:before{content:\"\\F10E\"}.fa-spinner:before{content:\"\\F110\"}.fa-circle:before{content:\"\\F111\"}.fa-mail-reply:before,.fa-reply:before{content:\"\\F112\"}.fa-github-alt:before{content:\"\\F113\"}.fa-folder-o:before{content:\"\\F114\"}.fa-folder-open-o:before{content:\"\\F115\"}.fa-smile-o:before{content:\"\\F118\"}.fa-frown-o:before{content:\"\\F119\"}.fa-meh-o:before{content:\"\\F11A\"}.fa-gamepad:before{content:\"\\F11B\"}.fa-keyboard-o:before{content:\"\\F11C\"}.fa-flag-o:before{content:\"\\F11D\"}.fa-flag-checkered:before{content:\"\\F11E\"}.fa-terminal:before{content:\"\\F120\"}.fa-code:before{content:\"\\F121\"}.fa-mail-reply-all:before,.fa-reply-all:before{content:\"\\F122\"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:\"\\F123\"}.fa-location-arrow:before{content:\"\\F124\"}.fa-crop:before{content:\"\\F125\"}.fa-code-fork:before{content:\"\\F126\"}.fa-unlink:before,.fa-chain-broken:before{content:\"\\F127\"}.fa-question:before{content:\"\\F128\"}.fa-info:before{content:\"\\F129\"}.fa-exclamation:before{content:\"\\F12A\"}.fa-superscript:before{content:\"\\F12B\"}.fa-subscript:before{content:\"\\F12C\"}.fa-eraser:before{content:\"\\F12D\"}.fa-puzzle-piece:before{content:\"\\F12E\"}.fa-microphone:before{content:\"\\F130\"}.fa-microphone-slash:before{content:\"\\F131\"}.fa-shield:before{content:\"\\F132\"}.fa-calendar-o:before{content:\"\\F133\"}.fa-fire-extinguisher:before{content:\"\\F134\"}.fa-rocket:before{content:\"\\F135\"}.fa-maxcdn:before{content:\"\\F136\"}.fa-chevron-circle-left:before{content:\"\\F137\"}.fa-chevron-circle-right:before{content:\"\\F138\"}.fa-chevron-circle-up:before{content:\"\\F139\"}.fa-chevron-circle-down:before{content:\"\\F13A\"}.fa-html5:before{content:\"\\F13B\"}.fa-css3:before{content:\"\\F13C\"}.fa-anchor:before{content:\"\\F13D\"}.fa-unlock-alt:before{content:\"\\F13E\"}.fa-bullseye:before{content:\"\\F140\"}.fa-ellipsis-h:before{content:\"\\F141\"}.fa-ellipsis-v:before{content:\"\\F142\"}.fa-rss-square:before{content:\"\\F143\"}.fa-play-circle:before{content:\"\\F144\"}.fa-ticket:before{content:\"\\F145\"}.fa-minus-square:before{content:\"\\F146\"}.fa-minus-square-o:before{content:\"\\F147\"}.fa-level-up:before{content:\"\\F148\"}.fa-level-down:before{content:\"\\F149\"}.fa-check-square:before{content:\"\\F14A\"}.fa-pencil-square:before{content:\"\\F14B\"}.fa-external-link-square:before{content:\"\\F14C\"}.fa-share-square:before{content:\"\\F14D\"}.fa-compass:before{content:\"\\F14E\"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:\"\\F150\"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:\"\\F151\"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:\"\\F152\"}.fa-euro:before,.fa-eur:before{content:\"\\F153\"}.fa-gbp:before{content:\"\\F154\"}.fa-dollar:before,.fa-usd:before{content:\"\\F155\"}.fa-rupee:before,.fa-inr:before{content:\"\\F156\"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:\"\\F157\"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:\"\\F158\"}.fa-won:before,.fa-krw:before{content:\"\\F159\"}.fa-bitcoin:before,.fa-btc:before{content:\"\\F15A\"}.fa-file:before{content:\"\\F15B\"}.fa-file-text:before{content:\"\\F15C\"}.fa-sort-alpha-asc:before{content:\"\\F15D\"}.fa-sort-alpha-desc:before{content:\"\\F15E\"}.fa-sort-amount-asc:before{content:\"\\F160\"}.fa-sort-amount-desc:before{content:\"\\F161\"}.fa-sort-numeric-asc:before{content:\"\\F162\"}.fa-sort-numeric-desc:before{content:\"\\F163\"}.fa-thumbs-up:before{content:\"\\F164\"}.fa-thumbs-down:before{content:\"\\F165\"}.fa-youtube-square:before{content:\"\\F166\"}.fa-youtube:before{content:\"\\F167\"}.fa-xing:before{content:\"\\F168\"}.fa-xing-square:before{content:\"\\F169\"}.fa-youtube-play:before{content:\"\\F16A\"}.fa-dropbox:before{content:\"\\F16B\"}.fa-stack-overflow:before{content:\"\\F16C\"}.fa-instagram:before{content:\"\\F16D\"}.fa-flickr:before{content:\"\\F16E\"}.fa-adn:before{content:\"\\F170\"}.fa-bitbucket:before{content:\"\\F171\"}.fa-bitbucket-square:before{content:\"\\F172\"}.fa-tumblr:before{content:\"\\F173\"}.fa-tumblr-square:before{content:\"\\F174\"}.fa-long-arrow-down:before{content:\"\\F175\"}.fa-long-arrow-up:before{content:\"\\F176\"}.fa-long-arrow-left:before{content:\"\\F177\"}.fa-long-arrow-right:before{content:\"\\F178\"}.fa-apple:before{content:\"\\F179\"}.fa-windows:before{content:\"\\F17A\"}.fa-android:before{content:\"\\F17B\"}.fa-linux:before{content:\"\\F17C\"}.fa-dribbble:before{content:\"\\F17D\"}.fa-skype:before{content:\"\\F17E\"}.fa-foursquare:before{content:\"\\F180\"}.fa-trello:before{content:\"\\F181\"}.fa-female:before{content:\"\\F182\"}.fa-male:before{content:\"\\F183\"}.fa-gittip:before,.fa-gratipay:before{content:\"\\F184\"}.fa-sun-o:before{content:\"\\F185\"}.fa-moon-o:before{content:\"\\F186\"}.fa-archive:before{content:\"\\F187\"}.fa-bug:before{content:\"\\F188\"}.fa-vk:before{content:\"\\F189\"}.fa-weibo:before{content:\"\\F18A\"}.fa-renren:before{content:\"\\F18B\"}.fa-pagelines:before{content:\"\\F18C\"}.fa-stack-exchange:before{content:\"\\F18D\"}.fa-arrow-circle-o-right:before{content:\"\\F18E\"}.fa-arrow-circle-o-left:before{content:\"\\F190\"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:\"\\F191\"}.fa-dot-circle-o:before{content:\"\\F192\"}.fa-wheelchair:before{content:\"\\F193\"}.fa-vimeo-square:before{content:\"\\F194\"}.fa-turkish-lira:before,.fa-try:before{content:\"\\F195\"}.fa-plus-square-o:before{content:\"\\F196\"}.fa-space-shuttle:before{content:\"\\F197\"}.fa-slack:before{content:\"\\F198\"}.fa-envelope-square:before{content:\"\\F199\"}.fa-wordpress:before{content:\"\\F19A\"}.fa-openid:before{content:\"\\F19B\"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:\"\\F19C\"}.fa-mortar-board:before,.fa-graduation-cap:before{content:\"\\F19D\"}.fa-yahoo:before{content:\"\\F19E\"}.fa-google:before{content:\"\\F1A0\"}.fa-reddit:before{content:\"\\F1A1\"}.fa-reddit-square:before{content:\"\\F1A2\"}.fa-stumbleupon-circle:before{content:\"\\F1A3\"}.fa-stumbleupon:before{content:\"\\F1A4\"}.fa-delicious:before{content:\"\\F1A5\"}.fa-digg:before{content:\"\\F1A6\"}.fa-pied-piper-pp:before{content:\"\\F1A7\"}.fa-pied-piper-alt:before{content:\"\\F1A8\"}.fa-drupal:before{content:\"\\F1A9\"}.fa-joomla:before{content:\"\\F1AA\"}.fa-language:before{content:\"\\F1AB\"}.fa-fax:before{content:\"\\F1AC\"}.fa-building:before{content:\"\\F1AD\"}.fa-child:before{content:\"\\F1AE\"}.fa-paw:before{content:\"\\F1B0\"}.fa-spoon:before{content:\"\\F1B1\"}.fa-cube:before{content:\"\\F1B2\"}.fa-cubes:before{content:\"\\F1B3\"}.fa-behance:before{content:\"\\F1B4\"}.fa-behance-square:before{content:\"\\F1B5\"}.fa-steam:before{content:\"\\F1B6\"}.fa-steam-square:before{content:\"\\F1B7\"}.fa-recycle:before{content:\"\\F1B8\"}.fa-automobile:before,.fa-car:before{content:\"\\F1B9\"}.fa-cab:before,.fa-taxi:before{content:\"\\F1BA\"}.fa-tree:before{content:\"\\F1BB\"}.fa-spotify:before{content:\"\\F1BC\"}.fa-deviantart:before{content:\"\\F1BD\"}.fa-soundcloud:before{content:\"\\F1BE\"}.fa-database:before{content:\"\\F1C0\"}.fa-file-pdf-o:before{content:\"\\F1C1\"}.fa-file-word-o:before{content:\"\\F1C2\"}.fa-file-excel-o:before{content:\"\\F1C3\"}.fa-file-powerpoint-o:before{content:\"\\F1C4\"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:\"\\F1C5\"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:\"\\F1C6\"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:\"\\F1C7\"}.fa-file-movie-o:before,.fa-file-video-o:before{content:\"\\F1C8\"}.fa-file-code-o:before{content:\"\\F1C9\"}.fa-vine:before{content:\"\\F1CA\"}.fa-codepen:before{content:\"\\F1CB\"}.fa-jsfiddle:before{content:\"\\F1CC\"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:\"\\F1CD\"}.fa-circle-o-notch:before{content:\"\\F1CE\"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:\"\\F1D0\"}.fa-ge:before,.fa-empire:before{content:\"\\F1D1\"}.fa-git-square:before{content:\"\\F1D2\"}.fa-git:before{content:\"\\F1D3\"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:\"\\F1D4\"}.fa-tencent-weibo:before{content:\"\\F1D5\"}.fa-qq:before{content:\"\\F1D6\"}.fa-wechat:before,.fa-weixin:before{content:\"\\F1D7\"}.fa-send:before,.fa-paper-plane:before{content:\"\\F1D8\"}.fa-send-o:before,.fa-paper-plane-o:before{content:\"\\F1D9\"}.fa-history:before{content:\"\\F1DA\"}.fa-circle-thin:before{content:\"\\F1DB\"}.fa-header:before{content:\"\\F1DC\"}.fa-paragraph:before{content:\"\\F1DD\"}.fa-sliders:before{content:\"\\F1DE\"}.fa-share-alt:before{content:\"\\F1E0\"}.fa-share-alt-square:before{content:\"\\F1E1\"}.fa-bomb:before{content:\"\\F1E2\"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:\"\\F1E3\"}.fa-tty:before{content:\"\\F1E4\"}.fa-binoculars:before{content:\"\\F1E5\"}.fa-plug:before{content:\"\\F1E6\"}.fa-slideshare:before{content:\"\\F1E7\"}.fa-twitch:before{content:\"\\F1E8\"}.fa-yelp:before{content:\"\\F1E9\"}.fa-newspaper-o:before{content:\"\\F1EA\"}.fa-wifi:before{content:\"\\F1EB\"}.fa-calculator:before{content:\"\\F1EC\"}.fa-paypal:before{content:\"\\F1ED\"}.fa-google-wallet:before{content:\"\\F1EE\"}.fa-cc-visa:before{content:\"\\F1F0\"}.fa-cc-mastercard:before{content:\"\\F1F1\"}.fa-cc-discover:before{content:\"\\F1F2\"}.fa-cc-amex:before{content:\"\\F1F3\"}.fa-cc-paypal:before{content:\"\\F1F4\"}.fa-cc-stripe:before{content:\"\\F1F5\"}.fa-bell-slash:before{content:\"\\F1F6\"}.fa-bell-slash-o:before{content:\"\\F1F7\"}.fa-trash:before{content:\"\\F1F8\"}.fa-copyright:before{content:\"\\F1F9\"}.fa-at:before{content:\"\\F1FA\"}.fa-eyedropper:before{content:\"\\F1FB\"}.fa-paint-brush:before{content:\"\\F1FC\"}.fa-birthday-cake:before{content:\"\\F1FD\"}.fa-area-chart:before{content:\"\\F1FE\"}.fa-pie-chart:before{content:\"\\F200\"}.fa-line-chart:before{content:\"\\F201\"}.fa-lastfm:before{content:\"\\F202\"}.fa-lastfm-square:before{content:\"\\F203\"}.fa-toggle-off:before{content:\"\\F204\"}.fa-toggle-on:before{content:\"\\F205\"}.fa-bicycle:before{content:\"\\F206\"}.fa-bus:before{content:\"\\F207\"}.fa-ioxhost:before{content:\"\\F208\"}.fa-angellist:before{content:\"\\F209\"}.fa-cc:before{content:\"\\F20A\"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:\"\\F20B\"}.fa-meanpath:before{content:\"\\F20C\"}.fa-buysellads:before{content:\"\\F20D\"}.fa-connectdevelop:before{content:\"\\F20E\"}.fa-dashcube:before{content:\"\\F210\"}.fa-forumbee:before{content:\"\\F211\"}.fa-leanpub:before{content:\"\\F212\"}.fa-sellsy:before{content:\"\\F213\"}.fa-shirtsinbulk:before{content:\"\\F214\"}.fa-simplybuilt:before{content:\"\\F215\"}.fa-skyatlas:before{content:\"\\F216\"}.fa-cart-plus:before{content:\"\\F217\"}.fa-cart-arrow-down:before{content:\"\\F218\"}.fa-diamond:before{content:\"\\F219\"}.fa-ship:before{content:\"\\F21A\"}.fa-user-secret:before{content:\"\\F21B\"}.fa-motorcycle:before{content:\"\\F21C\"}.fa-street-view:before{content:\"\\F21D\"}.fa-heartbeat:before{content:\"\\F21E\"}.fa-venus:before{content:\"\\F221\"}.fa-mars:before{content:\"\\F222\"}.fa-mercury:before{content:\"\\F223\"}.fa-intersex:before,.fa-transgender:before{content:\"\\F224\"}.fa-transgender-alt:before{content:\"\\F225\"}.fa-venus-double:before{content:\"\\F226\"}.fa-mars-double:before{content:\"\\F227\"}.fa-venus-mars:before{content:\"\\F228\"}.fa-mars-stroke:before{content:\"\\F229\"}.fa-mars-stroke-v:before{content:\"\\F22A\"}.fa-mars-stroke-h:before{content:\"\\F22B\"}.fa-neuter:before{content:\"\\F22C\"}.fa-genderless:before{content:\"\\F22D\"}.fa-facebook-official:before{content:\"\\F230\"}.fa-pinterest-p:before{content:\"\\F231\"}.fa-whatsapp:before{content:\"\\F232\"}.fa-server:before{content:\"\\F233\"}.fa-user-plus:before{content:\"\\F234\"}.fa-user-times:before{content:\"\\F235\"}.fa-hotel:before,.fa-bed:before{content:\"\\F236\"}.fa-viacoin:before{content:\"\\F237\"}.fa-train:before{content:\"\\F238\"}.fa-subway:before{content:\"\\F239\"}.fa-medium:before{content:\"\\F23A\"}.fa-yc:before,.fa-y-combinator:before{content:\"\\F23B\"}.fa-optin-monster:before{content:\"\\F23C\"}.fa-opencart:before{content:\"\\F23D\"}.fa-expeditedssl:before{content:\"\\F23E\"}.fa-battery-4:before,.fa-battery-full:before{content:\"\\F240\"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:\"\\F241\"}.fa-battery-2:before,.fa-battery-half:before{content:\"\\F242\"}.fa-battery-1:before,.fa-battery-quarter:before{content:\"\\F243\"}.fa-battery-0:before,.fa-battery-empty:before{content:\"\\F244\"}.fa-mouse-pointer:before{content:\"\\F245\"}.fa-i-cursor:before{content:\"\\F246\"}.fa-object-group:before{content:\"\\F247\"}.fa-object-ungroup:before{content:\"\\F248\"}.fa-sticky-note:before{content:\"\\F249\"}.fa-sticky-note-o:before{content:\"\\F24A\"}.fa-cc-jcb:before{content:\"\\F24B\"}.fa-cc-diners-club:before{content:\"\\F24C\"}.fa-clone:before{content:\"\\F24D\"}.fa-balance-scale:before{content:\"\\F24E\"}.fa-hourglass-o:before{content:\"\\F250\"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:\"\\F251\"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:\"\\F252\"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:\"\\F253\"}.fa-hourglass:before{content:\"\\F254\"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:\"\\F255\"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:\"\\F256\"}.fa-hand-scissors-o:before{content:\"\\F257\"}.fa-hand-lizard-o:before{content:\"\\F258\"}.fa-hand-spock-o:before{content:\"\\F259\"}.fa-hand-pointer-o:before{content:\"\\F25A\"}.fa-hand-peace-o:before{content:\"\\F25B\"}.fa-trademark:before{content:\"\\F25C\"}.fa-registered:before{content:\"\\F25D\"}.fa-creative-commons:before{content:\"\\F25E\"}.fa-gg:before{content:\"\\F260\"}.fa-gg-circle:before{content:\"\\F261\"}.fa-tripadvisor:before{content:\"\\F262\"}.fa-odnoklassniki:before{content:\"\\F263\"}.fa-odnoklassniki-square:before{content:\"\\F264\"}.fa-get-pocket:before{content:\"\\F265\"}.fa-wikipedia-w:before{content:\"\\F266\"}.fa-safari:before{content:\"\\F267\"}.fa-chrome:before{content:\"\\F268\"}.fa-firefox:before{content:\"\\F269\"}.fa-opera:before{content:\"\\F26A\"}.fa-internet-explorer:before{content:\"\\F26B\"}.fa-tv:before,.fa-television:before{content:\"\\F26C\"}.fa-contao:before{content:\"\\F26D\"}.fa-500px:before{content:\"\\F26E\"}.fa-amazon:before{content:\"\\F270\"}.fa-calendar-plus-o:before{content:\"\\F271\"}.fa-calendar-minus-o:before{content:\"\\F272\"}.fa-calendar-times-o:before{content:\"\\F273\"}.fa-calendar-check-o:before{content:\"\\F274\"}.fa-industry:before{content:\"\\F275\"}.fa-map-pin:before{content:\"\\F276\"}.fa-map-signs:before{content:\"\\F277\"}.fa-map-o:before{content:\"\\F278\"}.fa-map:before{content:\"\\F279\"}.fa-commenting:before{content:\"\\F27A\"}.fa-commenting-o:before{content:\"\\F27B\"}.fa-houzz:before{content:\"\\F27C\"}.fa-vimeo:before{content:\"\\F27D\"}.fa-black-tie:before{content:\"\\F27E\"}.fa-fonticons:before{content:\"\\F280\"}.fa-reddit-alien:before{content:\"\\F281\"}.fa-edge:before{content:\"\\F282\"}.fa-credit-card-alt:before{content:\"\\F283\"}.fa-codiepie:before{content:\"\\F284\"}.fa-modx:before{content:\"\\F285\"}.fa-fort-awesome:before{content:\"\\F286\"}.fa-usb:before{content:\"\\F287\"}.fa-product-hunt:before{content:\"\\F288\"}.fa-mixcloud:before{content:\"\\F289\"}.fa-scribd:before{content:\"\\F28A\"}.fa-pause-circle:before{content:\"\\F28B\"}.fa-pause-circle-o:before{content:\"\\F28C\"}.fa-stop-circle:before{content:\"\\F28D\"}.fa-stop-circle-o:before{content:\"\\F28E\"}.fa-shopping-bag:before{content:\"\\F290\"}.fa-shopping-basket:before{content:\"\\F291\"}.fa-hashtag:before{content:\"\\F292\"}.fa-bluetooth:before{content:\"\\F293\"}.fa-bluetooth-b:before{content:\"\\F294\"}.fa-percent:before{content:\"\\F295\"}.fa-gitlab:before{content:\"\\F296\"}.fa-wpbeginner:before{content:\"\\F297\"}.fa-wpforms:before{content:\"\\F298\"}.fa-envira:before{content:\"\\F299\"}.fa-universal-access:before{content:\"\\F29A\"}.fa-wheelchair-alt:before{content:\"\\F29B\"}.fa-question-circle-o:before{content:\"\\F29C\"}.fa-blind:before{content:\"\\F29D\"}.fa-audio-description:before{content:\"\\F29E\"}.fa-volume-control-phone:before{content:\"\\F2A0\"}.fa-braille:before{content:\"\\F2A1\"}.fa-assistive-listening-systems:before{content:\"\\F2A2\"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:\"\\F2A3\"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:\"\\F2A4\"}.fa-glide:before{content:\"\\F2A5\"}.fa-glide-g:before{content:\"\\F2A6\"}.fa-signing:before,.fa-sign-language:before{content:\"\\F2A7\"}.fa-low-vision:before{content:\"\\F2A8\"}.fa-viadeo:before{content:\"\\F2A9\"}.fa-viadeo-square:before{content:\"\\F2AA\"}.fa-snapchat:before{content:\"\\F2AB\"}.fa-snapchat-ghost:before{content:\"\\F2AC\"}.fa-snapchat-square:before{content:\"\\F2AD\"}.fa-pied-piper:before{content:\"\\F2AE\"}.fa-first-order:before{content:\"\\F2B0\"}.fa-yoast:before{content:\"\\F2B1\"}.fa-themeisle:before{content:\"\\F2B2\"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:\"\\F2B3\"}.fa-fa:before,.fa-font-awesome:before{content:\"\\F2B4\"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}\n", ""]);
	
	// exports


/***/ },
/* 72 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "25a32416abee198dd821b0b17a198a8f.eot";

/***/ },
/* 73 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "25a32416abee198dd821b0b17a198a8f.eot";

/***/ },
/* 74 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "e6cf7c6ec7c2d6f670ae9d762604cb0b.woff2";

/***/ },
/* 75 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "c8ddf1e5e5bf3682bc7bebf30f394148.woff";

/***/ },
/* 76 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "1dc35d25e61d819a9c357074014867ab.ttf";

/***/ },
/* 77 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "d7c639084f684d66a1bc66855d193ed8.svg";

/***/ },
/* 78 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(79);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../../css-loader/index.js!./index.css", function() {
				var newContent = require("!!./../../../css-loader/index.js!./index.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 79 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	exports.i(__webpack_require__(80), "");
	exports.i(__webpack_require__(81), "");
	exports.i(__webpack_require__(82), "");
	exports.i(__webpack_require__(86), "");
	exports.i(__webpack_require__(92), "");
	exports.i(__webpack_require__(93), "");
	exports.i(__webpack_require__(94), "");
	exports.i(__webpack_require__(95), "");
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) Jupyter Development Team.\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n\n\nbody {\n  margin: 0;\n  padding: 0;\n  background: #E0E0E0;\n  overflow: hidden;\n}\n\n\n.p-ApplicationShell.p-Widget {\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  font-size: 13px;\n}\n\n\n.jp-Document {\n  min-width: 120px;\n  min-height: 120px;\n  outline: none;\n}\n\n\n.jp-NotebookContainer-widget {\n  flex: 0 0 auto;\n}\n\n\n.jp-Notebook {\n  flex: 1 1 auto;\n}\n\n\n\n.jp-FileBrowser {\n  min-width: 300px;\n}\n\n\n.p-SideBar {\n  min-width: 36px;\n  max-width: 36px;\n  font-size: 13px;\n  font-family: Helvetica, Arial;\n  color: #757575;\n  background: #EEEEEE;\n}\n\n\n.p-SideBar.p-Widget {\n  overflow: visible;\n}\n\n\n.p-SideBar.p-mod-left {\n  border-right: 1px solid #BDBDBD;\n}\n\n\n.p-SideBar.p-mod-right {\n  border-left: 1px solid #BDBDBD;\n}\n\n\n.p-SideBar-content {\n  height: 35px;\n  transform-origin: 0 0 0;\n}\n\n\n.p-SideBar.p-mod-left > .p-SideBar-content {\n  flex-direction: row-reverse;\n  transform: rotate(-90deg) translateX(-100%);\n}\n\n\n.p-SideBar.p-mod-right > .p-SideBar-content {\n  flex-direction: row;\n  transform: rotate(90deg) translateY(-100%);\n}\n\n\n.p-SideBar-button {\n  padding: 0 18px;\n  line-height: 35px;\n}\n\n\n.p-SideBar-button:hover:not(.p-mod-current) {\n  background: #FAFAFA;\n}\n\n\n.p-SideBar-button.p-mod-current {\n  color: #F27624;\n  background: #FAFAFA;\n}\n\n\n.p-SideBar.p-mod-left .p-SideBar-button {\n  border-left: 1px solid #BDBDBD;\n}\n\n\n.p-SideBar.p-mod-right .p-SideBar-button {\n  border-right: 1px solid #BDBDBD;\n}\n\n\n#p-main-dock-panel {\n  padding: 8px;\n}\n\n\n.p-DockTabPanel {\n  border: 1px solid #BDBDBD;\n  border-top: none;\n}\n\n\n.p-DockTabPanel > .p-StackedPanel {\n  background: white;\n}\n\n\n.p-DockPanel-overlay {\n  background: rgba(242, 118, 36, 0.1);\n  border: 1px dashed #F27624;\n}\n\n\n.p-DockPanel-overlay.p-mod-root-top,\n.p-DockPanel-overlay.p-mod-root-left,\n.p-DockPanel-overlay.p-mod-root-right,\n.p-DockPanel-overlay.p-mod-root-bottom,\n.p-DockPanel-overlay.p-mod-root-center {\n  border-width: 2px;\n}\n\n\n.p-TabBar {\n  min-height: 28px;\n  max-height: 28px;\n  color: #757575;\n  background: #F5F5F5;\n  font: 12px Helvetica, Arial, sans-serif;\n}\n\n\n/* increase specificity to override default */\n.p-TabBar > .p-TabBar-header {\n  flex: 0 0 1px;\n  background: #BDBDBD;\n}\n\n\n.p-TabBar-content {\n  min-width: 0;\n  max-height: 22px;\n}\n\n\n/* increase specificity to override default */\n.p-TabBar > .p-TabBar-footer {\n  flex: 0 0 3px;\n  background: #FAFAFA;\n  border-top: 1px solid #BDBDBD;\n  border-bottom: 1px solid #E0E0E0;\n}\n\n\n.p-TabBar-tab {\n  flex-basis: 144px;\n  min-height: 23px;\n  max-height: 23px;\n  min-width: 35px;\n  margin-left: -1px;\n  padding: 0px 10px;\n  background: #EEEEEE;\n  border: 1px solid #BDBDBD;\n  border-bottom: none;\n  transform: translateY(-1px);\n}\n\n\n.p-TabBar-tab:last-child {\n  margin-right: -1px;\n}\n\n\n.p-TabBar-tab.p-mod-current {\n  min-height: 24px;\n  max-height: 24px;\n  background: #FAFAFA;\n  border-top: 1px solid #F27624;\n}\n\n\n.p-TabBar-tab:hover:not(.p-mod-current) {\n  background: #FAFAFA;\n}\n\n\n.p-TabBar-tabIcon,\n.p-TabBar-tabText,\n.p-TabBar-tabCloseIcon {\n  line-height: 22px;\n}\n\n\n.p-TabBar-tab.p-mod-closable > .p-TabBar-tabCloseIcon {\n  margin-left: 4px;\n}\n\n\n.p-TabBar-tab.p-mod-closable > .p-TabBar-tabCloseIcon:before {\n  font-family: FontAwesome;\n  content: '\\F00D'; /* close */\n}\n\n\n.p-TabBar-tab.p-mod-closable.jp-mod-dirty > .p-TabBar-tabCloseIcon:before {\n  font-family: FontAwesome;\n  content: '\\F069'; /* asterisk */\n}\n\n\n.p-TabBar-tab.p-mod-drag-image {\n  min-height: 24px;\n  min-width: 124px;\n  color: #757575;\n  background: white;\n  border: 1px solid #BDBDBD;\n  border-top: 1px solid #F27624;\n  font: 12px Helvetica, Arial, sans-serif;\n  box-shadow: 1px 1px 2px rgba(0, 0, 1, 0.1);\n  transform: translateX(-40%) translateY(-58%);\n}\n\n\n#p-main-split-panel > .p-SplitPanel-handle {\n  background: #BDBDBD;\n}\n\n\n.p-MenuBar {\n  padding-left: 5px;\n  background: #FAFAFA;\n  color: rgba(0, 0, 0, 0.87);\n  border-bottom: 1px solid #DDDDDD;\n  font: 13px Helvetica, Arial, sans-serif;\n}\n\n\n.p-MenuBar-menu {\n  transform: translateY(-1px);\n}\n\n\n.p-MenuBar-item {\n  padding: 4px 8px;\n  border-left: 1px solid transparent;\n  border-right: 1px solid transparent;\n}\n\n\n.p-MenuBar-item.p-mod-active {\n  background: #E5E5E5;\n}\n\n\n.p-MenuBar-item.p-mod-disabled {\n  color: rgba(0, 0, 0, 0.26);\n}\n\n\n.p-MenuBar-item.p-type-separator {\n  margin: 2px;\n  padding: 0;\n  border: none;\n  border-left: 1px solid #DDDDDD;\n}\n\n\n.p-MenuBar.p-mod-active .p-MenuBar-item.p-mod-active {\n  z-index: 10001;\n  background: white;\n  border-left: 1px solid #C0C0C0;\n  border-right: 1px solid #C0C0C0;\n  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2);\n}\n\n\n.p-Menu {\n  z-index: 10000;\n  padding: 3px 0px;\n  background: white;\n  color: rgba(0, 0, 0, 0.87);\n  border: 1px solid #C0C0C0;\n  font: 12px Helvetica, Arial, sans-serif;\n  box-shadow: 0px 1px 6px rgba(0, 0, 0, 0.2);\n}\n\n\n.p-Menu-item.p-mod-active {\n  background: #E5E5E5;\n}\n\n\n.p-Menu-item.p-mod-disabled {\n  color: rgba(0, 0, 0, 0.26);\n}\n\n\n.p-Menu-itemIcon {\n  width: 21px;\n  padding: 4px 2px;\n}\n\n\n.p-Menu-itemText {\n  padding: 4px 35px 4px 2px;\n}\n\n\n.p-Menu-itemShortcut {\n  padding: 4px 0px;\n}\n\n\n.p-Menu-itemSubmenuIcon {\n  width: 16px;\n  padding: 4px 0px;\n}\n\n\n.p-Menu-item.p-type-separator > span {\n  padding: 0;\n  height: 9px;\n}\n\n\n.p-Menu-item.p-type-separator > span::after {\n  content: '';\n  display: block;\n  position: relative;\n  top: 4px;\n  border-top: 1px solid #DDDDDD;\n}\n\n\n.p-Menu-itemIcon::before,\n.p-Menu-itemSubmenuIcon::before {\n  font-family: FontAwesome;\n}\n\n\n.p-Menu-item.p-type-check.p-mod-checked > .p-Menu-itemIcon::before {\n  content: '\\F00C';\n}\n\n\n.p-Menu-item.p-type-submenu > .p-Menu-itemSubmenuIcon::before {\n  content: '\\F0DA';\n}\n", ""]);
	
	// exports


/***/ },
/* 80 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2016, Jupyter Development Team.\n|\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n.jp-Notebook-panel {\n  display: flex;\n  flex-direction: column;\n}\n\n\n.p-Widget.jp-NBToolbar {\n  flex: 0 0 auto;\n}\n\n\n.p-Widget.jp-Notebook-container {\n  flex: 1 1 auto;\n}\n\n\n.jp-InputArea {\n  display: flex;\n  flex-direction: row;\n}\n\n\n.jp-InputArea-prompt {\n  flex-grow: 0;\n  flex-shrink: 0;\n}\n\n\n.jp-InputArea-editor {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n\n.jp-MarkdownCell-renderer.p-Widget {\n  user-select: text;\n  -moz-user-select: text;\n  -webkit-user-select: text;\n  -ms-user-select: text;\n}\n\n\n.jp-OutputArea-result.p-Widget {\n  user-select: text;\n  -moz-user-select: text;\n  -webkit-user-select: text;\n  -ms-user-select: text;\n}\n\n\n.jp-Console-panel {\n  display: flex;\n  flex: 1 1 auto;\n  flex-direction: column;\n}\n\n.p-Widget.jp-Console {\n  overflow: auto;\n}\n", ""]);
	
	// exports


/***/ },
/* 81 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2016, Jupyter Development Team.\n|\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n/* Increased specificity in case phosphor css is loaded later. */\n.p-Widget.jp-Notebook {\n  margin-top: 20px;\n  min-width: 50px;\n  min-height: 50px;\n  outline: none;\n}\n\n\n.p-Widget.jp-Notebook-panel {\n  height: 100%;\n}\n\n\n.p-Widget.jp-Notebook-container {\n  overflow: auto;\n  padding-left: 10px;\n  padding-right: 10px;\n  padding-bottom: 20px;\n}\n\n\n.jp-InputArea-prompt {\n  flex-basis: 90px;\n  color: #303F9F;\n  font-family: monospace;\n  padding: 0.4em;\n  text-align: right;\n  line-height: 20px;\n  font-size: 14px;\n}\n\n\n.jp-InputArea-editor {\n  height: auto;\n  min-height: 2em;\n}\n\n\n.jp-CellEditor {\n  border: 1px solid #cfcfcf;\n  border-radius: 2px;\n  background: #f7f7f7;\n  line-height: 1.2em;\n  padding: 4px;\n}\n\n\n.jp-MarkdownCell {\n  outline: 0;\n}\n\n\n.jp-MarkdownCell.jp-mod-rendered {\n  padding-left: 100px;\n}\n\n\n.jp-MarkdownCell-renderer {\n  padding-left: 4px;\n}\n\n\n.jp-OutputArea {\n  background: #FFFFFF;\n}\n\n\n.jp-OutputArea > .jp-OutputArea-output {\n  margin-left: 90px;\n  display: flex;\n  flex-direction: row;\n}\n\n\n.jp-OutputArea > .jp-OutputArea-output.jp-OutputArea-executeResult {\n  margin-left: 0px;\n  flex: 1 1 auto;\n}\n\n\n.jp-OutputArea-output.jp-OutputArea-executeResult > .jp-OutputArea-prompt {\n  color: #D84315;\n  font-family: monospace;\n  text-align: right;\n  line-height: 20px;\n  padding: 0.4em;\n  font-size: 14px;\n  flex: 0 0 90px;\n  box-sizing: border-box;\n}\n\n\n.jp-OutputArea-output > .jp-OutputArea-result {\n  padding: 4px;\n}\n\n\n.jp-OutputArea pre {\n  border: none;\n}\n\n\n.jp-OutputArea > .jp-OutputArea-output.jp-OutputArea-stderr {\n  background: #fdd;\n}\n\n\n.jp-Notebook.jp-mod-commandMode .jp-Notebook-cell.jp-mod-active.jp-mod-selected {\n  border-color: #ABABAB;\n  border-left-width: 1px;\n  background: linear-gradient(to right, #42A5F5 -40px, #42A5F5 5px, transparent 5px, transparent 100%);\n}\n\n\n.jp-Notebook.jp-mod-commandMode .jp-Notebook-cell.jp-mod-multiSelected.jp-mod-active {\n  background: linear-gradient(to right, #42A5F5 -40px, #42A5F5 7px, #E3F2FD 7px, #E3F2FD 100%);\n}\n\n\n.jp-Notebook.jp-mod-commandMode .jp-Notebook-cell.jp-mod-selected {\n  background: #E3F2FD;\n}\n\n\n.jp-Notebook.jp-mod-editMode .jp-Notebook-cell.jp-mod-active {\n  border-color: #66BB6A;\n  border-left-width: 1px;\n  background: linear-gradient(to right, #66BB6A -40px, #66BB6A 5px, transparent 5px, transparent 100%);\n}\n\n\n.jp-Cell {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  padding-left: 10px;\n  padding-right: 10px;\n  border-width: 1px;\n  border-style: solid;\n  border-color: transparent;\n  outline: none;\n}\n\n\n.jp-MarkdownCell {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\n\n\n.jp-NBToolbar {\n    display: flex;\n    flex-direction: row;\n    background-color: #F8F8F8;\n    border-top: 1px solid #E0E0E0;\n    border-bottom: 1px solid #E0E0E0;\n}\n\n\n.jp-NBToolbar > .jp-NBToolbar-item {\n    flex: 0 0 auto;\n    padding-left: 8px;\n    padding-right: 8px;\n    vertical-align: middle;\n    font-size: 13px;\n    font-family: \"Helvetica Neue\";\n    color: #767676;\n}\n\n\n.jp-NBToolbar-item.jp-NBToolbar-button,\n.jp-NBToolbar-item.jp-NBToolbar-kernelIndicator {\n    font-family: FontAwesome;\n    padding-top: 5px;\n    padding-bottom: 6px;\n    color: #616161;\n    text-align: center;\n    display: inline-block;\n}\n\n\n.jp-NBToolbar-item.jp-NBToolbar-cellWrapper {\n    border-left: 1px solid #E0E0E0;\n    border-right: 1px solid #E0E0E0;\n    flex-basis: 100px;\n    padding-top: 3px;\n    padding-bottom: 3px;\n}\n\n\n.jp-NBToolbar-cellType.jp-NBToolbar-item {\n    font-size: 13px;\n    font-family: \"Helvetica Neue\";\n    color: #767676;\n}\n\n\n.jp-NBToolbar-cellWrapper .jp-NBToolbar-cellType {\n    border: none;\n    border-radius: 0;\n    outline: none;\n    width: 100%;\n}\n\n\n.jp-NBToolbar-item.jp-NBToolbar-kernelIndicator {\n  border-right: none;\n}\n\n\n.jp-NBToolbar-button.jp-mod-pressed {\n    background-color: #E0E0E0;\n    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5);\n}\n\n\n.jp-NBToolbar-button:hover {\n    background-color: #EEEEEE;\n    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5);\n}\n\n\n.jp-NBToolbar-item.jp-NBToolbar-kernelName {\n    text-align: right;\n    color: #767676;\n    flex-grow: 1;\n    flex-shrink: 1;\n    padding-top: 4px;\n    padding-bottom: 4px;\n}\n\n\n.jp-NBToolbar-button.jp-NBToolbar-save::before {\n   content: \"\\F0C7\";  /* Save */\n}\n\n\n.jp-NBToolbar-button.jp-NBToolbar-insert::before {\n   content: \"\\F067\";  /* Plus */\n}\n\n\n.jp-NBToolbar-button.jp-NBToolbar-cut::before {\n   content: \"\\F0C4\";  /* Cut */\n}\n\n\n.jp-NBToolbar-button.jp-NBToolbar-copy::before {\n   content: \"\\F0C5\";  /* Copy */\n}\n\n\n.jp-NBToolbar-button.jp-NBToolbar-paste::before {\n   content: \"\\F0EA\";  /* Paste */\n}\n\n\n.jp-NBToolbar-button.jp-NBToolbar-run::before {\n   content: \"\\F051\";  /* Step-forward */\n}\n\n\n.jp-NBToolbar-button.jp-NBToolbar-interrupt::before {\n   content: \"\\F04D\";  /* Stop */\n}\n\n\n.jp-NBToolbar-button.jp-NBToolbar-restart::before {\n   content: \"\\F01E\";  /* Rotate-right */\n}\n\n\n.jp-NBToolbar-item.jp-NBToolbar-kernelIndicator::before {\n    content: \"\\F10C\";  /* Circle-o */\n}\n\n\n.jp-NBToolbar-item.jp-NBToolbar-kernelIndicator.jp-mod-busy::before {\n    content: \"\\F111\";  /* Circle */\n}\n\n\n.jp-CellEditor > .CodeMirror {\n  line-height: 1.21429em;\n  /* Changed from 1em to our global default */\n  font-size: 14px;\n  height: auto;\n  /* Changed to auto to autogrow */\n  background: none;\n  /* Changed from white to allow our bg to show through */\n}\n\n\n.jp-CellEditor > .CodeMirror-scroll {\n  /*  The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/\n  /*  We have found that if it is visible, vertical scrollbars appear with font size changes.*/\n  overflow-y: hidden;\n  overflow-x: auto;\n}\n\n\n.jp-CellEditor > .CodeMirror-lines {\n  /* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */\n  /* we have set a different line-height and want this to scale with that. */\n  padding: 0.4em;\n}\n\n\n.jp-CellEditor > .CodeMirror-linenumber {\n  padding: 0 8px 0 4px;\n}\n\n\n.jp-CellEditor > .CodeMirror-gutters {\n  border-bottom-left-radius: 2px;\n  border-top-left-radius: 2px;\n}\n\n\n.jp-CellEditor > .CodeMirror pre {\n  /* In CM3 this went to 4px from 0 in CM2. We need the 0 value because of how we size */\n  /* .CodeMirror-lines */\n  padding: 0;\n  border: 0;\n  border-radius: 0;\n}\n\n\n.jp-Console {\n  height: 100%;\n}\n\n\n.jp-Console .jp-Cell {\n  padding-top: 0;\n  padding-bottom: 0;\n}\n\n\n.jp-Console .jp-InputArea-editor.jp-CellEditor {\n  background: transparent;\n  border-color: transparent;\n}\n\n\n.jp-Console .jp-InputArea-prompt {\n  flex-basis: auto;\n  text-align: left;\n}\n\n\n.jp-Console .jp-OutputArea-output.jp-OutputArea-executeResult > .jp-OutputArea-prompt {\n  flex-basis: auto;\n  text-align: left;\n}\n\n\n.jp-Console .jp-OutputArea pre {\n  border: none;\n  line-height: 25px;\n  margin: 0;\n}\n\n\n.jp-Console .jp-Console-banner .jp-InputArea-prompt {\n  display: none;\n}\n\n\n.jp-ConsoleTooltip {\n  position: absolute;\n  background: #FFFFCA;\n  border: 1px solid #000000;\n  z-index: 10001;\n}\n\n.jp-ConsoleTooltip pre {\n  margin: 0;\n  padding: 2px;\n}\n\n\n/* ansi_up creates classed spans for console foregrounds and backgrounds. */\n.jp-ConsoleTooltip pre .ansi-black-fg { color: #3A3A3A; }\n\n\n.jp-ConsoleTooltip pre .ansi-red-fg { color: #DD948E; }\n\n\n.jp-ConsoleTooltip pre .ansi-green-fg { color: #B6D1AA; }\n\n\n.jp-ConsoleTooltip pre .ansi-yellow-fg { color: #F3D57C; }\n\n\n.jp-ConsoleTooltip pre .ansi-blue-fg { color: #8AA9D5; }\n\n\n.jp-ConsoleTooltip pre .ansi-magenta-fg { color: #CBAFD5; }\n\n\n.jp-ConsoleTooltip pre .ansi-cyan-fg { color: #9AD1D4; }\n\n\n.jp-ConsoleTooltip pre .ansi-white-fg { color: #EFEFEF; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-black-fg { color: #5E5D5E; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-red-fg { color: #E69B94; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-green-fg { color: #D1F0C3; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-yellow-fg { color: #F4D799; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-blue-fg { color: #A6CBFE; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-magenta-fg { color: #E8C8F3; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-cyan-fg { color: #B1F1F6; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-white-fg { color: #FFFFFF; }\n\n\n.jp-ConsoleTooltip pre .ansi-black-bg { background-color: #3B3B3B; }\n\n\n.jp-ConsoleTooltip pre .ansi-red-bg { background-color: #DE958F; }\n\n\n.jp-ConsoleTooltip pre .ansi-green-bg { background-color: #B7D2AB; }\n\n\n.jp-ConsoleTooltip pre .ansi-yellow-bg { background-color: #F4D67D; }\n\n\n.jp-ConsoleTooltip pre .ansi-blue-bg { background-color: #8BAAD6; }\n\n\n.jp-ConsoleTooltip pre .ansi-magenta-bg { background-color: #CCB0D6; }\n\n\n.jp-ConsoleTooltip pre .ansi-cyan-bg { background-color: #9BD2D5; }\n\n\n.jp-ConsoleTooltip pre .ansi-white-bg { background-color: #F0F0F0; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-black-bg { background-color: #5F5E5F; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-red-bg { background-color: #E79C95; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-green-bg { background-color: #D2F1C4; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-yellow-bg { background-color: #F5D89A; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-blue-bg { background-color: #A7CCFF; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-magenta-bg { background-color: #E8C8F3; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-cyan-bg { background-color: #B1F1F6; }\n\n\n.jp-ConsoleTooltip pre .ansi-bright-white-bg { background-color: #FFFFFF; }\n\n\n.jp-Completion {\n  background: #EEEEEE;\n  border: 1px solid #000000;\n  list-style-type: none;\n  margin: 0;\n  overflow: auto;\n  padding: 0;\n  position: absolute;\n  z-index: 10001;\n}\n\n\n.jp-Completion-item {\n  margin: 0;\n  min-width: 150px;\n  padding: 0 2px;\n}\n\n\n.jp-Completion-item:nth-child(odd) {\n  background: #FFFFFF;\n}\n\n\n.jp-Completion-item.jp-mod-active {\n  background: #BFBFBF;\n}\n\n\n.jp-Completion-item code {\n  font-size: 13px;\n  line-height: 25px;\n}\n\n\n.jp-Completion-item mark {\n  font-weight: bold;\n  text-decoration: underline;\n  background: inherit;\n  color: inherit;\n}\n", ""]);
	
	// exports


/***/ },
/* 82 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	exports.i(__webpack_require__(83), "");
	exports.i(__webpack_require__(84), "");
	exports.i(__webpack_require__(85), "");
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2016, Jupyter Development Team.\n|\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n", ""]);
	
	// exports


/***/ },
/* 83 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2016, Jupyter Development Team.\n|\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n.jp-Dialog {\n  position: absolute;\n  z-index: 10000;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  top: 0px;\n  left: 0px;\n  margin: 0;\n  padding: 0;\n  width: 100%;\n  height: 100%;\n}\n\n\n.jp-Dialog-content {\n  margin-left: auto;\n  margin-right: auto;\n}\n\n\n.jp-Dialog-header {\n\n}\n\n\n.jp-Dialog-footer {\n\n}\n\n\n.jp-Dialog-title {\n  overflow: hidden;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n}\n", ""]);
	
	// exports


/***/ },
/* 84 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) Jupyter Development Team.\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n.jp-FileBrowser {\n  display: flex;\n  flex-direction: column;\n}\n\n\n.jp-BreadCrumbs {\n  flex: 0 0 auto;\n}\n\n\n.jp-FileButtons {\n  flex: 0 0 auto;\n  display: flex;\n  flex-direction: row;\n  justify-content: center;\n}\n\n\n.jp-FileButtons-buttonContent {\n  display: flex;\n  flex-direction: row;\n  align-items: baseline;\n}\n\n\n.jp-FileButtons-buttonIcon {\n  margin-left: auto;\n  margin-right: auto;\n}\n\n\n.jp-DirListing {\n  flex: 1 1 auto;\n  display: flex;\n  flex-direction: column;\n}\n\n\n.jp-DirListing-header {\n  flex: 0 0 auto;\n  display: flex;\n  flex-direction: row;\n  overflow: hidden;\n}\n\n\n.jp-DirListing-content {\n  flex: 1 1 auto;\n  margin: 0;\n  padding: 0;\n  list-style-type: none;\n  overflow: auto;\n}\n\n\n.jp-DirListing-item {\n  display: flex;\n  flex-direction: row;\n}\n", ""]);
	
	// exports


/***/ },
/* 85 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) Jupyter Development Team.\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n.jp-TerminalWidget {\n  padding: 0;\n  margin: 0;\n}\n\n.jp-TerminalWidget-body {\n  font-family: \"DejaVu Sans Mono\", \"Liberation Mono\", monospace;\n}\n", ""]);
	
	// exports


/***/ },
/* 86 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	exports.i(__webpack_require__(87), "");
	exports.i(__webpack_require__(88), "");
	exports.i(__webpack_require__(89), "");
	exports.i(__webpack_require__(90), "");
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2016, Jupyter Development Team.\n|\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n\n\n", ""]);
	
	// exports


/***/ },
/* 87 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2016, Jupyter Development Team.\n|\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n.jp-CodeMirrorWidget {\n  height: 100%;\n}\n\n\n.jp-CodeMirrorWidget > .CodeMirror {\n  line-height: 1.21429em;\n  /* Changed from 1em to our global default */\n  font-size: 14px;\n  height: 100%;\n  /* Changed to auto to autogrow */\n  background: none;\n  /* Changed from white to allow our bg to show through */\n}\n\n\n.jp-CodeMirrorWidget .CodeMirror-scroll {\n  /*  The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/\n  /*  We have found that if it is visible, vertical scrollbars appear with font size changes.*/\n  overflow-y: hidden;\n  overflow-x: auto;\n}\n\n\n.jp-CodeMirrorWidget .CodeMirror-lines {\n  /* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */\n  /* we have set a different line-height and want this to scale with that. */\n  padding: 0.4em;\n}\n\n\n.jp-CodeMirrorWidget .CodeMirror-linenumber {\n  padding: 0 8px 0 4px;\n}\n\n\n.jp-CodeMirrorWidget .CodeMirror-gutters {\n  border-bottom-left-radius: 2px;\n  border-top-left-radius: 2px;\n}\n\n\n.jp-CodeMirrorWidget > .CodeMirror pre {\n  /* In CM3 this went to 4px from 0 in CM2. We need the 0 value because of how we size */\n  /* .CodeMirror-lines */\n  padding: 0;\n  border: 0;\n  border-radius: 0;\n}\n\n\n", ""]);
	
	// exports


/***/ },
/* 88 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2016, Jupyter Development Team.\n|\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n.jp-Dialog {\n  background: rgba(0,0,0,0.25);\n  color: #757575;\n}\n\n\n.jp-Dialog-content {\n  background: #FAFAFA;\n  padding: 24px;\n  width: 300px;\n  box-sizing: border-box;\n  box-shadow: 0px 2px 2px 0px rgba(0,0,0,0.5);\n}\n\n\n.jp-Dialog-header {\n  padding-bottom: 12px;\n  font: 18px Helvetica-Neue Medium, Arial, sans-serif;\n  color: #616161;\n}\n\n\n.jp-Dialog-body {\n  font: 15px Helvetica-Neue Regular, Arial, sans-serif;\n  background: #FAFAFA;\n}\n\n\n.jp-Dialog-bodyContent {\n  font: 15px Helvetica-Neue Regular, Arial, sans-serif;\n  outline: none;\n  margin-bottom: 12px;\n}\n\n\n.jp-Dialog-footer {\n  margin-top: 24px;\n}\n\n\n.jp-Dialog-button {\n  font: 15px Helvetica-Neue Medium, Arial, sans-serif;\n  border: none;\n  min-width: 120px;\n  max-width: 120px;\n  text-transform: uppercase;\n  line-height: 38px;\n  border-radius: 2px;\n  outline: none;\n  padding: 0px;\n}\n\n\n.jp-Dialog-okButton {\n  background: #F27624;\n  color: white;\n}\n\n\n.jp-Dialog-cancelButton {\n  background: #9E9E9E;\n  margin-right: 12px;\n  color: white;\n}\n\n\n.jp-Dialog-inputWrapper {\n  padding: 7px;\n  background: white;\n  width: 252px;\n  box-sizing: border-box;\n  border: 1px solid #BDBDBD;\n  border-radius: 2px;\n  margin-bottom: 12px;\n}\n\n\n.jp-Dialog-input {\n  font: 15px Helvetica-Neue Regular, Arial, sans-serif;\n  color: #676767;\n  width: 100%;\n  outline: none;\n  border: none;\n}\n\n\n.jp-Dialog-selectWrapper {\n  padding-top: 6px;\n  padding-bottom: 6px;\n  background: white;\n  width: 252px;\n  box-sizing: border-box;\n  border: 1px solid #BDBDBD;\n  border-radius: 2px;\n  margin-bottom: 12px;\n}\n\n\n.jp-Dialog-select {\n  font: 15px Helvetica-Neue Regular, Arial, sans-serif;\n  background: white;\n  color: #676767;\n  width: 100%;\n  outline: none;\n  border: none;\n}\n", ""]);
	
	// exports


/***/ },
/* 89 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) Jupyter Development Team.\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n.jp-FileBrowser {\n  min-width: 300px;\n  color: #757575;\n  background: #FAFAFA;\n  font: 13px Helvetica-Neue, Arial, sans-serif;\n}\n\n\n.jp-BreadCrumbs {\n  margin: 8px;\n  margin-bottom: 0px;\n}\n\n\n.jp-BreadCrumbs-item {\n  margin: 0px 4px;\n  cursor: pointer;\n}\n\n\n.jp-BreadCrumbs-item:first-child {\n  margin-left: 0px;\n}\n\n\n.jp-BreadCrumbs-item.jp-mod-dropTarget {\n  background: #FEDBC4;\n}\n\n\n.jp-FileButtons {\n  margin: 8px;\n}\n\n\n.jp-FileButtons-button {\n  flex: 1 1 auto;\n  max-width: 100px;\n  padding: 4px 6px;\n  color: #757575;\n  background: #FFFFFF;\n  border: 1px solid #E0E0E0;\n  font-size: 16px;\n  outline: 0;\n}\n\n\n.jp-FileButtons-button::-moz-focus-inner {\n  border: 0;\n}\n\n\n.jp-FileButtons-button:hover {\n  background: #F5F5F5;\n  border-color: #D0D0D0;\n  z-index: 1; /* raise overlapping border */\n}\n\n\n.jp-FileButtons-button:active,\n.jp-FileButtons-button.jp-id-create.jp-mod-active {\n  background: #EEEEEE;\n  border-color: #BDBDBD;\n  z-index: 1; /* raise overlapping border */\n}\n\n\n.jp-FileButtons-button.jp-id-create {\n  border-top-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n\n\n.jp-FileButtons-button.jp-id-upload {\n  margin-left: -1px; /* overlap borders */\n}\n\n\n.jp-FileButtons-button.jp-id-refresh {\n  margin-left: -1px; /* overlap borders */\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n\n.jp-DirListing {\n  outline: 0;\n}\n\n\n.jp-DirListing-header {\n  margin-bottom: 4px;\n  border-top: 1px solid #E0E0E0;\n  border-bottom: 1px solid #E0E0E0;\n}\n\n\n.jp-DirListing-headerItem {\n  padding: 4px 6px;\n  font-weight: 500;\n}\n\n\n.jp-DirListing-headerItem:hover {\n  background: #EEEEEE;\n  border-radius: 2px;\n}\n\n\n.jp-DirListing-headerItem.jp-id-name {\n  flex: 1 0 84px;\n}\n\n\n.jp-DirListing-headerItem.jp-id-modified {\n  flex: 0 0 112px;\n  border-left: 1px solid #E0E0E0;\n}\n\n\n.jp-DirListing-headerItem.jp-mod-selected {\n  font-weight: 600;\n}\n\n\n.jp-DirListing-headerItem.jp-mod-selected .jp-DirListing-headerItemIcon:before {\n  font-family: FontAwesome;\n  content: \"\\F0D8\";\n  float: right;\n}\n\n\n.jp-DirListing-headerItem.jp-mod-selected.jp-mod-descending .jp-DirListing-headerItemIcon:before {\n  font-family: FontAwesome;\n  content: \"\\F0D7\";\n  float: right;\n}\n\n\n/* increase specificity to override bundled default */\n.jp-DirListing > .jp-DirListing-content {\n  padding: 0px 8px;\n}\n\n\n.jp-DirListing-item {\n  padding: 4px;\n}\n\n\n.jp-DirListing-item.jp-mod-selected {\n  color: white;\n  background: #F27624;\n  border-radius: 2px;\n}\n\n\n.jp-DirListing-item.jp-mod-dropTarget {\n  background: #FEDBC4;\n}\n\n\n.jp-DirListing-item:hover:not(.jp-mod-selected) {\n  background: #EEEEEE;\n}\n\n\n.jp-DirListing-itemIcon {\n  flex: 0 0 20px;\n  font-family: FontAwesome;\n}\n\n\n.jp-DirListing-itemText {\n  flex: 1 0 64px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n\n.jp-DirListing-itemModified {\n  flex: 0 0 108px;\n  text-align: right;\n}\n\n\n.jp-DirListing-editor {\n  flex: 1 0 64px;\n}\n\n\n/** TODO\n.jp-DirListing-item.jp-mod-selected.jp-mod-cut {\n  background: #F1C40F;\n  color: #F5F5F5;\n}\n**/\n\n\n.jp-DirListing-item.jp-type-folder .jp-DirListing-itemIcon:before {\n  content: \"\\F114\";\n}\n\n\n.jp-DirListing-item.jp-type-file .jp-DirListing-itemIcon:before {\n  content: \"\\F016\";\n}\n\n\n.jp-DirListing-item.jp-type-notebook .jp-DirListing-itemIcon:before {\n  content: \"\\F02D\";\n}\n\n\n.jp-DirListing-item.jp-mod-running .jp-DirListing-itemIcon {\n  color: #27AE60;\n}\n", ""]);
	
	// exports


/***/ },
/* 90 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	exports.i(__webpack_require__(91), "");
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) Jupyter Development Team.\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n.jp-TerminalWidget {\n  min-width: 200px;\n  min-height: 200px;\n  padding: 8px;\n}\n\n\n.jp-TerminalWidget-body {\n  outline: none;\n  user-select: text;\n  -webkit-user-select: text;\n}\n\n", ""]);
	
	// exports


/***/ },
/* 91 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/**\n * xterm.js: xterm, in the browser\n * Copyright (c) 2014, sourceLair Limited (www.sourcelair.com (MIT License)\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * https://github.com/chjj/term.js\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n * Originally forked from (with the author's permission):\n *   Fabrice Bellard's javascript vt100 for jslinux:\n *   http://bellard.org/jslinux/\n *   Copyright (c) 2011 Fabrice Bellard\n *   The original design remains. The terminal itself\n *   has been extended to include xterm CSI codes, among\n *   other features.\n */\n\n/*\n *  Default style for xterm.js\n */\n\n.terminal {\n    background-color: #000;\n    color: #fff;\n    font-family: courier-new, courier, monospace;\n    position: relative;\n}\n\n.terminal:focus {\n    outline: none;\n}\n\n.terminal .terminal-cursor {\n    background-color: #fff;\n    color: #000;\n}\n\n.terminal .xterm-helpers {\n    position: absolute;\n    top: 0;\n}\n\n.terminal .xterm-helper-textarea {\n    /*\n     * HACK: to fix IE's blinking cursor\n     * Move textarea out of the screen to the far left, so that the cursor is not visible.\n     */\n    text-indent: -9999em;\n    opacity: 0;\n    width: 0;\n    height: 0;\n    z-index: -10;\n}\n\n/*\n *  Determine default colors for xterm.js\n */\n.terminal .xterm-bold {\n    font-weight: bold;\n}\n\n.terminal .xterm-underline {\n    text-decoration: underline;\n}\n\n.terminal .xterm-blink {\n    text-decoration: blink;\n}\n\n.terminal .xterm-hidden {\n    visibility: hidden;\n}\n\n.terminal .xterm-color-0 {\n    color: #2e3436;\n}\n\n.terminal .xterm-bg-color-0 {\n    background-color: #2e3436;\n}\n\n.terminal .xterm-color-1 {\n    color: #cc0000;\n}\n\n.terminal .xterm-bg-color-1 {\n    background-color: #cc0000;\n}\n\n.terminal .xterm-color-2 {\n    color: #4e9a06;\n}\n\n.terminal .xterm-bg-color-2 {\n    background-color: #4e9a06;\n}\n\n.terminal .xterm-color-3 {\n    color: #c4a000;\n}\n\n.terminal .xterm-bg-color-3 {\n    background-color: #c4a000;\n}\n\n.terminal .xterm-color-4 {\n    color: #3465a4;\n}\n\n.terminal .xterm-bg-color-4 {\n    background-color: #3465a4;\n}\n\n.terminal .xterm-color-5 {\n    color: #75507b;\n}\n\n.terminal .xterm-bg-color-5 {\n    background-color: #75507b;\n}\n\n.terminal .xterm-color-6 {\n    color: #06989a;\n}\n\n.terminal .xterm-bg-color-6 {\n    background-color: #06989a;\n}\n\n.terminal .xterm-color-7 {\n    color: #d3d7cf;\n}\n\n.terminal .xterm-bg-color-7 {\n    background-color: #d3d7cf;\n}\n\n.terminal .xterm-color-8 {\n    color: #555753;\n}\n\n.terminal .xterm-bg-color-8 {\n    background-color: #555753;\n}\n\n.terminal .xterm-color-9 {\n    color: #ef2929;\n}\n\n.terminal .xterm-bg-color-9 {\n    background-color: #ef2929;\n}\n\n.terminal .xterm-color-10 {\n    color: #8ae234;\n}\n\n.terminal .xterm-bg-color-10 {\n    background-color: #8ae234;\n}\n\n.terminal .xterm-color-11 {\n    color: #fce94f;\n}\n\n.terminal .xterm-bg-color-11 {\n    background-color: #fce94f;\n}\n\n.terminal .xterm-color-12 {\n    color: #729fcf;\n}\n\n.terminal .xterm-bg-color-12 {\n    background-color: #729fcf;\n}\n\n.terminal .xterm-color-13 {\n    color: #ad7fa8;\n}\n\n.terminal .xterm-bg-color-13 {\n    background-color: #ad7fa8;\n}\n\n.terminal .xterm-color-14 {\n    color: #34e2e2;\n}\n\n.terminal .xterm-bg-color-14 {\n    background-color: #34e2e2;\n}\n\n.terminal .xterm-color-15 {\n    color: #eeeeec;\n}\n\n.terminal .xterm-bg-color-15 {\n    background-color: #eeeeec;\n}\n\n.terminal .xterm-color-16 {\n    color: #000000;\n}\n\n.terminal .xterm-bg-color-16 {\n    background-color: #000000;\n}\n\n.terminal .xterm-color-17 {\n    color: #00005f;\n}\n\n.terminal .xterm-bg-color-17 {\n    background-color: #00005f;\n}\n\n.terminal .xterm-color-18 {\n    color: #000087;\n}\n\n.terminal .xterm-bg-color-18 {\n    background-color: #000087;\n}\n\n.terminal .xterm-color-19 {\n    color: #0000af;\n}\n\n.terminal .xterm-bg-color-19 {\n    background-color: #0000af;\n}\n\n.terminal .xterm-color-20 {\n    color: #0000d7;\n}\n\n.terminal .xterm-bg-color-20 {\n    background-color: #0000d7;\n}\n\n.terminal .xterm-color-21 {\n    color: #0000ff;\n}\n\n.terminal .xterm-bg-color-21 {\n    background-color: #0000ff;\n}\n\n.terminal .xterm-color-22 {\n    color: #005f00;\n}\n\n.terminal .xterm-bg-color-22 {\n    background-color: #005f00;\n}\n\n.terminal .xterm-color-23 {\n    color: #005f5f;\n}\n\n.terminal .xterm-bg-color-23 {\n    background-color: #005f5f;\n}\n\n.terminal .xterm-color-24 {\n    color: #005f87;\n}\n\n.terminal .xterm-bg-color-24 {\n    background-color: #005f87;\n}\n\n.terminal .xterm-color-25 {\n    color: #005faf;\n}\n\n.terminal .xterm-bg-color-25 {\n    background-color: #005faf;\n}\n\n.terminal .xterm-color-26 {\n    color: #005fd7;\n}\n\n.terminal .xterm-bg-color-26 {\n    background-color: #005fd7;\n}\n\n.terminal .xterm-color-27 {\n    color: #005fff;\n}\n\n.terminal .xterm-bg-color-27 {\n    background-color: #005fff;\n}\n\n.terminal .xterm-color-28 {\n    color: #008700;\n}\n\n.terminal .xterm-bg-color-28 {\n    background-color: #008700;\n}\n\n.terminal .xterm-color-29 {\n    color: #00875f;\n}\n\n.terminal .xterm-bg-color-29 {\n    background-color: #00875f;\n}\n\n.terminal .xterm-color-30 {\n    color: #008787;\n}\n\n.terminal .xterm-bg-color-30 {\n    background-color: #008787;\n}\n\n.terminal .xterm-color-31 {\n    color: #0087af;\n}\n\n.terminal .xterm-bg-color-31 {\n    background-color: #0087af;\n}\n\n.terminal .xterm-color-32 {\n    color: #0087d7;\n}\n\n.terminal .xterm-bg-color-32 {\n    background-color: #0087d7;\n}\n\n.terminal .xterm-color-33 {\n    color: #0087ff;\n}\n\n.terminal .xterm-bg-color-33 {\n    background-color: #0087ff;\n}\n\n.terminal .xterm-color-34 {\n    color: #00af00;\n}\n\n.terminal .xterm-bg-color-34 {\n    background-color: #00af00;\n}\n\n.terminal .xterm-color-35 {\n    color: #00af5f;\n}\n\n.terminal .xterm-bg-color-35 {\n    background-color: #00af5f;\n}\n\n.terminal .xterm-color-36 {\n    color: #00af87;\n}\n\n.terminal .xterm-bg-color-36 {\n    background-color: #00af87;\n}\n\n.terminal .xterm-color-37 {\n    color: #00afaf;\n}\n\n.terminal .xterm-bg-color-37 {\n    background-color: #00afaf;\n}\n\n.terminal .xterm-color-38 {\n    color: #00afd7;\n}\n\n.terminal .xterm-bg-color-38 {\n    background-color: #00afd7;\n}\n\n.terminal .xterm-color-39 {\n    color: #00afff;\n}\n\n.terminal .xterm-bg-color-39 {\n    background-color: #00afff;\n}\n\n.terminal .xterm-color-40 {\n    color: #00d700;\n}\n\n.terminal .xterm-bg-color-40 {\n    background-color: #00d700;\n}\n\n.terminal .xterm-color-41 {\n    color: #00d75f;\n}\n\n.terminal .xterm-bg-color-41 {\n    background-color: #00d75f;\n}\n\n.terminal .xterm-color-42 {\n    color: #00d787;\n}\n\n.terminal .xterm-bg-color-42 {\n    background-color: #00d787;\n}\n\n.terminal .xterm-color-43 {\n    color: #00d7af;\n}\n\n.terminal .xterm-bg-color-43 {\n    background-color: #00d7af;\n}\n\n.terminal .xterm-color-44 {\n    color: #00d7d7;\n}\n\n.terminal .xterm-bg-color-44 {\n    background-color: #00d7d7;\n}\n\n.terminal .xterm-color-45 {\n    color: #00d7ff;\n}\n\n.terminal .xterm-bg-color-45 {\n    background-color: #00d7ff;\n}\n\n.terminal .xterm-color-46 {\n    color: #00ff00;\n}\n\n.terminal .xterm-bg-color-46 {\n    background-color: #00ff00;\n}\n\n.terminal .xterm-color-47 {\n    color: #00ff5f;\n}\n\n.terminal .xterm-bg-color-47 {\n    background-color: #00ff5f;\n}\n\n.terminal .xterm-color-48 {\n    color: #00ff87;\n}\n\n.terminal .xterm-bg-color-48 {\n    background-color: #00ff87;\n}\n\n.terminal .xterm-color-49 {\n    color: #00ffaf;\n}\n\n.terminal .xterm-bg-color-49 {\n    background-color: #00ffaf;\n}\n\n.terminal .xterm-color-50 {\n    color: #00ffd7;\n}\n\n.terminal .xterm-bg-color-50 {\n    background-color: #00ffd7;\n}\n\n.terminal .xterm-color-51 {\n    color: #00ffff;\n}\n\n.terminal .xterm-bg-color-51 {\n    background-color: #00ffff;\n}\n\n.terminal .xterm-color-52 {\n    color: #5f0000;\n}\n\n.terminal .xterm-bg-color-52 {\n    background-color: #5f0000;\n}\n\n.terminal .xterm-color-53 {\n    color: #5f005f;\n}\n\n.terminal .xterm-bg-color-53 {\n    background-color: #5f005f;\n}\n\n.terminal .xterm-color-54 {\n    color: #5f0087;\n}\n\n.terminal .xterm-bg-color-54 {\n    background-color: #5f0087;\n}\n\n.terminal .xterm-color-55 {\n    color: #5f00af;\n}\n\n.terminal .xterm-bg-color-55 {\n    background-color: #5f00af;\n}\n\n.terminal .xterm-color-56 {\n    color: #5f00d7;\n}\n\n.terminal .xterm-bg-color-56 {\n    background-color: #5f00d7;\n}\n\n.terminal .xterm-color-57 {\n    color: #5f00ff;\n}\n\n.terminal .xterm-bg-color-57 {\n    background-color: #5f00ff;\n}\n\n.terminal .xterm-color-58 {\n    color: #5f5f00;\n}\n\n.terminal .xterm-bg-color-58 {\n    background-color: #5f5f00;\n}\n\n.terminal .xterm-color-59 {\n    color: #5f5f5f;\n}\n\n.terminal .xterm-bg-color-59 {\n    background-color: #5f5f5f;\n}\n\n.terminal .xterm-color-60 {\n    color: #5f5f87;\n}\n\n.terminal .xterm-bg-color-60 {\n    background-color: #5f5f87;\n}\n\n.terminal .xterm-color-61 {\n    color: #5f5faf;\n}\n\n.terminal .xterm-bg-color-61 {\n    background-color: #5f5faf;\n}\n\n.terminal .xterm-color-62 {\n    color: #5f5fd7;\n}\n\n.terminal .xterm-bg-color-62 {\n    background-color: #5f5fd7;\n}\n\n.terminal .xterm-color-63 {\n    color: #5f5fff;\n}\n\n.terminal .xterm-bg-color-63 {\n    background-color: #5f5fff;\n}\n\n.terminal .xterm-color-64 {\n    color: #5f8700;\n}\n\n.terminal .xterm-bg-color-64 {\n    background-color: #5f8700;\n}\n\n.terminal .xterm-color-65 {\n    color: #5f875f;\n}\n\n.terminal .xterm-bg-color-65 {\n    background-color: #5f875f;\n}\n\n.terminal .xterm-color-66 {\n    color: #5f8787;\n}\n\n.terminal .xterm-bg-color-66 {\n    background-color: #5f8787;\n}\n\n.terminal .xterm-color-67 {\n    color: #5f87af;\n}\n\n.terminal .xterm-bg-color-67 {\n    background-color: #5f87af;\n}\n\n.terminal .xterm-color-68 {\n    color: #5f87d7;\n}\n\n.terminal .xterm-bg-color-68 {\n    background-color: #5f87d7;\n}\n\n.terminal .xterm-color-69 {\n    color: #5f87ff;\n}\n\n.terminal .xterm-bg-color-69 {\n    background-color: #5f87ff;\n}\n\n.terminal .xterm-color-70 {\n    color: #5faf00;\n}\n\n.terminal .xterm-bg-color-70 {\n    background-color: #5faf00;\n}\n\n.terminal .xterm-color-71 {\n    color: #5faf5f;\n}\n\n.terminal .xterm-bg-color-71 {\n    background-color: #5faf5f;\n}\n\n.terminal .xterm-color-72 {\n    color: #5faf87;\n}\n\n.terminal .xterm-bg-color-72 {\n    background-color: #5faf87;\n}\n\n.terminal .xterm-color-73 {\n    color: #5fafaf;\n}\n\n.terminal .xterm-bg-color-73 {\n    background-color: #5fafaf;\n}\n\n.terminal .xterm-color-74 {\n    color: #5fafd7;\n}\n\n.terminal .xterm-bg-color-74 {\n    background-color: #5fafd7;\n}\n\n.terminal .xterm-color-75 {\n    color: #5fafff;\n}\n\n.terminal .xterm-bg-color-75 {\n    background-color: #5fafff;\n}\n\n.terminal .xterm-color-76 {\n    color: #5fd700;\n}\n\n.terminal .xterm-bg-color-76 {\n    background-color: #5fd700;\n}\n\n.terminal .xterm-color-77 {\n    color: #5fd75f;\n}\n\n.terminal .xterm-bg-color-77 {\n    background-color: #5fd75f;\n}\n\n.terminal .xterm-color-78 {\n    color: #5fd787;\n}\n\n.terminal .xterm-bg-color-78 {\n    background-color: #5fd787;\n}\n\n.terminal .xterm-color-79 {\n    color: #5fd7af;\n}\n\n.terminal .xterm-bg-color-79 {\n    background-color: #5fd7af;\n}\n\n.terminal .xterm-color-80 {\n    color: #5fd7d7;\n}\n\n.terminal .xterm-bg-color-80 {\n    background-color: #5fd7d7;\n}\n\n.terminal .xterm-color-81 {\n    color: #5fd7ff;\n}\n\n.terminal .xterm-bg-color-81 {\n    background-color: #5fd7ff;\n}\n\n.terminal .xterm-color-82 {\n    color: #5fff00;\n}\n\n.terminal .xterm-bg-color-82 {\n    background-color: #5fff00;\n}\n\n.terminal .xterm-color-83 {\n    color: #5fff5f;\n}\n\n.terminal .xterm-bg-color-83 {\n    background-color: #5fff5f;\n}\n\n.terminal .xterm-color-84 {\n    color: #5fff87;\n}\n\n.terminal .xterm-bg-color-84 {\n    background-color: #5fff87;\n}\n\n.terminal .xterm-color-85 {\n    color: #5fffaf;\n}\n\n.terminal .xterm-bg-color-85 {\n    background-color: #5fffaf;\n}\n\n.terminal .xterm-color-86 {\n    color: #5fffd7;\n}\n\n.terminal .xterm-bg-color-86 {\n    background-color: #5fffd7;\n}\n\n.terminal .xterm-color-87 {\n    color: #5fffff;\n}\n\n.terminal .xterm-bg-color-87 {\n    background-color: #5fffff;\n}\n\n.terminal .xterm-color-88 {\n    color: #870000;\n}\n\n.terminal .xterm-bg-color-88 {\n    background-color: #870000;\n}\n\n.terminal .xterm-color-89 {\n    color: #87005f;\n}\n\n.terminal .xterm-bg-color-89 {\n    background-color: #87005f;\n}\n\n.terminal .xterm-color-90 {\n    color: #870087;\n}\n\n.terminal .xterm-bg-color-90 {\n    background-color: #870087;\n}\n\n.terminal .xterm-color-91 {\n    color: #8700af;\n}\n\n.terminal .xterm-bg-color-91 {\n    background-color: #8700af;\n}\n\n.terminal .xterm-color-92 {\n    color: #8700d7;\n}\n\n.terminal .xterm-bg-color-92 {\n    background-color: #8700d7;\n}\n\n.terminal .xterm-color-93 {\n    color: #8700ff;\n}\n\n.terminal .xterm-bg-color-93 {\n    background-color: #8700ff;\n}\n\n.terminal .xterm-color-94 {\n    color: #875f00;\n}\n\n.terminal .xterm-bg-color-94 {\n    background-color: #875f00;\n}\n\n.terminal .xterm-color-95 {\n    color: #875f5f;\n}\n\n.terminal .xterm-bg-color-95 {\n    background-color: #875f5f;\n}\n\n.terminal .xterm-color-96 {\n    color: #875f87;\n}\n\n.terminal .xterm-bg-color-96 {\n    background-color: #875f87;\n}\n\n.terminal .xterm-color-97 {\n    color: #875faf;\n}\n\n.terminal .xterm-bg-color-97 {\n    background-color: #875faf;\n}\n\n.terminal .xterm-color-98 {\n    color: #875fd7;\n}\n\n.terminal .xterm-bg-color-98 {\n    background-color: #875fd7;\n}\n\n.terminal .xterm-color-99 {\n    color: #875fff;\n}\n\n.terminal .xterm-bg-color-99 {\n    background-color: #875fff;\n}\n\n.terminal .xterm-color-100 {\n    color: #878700;\n}\n\n.terminal .xterm-bg-color-100 {\n    background-color: #878700;\n}\n\n.terminal .xterm-color-101 {\n    color: #87875f;\n}\n\n.terminal .xterm-bg-color-101 {\n    background-color: #87875f;\n}\n\n.terminal .xterm-color-102 {\n    color: #878787;\n}\n\n.terminal .xterm-bg-color-102 {\n    background-color: #878787;\n}\n\n.terminal .xterm-color-103 {\n    color: #8787af;\n}\n\n.terminal .xterm-bg-color-103 {\n    background-color: #8787af;\n}\n\n.terminal .xterm-color-104 {\n    color: #8787d7;\n}\n\n.terminal .xterm-bg-color-104 {\n    background-color: #8787d7;\n}\n\n.terminal .xterm-color-105 {\n    color: #8787ff;\n}\n\n.terminal .xterm-bg-color-105 {\n    background-color: #8787ff;\n}\n\n.terminal .xterm-color-106 {\n    color: #87af00;\n}\n\n.terminal .xterm-bg-color-106 {\n    background-color: #87af00;\n}\n\n.terminal .xterm-color-107 {\n    color: #87af5f;\n}\n\n.terminal .xterm-bg-color-107 {\n    background-color: #87af5f;\n}\n\n.terminal .xterm-color-108 {\n    color: #87af87;\n}\n\n.terminal .xterm-bg-color-108 {\n    background-color: #87af87;\n}\n\n.terminal .xterm-color-109 {\n    color: #87afaf;\n}\n\n.terminal .xterm-bg-color-109 {\n    background-color: #87afaf;\n}\n\n.terminal .xterm-color-110 {\n    color: #87afd7;\n}\n\n.terminal .xterm-bg-color-110 {\n    background-color: #87afd7;\n}\n\n.terminal .xterm-color-111 {\n    color: #87afff;\n}\n\n.terminal .xterm-bg-color-111 {\n    background-color: #87afff;\n}\n\n.terminal .xterm-color-112 {\n    color: #87d700;\n}\n\n.terminal .xterm-bg-color-112 {\n    background-color: #87d700;\n}\n\n.terminal .xterm-color-113 {\n    color: #87d75f;\n}\n\n.terminal .xterm-bg-color-113 {\n    background-color: #87d75f;\n}\n\n.terminal .xterm-color-114 {\n    color: #87d787;\n}\n\n.terminal .xterm-bg-color-114 {\n    background-color: #87d787;\n}\n\n.terminal .xterm-color-115 {\n    color: #87d7af;\n}\n\n.terminal .xterm-bg-color-115 {\n    background-color: #87d7af;\n}\n\n.terminal .xterm-color-116 {\n    color: #87d7d7;\n}\n\n.terminal .xterm-bg-color-116 {\n    background-color: #87d7d7;\n}\n\n.terminal .xterm-color-117 {\n    color: #87d7ff;\n}\n\n.terminal .xterm-bg-color-117 {\n    background-color: #87d7ff;\n}\n\n.terminal .xterm-color-118 {\n    color: #87ff00;\n}\n\n.terminal .xterm-bg-color-118 {\n    background-color: #87ff00;\n}\n\n.terminal .xterm-color-119 {\n    color: #87ff5f;\n}\n\n.terminal .xterm-bg-color-119 {\n    background-color: #87ff5f;\n}\n\n.terminal .xterm-color-120 {\n    color: #87ff87;\n}\n\n.terminal .xterm-bg-color-120 {\n    background-color: #87ff87;\n}\n\n.terminal .xterm-color-121 {\n    color: #87ffaf;\n}\n\n.terminal .xterm-bg-color-121 {\n    background-color: #87ffaf;\n}\n\n.terminal .xterm-color-122 {\n    color: #87ffd7;\n}\n\n.terminal .xterm-bg-color-122 {\n    background-color: #87ffd7;\n}\n\n.terminal .xterm-color-123 {\n    color: #87ffff;\n}\n\n.terminal .xterm-bg-color-123 {\n    background-color: #87ffff;\n}\n\n.terminal .xterm-color-124 {\n    color: #af0000;\n}\n\n.terminal .xterm-bg-color-124 {\n    background-color: #af0000;\n}\n\n.terminal .xterm-color-125 {\n    color: #af005f;\n}\n\n.terminal .xterm-bg-color-125 {\n    background-color: #af005f;\n}\n\n.terminal .xterm-color-126 {\n    color: #af0087;\n}\n\n.terminal .xterm-bg-color-126 {\n    background-color: #af0087;\n}\n\n.terminal .xterm-color-127 {\n    color: #af00af;\n}\n\n.terminal .xterm-bg-color-127 {\n    background-color: #af00af;\n}\n\n.terminal .xterm-color-128 {\n    color: #af00d7;\n}\n\n.terminal .xterm-bg-color-128 {\n    background-color: #af00d7;\n}\n\n.terminal .xterm-color-129 {\n    color: #af00ff;\n}\n\n.terminal .xterm-bg-color-129 {\n    background-color: #af00ff;\n}\n\n.terminal .xterm-color-130 {\n    color: #af5f00;\n}\n\n.terminal .xterm-bg-color-130 {\n    background-color: #af5f00;\n}\n\n.terminal .xterm-color-131 {\n    color: #af5f5f;\n}\n\n.terminal .xterm-bg-color-131 {\n    background-color: #af5f5f;\n}\n\n.terminal .xterm-color-132 {\n    color: #af5f87;\n}\n\n.terminal .xterm-bg-color-132 {\n    background-color: #af5f87;\n}\n\n.terminal .xterm-color-133 {\n    color: #af5faf;\n}\n\n.terminal .xterm-bg-color-133 {\n    background-color: #af5faf;\n}\n\n.terminal .xterm-color-134 {\n    color: #af5fd7;\n}\n\n.terminal .xterm-bg-color-134 {\n    background-color: #af5fd7;\n}\n\n.terminal .xterm-color-135 {\n    color: #af5fff;\n}\n\n.terminal .xterm-bg-color-135 {\n    background-color: #af5fff;\n}\n\n.terminal .xterm-color-136 {\n    color: #af8700;\n}\n\n.terminal .xterm-bg-color-136 {\n    background-color: #af8700;\n}\n\n.terminal .xterm-color-137 {\n    color: #af875f;\n}\n\n.terminal .xterm-bg-color-137 {\n    background-color: #af875f;\n}\n\n.terminal .xterm-color-138 {\n    color: #af8787;\n}\n\n.terminal .xterm-bg-color-138 {\n    background-color: #af8787;\n}\n\n.terminal .xterm-color-139 {\n    color: #af87af;\n}\n\n.terminal .xterm-bg-color-139 {\n    background-color: #af87af;\n}\n\n.terminal .xterm-color-140 {\n    color: #af87d7;\n}\n\n.terminal .xterm-bg-color-140 {\n    background-color: #af87d7;\n}\n\n.terminal .xterm-color-141 {\n    color: #af87ff;\n}\n\n.terminal .xterm-bg-color-141 {\n    background-color: #af87ff;\n}\n\n.terminal .xterm-color-142 {\n    color: #afaf00;\n}\n\n.terminal .xterm-bg-color-142 {\n    background-color: #afaf00;\n}\n\n.terminal .xterm-color-143 {\n    color: #afaf5f;\n}\n\n.terminal .xterm-bg-color-143 {\n    background-color: #afaf5f;\n}\n\n.terminal .xterm-color-144 {\n    color: #afaf87;\n}\n\n.terminal .xterm-bg-color-144 {\n    background-color: #afaf87;\n}\n\n.terminal .xterm-color-145 {\n    color: #afafaf;\n}\n\n.terminal .xterm-bg-color-145 {\n    background-color: #afafaf;\n}\n\n.terminal .xterm-color-146 {\n    color: #afafd7;\n}\n\n.terminal .xterm-bg-color-146 {\n    background-color: #afafd7;\n}\n\n.terminal .xterm-color-147 {\n    color: #afafff;\n}\n\n.terminal .xterm-bg-color-147 {\n    background-color: #afafff;\n}\n\n.terminal .xterm-color-148 {\n    color: #afd700;\n}\n\n.terminal .xterm-bg-color-148 {\n    background-color: #afd700;\n}\n\n.terminal .xterm-color-149 {\n    color: #afd75f;\n}\n\n.terminal .xterm-bg-color-149 {\n    background-color: #afd75f;\n}\n\n.terminal .xterm-color-150 {\n    color: #afd787;\n}\n\n.terminal .xterm-bg-color-150 {\n    background-color: #afd787;\n}\n\n.terminal .xterm-color-151 {\n    color: #afd7af;\n}\n\n.terminal .xterm-bg-color-151 {\n    background-color: #afd7af;\n}\n\n.terminal .xterm-color-152 {\n    color: #afd7d7;\n}\n\n.terminal .xterm-bg-color-152 {\n    background-color: #afd7d7;\n}\n\n.terminal .xterm-color-153 {\n    color: #afd7ff;\n}\n\n.terminal .xterm-bg-color-153 {\n    background-color: #afd7ff;\n}\n\n.terminal .xterm-color-154 {\n    color: #afff00;\n}\n\n.terminal .xterm-bg-color-154 {\n    background-color: #afff00;\n}\n\n.terminal .xterm-color-155 {\n    color: #afff5f;\n}\n\n.terminal .xterm-bg-color-155 {\n    background-color: #afff5f;\n}\n\n.terminal .xterm-color-156 {\n    color: #afff87;\n}\n\n.terminal .xterm-bg-color-156 {\n    background-color: #afff87;\n}\n\n.terminal .xterm-color-157 {\n    color: #afffaf;\n}\n\n.terminal .xterm-bg-color-157 {\n    background-color: #afffaf;\n}\n\n.terminal .xterm-color-158 {\n    color: #afffd7;\n}\n\n.terminal .xterm-bg-color-158 {\n    background-color: #afffd7;\n}\n\n.terminal .xterm-color-159 {\n    color: #afffff;\n}\n\n.terminal .xterm-bg-color-159 {\n    background-color: #afffff;\n}\n\n.terminal .xterm-color-160 {\n    color: #d70000;\n}\n\n.terminal .xterm-bg-color-160 {\n    background-color: #d70000;\n}\n\n.terminal .xterm-color-161 {\n    color: #d7005f;\n}\n\n.terminal .xterm-bg-color-161 {\n    background-color: #d7005f;\n}\n\n.terminal .xterm-color-162 {\n    color: #d70087;\n}\n\n.terminal .xterm-bg-color-162 {\n    background-color: #d70087;\n}\n\n.terminal .xterm-color-163 {\n    color: #d700af;\n}\n\n.terminal .xterm-bg-color-163 {\n    background-color: #d700af;\n}\n\n.terminal .xterm-color-164 {\n    color: #d700d7;\n}\n\n.terminal .xterm-bg-color-164 {\n    background-color: #d700d7;\n}\n\n.terminal .xterm-color-165 {\n    color: #d700ff;\n}\n\n.terminal .xterm-bg-color-165 {\n    background-color: #d700ff;\n}\n\n.terminal .xterm-color-166 {\n    color: #d75f00;\n}\n\n.terminal .xterm-bg-color-166 {\n    background-color: #d75f00;\n}\n\n.terminal .xterm-color-167 {\n    color: #d75f5f;\n}\n\n.terminal .xterm-bg-color-167 {\n    background-color: #d75f5f;\n}\n\n.terminal .xterm-color-168 {\n    color: #d75f87;\n}\n\n.terminal .xterm-bg-color-168 {\n    background-color: #d75f87;\n}\n\n.terminal .xterm-color-169 {\n    color: #d75faf;\n}\n\n.terminal .xterm-bg-color-169 {\n    background-color: #d75faf;\n}\n\n.terminal .xterm-color-170 {\n    color: #d75fd7;\n}\n\n.terminal .xterm-bg-color-170 {\n    background-color: #d75fd7;\n}\n\n.terminal .xterm-color-171 {\n    color: #d75fff;\n}\n\n.terminal .xterm-bg-color-171 {\n    background-color: #d75fff;\n}\n\n.terminal .xterm-color-172 {\n    color: #d78700;\n}\n\n.terminal .xterm-bg-color-172 {\n    background-color: #d78700;\n}\n\n.terminal .xterm-color-173 {\n    color: #d7875f;\n}\n\n.terminal .xterm-bg-color-173 {\n    background-color: #d7875f;\n}\n\n.terminal .xterm-color-174 {\n    color: #d78787;\n}\n\n.terminal .xterm-bg-color-174 {\n    background-color: #d78787;\n}\n\n.terminal .xterm-color-175 {\n    color: #d787af;\n}\n\n.terminal .xterm-bg-color-175 {\n    background-color: #d787af;\n}\n\n.terminal .xterm-color-176 {\n    color: #d787d7;\n}\n\n.terminal .xterm-bg-color-176 {\n    background-color: #d787d7;\n}\n\n.terminal .xterm-color-177 {\n    color: #d787ff;\n}\n\n.terminal .xterm-bg-color-177 {\n    background-color: #d787ff;\n}\n\n.terminal .xterm-color-178 {\n    color: #d7af00;\n}\n\n.terminal .xterm-bg-color-178 {\n    background-color: #d7af00;\n}\n\n.terminal .xterm-color-179 {\n    color: #d7af5f;\n}\n\n.terminal .xterm-bg-color-179 {\n    background-color: #d7af5f;\n}\n\n.terminal .xterm-color-180 {\n    color: #d7af87;\n}\n\n.terminal .xterm-bg-color-180 {\n    background-color: #d7af87;\n}\n\n.terminal .xterm-color-181 {\n    color: #d7afaf;\n}\n\n.terminal .xterm-bg-color-181 {\n    background-color: #d7afaf;\n}\n\n.terminal .xterm-color-182 {\n    color: #d7afd7;\n}\n\n.terminal .xterm-bg-color-182 {\n    background-color: #d7afd7;\n}\n\n.terminal .xterm-color-183 {\n    color: #d7afff;\n}\n\n.terminal .xterm-bg-color-183 {\n    background-color: #d7afff;\n}\n\n.terminal .xterm-color-184 {\n    color: #d7d700;\n}\n\n.terminal .xterm-bg-color-184 {\n    background-color: #d7d700;\n}\n\n.terminal .xterm-color-185 {\n    color: #d7d75f;\n}\n\n.terminal .xterm-bg-color-185 {\n    background-color: #d7d75f;\n}\n\n.terminal .xterm-color-186 {\n    color: #d7d787;\n}\n\n.terminal .xterm-bg-color-186 {\n    background-color: #d7d787;\n}\n\n.terminal .xterm-color-187 {\n    color: #d7d7af;\n}\n\n.terminal .xterm-bg-color-187 {\n    background-color: #d7d7af;\n}\n\n.terminal .xterm-color-188 {\n    color: #d7d7d7;\n}\n\n.terminal .xterm-bg-color-188 {\n    background-color: #d7d7d7;\n}\n\n.terminal .xterm-color-189 {\n    color: #d7d7ff;\n}\n\n.terminal .xterm-bg-color-189 {\n    background-color: #d7d7ff;\n}\n\n.terminal .xterm-color-190 {\n    color: #d7ff00;\n}\n\n.terminal .xterm-bg-color-190 {\n    background-color: #d7ff00;\n}\n\n.terminal .xterm-color-191 {\n    color: #d7ff5f;\n}\n\n.terminal .xterm-bg-color-191 {\n    background-color: #d7ff5f;\n}\n\n.terminal .xterm-color-192 {\n    color: #d7ff87;\n}\n\n.terminal .xterm-bg-color-192 {\n    background-color: #d7ff87;\n}\n\n.terminal .xterm-color-193 {\n    color: #d7ffaf;\n}\n\n.terminal .xterm-bg-color-193 {\n    background-color: #d7ffaf;\n}\n\n.terminal .xterm-color-194 {\n    color: #d7ffd7;\n}\n\n.terminal .xterm-bg-color-194 {\n    background-color: #d7ffd7;\n}\n\n.terminal .xterm-color-195 {\n    color: #d7ffff;\n}\n\n.terminal .xterm-bg-color-195 {\n    background-color: #d7ffff;\n}\n\n.terminal .xterm-color-196 {\n    color: #ff0000;\n}\n\n.terminal .xterm-bg-color-196 {\n    background-color: #ff0000;\n}\n\n.terminal .xterm-color-197 {\n    color: #ff005f;\n}\n\n.terminal .xterm-bg-color-197 {\n    background-color: #ff005f;\n}\n\n.terminal .xterm-color-198 {\n    color: #ff0087;\n}\n\n.terminal .xterm-bg-color-198 {\n    background-color: #ff0087;\n}\n\n.terminal .xterm-color-199 {\n    color: #ff00af;\n}\n\n.terminal .xterm-bg-color-199 {\n    background-color: #ff00af;\n}\n\n.terminal .xterm-color-200 {\n    color: #ff00d7;\n}\n\n.terminal .xterm-bg-color-200 {\n    background-color: #ff00d7;\n}\n\n.terminal .xterm-color-201 {\n    color: #ff00ff;\n}\n\n.terminal .xterm-bg-color-201 {\n    background-color: #ff00ff;\n}\n\n.terminal .xterm-color-202 {\n    color: #ff5f00;\n}\n\n.terminal .xterm-bg-color-202 {\n    background-color: #ff5f00;\n}\n\n.terminal .xterm-color-203 {\n    color: #ff5f5f;\n}\n\n.terminal .xterm-bg-color-203 {\n    background-color: #ff5f5f;\n}\n\n.terminal .xterm-color-204 {\n    color: #ff5f87;\n}\n\n.terminal .xterm-bg-color-204 {\n    background-color: #ff5f87;\n}\n\n.terminal .xterm-color-205 {\n    color: #ff5faf;\n}\n\n.terminal .xterm-bg-color-205 {\n    background-color: #ff5faf;\n}\n\n.terminal .xterm-color-206 {\n    color: #ff5fd7;\n}\n\n.terminal .xterm-bg-color-206 {\n    background-color: #ff5fd7;\n}\n\n.terminal .xterm-color-207 {\n    color: #ff5fff;\n}\n\n.terminal .xterm-bg-color-207 {\n    background-color: #ff5fff;\n}\n\n.terminal .xterm-color-208 {\n    color: #ff8700;\n}\n\n.terminal .xterm-bg-color-208 {\n    background-color: #ff8700;\n}\n\n.terminal .xterm-color-209 {\n    color: #ff875f;\n}\n\n.terminal .xterm-bg-color-209 {\n    background-color: #ff875f;\n}\n\n.terminal .xterm-color-210 {\n    color: #ff8787;\n}\n\n.terminal .xterm-bg-color-210 {\n    background-color: #ff8787;\n}\n\n.terminal .xterm-color-211 {\n    color: #ff87af;\n}\n\n.terminal .xterm-bg-color-211 {\n    background-color: #ff87af;\n}\n\n.terminal .xterm-color-212 {\n    color: #ff87d7;\n}\n\n.terminal .xterm-bg-color-212 {\n    background-color: #ff87d7;\n}\n\n.terminal .xterm-color-213 {\n    color: #ff87ff;\n}\n\n.terminal .xterm-bg-color-213 {\n    background-color: #ff87ff;\n}\n\n.terminal .xterm-color-214 {\n    color: #ffaf00;\n}\n\n.terminal .xterm-bg-color-214 {\n    background-color: #ffaf00;\n}\n\n.terminal .xterm-color-215 {\n    color: #ffaf5f;\n}\n\n.terminal .xterm-bg-color-215 {\n    background-color: #ffaf5f;\n}\n\n.terminal .xterm-color-216 {\n    color: #ffaf87;\n}\n\n.terminal .xterm-bg-color-216 {\n    background-color: #ffaf87;\n}\n\n.terminal .xterm-color-217 {\n    color: #ffafaf;\n}\n\n.terminal .xterm-bg-color-217 {\n    background-color: #ffafaf;\n}\n\n.terminal .xterm-color-218 {\n    color: #ffafd7;\n}\n\n.terminal .xterm-bg-color-218 {\n    background-color: #ffafd7;\n}\n\n.terminal .xterm-color-219 {\n    color: #ffafff;\n}\n\n.terminal .xterm-bg-color-219 {\n    background-color: #ffafff;\n}\n\n.terminal .xterm-color-220 {\n    color: #ffd700;\n}\n\n.terminal .xterm-bg-color-220 {\n    background-color: #ffd700;\n}\n\n.terminal .xterm-color-221 {\n    color: #ffd75f;\n}\n\n.terminal .xterm-bg-color-221 {\n    background-color: #ffd75f;\n}\n\n.terminal .xterm-color-222 {\n    color: #ffd787;\n}\n\n.terminal .xterm-bg-color-222 {\n    background-color: #ffd787;\n}\n\n.terminal .xterm-color-223 {\n    color: #ffd7af;\n}\n\n.terminal .xterm-bg-color-223 {\n    background-color: #ffd7af;\n}\n\n.terminal .xterm-color-224 {\n    color: #ffd7d7;\n}\n\n.terminal .xterm-bg-color-224 {\n    background-color: #ffd7d7;\n}\n\n.terminal .xterm-color-225 {\n    color: #ffd7ff;\n}\n\n.terminal .xterm-bg-color-225 {\n    background-color: #ffd7ff;\n}\n\n.terminal .xterm-color-226 {\n    color: #ffff00;\n}\n\n.terminal .xterm-bg-color-226 {\n    background-color: #ffff00;\n}\n\n.terminal .xterm-color-227 {\n    color: #ffff5f;\n}\n\n.terminal .xterm-bg-color-227 {\n    background-color: #ffff5f;\n}\n\n.terminal .xterm-color-228 {\n    color: #ffff87;\n}\n\n.terminal .xterm-bg-color-228 {\n    background-color: #ffff87;\n}\n\n.terminal .xterm-color-229 {\n    color: #ffffaf;\n}\n\n.terminal .xterm-bg-color-229 {\n    background-color: #ffffaf;\n}\n\n.terminal .xterm-color-230 {\n    color: #ffffd7;\n}\n\n.terminal .xterm-bg-color-230 {\n    background-color: #ffffd7;\n}\n\n.terminal .xterm-color-231 {\n    color: #ffffff;\n}\n\n.terminal .xterm-bg-color-231 {\n    background-color: #ffffff;\n}\n\n.terminal .xterm-color-232 {\n    color: #080808;\n}\n\n.terminal .xterm-bg-color-232 {\n    background-color: #080808;\n}\n\n.terminal .xterm-color-233 {\n    color: #121212;\n}\n\n.terminal .xterm-bg-color-233 {\n    background-color: #121212;\n}\n\n.terminal .xterm-color-234 {\n    color: #1c1c1c;\n}\n\n.terminal .xterm-bg-color-234 {\n    background-color: #1c1c1c;\n}\n\n.terminal .xterm-color-235 {\n    color: #262626;\n}\n\n.terminal .xterm-bg-color-235 {\n    background-color: #262626;\n}\n\n.terminal .xterm-color-236 {\n    color: #303030;\n}\n\n.terminal .xterm-bg-color-236 {\n    background-color: #303030;\n}\n\n.terminal .xterm-color-237 {\n    color: #3a3a3a;\n}\n\n.terminal .xterm-bg-color-237 {\n    background-color: #3a3a3a;\n}\n\n.terminal .xterm-color-238 {\n    color: #444444;\n}\n\n.terminal .xterm-bg-color-238 {\n    background-color: #444444;\n}\n\n.terminal .xterm-color-239 {\n    color: #4e4e4e;\n}\n\n.terminal .xterm-bg-color-239 {\n    background-color: #4e4e4e;\n}\n\n.terminal .xterm-color-240 {\n    color: #585858;\n}\n\n.terminal .xterm-bg-color-240 {\n    background-color: #585858;\n}\n\n.terminal .xterm-color-241 {\n    color: #626262;\n}\n\n.terminal .xterm-bg-color-241 {\n    background-color: #626262;\n}\n\n.terminal .xterm-color-242 {\n    color: #6c6c6c;\n}\n\n.terminal .xterm-bg-color-242 {\n    background-color: #6c6c6c;\n}\n\n.terminal .xterm-color-243 {\n    color: #767676;\n}\n\n.terminal .xterm-bg-color-243 {\n    background-color: #767676;\n}\n\n.terminal .xterm-color-244 {\n    color: #808080;\n}\n\n.terminal .xterm-bg-color-244 {\n    background-color: #808080;\n}\n\n.terminal .xterm-color-245 {\n    color: #8a8a8a;\n}\n\n.terminal .xterm-bg-color-245 {\n    background-color: #8a8a8a;\n}\n\n.terminal .xterm-color-246 {\n    color: #949494;\n}\n\n.terminal .xterm-bg-color-246 {\n    background-color: #949494;\n}\n\n.terminal .xterm-color-247 {\n    color: #9e9e9e;\n}\n\n.terminal .xterm-bg-color-247 {\n    background-color: #9e9e9e;\n}\n\n.terminal .xterm-color-248 {\n    color: #a8a8a8;\n}\n\n.terminal .xterm-bg-color-248 {\n    background-color: #a8a8a8;\n}\n\n.terminal .xterm-color-249 {\n    color: #b2b2b2;\n}\n\n.terminal .xterm-bg-color-249 {\n    background-color: #b2b2b2;\n}\n\n.terminal .xterm-color-250 {\n    color: #bcbcbc;\n}\n\n.terminal .xterm-bg-color-250 {\n    background-color: #bcbcbc;\n}\n\n.terminal .xterm-color-251 {\n    color: #c6c6c6;\n}\n\n.terminal .xterm-bg-color-251 {\n    background-color: #c6c6c6;\n}\n\n.terminal .xterm-color-252 {\n    color: #d0d0d0;\n}\n\n.terminal .xterm-bg-color-252 {\n    background-color: #d0d0d0;\n}\n\n.terminal .xterm-color-253 {\n    color: #dadada;\n}\n\n.terminal .xterm-bg-color-253 {\n    background-color: #dadada;\n}\n\n.terminal .xterm-color-254 {\n    color: #e4e4e4;\n}\n\n.terminal .xterm-bg-color-254 {\n    background-color: #e4e4e4;\n}\n\n.terminal .xterm-color-255 {\n    color: #eeeeee;\n}\n\n.terminal .xterm-bg-color-255 {\n    background-color: #eeeeee;\n}\n", ""]);
	
	// exports


/***/ },
/* 92 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) Jupyter Development Team.\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n.p-CommandPalette {\n  min-width: 300px;\n  padding: 8px;\n  padding-bottom: 0px;\n  color: #757575;\n  background: #FAFAFA;\n  font-family: \"Helvetica Neue\", Helvetica;\n}\n\n\n.p-CommandPalette-search {\n  margin-bottom: 4px;\n}\n\n\n.p-CommandPalette-inputWrapper {\n  padding: 4px 6px;\n  background: white;\n  border: 1px solid #E0E0E0;\n  border-radius: 4px;\n}\n\n\n.p-CommandPalette-input {\n  width: 100%;\n  outline: none;\n  border: none;\n}\n\n\n.p-CommandPalette-header {\n  margin: 4px 0px;\n  padding: 4px 0px;\n  font-size: 11px;\n  font-weight: 500;\n  text-transform: capitalize;\n  border-bottom: 1px solid #E0E0E0;\n}\n\n\n.p-CommandPalette-command {\n  padding: 4px;\n  font-size: 13px;\n  font-weight: 500;\n}\n\n\n.p-CommandPalette-commandCaption {\n  font-size: 10px;\n  font-weight: 400;\n  color: #9E9E9E;\n}\n\n\n.p-CommandPalette-header:hover:not(.p-mod-active),\n.p-CommandPalette-command:hover:not(.p-mod-active) {\n  background: #EEEEEE;\n  border-radius: 2px;\n}\n\n\n.p-CommandPalette-header.p-mod-active,\n.p-CommandPalette-command.p-mod-active {\n  color: white;\n  background: #F27624;\n  border-radius: 2px;\n}\n\n\n.p-CommandPalette-command.p-mod-active .p-CommandPalette-commandCaption {\n  color: inherit;\n}\n\n\n.p-CommandPalette mark {\n  color: #424242;\n  font-weight: bold;\n  background: inherit;\n}\n", ""]);
	
	// exports


/***/ },
/* 93 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) Jupyter Development Team.\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n.jp-Help {\n  min-width: 480px;\n  background: white;\n}\n\n\n.jp-Help > iframe {\n  border: none;\n}\n\n\n/*\nWhen drag events occur, `p-mod-override-cursor` is added to the body.\nBecause iframes steal all cursor events, the following two rules are necessary\nto suppress pointer events while resize drags are occuring. There may be a\nbetter solution to this problem.\n*/\nbody.p-mod-override-cursor .jp-Help {\n  position: relative;\n}\n\nbody.p-mod-override-cursor .jp-Help:before {\n  content: '';\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  background: transparent;\n}\n", ""]);
	
	// exports


/***/ },
/* 94 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "#about-jupyterlab {\n    font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n    padding: 2em;    \n}\n", ""]);
	
	// exports


/***/ },
/* 95 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\n| Copyright (c) Jupyter Development Team.\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n.jp-Landing {\n  background: rgba(0,0,0,0.25);\n  color: #757575;\n  position: absolute;\n  z-index: 10000;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  top: 0px;\n  left: 0px;\n  margin: 0;\n  padding: 0;\n  width: 100%;\n  height: 100%;\n}\n\n\n.jp-Landing-dialog {\n  padding-bottom: 20px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 16px;\n  color: #757575;\n   background: #FAFAFA;\n  margin-left: auto;\n  margin-right: auto;\n  text-align: center;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  flex-direction: column;\n  border: 1px solid #BDBDBD;\n  border-radius: 2px;\n  box-shadow: 0px 2px 2px 0px rgba(0,0,0,0.5);\n}\n\n\n.jp-Landing-logo {\n  flex: 0 0 40px;\n  margin-left: auto;\n  margin-right: auto;\n  width: 100%;\n  background: white;\n  background-image: url(" + __webpack_require__(96) + ");\n  background-size: 193px 40px;\n  background-repeat: no-repeat;\n  background-position: center top;\n  padding-bottom: 20px;\n  border-bottom: 1px solid #BDBDBD;\n}\n\n\n.jp-Landing-title {\n  padding-top: 20px;\n  background: white;\n  width: 100%;\n}\n\n\n.jp-Landing-header {\n  \n  padding-top: 20px;\n  padding-bottom: 8px;\n}\n\n\n.jp-Landing-body {\n  display: flex;\n  flex-direction: row;\n  padding-left: 20px;\n  padding-right: 20px;\n}\n\n\n.jp-Landing-column {\n  padding-left: 20px;\n  padding-right: 20px;\n  display: flex;\n  flex-direction: column;\n}\n\n\n.jp-Landing-image {\n  flex: 0 0 auto;\n  min-height: 72px;\n  max-height: 72px;\n  min-width: 56px;\n  max-width: 56px;\n  background-size: 56px 72px;\n  background-repeat: no-repeat;\n\n}\n\n\n.jp-Landing-image:hover {\n  cursor: pointer;\n}\n\n\n.jp-Landing-text {\n  flex: 0 0 auto;\n  font-size: 12px;\n  padding-top: 8px;\n}\n\n\n.jp-Landing-imageNotebook {\n  background-image: url(" + __webpack_require__(97) + ");\n}\n\n\n.jp-Landing-imageTerminal {\n  background-image: url(" + __webpack_require__(98) + ");\n}\n\n\n.jp-Landing-imageTextEditor {\n  background-image: url(" + __webpack_require__(99) + ");\n}\n", ""]);
	
	// exports


/***/ },
/* 96 */
/***/ function(module, exports) {

	module.exports = "data:image/svg+xml;base64, "

/***/ },
/* 97 */
/***/ function(module, exports) {

	module.exports = "data:image/svg+xml;base64, "

/***/ },
/* 98 */
/***/ function(module, exports) {

	module.exports = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjM4NXB4IiBoZWlnaHQ9IjI5NXB4IiB2aWV3Qm94PSIwIDAgMzg1IDI5NSIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KICAgIDwhLS0gR2VuZXJhdG9yOiBTa2V0Y2ggMy43LjEgKDI4MjE1KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Hcm91cCA4PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Ikdyb3VwLTgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zLjAwMDAwMCwgMy45MDA4MTQpIj4KICAgICAgICAgICAgPHBvbHlnb24gaWQ9IlJlY3RhbmdsZS04IiBzdHJva2U9IiM5RTlFOUUiIHN0cm9rZS13aWR0aD0iNi44MDcwMTc1NCIgZmlsbD0iIzAwMDAwMCIgcG9pbnRzPSI2Ljc3NDkwNTA3IDAgMzg0LjUwNTY0MSAwIDM4NC41MDU2NDEgMjg3LjI3NTg3MSA2Ljc5MTA3MDQ0IDI4Ny4yNzU4NzEiPjwvcG9seWdvbj4KICAgICAgICAgICAgPHBhdGggZD0iTTExOC4wNzM4OCw3MS43NDExMjQ4IEw0OS43NTAwMDg4LDk4LjQ1MTE0MTMgTDQ5Ljc1MDAwODgsODcuOTMwNzg0NyBMMTA1LjU2NjM0NSw2Ni43NzMxNzg2IEw0OS43NTAwMDg4LDQ1LjY3NDAxOSBMNDkuNzUwMDA4OCwzNS4xNTM2NjI0IEwxMTguMDczODgsNjEuOTIyMTI1MyBMMTE4LjA3Mzg4LDcxLjc0MTEyNDggWiBNMTE2LjQxOTQ1NywxMTIuMzAyOTQ0IEwxMTYuNDE5NDU3LDEwNi4zOTk4NTUgTDE4Mi45ODk5MzUsMTA2LjM5OTg1NSBMMTgyLjk4OTkzNSwxMTIuMzAyOTQ0IEwxMTYuNDE5NDU3LDExMi4zMDI5NDQgWiIgaWQ9IiZndDtfIiBmaWxsPSIjRkZGRkZGIj48L3BhdGg+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4="

/***/ },
/* 99 */
/***/ function(module, exports) {

	module.exports = "data:image/svg+xml;base64, "

/***/ },
/* 100 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * The about page extension.
	 */
	exports.aboutExtension = {
	    id: 'jupyter.extensions.about',
	    activate: activateAbout
	};
	function activateAbout(app) {
	    var widget = new phosphor_widget_1.Widget();
	    var commandId = 'about-jupyterlab:show';
	    widget.id = 'about-jupyterlab';
	    widget.title.text = 'About';
	    widget.title.closable = true;
	    widget.node.innerHTML = "\n<h1>Welcome to the JupyterLab alpha preview</h1>\n\n<p>This demo gives an alpha-level preview of the JupyterLab environment.  Here is a brief description of some of the things you'll find in this demo.</p>\n\n<h2>File Browser</h2>\n\n<p>Clicking the \"Files\" tab, located on the left, will toggle the file browser. Navigate into directories by double-clicking, and use the breadcrumbs at the top to navigate out. Create a new file/directory by clicking the plus icon at the top. Click the middle icon to upload files,and click the last icon to reload the file listing. Drag and drop files to move them to subdirectories. Click on a selected file to rename it. Sort the list by clicking on a column header. Open a file by double-clicking it or dragging it into the main area. Opening an image displays the image. Opening a code file opens a code editor. Opening a notebook opens a very preliminary proof-of-concept <strong>non-executable</strong> view of the notebook.</p>\n\n<h2>Command Palette</h2>\n\n<p>Clicking the \"Commands\" tab, located on the left, will toggle the command palette. Execute a command by clicking, or navigating with your arrow keys and pressing Enter. Filter commands by typing in the text box at the top of the palette. The palette is organized into categories, and you can filter on a single category by clicking on the category header or by typing the header surrounded by colons in the search input (e.g., <code>:file:</code>).</p>\n\n<p>You can try these things out from the command palette:</p>\n\n<ul>\n<li>Open a new terminal (requires OS X or Linux)</li>\n<li>Open a new file</li>\n<li>Save a file</li>\n<li>Open up a help panel on the right</li>\n</ul>\n\n<h2>Main area</h2>\n\n<p>The main area is divided into panels of tabs. Drag a tab around the area to split the main area in different ways. Drag a tab to the center of a panel to move a tab without splitting the panel (in this case, the whole panel will highlight, instead of just a portion). Resize panels by dragging their borders (be aware that panels and sidebars also have a minimum width). A file that contains changes to be saved has a star for a close icon.</p>\n\n<h2>Notebook</h2>\n\n<p>Opening a notebook will open a minimally featured notebook. Code execution, Markdown rendering, and basic cell toolbar actions are supported.  Future versions will add more features from the existing Jupyter notebook.</p>\n";
	    app.commands.add([{
	            id: commandId,
	            handler: function () {
	                if (!widget.isAttached)
	                    app.shell.addToMainArea(widget);
	                app.shell.activateMain(widget.id);
	            }
	        }]);
	    app.palette.add([{
	            command: commandId,
	            text: 'About JupyterLab',
	            category: 'Help'
	        }]);
	}


/***/ },
/* 101 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var console_1 = __webpack_require__(102);
	var rendermime_1 = __webpack_require__(273);
	var docmanager_1 = __webpack_require__(274);
	var phosphor_tabs_1 = __webpack_require__(40);
	var plugin_1 = __webpack_require__(282);
	/**
	 * The console extension.
	 */
	exports.consoleExtension = {
	    id: 'jupyter.extensions.console',
	    requires: [plugin_1.JupyterServices, rendermime_1.RenderMime],
	    activate: activateConsole
	};
	/**
	 * Activate the console extension.
	 */
	function activateConsole(app, services, rendermime) {
	    var manager = services.notebookSessionManager;
	    // Add the ability to create new consoles for each kernel.
	    var specs = services.kernelspecs;
	    var displayNameMap = Object.create(null);
	    for (var kernelName in specs.kernelspecs) {
	        var displayName = specs.kernelspecs[kernelName].spec.display_name;
	        displayNameMap[displayName] = kernelName;
	    }
	    var displayNames = Object.keys(displayNameMap).sort(function (a, b) {
	        return a.localeCompare(b);
	    });
	    var count = 0;
	    var _loop_1 = function(displayName) {
	        var id = "console:create-" + displayNameMap[displayName];
	        app.commands.add([{
	                id: id,
	                handler: function () {
	                    manager.startNew({
	                        notebookPath: "Console-" + count++,
	                        kernelName: "" + displayNameMap[displayName]
	                    }).then(function (session) {
	                        var console = new console_1.ConsolePanel(session, rendermime.clone());
	                        console.id = "console-" + count;
	                        console.title.text = "Console-" + count;
	                        console.title.closable = true;
	                        app.shell.addToMainArea(console);
	                        Private.activeWidget = console;
	                        // TODO: Move this logic to the shell.
	                        var stack = console.parent;
	                        if (!stack) {
	                            return;
	                        }
	                        var tabs = stack.parent;
	                        if (tabs instanceof phosphor_tabs_1.TabPanel) {
	                            tabs.currentWidget = console;
	                        }
	                        console.content.prompt.focus();
	                        console.disposed.connect(function () {
	                            var index = Private.widgets.indexOf(console);
	                            Private.widgets.splice(index, 1);
	                            if (Private.activeWidget === console) {
	                                Private.activeWidget = null;
	                            }
	                        });
	                    });
	                }
	            }]);
	        app.palette.add([{
	                command: id,
	                category: 'Console',
	                text: "New " + displayName
	            }]);
	    };
	    for (var _i = 0, displayNames_1 = displayNames; _i < displayNames_1.length; _i++) {
	        var displayName = displayNames_1[_i];
	        _loop_1(displayName);
	    }
	    // Temporary console focus follower.
	    document.body.addEventListener('focus', function (event) {
	        for (var _i = 0, _a = Private.widgets; _i < _a.length; _i++) {
	            var widget = _a[_i];
	            var target = event.target;
	            if (widget.isAttached && widget.isVisible) {
	                if (widget.node.contains(target)) {
	                    Private.activeWidget = widget;
	                    return;
	                }
	            }
	        }
	    }, true);
	    app.commands.add([
	        {
	            id: 'console:clear',
	            handler: function () {
	                if (Private.activeWidget) {
	                    Private.activeWidget.content.clear();
	                }
	            }
	        },
	        {
	            id: 'console:execute',
	            handler: function () {
	                if (Private.activeWidget) {
	                    Private.activeWidget.content.execute();
	                }
	            }
	        },
	        {
	            id: 'console:interrupt-kernel',
	            handler: function () {
	                if (Private.activeWidget) {
	                    var kernel = Private.activeWidget.content.session.kernel;
	                    if (kernel) {
	                        kernel.interrupt();
	                    }
	                }
	            }
	        },
	        {
	            id: 'console:switch-kernel',
	            handler: function () {
	                if (Private.activeWidget) {
	                    var widget_1 = Private.activeWidget.content;
	                    var session_1 = widget_1.session;
	                    var lang_1 = '';
	                    if (session_1.kernel) {
	                        lang_1 = specs.kernelspecs[session_1.kernel.name].spec.language;
	                    }
	                    manager.listRunning().then(function (sessions) {
	                        var options = {
	                            name: widget_1.parent.title.text,
	                            specs: specs,
	                            sessions: sessions,
	                            preferredLanguage: lang_1,
	                            kernel: session_1.kernel,
	                            host: widget_1.parent.node
	                        };
	                        return docmanager_1.selectKernel(options);
	                    }).then(function (kernelId) {
	                        if (kernelId) {
	                            session_1.changeKernel(kernelId);
	                        }
	                        else {
	                            session_1.kernel.shutdown();
	                        }
	                    });
	                }
	            }
	        }
	    ]);
	    app.palette.add([
	        {
	            command: 'console:clear',
	            category: 'Console',
	            text: 'Clear Cells'
	        },
	        {
	            command: 'console:execute',
	            category: 'Console',
	            text: 'Execute Cell'
	        },
	        {
	            command: 'console:interrupt-kernel',
	            category: 'Console',
	            text: 'Interrupt Kernel'
	        },
	        {
	            command: 'console:switch-kernel',
	            category: 'Console',
	            text: 'Switch Kernel'
	        }]);
	    return Promise.resolve(void 0);
	}
	/**
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    Private.widgets = [];
	    Private.activeWidget = null;
	})(Private || (Private = {}));


/***/ },
/* 102 */
/***/ function(module, exports, __webpack_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];
	}
	__export(__webpack_require__(103));


/***/ },
/* 103 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var jupyter_js_services_1 = __webpack_require__(104);
	var dialog_1 = __webpack_require__(115);
	var phosphor_signaling_1 = __webpack_require__(22);
	var phosphor_widget_1 = __webpack_require__(20);
	var phosphor_panel_1 = __webpack_require__(18);
	var cells_1 = __webpack_require__(116);
	var mimetype_1 = __webpack_require__(267);
	var tooltip_1 = __webpack_require__(268);
	var history_1 = __webpack_require__(269);
	var completion_1 = __webpack_require__(270);
	/**
	 * The class name added to console widgets.
	 */
	var CONSOLE_CLASS = 'jp-Console';
	/**
	 * The class name added to console panels.
	 */
	var CONSOLE_PANEL = 'jp-Console-panel';
	/**
	 * The class name added to the console banner.
	 */
	var BANNER_CLASS = 'jp-Console-banner';
	/**
	 * A panel which contains a toolbar and a console.
	 */
	var ConsolePanel = (function (_super) {
	    __extends(ConsolePanel, _super);
	    /**
	     * Construct a console panel.
	     */
	    function ConsolePanel(session, rendermime) {
	        _super.call(this);
	        this._console = null;
	        this.addClass(CONSOLE_PANEL);
	        var constructor = this.constructor;
	        this._console = constructor.createConsole(session, rendermime);
	        this.addChild(this._console);
	    }
	    /**
	     * Create a new console widget for the panel.
	     */
	    ConsolePanel.createConsole = function (session, rendermime) {
	        return new ConsoleWidget(session, rendermime);
	    };
	    Object.defineProperty(ConsolePanel.prototype, "content", {
	        /**
	         * The console widget used by the panel.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._console;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    ConsolePanel.prototype.dispose = function () {
	        this._console = 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.
	     */
	    ConsolePanel.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'click':
	                var prompt_1 = this.content.prompt;
	                if (prompt_1) {
	                    prompt_1.focus();
	                }
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle `after_attach` messages for the widget.
	     */
	    ConsolePanel.prototype.onAfterAttach = function (msg) {
	        this.content.node.addEventListener('click', this);
	    };
	    /**
	     * Handle `before_detach` messages for the widget.
	     */
	    ConsolePanel.prototype.onBeforeDetach = function (msg) {
	        this.content.node.removeEventListener('click', this);
	    };
	    /**
	     * Handle `'close-request'` messages.
	     */
	    ConsolePanel.prototype.onCloseRequest = function (msg) {
	        var _this = this;
	        var session = this.content.session;
	        if (!session.kernel) {
	            this.dispose();
	        }
	        session.kernel.getKernelSpec().then(function (spec) {
	            var name = spec.display_name;
	            return dialog_1.showDialog({
	                title: 'Shut down kernel?',
	                body: "Shut down " + name + "?",
	                host: _this.node
	            });
	        }).then(function (value) {
	            if (value && value.text === 'OK') {
	                return session.shutdown();
	            }
	        }).then(function () {
	            _super.prototype.onCloseRequest.call(_this, msg);
	            _this.dispose();
	        });
	    };
	    return ConsolePanel;
	}(phosphor_panel_1.Panel));
	exports.ConsolePanel = ConsolePanel;
	/**
	 * A widget containing a Jupyter console.
	 */
	var ConsoleWidget = (function (_super) {
	    __extends(ConsoleWidget, _super);
	    /**
	     * Construct a console widget.
	     */
	    function ConsoleWidget(session, rendermime) {
	        var _this = this;
	        _super.call(this);
	        this._completion = null;
	        this._mimetype = 'text/x-ipython';
	        this._rendermime = null;
	        this._tooltip = null;
	        this._history = null;
	        this._session = null;
	        this._pendingComplete = 0;
	        this._pendingInspect = 0;
	        this.addClass(CONSOLE_CLASS);
	        var constructor = this.constructor;
	        var layout = new phosphor_panel_1.PanelLayout();
	        this.layout = layout;
	        this._rendermime = rendermime;
	        this._session = session;
	        this._history = constructor.createHistory(session.kernel);
	        // Instantiate tab completion widget.
	        this._completion = constructor.createCompletion();
	        this._completion.reference = this;
	        this._completion.attach(document.body);
	        this._completion.selected.connect(this.onCompletionSelect, this);
	        // Instantiate tooltip widget.
	        this._tooltip = constructor.createTooltip();
	        this._tooltip.attach(document.body);
	        // Create the banner.
	        var banner = constructor.createBanner();
	        banner.addClass(BANNER_CLASS);
	        banner.readOnly = true;
	        banner.model.source = '...';
	        layout.addChild(banner);
	        // Set the banner text and the mimetype.
	        this.initialize();
	        // Create the prompt.
	        this.newPrompt();
	        // Handle changes to the kernel.
	        session.kernelChanged.connect(function (s, kernel) {
	            _this.clear();
	            _this.newPrompt();
	            _this.initialize();
	            _this._history = constructor.createHistory(kernel);
	        });
	    }
	    /**
	     * Create a new banner widget given a banner model.
	     */
	    ConsoleWidget.createBanner = function () {
	        var model = new cells_1.RawCellModel();
	        return new cells_1.RawCellWidget(model);
	    };
	    /**
	     * Create a new prompt widget given a prompt model and a rendermime.
	     */
	    ConsoleWidget.createPrompt = function (rendermime) {
	        var model = new cells_1.CodeCellModel();
	        return new cells_1.CodeCellWidget(model, rendermime);
	    };
	    /**
	     * Create a new completion widget.
	     */
	    ConsoleWidget.createCompletion = function () {
	        var model = new completion_1.CompletionModel();
	        return new completion_1.CompletionWidget(model);
	    };
	    /**
	     * Create a console history.
	     */
	    ConsoleWidget.createHistory = function (kernel) {
	        return new history_1.ConsoleHistory(kernel);
	    };
	    /**
	     * Create a new tooltip widget.
	     *
	     * @returns A ConsoleTooltip widget.
	     */
	    ConsoleWidget.createTooltip = function () {
	        return new tooltip_1.ConsoleTooltip();
	    };
	    Object.defineProperty(ConsoleWidget.prototype, "prompt", {
	        /*
	         * The last cell in a console is always a `CodeCellWidget` prompt.
	         */
	        get: function () {
	            var layout = this.layout;
	            var last = layout.childCount() - 1;
	            return last > 0 ? layout.childAt(last) : null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ConsoleWidget.prototype, "session", {
	        /**
	         * Get the session used by the console.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._session;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    ConsoleWidget.prototype.dispose = function () {
	        // Do nothing if already disposed.
	        if (this.isDisposed) {
	            return;
	        }
	        this._tooltip.dispose();
	        this._tooltip = null;
	        this._history.dispose();
	        this._history = null;
	        this._completion.dispose();
	        this._completion = null;
	        this._session.dispose();
	        this._session = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Execute the current prompt.
	     */
	    ConsoleWidget.prototype.execute = function () {
	        var _this = this;
	        if (this._session.status === jupyter_js_services_1.KernelStatus.Dead) {
	            return;
	        }
	        var prompt = this.prompt;
	        prompt.trusted = true;
	        this._history.push(prompt.model.source);
	        return prompt.execute(this._session.kernel).then(function () { return _this.newPrompt(); }, function () { return _this.newPrompt(); });
	    };
	    /**
	     * Clear the code cells.
	     */
	    ConsoleWidget.prototype.clear = function () {
	        while (this.prompt) {
	            this.prompt.dispose();
	        }
	        this.newPrompt();
	    };
	    /**
	     * Serialize the output.
	     */
	    ConsoleWidget.prototype.serialize = function () {
	        var output = [];
	        var layout = this.layout;
	        for (var i = 1; i < layout.childCount(); i++) {
	            var widget = layout.childAt(i);
	            output.push(widget.model.toJSON());
	        }
	        return output;
	    };
	    /**
	     * Handle `after_attach` messages for the widget.
	     */
	    ConsoleWidget.prototype.onAfterAttach = function (msg) {
	        var prompt = this.prompt;
	        if (prompt) {
	            prompt.focus();
	        }
	    };
	    /**
	     * Handle `update_request` messages.
	     */
	    ConsoleWidget.prototype.onUpdateRequest = function (msg) {
	        var prompt = this.prompt;
	        Private.scrollIfNeeded(this.parent.node, prompt.node);
	    };
	    /**
	     * Make a new prompt.
	     */
	    ConsoleWidget.prototype.newPrompt = function () {
	        // Make the previous editor read-only and clear its signals.
	        var prompt = this.prompt;
	        if (prompt) {
	            prompt.readOnly = true;
	            phosphor_signaling_1.clearSignalData(prompt.editor);
	        }
	        // Create the new prompt and add to layout.
	        var layout = this.layout;
	        var constructor = this.constructor;
	        prompt = constructor.createPrompt(this._rendermime);
	        prompt.mimetype = this._mimetype;
	        layout.addChild(prompt);
	        // Hook up completion, tooltip, and history handling.
	        var editor = prompt.editor;
	        editor.textChanged.connect(this.onTextChange, this);
	        editor.completionRequested.connect(this.onCompletionRequest, this);
	        editor.edgeRequested.connect(this.onEdgeRequest, this);
	        prompt.focus();
	    };
	    /**
	     * Initialize the banner and mimetype.
	     */
	    ConsoleWidget.prototype.initialize = function () {
	        var _this = this;
	        var layout = this.layout;
	        var banner = layout.childAt(0);
	        this._session.kernel.kernelInfo().then(function (info) {
	            banner.model.source = info.banner;
	            _this._mimetype = mimetype_1.mimetypeForLanguage(info.language_info);
	            _this.prompt.mimetype = _this._mimetype;
	        });
	    };
	    /**
	     * Handle a text changed signal from an editor.
	     */
	    ConsoleWidget.prototype.onTextChange = function (editor, change) {
	        var line = change.newValue.split('\n')[change.line];
	        var lastChar = change.ch - 1;
	        var model = this._completion.model;
	        var hasCompletion = !!model.original;
	        // If last character entered is not whitespace, update completion.
	        if (line[lastChar] && line[lastChar].match(/\S/) && hasCompletion) {
	            // Update the current completion state.
	            model.current = change;
	        }
	        else {
	            // If final character is whitespace, reset completion.
	            model.options = null;
	            model.original = null;
	            model.cursor = null;
	        }
	        // Displaying completion widget overrides displaying tooltip.
	        if (hasCompletion) {
	            this._tooltip.hide();
	        }
	        else if (change.newValue) {
	            this.updateTooltip(change);
	        }
	    };
	    /**
	     * Update the tooltip based on a text change.
	     */
	    ConsoleWidget.prototype.updateTooltip = function (change) {
	        var _this = this;
	        var line = change.newValue.split('\n')[change.line];
	        var contents = { code: line, cursor_pos: change.ch, detail_level: 0 };
	        var pendingInspect = ++this._pendingInspect;
	        this._session.kernel.inspect(contents).then(function (value) {
	            // If widget has been disposed, bail.
	            if (_this.isDisposed) {
	                return;
	            }
	            // If a newer text change has created a pending request, bail.
	            if (pendingInspect !== _this._pendingInspect) {
	                return;
	            }
	            // Tooltip request failures or negative results fail silently.
	            if (value.status !== 'ok' || !value.found) {
	                return;
	            }
	            var bundle = Private.processInspectReply(value.data);
	            _this.showTooltip(change, bundle);
	        });
	    };
	    /**
	     * Show the tooltip.
	     */
	    ConsoleWidget.prototype.showTooltip = function (change, bundle) {
	        var _a = change.coords, top = _a.top, bottom = _a.bottom, left = _a.left;
	        var tooltip = this._tooltip;
	        var heightAbove = top + 1; // 1px border
	        var heightBelow = window.innerHeight - bottom - 1; // 1px border
	        var widthLeft = left;
	        var widthRight = window.innerWidth - left;
	        // Add content and measure.
	        tooltip.content = this._rendermime.render(bundle);
	        tooltip.show();
	        var _b = tooltip.node.getBoundingClientRect(), width = _b.width, height = _b.height;
	        var maxWidth;
	        var maxHeight;
	        // Prefer displaying below.
	        if (heightBelow >= height || heightBelow >= heightAbove) {
	            // Offset the height of the tooltip by the height of cursor characters.
	            top += change.chHeight;
	            maxHeight = heightBelow;
	        }
	        else {
	            maxHeight = heightAbove;
	            top -= Math.min(height, maxHeight);
	        }
	        // Prefer displaying on the right.
	        if (widthRight >= width || widthRight >= widthLeft) {
	            // Account for 1px border width.
	            left += 1;
	            maxWidth = widthRight;
	        }
	        else {
	            maxWidth = widthLeft;
	            left -= Math.min(width, maxWidth);
	        }
	        tooltip.node.style.top = top + "px";
	        tooltip.node.style.left = left + "px";
	        tooltip.node.style.maxHeight = maxHeight + "px";
	        tooltip.node.style.maxWidth = maxWidth + "px";
	    };
	    /**
	     * Handle a completion requested signal from an editor.
	     */
	    ConsoleWidget.prototype.onCompletionRequest = function (editor, change) {
	        var _this = this;
	        var contents = {
	            // Only send the current line of code for completion.
	            code: change.currentValue.split('\n')[change.line],
	            cursor_pos: change.ch
	        };
	        var pendingComplete = ++this._pendingComplete;
	        var model = this._completion.model;
	        this._session.kernel.complete(contents).then(function (value) {
	            // If model has been disposed, bail.
	            if (model.isDisposed) {
	                return;
	            }
	            // If a newer completion requesy has created a pending request, bail.
	            if (pendingComplete !== _this._pendingComplete) {
	                return;
	            }
	            // Completion request failures or negative results fail silently.
	            if (value.status !== 'ok') {
	                return;
	            }
	            // Update the model.
	            model.options = value.matches;
	            model.cursor = { start: value.cursor_start, end: value.cursor_end };
	        }).then(function () {
	            model.original = change;
	        });
	    };
	    /**
	     * Handle an edge requested signal.
	     */
	    ConsoleWidget.prototype.onEdgeRequest = function (editor, location) {
	        var doc = editor.editor.getDoc();
	        if (location === 'top') {
	            this._history.back().then(function (value) {
	                if (!value) {
	                    return;
	                }
	                doc.setValue(value);
	                doc.setCursor(doc.posFromIndex(0));
	            });
	        }
	        else {
	            this._history.forward().then(function (value) {
	                // If at the bottom end of history, then clear the prompt.
	                var text = value || '';
	                doc.setValue(text);
	                doc.setCursor(doc.posFromIndex(text.length));
	            });
	        }
	    };
	    /**
	     * Handle a completion selected signal from the completion widget.
	     */
	    ConsoleWidget.prototype.onCompletionSelect = function (widget, value) {
	        var prompt = this.prompt;
	        var patch = this._completion.model.createPatch(value);
	        prompt.model.source = patch.text;
	        prompt.editor.setCursorPosition(patch.position);
	    };
	    return ConsoleWidget;
	}(phosphor_widget_1.Widget));
	exports.ConsoleWidget = ConsoleWidget;
	/**
	 * A namespace for Console widget private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Scroll an element into view if needed.
	     *
	     * @param area - The scroll area element.
	     *
	     * @param elem - The element of interest.
	     */
	    function scrollIfNeeded(area, elem) {
	        var ar = area.getBoundingClientRect();
	        var er = elem.getBoundingClientRect();
	        if (er.top < ar.top - 10) {
	            area.scrollTop -= ar.top - er.top + 10;
	        }
	        else if (er.bottom > ar.bottom + 10) {
	            area.scrollTop += er.bottom - ar.bottom + 10;
	        }
	    }
	    Private.scrollIfNeeded = scrollIfNeeded;
	    /**
	     * Process the IInspectReply plain text data.
	     *
	     * @param bundle - The MIME bundle of an API inspect reply.
	     *
	     * #### Notes
	     * The `text/plain` value sent by the API in inspect replies contains ANSI
	     * terminal escape sequences. In order for these sequences to be parsed into
	     * usable data in the client, they must have the MIME type that the console
	     * text renderer expects: `application/vnd.jupyter.console-text`.
	     */
	    function processInspectReply(bundle) {
	        var textMime = 'text/plain';
	        var consoleMime = 'application/vnd.jupyter.console-text';
	        bundle[consoleMime] = bundle[consoleMime] || bundle[textMime];
	        return bundle;
	    }
	    Private.processInspectReply = processInspectReply;
	})(Private || (Private = {}));


/***/ },
/* 104 */
/***/ function(module, exports, __webpack_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];
	}
	__export(__webpack_require__(105));
	__export(__webpack_require__(108));
	__export(__webpack_require__(110));
	__export(__webpack_require__(111));
	__export(__webpack_require__(114));


/***/ },
/* 105 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var utils = __webpack_require__(106);
	/**
	 * The url for the config service.
	 */
	var SERVICE_CONFIG_URL = 'api/config';
	/**
	 * Create a config section.
	 *
	 * @returns A Promise that is fulfilled with the config section is loaded.
	 */
	function getConfigSection(sectionName, baseUrl, ajaxSettings) {
	    var section = new ConfigSection(sectionName, baseUrl, ajaxSettings);
	    return section.load();
	}
	exports.getConfigSection = getConfigSection;
	/**
	 * Implementation of the Configurable data section.
	 */
	var ConfigSection = (function () {
	    /**
	     * Create a config section.
	     */
	    function ConfigSection(sectionName, baseUrl, ajaxSettings) {
	        this._url = 'unknown';
	        this._data = {};
	        this._ajaxSettings = '{}';
	        baseUrl = baseUrl || utils.getBaseUrl();
	        if (ajaxSettings)
	            this.ajaxSettings = ajaxSettings;
	        this._url = utils.urlPathJoin(baseUrl, SERVICE_CONFIG_URL, utils.urlJoinEncode(sectionName));
	    }
	    Object.defineProperty(ConfigSection.prototype, "ajaxSettings", {
	        /**
	         * Get a copy of the default ajax settings for the section.
	         */
	        get: function () {
	            return JSON.parse(this._ajaxSettings);
	        },
	        /**
	         * Set the default ajax settings for the section.
	         */
	        set: function (value) {
	            this._ajaxSettings = JSON.stringify(value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ConfigSection.prototype, "data", {
	        /**
	         * Get the data for this section.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        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.
	     */
	    ConfigSection.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 Error('Invalid Status: ' + success.xhr.status);
	            }
	            _this._data = success.data;
	            return _this;
	        });
	    };
	    /**
	     * 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.
	     */
	    ConfigSection.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 Error('Invalid Status: ' + success.xhr.status);
	            }
	            _this._data = success.data;
	            return _this._data;
	        });
	    };
	    return ConfigSection;
	}());
	/**
	 * Configurable object with defaults.
	 */
	var ConfigWithDefaults = (function () {
	    /**
	     * Create a new config with defaults.
	     */
	    function ConfigWithDefaults(section, defaults, classname) {
	        this._section = null;
	        this._defaults = null;
	        this._className = 'unknown';
	        this._section = section;
	        this._defaults = defaults;
	        this._className = classname;
	    }
	    /**
	     * Get data from the config section or fall back to defaults.
	     */
	    ConfigWithDefaults.prototype.get = function (key) {
	        return this._classData()[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 () {
	        if (this._className) {
	            return this._section.data[this._className] || {};
	        }
	        else {
	            return this._section.data;
	        }
	    };
	    return ConfigWithDefaults;
	}());
	exports.ConfigWithDefaults = ConfigWithDefaults;


/***/ },
/* 106 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process) {// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var minimist = __webpack_require__(107);
	/**
	 * 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 copy of an object, or null.
	 */
	function copy(object) {
	    if (object !== null && typeof object === 'object') {
	        return JSON.parse(JSON.stringify(object));
	    }
	    return null;
	}
	exports.copy = copy;
	/**
	 * Check for shallow equality of two objects.
	 */
	function shallowEquals(o1, o2) {
	    for (var p in o1) {
	        if (o1.hasOwnProperty(p)) {
	            if (o1[p] !== o2[p]) {
	                return false;
	            }
	        }
	    }
	    for (var p in o2) {
	        if (o2.hasOwnProperty(p) && !o1.hasOwnProperty(p)) {
	            return false;
	        }
	    }
	    return true;
	}
	exports.shallowEquals = shallowEquals;
	;
	/**
	 * 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;
	/**
	 * Join a sequence of url components with `'/'`.
	 */
	function urlPathJoin() {
	    var paths = [];
	    for (var _i = 0; _i < arguments.length; _i++) {
	        paths[_i - 0] = arguments[_i];
	    }
	    var url = '';
	    for (var i = 0; i < paths.length; i++) {
	        var path = paths[i];
	        if (path === '') {
	            continue;
	        }
	        if (i > 0) {
	            path = path.replace(/\/\/+/, '/');
	        }
	        if (url.length > 0 && url.charAt(url.length - 1) != '/' && path[0] != '/') {
	            url = url + '/' + path;
	        }
	        else {
	            url = url + path;
	        }
	    }
	    return url;
	}
	exports.urlPathJoin = urlPathJoin;
	/**
	 * Encode just the components of a multi-segment uri.
	 *
	 * Preserves the `'/'` separators.
	 */
	function encodeURIComponents(uri) {
	    return uri.split('/').map(encodeURIComponent).join('/');
	}
	exports.encodeURIComponents = encodeURIComponents;
	/**
	 * Encode and join a sequence of url components with `'/'`.
	 */
	function urlJoinEncode() {
	    var args = [];
	    for (var _i = 0; _i < arguments.length; _i++) {
	        args[_i - 0] = arguments[_i];
	    }
	    return encodeURIComponents(urlPathJoin.apply(null, args));
	}
	exports.urlJoinEncode = urlJoinEncode;
	/**
	 * 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(json[key]);
	    }).join('&');
	}
	exports.jsonToQueryString = jsonToQueryString;
	/**
	 * 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, settings) {
	    var method = settings.method || 'GET';
	    var user = settings.user || '';
	    var password = settings.password || '';
	    if (!settings.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 req = new XMLHttpRequest();
	        req.open(method, url, true, user, password);
	        if (settings.contentType !== void 0) {
	            req.setRequestHeader('Content-Type', settings.contentType);
	        }
	        if (settings.timeout !== void 0)
	            req.timeout = settings.timeout;
	        if (!!settings.withCredentials) {
	            req.withCredentials = true;
	        }
	        if (settings.requestHeaders !== void 0) {
	            for (var prop in settings.requestHeaders) {
	                req.setRequestHeader(prop, settings.requestHeaders[prop]);
	            }
	        }
	        req.onload = function () {
	            if (req.status >= 400) {
	                var error = new Error(req.statusText);
	                reject({ xhr: req, statusText: req.statusText, error: error });
	                return;
	            }
	            var response = req.responseText;
	            if (settings.dataType === 'json' && response) {
	                response = JSON.parse(response);
	            }
	            resolve({ data: response, statusText: req.statusText, xhr: req });
	        };
	        req.onerror = function (err) {
	            reject({ xhr: req, statusText: req.statusText, error: err });
	        };
	        req.ontimeout = function () {
	            reject({ xhr: req, statusText: req.statusText,
	                error: new Error('Operation Timed Out') });
	        };
	        if (settings.data) {
	            req.send(settings.data);
	        }
	        else {
	            req.send();
	        }
	    });
	}
	exports.ajaxRequest = ajaxRequest;
	/**
	 * 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;
	;
	/**
	 * A Promise that can be resolved or rejected by another object.
	 */
	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;
	        });
	    }
	    Object.defineProperty(PromiseDelegate.prototype, "promise", {
	        /**
	         * Get the underlying Promise.
	         */
	        get: function () {
	            return this._promise;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Resolve the underlying Promise with an optional value or another Promise.
	     */
	    PromiseDelegate.prototype.resolve = function (value) {
	        // Note: according to the Promise spec, and the `this` context for resolve
	        // and reject are ignored
	        this._resolve(value);
	    };
	    /**
	     * Reject the underlying Promise with an optional reason.
	     */
	    PromiseDelegate.prototype.reject = function (reason) {
	        // Note: according to the Promise spec, the `this` context for resolve
	        // and reject are ignored
	        this._reject(reason);
	    };
	    return PromiseDelegate;
	})();
	exports.PromiseDelegate = PromiseDelegate;
	/**
	 * 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);
	}
	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 = urlPathJoin(location.origin, baseUrl);
	            }
	            else {
	                baseUrl = urlPathJoin('http://localhost:8888/', baseUrl);
	            }
	        }
	        wsUrl = 'ws' + baseUrl.slice(4);
	    }
	    return wsUrl;
	}
	exports.getWsUrl = getWsUrl;
	//# sourceMappingURL=index.js.map
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(15)))

/***/ },
/* 107 */
/***/ function(module, exports) {

	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);
	}
	


/***/ },
/* 108 */
/***/ function(module, exports, __webpack_require__) {

	"use strict";
	var utils = __webpack_require__(106);
	var validate = __webpack_require__(109);
	/**
	 * The url for the contents service.
	 */
	var SERVICE_CONTENTS_URL = 'api/contents';
	/**
	 * 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 baseUrl - The base URL for the server.
	     *
	     * @param ajaxSettings - Optional initial ajax settings.
	     */
	    function ContentsManager(baseUrl, ajaxSettings) {
	        this._apiUrl = 'unknown';
	        this._ajaxSettings = '{}';
	        baseUrl = baseUrl || utils.getBaseUrl();
	        if (ajaxSettings)
	            this.ajaxSettings = ajaxSettings;
	        this._apiUrl = utils.urlPathJoin(baseUrl, SERVICE_CONTENTS_URL);
	    }
	    Object.defineProperty(ContentsManager.prototype, "ajaxSettings", {
	        /**
	         * Get a copy of the default ajax settings for the contents manager.
	         */
	        get: function () {
	            return JSON.parse(this._ajaxSettings);
	        },
	        /**
	         * Set the default ajax settings for the contents manager.
	         */
	        set: function (value) {
	            this._ajaxSettings = JSON.stringify(value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get a file or directory.
	     *
	     * @param path: Path to the file or directory.
	     *
	     * @param options: The options describing the file.
	     *   Use `options.content = true` to return file contents.
	     *
	     * @returns A promise which resolves with the file content.
	     *
	     * #### 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.get = function (path, options) {
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'GET';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        var url = this._getUrl(path);
	        if (options) {
	            var params = {};
	            if (options.type) {
	                params.type = options.type;
	            }
	            if (options.format) {
	                params.format = options.format;
	            }
	            if (options.content === false) {
	                params.content = '0';
	            }
	            url += utils.jsonToQueryString(params);
	        }
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw Error('Invalid Status: ' + success.xhr.status);
	            }
	            validate.validateContentsModel(success.data);
	            return success.data;
	        });
	    };
	    /**
	     * Create a new untitled file or directory in the specified directory path.
	     *
	     * @param path: The directory in which to create the new file/directory.
	     *
	     * @param options: The options describing the new item.
	     *
	     * @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 (path, options) {
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'POST';
	        ajaxSettings.dataType = 'json';
	        if (options) {
	            var data = JSON.stringify({
	                ext: options.ext,
	                type: options.type
	            });
	            ajaxSettings.data = data;
	            ajaxSettings.contentType = 'application/json';
	        }
	        var url = this._getUrl(path);
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 201) {
	                throw Error('Invalid Status: ' + success.xhr.status);
	            }
	            validate.validateContentsModel(success.data);
	            return success.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 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 Error('Invalid Status: ' + success.xhr.status);
	            }
	        }, 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) {
	                    throw new Error(err.message);
	                }
	            }
	            throw new Error(error.xhr.statusText);
	        });
	    };
	    /**
	     * 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 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 Error('Invalid Status: ' + success.xhr.status);
	            }
	            validate.validateContentsModel(success.data);
	            return success.data;
	        });
	    };
	    /**
	     * Save a file.
	     *
	     * @param path - The desired file path.
	     *
	     * @param model - The file model to save.
	     *
	     * @returns A promise which resolves with the file contents 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, model) {
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'PUT';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.data = JSON.stringify(model);
	        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 Error('Invalid Status: ' + success.xhr.status);
	            }
	            validate.validateContentsModel(success.data);
	            return success.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 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 Error('Invalid Status: ' + success.xhr.status);
	            }
	            validate.validateContentsModel(success.data);
	            return success.data;
	        });
	    };
	    /**
	     * List notebooks and directories at a given path.
	     *
	     * @param: path - The path in which to list the contents.
	     *
	     * @returns A promise which resolves with a model with the directory
	     *    contents.
	     *
	     * #### 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.listContents = function (path) {
	        return this.get(path, { type: 'directory' });
	    };
	    /**
	     * 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 Error('Invalid Status: ' + success.xhr.status);
	            }
	            validate.validateCheckpointModel(success.data);
	            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 Error('Invalid Status: ' + success.xhr.status);
	            }
	            if (!Array.isArray(success.data)) {
	                throw Error('Invalid Checkpoint list');
	            }
	            for (var i = 0; i < success.data.length; i++) {
	                validate.validateCheckpointModel(success.data[i]);
	            }
	            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 Error('Invalid Status: ' + success.xhr.status);
	            }
	        });
	    };
	    /**
	     * 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 Error('Invalid Status: ' + success.xhr.status);
	            }
	        });
	    };
	    /**
	     * Get a REST url for this file given a path.
	     */
	    ContentsManager.prototype._getUrl = function () {
	        var args = [];
	        for (var _i = 0; _i < arguments.length; _i++) {
	            args[_i - 0] = arguments[_i];
	        }
	        var url_parts = [].concat(Array.prototype.slice.apply(args));
	        return utils.urlPathJoin(this._apiUrl, utils.urlJoinEncode.apply(null, url_parts));
	    };
	    return ContentsManager;
	}());
	exports.ContentsManager = ContentsManager;


/***/ },
/* 109 */
/***/ function(module, exports) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	/**
	 * Required fields for `IKernelHeader`.
	 */
	var HEADER_FIELDS = ['username', 'version', 'session', 'msg_id', 'msg_type'];
	/**
	 * Requred fields and types for contents of various types of `IKernelMessage`
	 * messages on the iopub channel.
	 */
	var IOPUB_CONTENT_FIELDS = {
	    stream: { name: 'string', text: 'string' },
	    display_data: { data: 'any', metadata: 'any' },
	    execute_input: { code: 'string', execution_count: 'number' },
	    execute_result: { execution_count: 'number', data: 'any',
	        metadata: 'any' },
	    error: { ename: 'string', evalue: 'string', traceback: 'any' },
	    status: { execution_state: 'string' },
	    clear_output: { wait: 'boolean' },
	    comm_open: { comm_id: 'string', target_name: 'string', data: 'any' },
	    comm_msg: { comm_id: 'string', data: 'any' },
	    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 'any':
	                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 an `IKernelMessage`.
	 */
	function validateKernelHeader(header) {
	    for (var i = 0; i < HEADER_FIELDS.length; i++) {
	        validateProperty(header, HEADER_FIELDS[i], 'string');
	    }
	}
	/**
	 * Validate an `IKernelMessage` object.
	 */
	function validateKernelMessage(msg) {
	    validateProperty(msg, 'metadata', 'any');
	    validateProperty(msg, 'content', 'any');
	    validateProperty(msg, 'channel', 'string');
	    validateProperty(msg, 'buffers', 'array');
	    validateKernelHeader(msg.header);
	    if (Object.keys(msg.parent_header).length > 0) {
	        validateKernelHeader(msg.parent_header);
	    }
	    if (msg.channel === 'iopub') {
	        validateIOPubContent(msg);
	    }
	}
	exports.validateKernelMessage = validateKernelMessage;
	/**
	 * Validate content of an IKernelMessage on the iopub channel.
	 */
	function validateIOPubContent(msg) {
	    if (msg.channel === 'iopub') {
	        var fields = IOPUB_CONTENT_FIELDS[msg.header.msg_type];
	        if (fields === void 0) {
	            throw Error("Invalid Kernel message: iopub message type " + msg.header.msg_type + " not recognized");
	        }
	        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 an `IKernelId` object.
	 */
	function validateKernelId(info) {
	    validateProperty(info, 'name', 'string');
	    validateProperty(info, 'id', 'string');
	}
	exports.validateKernelId = validateKernelId;
	/**
	 * Validate an `ISessionId` object.
	 */
	function validateSessionId(info) {
	    validateProperty(info, 'id', 'string');
	    validateProperty(info, 'notebook', 'any');
	    validateProperty(info, 'kernel', 'any');
	    validateKernelId(info.kernel);
	    validateProperty(info.notebook, 'path', 'string');
	}
	exports.validateSessionId = validateSessionId;
	/**
	 * Validate an `IKernelSpecID` object.
	 */
	function validateKernelSpec(info) {
	    validateProperty(info, 'name', 'string');
	    validateProperty(info, 'spec', 'any');
	    validateProperty(info, 'resources', 'any');
	    var spec = info.spec;
	    validateProperty(spec, 'language', 'string');
	    validateProperty(spec, 'display_name', 'string');
	    validateProperty(spec, 'argv', 'array');
	}
	exports.validateKernelSpec = validateKernelSpec;
	/**
	 * Validate an `IContentsModel` 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', 'any');
	    validateProperty(model, 'content', 'any');
	    validateProperty(model, 'format', 'any');
	}
	exports.validateContentsModel = validateContentsModel;
	/**
	 * Validate an `ICheckpointModel` object.
	 */
	function validateCheckpointModel(model) {
	    validateProperty(model, 'id', 'string');
	    validateProperty(model, 'last_modified', 'string');
	}
	exports.validateCheckpointModel = validateCheckpointModel;


/***/ },
/* 110 */
/***/ function(module, exports) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	/**
	 * Check if an IKernelMessage is an iopub stream message.
	 */
	function isStreamMessage(msg) {
	    return msg.header.msg_type === 'stream';
	}
	exports.isStreamMessage = isStreamMessage;
	/**
	 * Check if an IKernelMessage is an iopub display_data message.
	 */
	function isDisplayDataMessage(msg) {
	    return msg.header.msg_type === 'display_data';
	}
	exports.isDisplayDataMessage = isDisplayDataMessage;
	/**
	 * Check if an IKernelMessage is an iopub execute_input message.
	 */
	function isExecuteInputMessage(msg) {
	    return msg.header.msg_type === 'execute_input';
	}
	exports.isExecuteInputMessage = isExecuteInputMessage;
	/**
	 * Check if an IKernelMessage is an iopub execute_result message.
	 */
	function isExecuteResultMessage(msg) {
	    return msg.header.msg_type === 'execute_result';
	}
	exports.isExecuteResultMessage = isExecuteResultMessage;
	/**
	 * Check if an IKernelMessage is an iopub error message.
	 */
	function isErrorMessage(msg) {
	    return msg.header.msg_type === 'error';
	}
	exports.isErrorMessage = isErrorMessage;
	/**
	 * Check if an IKernelMessage is an iopub status message.
	 */
	function isStatusMessage(msg) {
	    return msg.header.msg_type === 'status';
	}
	exports.isStatusMessage = isStatusMessage;
	/**
	 * Check if an IKernelMessage is an iopub clear_output message.
	 */
	function isClearOutputMessage(msg) {
	    return msg.header.msg_type === 'clear_output';
	}
	exports.isClearOutputMessage = isClearOutputMessage;
	/**
	 * Check if an IKernelMessage is an iopub comm_open message.
	 */
	function isCommOpenMessage(msg) {
	    return msg.header.msg_type === 'comm_open';
	}
	exports.isCommOpenMessage = isCommOpenMessage;
	/**
	 * Enumeration of valid Kernel status states.
	 */
	(function (KernelStatus) {
	    KernelStatus[KernelStatus["Unknown"] = 0] = "Unknown";
	    KernelStatus[KernelStatus["Starting"] = 1] = "Starting";
	    KernelStatus[KernelStatus["Reconnecting"] = 2] = "Reconnecting";
	    KernelStatus[KernelStatus["Idle"] = 3] = "Idle";
	    KernelStatus[KernelStatus["Busy"] = 4] = "Busy";
	    KernelStatus[KernelStatus["Restarting"] = 5] = "Restarting";
	    KernelStatus[KernelStatus["Dead"] = 6] = "Dead";
	})(exports.KernelStatus || (exports.KernelStatus = {}));
	var KernelStatus = exports.KernelStatus;


/***/ },
/* 111 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var utils = __webpack_require__(106);
	var phosphor_disposable_1 = __webpack_require__(8);
	var phosphor_signaling_1 = __webpack_require__(22);
	var ikernel_1 = __webpack_require__(110);
	var kernelfuture_1 = __webpack_require__(112);
	var serialize = __webpack_require__(113);
	var validate = __webpack_require__(109);
	/**
	 * The url for the kernel service.
	 */
	var KERNEL_SERVICE_URL = 'api/kernels';
	/**
	 * The url for the kernelspec service.
	 */
	var KERNELSPEC_SERVICE_URL = 'api/kernelspecs';
	/**
	 * An implementation of a kernel manager.
	 */
	var KernelManager = (function () {
	    /**
	     * Construct a new kernel manager.
	     *
	     * @param options - The default options for kernel.
	     */
	    function KernelManager(options) {
	        this._options = null;
	        this._options = utils.copy(options || {});
	    }
	    /**
	     * Get the kernel specs.  See also [[getKernelSpecs]].
	     *
	     * @param options - Overrides for the default options.
	     */
	    KernelManager.prototype.getSpecs = function (options) {
	        return getKernelSpecs(this._getOptions(options));
	    };
	    /**
	     * List the running kernels.  See also [[listRunningKernels]].
	     *
	     * @param options - Overrides for the default options.
	     */
	    KernelManager.prototype.listRunning = function (options) {
	        return listRunningKernels(this._getOptions(options));
	    };
	    /**
	     * Start a new kernel.  See also [[startNewKernel]].
	     *
	     * @param options - Overrides for the default options.
	     */
	    KernelManager.prototype.startNew = function (options) {
	        return startNewKernel(this._getOptions(options));
	    };
	    /**
	     * Find a kernel by id.
	     *
	     * @param options - Overrides for the default options.
	     */
	    KernelManager.prototype.findById = function (id, options) {
	        return findKernelById(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) {
	        if (options) {
	            options = this._getOptions(options);
	        }
	        else {
	            options = utils.copy(this._options);
	        }
	        return connectToKernel(id, options);
	    };
	    /**
	     * Get optionally overidden options.
	     */
	    KernelManager.prototype._getOptions = function (options) {
	        if (options) {
	            options = utils.extend(utils.copy(this._options), options);
	        }
	        else {
	            options = this._options;
	        }
	        return options;
	    };
	    return KernelManager;
	}());
	exports.KernelManager = KernelManager;
	/**
	 * Find a kernel by id.
	 *
	 * #### Notes
	 * If the kernel was already started via `startNewKernel`, we return its
	 * `IKernelId`.
	 *
	 * 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 findKernelById(id, options) {
	    var kernels = Private.runningKernels;
	    for (var clientId in kernels) {
	        var kernel = kernels[clientId];
	        if (kernel.id === id) {
	            var result = { id: kernel.id, name: kernel.name };
	            return Promise.resolve(result);
	        }
	    }
	    return Private.getKernelId(id, options).catch(function () {
	        return Private.typedThrow("No running kernel with id: " + id);
	    });
	}
	exports.findKernelById = findKernelById;
	/**
	 * Fetch 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 getKernelSpecs(options) {
	    options = options || {};
	    var baseUrl = options.baseUrl || utils.getBaseUrl();
	    var url = utils.urlPathJoin(baseUrl, KERNELSPEC_SERVICE_URL);
	    var ajaxSettings = utils.copy(options.ajaxSettings) || {};
	    ajaxSettings.method = 'GET';
	    ajaxSettings.dataType = 'json';
	    return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	        var err = new Error('Invalid KernelSpecs Model');
	        if (success.xhr.status !== 200) {
	            throw new Error('Invalid Response: ' + success.xhr.status);
	        }
	        var data = success.data;
	        if (!data.hasOwnProperty('default') ||
	            typeof data.default !== 'string') {
	            throw err;
	        }
	        if (!data.hasOwnProperty('kernelspecs')) {
	            throw err;
	        }
	        if (!data.kernelspecs.hasOwnProperty(data.default)) {
	            throw err;
	        }
	        var keys = Object.keys(data.kernelspecs);
	        for (var i = 0; i < keys.length; i++) {
	            var ks = data.kernelspecs[keys[i]];
	            validate.validateKernelSpec(ks);
	        }
	        return data;
	    });
	}
	exports.getKernelSpecs = getKernelSpecs;
	/**
	 * 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 listRunningKernels(options) {
	    options = options || {};
	    var baseUrl = options.baseUrl || utils.getBaseUrl();
	    var url = utils.urlPathJoin(baseUrl, KERNEL_SERVICE_URL);
	    var ajaxSettings = utils.copy(options.ajaxSettings) || {};
	    ajaxSettings.method = 'GET';
	    ajaxSettings.dataType = 'json';
	    ajaxSettings.cache = false;
	    return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	        if (success.xhr.status !== 200) {
	            throw Error('Invalid Status: ' + success.xhr.status);
	        }
	        if (!Array.isArray(success.data)) {
	            throw Error('Invalid kernel list');
	        }
	        for (var i = 0; i < success.data.length; i++) {
	            validate.validateKernelId(success.data[i]);
	        }
	        return success.data;
	    }, Private.onKernelError);
	}
	exports.listRunningKernels = listRunningKernels;
	/**
	 * 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 startNewKernel(options) {
	    options = options || {};
	    var baseUrl = options.baseUrl || utils.getBaseUrl();
	    var url = utils.urlPathJoin(baseUrl, KERNEL_SERVICE_URL);
	    var ajaxSettings = utils.copy(options.ajaxSettings) || {};
	    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 Error('Invalid Status: ' + success.xhr.status);
	        }
	        validate.validateKernelId(success.data);
	        return new Kernel(options, success.data.id);
	    }, Private.onKernelError);
	}
	exports.startNewKernel = startNewKernel;
	/**
	 * 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 connectToKernel(id, options) {
	    for (var clientId in Private.runningKernels) {
	        var kernel = Private.runningKernels[clientId];
	        if (kernel.id === id) {
	            return Promise.resolve(kernel.clone());
	        }
	    }
	    return Private.getKernelId(id, options).then(function (kernelId) {
	        return new Kernel(options, id);
	    }).catch(function () {
	        return Private.typedThrow("No running kernel with id: " + id);
	    });
	}
	exports.connectToKernel = connectToKernel;
	/**
	 * Create a well-formed Kernel Message.
	 */
	function createKernelMessage(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
	    };
	}
	exports.createKernelMessage = createKernelMessage;
	/**
	 * Implementation of the Kernel object
	 */
	var Kernel = (function () {
	    /**
	     * Construct a kernel object.
	     */
	    function Kernel(options, id) {
	        this._id = '';
	        this._name = '';
	        this._baseUrl = '';
	        this._wsUrl = '';
	        this._status = ikernel_1.KernelStatus.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._spec = null;
	        this._pendingMessages = [];
	        this.ajaxSettings = options.ajaxSettings || {};
	        this._name = options.name;
	        this._id = id;
	        this._baseUrl = options.baseUrl || utils.getBaseUrl();
	        this._wsUrl = options.wsUrl || utils.getWsUrl(this._baseUrl);
	        this._clientId = options.clientId || utils.uuid();
	        this._username = options.username || '';
	        this._futures = new Map();
	        this._commPromises = new Map();
	        this._comms = new Map();
	        this._createSocket();
	        Private.runningKernels[this._clientId] = this;
	    }
	    Object.defineProperty(Kernel.prototype, "statusChanged", {
	        /**
	         * A signal emitted when the kernel status changes.
	         */
	        get: function () {
	            return Private.statusChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Kernel.prototype, "iopubMessage", {
	        /**
	         * A signal emitted for iopub kernel messages.
	         */
	        get: function () {
	            return Private.iopubMessageSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Kernel.prototype, "unhandledMessage", {
	        /**
	         * A signal emitted for unhandled kernel message.
	         */
	        get: function () {
	            return Private.unhandledMessageSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Kernel.prototype, "id", {
	        /**
	         * The id of the server-side kernel.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._id;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Kernel.prototype, "name", {
	        /**
	         * The name of the server-side kernel.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._name;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Kernel.prototype, "username", {
	        /**
	         * The client username.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._username;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Kernel.prototype, "clientId", {
	        /**
	         * The client unique id.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._clientId;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Kernel.prototype, "status", {
	        /**
	         * The current status of the kernel.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._status;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Kernel.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(Kernel.prototype, "isDisposed", {
	        /**
	         * Test whether the kernel has been disposed.
	         *
	         * #### Notes
	         * This is a read-only property which is always safe to access.
	         */
	        get: function () {
	            return this._futures === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Clone the current kernel with a new clientId.
	     */
	    Kernel.prototype.clone = function () {
	        var options = {
	            baseUrl: this._baseUrl,
	            wsUrl: this._wsUrl,
	            name: this._name,
	            username: this._username,
	            ajaxSettings: this.ajaxSettings
	        };
	        return new Kernel(options, this._id);
	    };
	    /**
	     * Dispose of the resources held by the kernel.
	     */
	    Kernel.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._status = ikernel_1.KernelStatus.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._status = ikernel_1.KernelStatus.Dead;
	        this._targetRegistry = null;
	        phosphor_signaling_1.clearSignalData(this);
	        delete Private.runningKernels[this._clientId];
	    };
	    /**
	     * 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.
	     */
	    Kernel.prototype.sendShellMessage = function (msg, expectReply, disposeOnDone) {
	        var _this = this;
	        if (expectReply === void 0) { expectReply = false; }
	        if (disposeOnDone === void 0) { disposeOnDone = true; }
	        if (this.status === ikernel_1.KernelStatus.Dead) {
	            throw new Error('Kernel is dead');
	        }
	        if (!this._isReady) {
	            this._pendingMessages.push(msg);
	        }
	        else {
	            this._ws.send(serialize.serialize(msg));
	        }
	        var future = new kernelfuture_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.
	     */
	    Kernel.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.
	     */
	    Kernel.prototype.restart = function () {
	        this._clearState();
	        this._updateStatus('restarting');
	        return Private.restartKernel(this, this._baseUrl, this.ajaxSettings);
	    };
	    /**
	     * 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.
	     */
	    Kernel.prototype.shutdown = function () {
	        var _this = this;
	        this._clearState();
	        return Private.shutdownKernel(this, this._baseUrl, this.ajaxSettings)
	            .then(function () {
	            _this.dispose();
	        });
	    };
	    /**
	     * Send a `kernel_info_request` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](http://jupyter-client.readthedocs.org/en/latest/messaging.html#kernel-info).
	     *
	     * Fulfills with the `kernel_info_response` content when the shell reply is
	     * received and validated.
	     */
	    Kernel.prototype.kernelInfo = function () {
	        var options = {
	            msgType: 'kernel_info_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = createKernelMessage(options);
	        return Private.sendKernelMessage(this, msg);
	    };
	    /**
	     * Send a `complete_request` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](http://jupyter-client.readthedocs.org/en/latest/messaging.html#completion).
	     *
	     * Fulfills with the `complete_reply` content when the shell reply is
	     * received and validated.
	     */
	    Kernel.prototype.complete = function (contents) {
	        var options = {
	            msgType: 'complete_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = createKernelMessage(options, contents);
	        return Private.sendKernelMessage(this, msg);
	    };
	    /**
	     * Send an `inspect_request` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](http://jupyter-client.readthedocs.org/en/latest/messaging.html#introspection).
	     *
	     * Fulfills with the `inspect_reply` content when the shell reply is
	     * received and validated.
	     */
	    Kernel.prototype.inspect = function (contents) {
	        var options = {
	            msgType: 'inspect_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = createKernelMessage(options, contents);
	        return Private.sendKernelMessage(this, msg);
	    };
	    /**
	     * Send a `history_request` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](http://jupyter-client.readthedocs.org/en/latest/messaging.html#history).
	     *
	     * Fulfills with the `history_reply` content when the shell reply is
	     * received and validated.
	     */
	    Kernel.prototype.history = function (contents) {
	        var options = {
	            msgType: 'history_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = createKernelMessage(options, contents);
	        return Private.sendKernelMessage(this, msg);
	    };
	    /**
	     * Send an `execute_request` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](http://jupyter-client.readthedocs.org/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]]
	     */
	    Kernel.prototype.execute = function (contents, 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
	        };
	        contents = utils.extend(defaults, contents);
	        var msg = createKernelMessage(options, contents);
	        return this.sendShellMessage(msg, true, disposeOnDone);
	    };
	    /**
	     * Send an `is_complete_request` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](http://jupyter-client.readthedocs.org/en/latest/messaging.html#code-completeness).
	     *
	     * Fulfills with the `is_complete_response` content when the shell reply is
	     * received and validated.
	     */
	    Kernel.prototype.isComplete = function (contents) {
	        var options = {
	            msgType: 'is_complete_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = createKernelMessage(options, contents);
	        return Private.sendKernelMessage(this, msg);
	    };
	    /**
	     * Send a `comm_info_request` message.
	     *
	     * #### Notes
	     * Fulfills with the `comm_info_reply` content when the shell reply is
	     * received and validated.
	     */
	    Kernel.prototype.commInfo = function (contents) {
	        var options = {
	            msgType: 'comm_info_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = createKernelMessage(options, contents);
	        return Private.sendKernelMessage(this, msg);
	    };
	    /**
	     * Send an `input_reply` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](http://jupyter-client.readthedocs.org/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets).
	     */
	    Kernel.prototype.sendInputReply = function (contents) {
	        if (this.status === ikernel_1.KernelStatus.Dead) {
	            throw new Error('Kernel is dead');
	        }
	        var options = {
	            msgType: 'input_reply',
	            channel: 'stdin',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = createKernelMessage(options, contents);
	        if (!this._isReady) {
	            this._pendingMessages.push(msg);
	        }
	        else {
	            this._ws.send(serialize.serialize(msg));
	        }
	    };
	    /**
	     * 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`.
	     */
	    Kernel.prototype.registerCommTarget = function (targetName, callback) {
	        var _this = this;
	        this._targetRegistry[targetName] = callback;
	        return new phosphor_disposable_1.DisposableDelegate(function () {
	            delete _this._targetRegistry[targetName];
	        });
	    };
	    /**
	     * Connect to a comm, or create a new one.
	     *
	     * #### Notes
	     * If a client-side comm already exists, it is returned.
	     */
	    Kernel.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(targetName, commId, this._sendCommMessage.bind(this), function () {
	                _this._unregisterComm(comm.commId);
	            });
	            this._comms.set(commId, comm);
	        }
	        return comm;
	    };
	    /**
	     * Get the kernel spec associated with the kernel.
	     *
	     * #### Notes
	     * This value is cached and only fetched the first time it is requested.
	     */
	    Kernel.prototype.getKernelSpec = function () {
	        var _this = this;
	        if (this._spec) {
	            return Promise.resolve(this._spec);
	        }
	        var name = this.name;
	        var options = { baseUrl: this._baseUrl, ajaxSettings: this._ajaxSettings };
	        return getKernelSpecs(options).then(function (ids) {
	            var id = ids.kernelspecs[name];
	            if (!id) {
	                throw new Error("Could not find kernel spec for " + name);
	            }
	            _this._spec = id.spec;
	            return _this._spec;
	        });
	    };
	    /**
	     * Create the kernel websocket connection and add socket status handlers.
	     */
	    Kernel.prototype._createSocket = function () {
	        var _this = this;
	        var partialUrl = utils.urlPathJoin(this._wsUrl, KERNEL_SERVICE_URL, utils.urlJoinEncode(this._id));
	        console.log('Starting WebSocket:', partialUrl);
	        var url = (utils.urlPathJoin(partialUrl, 'channels') +
	            '?session_id=' + this._clientId);
	        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.
	     */
	    Kernel.prototype._onWSOpen = function (evt) {
	        this._reconnectAttempt = 0;
	        // Allow the message to get through.
	        this._isReady = true;
	        // Trigger a status response.
	        this.kernelInfo();
	        this._isReady = false;
	    };
	    /**
	     * Handle a websocket message, validating and routing appropriately.
	     */
	    Kernel.prototype._onWSMessage = function (evt) {
	        if (this.status === ikernel_1.KernelStatus.Dead) {
	            // If the socket is being closed, ignore any messages
	            return;
	        }
	        var msg = serialize.deserialize(evt.data);
	        var handled = false;
	        try {
	            validate.validateKernelMessage(msg);
	        }
	        catch (error) {
	            console.error(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;
	            }
	            this.iopubMessage.emit(msg);
	        }
	    };
	    /**
	     * Handle a websocket close event.
	     */
	    Kernel.prototype._onWSClose = function (evt) {
	        if (this.status === ikernel_1.KernelStatus.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');
	        }
	    };
	    /**
	     * Handle status iopub messages from the kernel.
	     */
	    Kernel.prototype._updateStatus = function (state) {
	        var status;
	        this._isReady = false;
	        switch (state) {
	            case 'starting':
	                status = ikernel_1.KernelStatus.Starting;
	                this._isReady = true;
	                break;
	            case 'idle':
	                status = ikernel_1.KernelStatus.Idle;
	                this._isReady = true;
	                break;
	            case 'busy':
	                status = ikernel_1.KernelStatus.Busy;
	                this._isReady = true;
	                break;
	            case 'restarting':
	                status = ikernel_1.KernelStatus.Restarting;
	                break;
	            case 'reconnecting':
	                status = ikernel_1.KernelStatus.Reconnecting;
	                break;
	            case 'dead':
	                status = ikernel_1.KernelStatus.Dead;
	                break;
	            default:
	                console.error('invalid kernel status:', state);
	                return;
	        }
	        if (status !== this._status) {
	            this._status = status;
	            Private.logKernelStatus(this);
	            this.statusChanged.emit(status);
	            if (status === ikernel_1.KernelStatus.Dead)
	                this.dispose();
	        }
	        if (this._isReady) {
	            this._sendPending();
	        }
	    };
	    /**
	     * Send pending messages to the kernel.
	     */
	    Kernel.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.
	     */
	    Kernel.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.
	     */
	    Kernel.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(content.target_name, content.comm_id, _this._sendCommMessage.bind(_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.
	     */
	    Kernel.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.
	     */
	    Kernel.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) {
	                console.error('Comm not found for comm id ' + content.comm_id);
	                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;
	            });
	        }
	    };
	    /**
	     * Send a comm message to the kernel.
	     */
	    Kernel.prototype._sendCommMessage = function (payload, disposeOnDone) {
	        if (disposeOnDone === void 0) { disposeOnDone = true; }
	        var options = {
	            msgType: payload.msgType,
	            channel: 'shell',
	            username: this.username,
	            session: this.clientId
	        };
	        var msg = createKernelMessage(options, payload.content, payload.metadata, payload.buffers);
	        return this.sendShellMessage(msg, false, disposeOnDone);
	    };
	    /**
	     * Unregister a comm instance.
	     */
	    Kernel.prototype._unregisterComm = function (commId) {
	        this._comms.delete(commId);
	        this._commPromises.delete(commId);
	    };
	    return Kernel;
	}());
	/**
	 * A private namespace for the Kernel.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when the kernel status changes.
	     */
	    Private.statusChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted for iopub kernel messages.
	     */
	    Private.iopubMessageSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted for unhandled kernel message.
	     */
	    Private.unhandledMessageSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A module private store for running kernels.
	     */
	    Private.runningKernels = Object.create(null);
	    /**
	     * Restart a kernel.
	     */
	    function restartKernel(kernel, baseUrl, ajaxSettings) {
	        if (kernel.status === ikernel_1.KernelStatus.Dead) {
	            return Promise.reject(new Error('Kernel is dead'));
	        }
	        var url = utils.urlPathJoin(baseUrl, KERNEL_SERVICE_URL, utils.urlJoinEncode(kernel.id, 'restart'));
	        ajaxSettings = ajaxSettings || {};
	        ajaxSettings.method = 'POST';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.contentType = 'application/json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw Error('Invalid Status: ' + success.xhr.status);
	            }
	            validate.validateKernelId(success.data);
	        }, onKernelError);
	    }
	    Private.restartKernel = restartKernel;
	    /**
	     * Interrupt a kernel.
	     */
	    function interruptKernel(kernel, baseUrl, ajaxSettings) {
	        if (kernel.status === ikernel_1.KernelStatus.Dead) {
	            return Promise.reject(new Error('Kernel is dead'));
	        }
	        var url = utils.urlPathJoin(baseUrl, KERNEL_SERVICE_URL, utils.urlJoinEncode(kernel.id, 'interrupt'));
	        ajaxSettings = ajaxSettings || {};
	        ajaxSettings.method = 'POST';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.contentType = 'application/json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 204) {
	                throw Error('Invalid Status: ' + success.xhr.status);
	            }
	        }, onKernelError);
	    }
	    Private.interruptKernel = interruptKernel;
	    /**
	     * Delete a kernel.
	     */
	    function shutdownKernel(kernel, baseUrl, ajaxSettings) {
	        if (kernel.status === ikernel_1.KernelStatus.Dead) {
	            return Promise.reject(new Error('Kernel is dead'));
	        }
	        var url = utils.urlPathJoin(baseUrl, KERNEL_SERVICE_URL, utils.urlJoinEncode(kernel.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 Error('Invalid Status: ' + success.xhr.status);
	            }
	        }, onKernelError);
	    }
	    Private.shutdownKernel = shutdownKernel;
	    /**
	     * Get a full kernel id model from the server by kernel id string.
	     */
	    function getKernelId(id, options) {
	        options = options || {};
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var url = utils.urlPathJoin(baseUrl, KERNEL_SERVICE_URL, id);
	        var ajaxSettings = options.ajaxSettings || {};
	        ajaxSettings.method = 'GET';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw Error('Invalid Status: ' + success.xhr.status);
	            }
	            var data = success.data;
	            validate.validateKernelId(data);
	            return data;
	        }, Private.onKernelError);
	    }
	    Private.getKernelId = getKernelId;
	    /**
	     * Log the current kernel status.
	     */
	    function logKernelStatus(kernel) {
	        if (kernel.status === ikernel_1.KernelStatus.Idle ||
	            kernel.status === ikernel_1.KernelStatus.Busy ||
	            kernel.status === ikernel_1.KernelStatus.Unknown) {
	            return;
	        }
	        var status = '';
	        switch (kernel.status) {
	            case ikernel_1.KernelStatus.Starting:
	                status = 'starting';
	                break;
	            case ikernel_1.KernelStatus.Restarting:
	                status = 'restarting';
	                break;
	            case ikernel_1.KernelStatus.Dead:
	                status = 'dead';
	                break;
	        }
	        console.log('Kernel: ' + status + ' (' + kernel.id + ')');
	    }
	    Private.logKernelStatus = logKernelStatus;
	    /**
	     * Handle an error on a kernel Ajax call.
	     */
	    function onKernelError(error) {
	        console.error('API request failed (' + error.statusText + '): ');
	        throw Error(error.statusText);
	    }
	    Private.onKernelError = onKernelError;
	    /**
	     * Send a kernel message to the kernel and return the contents of the response.
	     */
	    function sendKernelMessage(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 (msg) {
	                resolve(msg.content);
	            };
	        });
	    }
	    Private.sendKernelMessage = sendKernelMessage;
	    /**
	     * Throw a typed error.
	     */
	    function typedThrow(msg) {
	        throw new Error(msg);
	    }
	    Private.typedThrow = typedThrow;
	})(Private || (Private = {}));
	/**
	 * Comm channel handler.
	 */
	var Comm = (function (_super) {
	    __extends(Comm, _super);
	    /**
	     * Construct a new comm channel.
	     */
	    function Comm(target, id, msgFunc, disposeCb) {
	        _super.call(this, disposeCb);
	        this._target = '';
	        this._id = '';
	        this._onClose = null;
	        this._onMsg = null;
	        this._msgFunc = null;
	        this._target = target;
	        this._id = id;
	        this._msgFunc = msgFunc;
	    }
	    Object.defineProperty(Comm.prototype, "commId", {
	        /**
	         * The unique id for the comm channel.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._id;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Comm.prototype, "targetName", {
	        /**
	         * The target name for the comm channel.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._target;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Comm.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:** [[ICommClose]], [[close]]
	         */
	        set: function (cb) {
	            this._onClose = cb;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Comm.prototype, "onMsg", {
	        /**
	         * Get the callback for a comm message received event.
	         *
	         * **See also:** [[ICommMsg]]
	         */
	        get: function () {
	            return this._onMsg;
	        },
	        /**
	         * Set the callback for a comm message received event.
	         *
	         * **See also:** [[ICommMsg]]
	         */
	        set: function (cb) {
	            this._onMsg = cb;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Comm.prototype, "isDisposed", {
	        /**
	         * Test whether the comm has been disposed.
	         *
	         * #### Notes
	         * This is a read-only property which is always safe to access.
	         */
	        get: function () {
	            return (this._msgFunc === 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]]
	     */
	    Comm.prototype.open = function (data, metadata) {
	        var content = {
	            comm_id: this._id,
	            target_name: this._target,
	            data: data || {}
	        };
	        var payload = {
	            msgType: 'comm_open', content: content, metadata: metadata
	        };
	        if (this._msgFunc === void 0) {
	            return;
	        }
	        return this._msgFunc(payload);
	    };
	    /**
	     * Send a `comm_msg` message to the kernel.
	     *
	     * #### Notes
	     * This is a no-op if the comm has been closed.
	     *
	     * **See also:** [[ICommMsg]]
	     */
	    Comm.prototype.send = function (data, metadata, buffers, disposeOnDone) {
	        if (metadata === void 0) { metadata = {}; }
	        if (buffers === void 0) { buffers = []; }
	        if (disposeOnDone === void 0) { disposeOnDone = true; }
	        if (this.isDisposed) {
	            throw Error('Comm is closed');
	        }
	        var content = { comm_id: this._id, data: data };
	        var payload = {
	            msgType: 'comm_msg',
	            content: content,
	            metadata: metadata,
	            buffers: buffers
	        };
	        if (this._msgFunc === void 0) {
	            return;
	        }
	        return this._msgFunc(payload, disposeOnDone);
	    };
	    /**
	     * 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]]
	     */
	    Comm.prototype.close = function (data, metadata) {
	        if (this.isDisposed) {
	            return;
	        }
	        var content = { comm_id: this._id, data: data || {} };
	        var payload = {
	            msgType: 'comm_close', content: content, metadata: metadata
	        };
	        var future = this._msgFunc(payload);
	        var onClose = this._onClose;
	        if (onClose)
	            onClose(future.msg);
	        this.dispose();
	        return future;
	    };
	    /**
	     * Dispose of the resources held by the comm.
	     */
	    Comm.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._onClose = null;
	        this._onMsg = null;
	        this._msgFunc = null;
	        this._id = null;
	        _super.prototype.dispose.call(this);
	    };
	    return Comm;
	}(phosphor_disposable_1.DisposableDelegate));


/***/ },
/* 112 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_disposable_1 = __webpack_require__(8);
	/**
	 * Implementation of a kernel future.
	 */
	var KernelFutureHandler = (function (_super) {
	    __extends(KernelFutureHandler, _super);
	    /**
	     * Construct a new KernelFutureHandler.
	     */
	    function KernelFutureHandler(cb, msg, expectShell, disposeOnDone) {
	        _super.call(this, cb);
	        this._msg = null;
	        this._status = 0;
	        this._stdin = null;
	        this._iopub = null;
	        this._reply = null;
	        this._done = null;
	        this._disposeOnDone = true;
	        this._msg = msg;
	        if (!expectShell) {
	            this._setFlag(KernelFutureFlag.GotReply);
	        }
	        this._disposeOnDone = disposeOnDone;
	    }
	    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(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
	    });
	    /**
	     * Dispose and unregister the future.
	     */
	    KernelFutureHandler.prototype.dispose = function () {
	        this._stdin = null;
	        this._iopub = null;
	        this._reply = null;
	        this._done = null;
	        this._msg = 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(KernelFutureFlag.GotReply);
	        if (this._testFlag(KernelFutureFlag.GotIdle)) {
	            this._handleDone(msg);
	        }
	    };
	    KernelFutureHandler.prototype._handleStdin = function (msg) {
	        var stdin = this._stdin;
	        if (stdin)
	            stdin(msg);
	    };
	    KernelFutureHandler.prototype._handleIOPub = function (msg) {
	        var iopub = this._iopub;
	        if (iopub)
	            iopub(msg);
	        if (msg.header.msg_type === 'status' &&
	            msg.content.execution_state === 'idle') {
	            this._setFlag(KernelFutureFlag.GotIdle);
	            if (this._testFlag(KernelFutureFlag.GotReply)) {
	                this._handleDone(msg);
	            }
	        }
	    };
	    KernelFutureHandler.prototype._handleDone = function (msg) {
	        if (this.isDone) {
	            return;
	        }
	        this._setFlag(KernelFutureFlag.IsDone);
	        var done = this._done;
	        if (done)
	            done(msg);
	        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;
	}(phosphor_disposable_1.DisposableDelegate));
	exports.KernelFutureHandler = KernelFutureHandler;
	/**
	 * 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 || (KernelFutureFlag = {}));


/***/ },
/* 113 */
/***/ function(module, exports) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	/**
	 * 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 json_bytes = new Uint8Array(buf.slice(offsets[0], offsets[1]));
	    var msg = JSON.parse((new TextDecoder('utf8')).decode(json_bytes));
	    // 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 = offsets[i + 1] || buf.byteLength;
	        msg.buffers.push(new DataView(buf.slice(start, stop)));
	    }
	    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 json_utf8 = encoder.encode(JSON.stringify(msg, replace_buffers));
	    buffers.push(json_utf8.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 (i = 0; i + 1 < buffers.length; i++) {
	        offsets.push(offsets[offsets.length - 1] + buffers[i].byteLength);
	    }
	    var msg_buf = new Uint8Array(offsets[offsets.length - 1] + buffers[buffers.length - 1].byteLength);
	    // use DataView.setUint32 for network byte-order
	    var view = new DataView(msg_buf.buffer);
	    // write nbufs to first 4 bytes
	    view.setUint32(0, nbufs);
	    // write offsets to next 4 * nbufs bytes
	    for (i = 0; i < offsets.length; i++) {
	        view.setUint32(4 * (i + 1), offsets[i]);
	    }
	    // write all the buffers at their respective offsets
	    for (i = 0; i < buffers.length; i++) {
	        msg_buf.set(new Uint8Array(buffers[i]), offsets[i]);
	    }
	    return msg_buf.buffer;
	}
	/**
	 * Filter `"buffers"` key for `JSON.stringify`.
	 */
	function replace_buffers(key, value) {
	    if (key === 'buffers') {
	        return undefined;
	    }
	    return value;
	}


/***/ },
/* 114 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var utils = __webpack_require__(106);
	var phosphor_signaling_1 = __webpack_require__(22);
	var ikernel_1 = __webpack_require__(110);
	var kernel_1 = __webpack_require__(111);
	var validate = __webpack_require__(109);
	/**
	 * The url for the session service.
	 */
	var SESSION_SERVICE_URL = 'api/sessions';
	/**
	 * An implementation of a notebook session manager.
	 */
	var NotebookSessionManager = (function () {
	    /**
	     * Construct a new notebook session manager.
	     *
	     * @param options - The default options for each session.
	     */
	    function NotebookSessionManager(options) {
	        this._options = null;
	        this._options = utils.copy(options || {});
	    }
	    /**
	     * Get the available kernel specs. See also [[getKernelSpecs]].
	     *
	     * @param options - Overrides for the default options.
	     */
	    NotebookSessionManager.prototype.getSpecs = function (options) {
	        return kernel_1.getKernelSpecs(this._getOptions(options));
	    };
	    /**
	     * List the running sessions.  See also [[listRunningSessions]].
	     *
	     * @param options - Overrides for the default options.
	     */
	    NotebookSessionManager.prototype.listRunning = function (options) {
	        return listRunningSessions(this._getOptions(options));
	    };
	    /**
	     * Start a new session.  See also [[startNewSession]].
	     *
	     * @param options - Overrides for the default options, must include a
	     *   `'notebookPath'`.
	     */
	    NotebookSessionManager.prototype.startNew = function (options) {
	        return startNewSession(this._getOptions(options));
	    };
	    /**
	     * Find a session by id.
	     */
	    NotebookSessionManager.prototype.findById = function (id, options) {
	        return findSessionById(id, this._getOptions(options));
	    };
	    /**
	     * Find a session by notebook path.
	     */
	    NotebookSessionManager.prototype.findByPath = function (path, options) {
	        return findSessionByPath(path, this._getOptions(options));
	    };
	    /*
	     * Connect to a running session.  See also [[connectToSession]].
	     */
	    NotebookSessionManager.prototype.connectTo = function (id, options) {
	        return connectToSession(id, this._getOptions(options));
	    };
	    /**
	     * Get optionally overidden options.
	     */
	    NotebookSessionManager.prototype._getOptions = function (options) {
	        if (options) {
	            options = utils.extend(utils.copy(this._options), options);
	        }
	        else {
	            options = this._options;
	        }
	        return options;
	    };
	    return NotebookSessionManager;
	}());
	exports.NotebookSessionManager = NotebookSessionManager;
	/**
	 * List the running sessions.
	 *
	 * #### 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 listRunningSessions(options) {
	    options = options || {};
	    var baseUrl = options.baseUrl || utils.getBaseUrl();
	    var url = utils.urlPathJoin(baseUrl, SESSION_SERVICE_URL);
	    var ajaxSettings = utils.copy(options.ajaxSettings) || {};
	    ajaxSettings.method = 'GET';
	    ajaxSettings.dataType = 'json';
	    ajaxSettings.cache = false;
	    return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	        if (success.xhr.status !== 200) {
	            throw Error('Invalid Status: ' + success.xhr.status);
	        }
	        if (!Array.isArray(success.data)) {
	            throw Error('Invalid Session list');
	        }
	        for (var i = 0; i < success.data.length; i++) {
	            validate.validateSessionId(success.data[i]);
	        }
	        return Private.updateRunningSessions(success.data);
	    }, Private.onSessionError);
	}
	exports.listRunningSessions = listRunningSessions;
	/**
	 * Start a new session.
	 *
	 * #### 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 notebook 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 NotebookSession object. The promise is fulfilled
	 * when the session is created on the server, otherwise the promise is
	 * rejected.
	 */
	function startNewSession(options) {
	    if (options.notebookPath === void 0) {
	        return Promise.reject(new Error('Must specify a notebook path'));
	    }
	    return Private.startSession(options).then(function (sessionId) {
	        return Private.createSession(sessionId, options);
	    });
	}
	exports.startNewSession = startNewSession;
	/**
	 * Find a session by id.
	 *
	 * #### Notes
	 * If the session was already started via `startNewSession`, the existing
	 * NotebookSession 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 findSessionById(id, options) {
	    var sessions = Private.runningSessions;
	    for (var clientId in sessions) {
	        var session = sessions[clientId];
	        if (session.id === id) {
	            var sessionId = {
	                id: id,
	                notebook: { path: session.notebookPath },
	                kernel: { name: session.kernel.name, id: session.kernel.id }
	            };
	            return Promise.resolve(sessionId);
	        }
	    }
	    return Private.getSessionId(id, options).catch(function () {
	        var msg = "No running session for id: " + id;
	        return Private.typedThrow(msg);
	    });
	}
	exports.findSessionById = findSessionById;
	/**
	 * Find a session by notebook path.
	 *
	 * #### Notes
	 * If the session was already started via `startNewSession`, the existing
	 * NotebookSession 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 findSessionByPath(path, options) {
	    var sessions = Private.runningSessions;
	    for (var clientId in sessions) {
	        var session = sessions[clientId];
	        if (session.notebookPath === path) {
	            var sessionId = {
	                id: session.id,
	                notebook: { path: session.notebookPath },
	                kernel: { name: session.kernel.name, id: session.kernel.id }
	            };
	            return Promise.resolve(sessionId);
	        }
	    }
	    return listRunningSessions(options).then(function (sessionIds) {
	        for (var _i = 0, sessionIds_1 = sessionIds; _i < sessionIds_1.length; _i++) {
	            var sessionId = sessionIds_1[_i];
	            if (sessionId.notebook.path === path) {
	                return sessionId;
	            }
	        }
	        var msg = "No running session for path: " + path;
	        return Private.typedThrow(msg);
	    });
	}
	exports.findSessionByPath = findSessionByPath;
	/**
	 * Connect to a running notebook session.
	 *
	 * #### Notes
	 * If the session was already started via `startNewSession`, the existing
	 * NotebookSession 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 connectToSession(id, options) {
	    for (var clientId in Private.runningSessions) {
	        var session = Private.runningSessions[clientId];
	        if (session.id === id) {
	            return session.clone();
	        }
	    }
	    return Private.getSessionId(id, options).then(function (sessionId) {
	        return Private.createSession(sessionId, options);
	    }).catch(function () {
	        var msg = "No running session with id: " + id;
	        return Private.typedThrow(msg);
	    });
	}
	exports.connectToSession = connectToSession;
	/**
	 * 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 NotebookSession = (function () {
	    /**
	     * Construct a new session.
	     */
	    function NotebookSession(options, id, kernel) {
	        this._id = '';
	        this._notebookPath = '';
	        this._ajaxSettings = '';
	        this._kernel = null;
	        this._uuid = '';
	        this._url = '';
	        this._options = null;
	        this._updating = false;
	        this.ajaxSettings = options.ajaxSettings || {};
	        this._id = id;
	        this._notebookPath = options.notebookPath;
	        options.baseUrl = options.baseUrl || utils.getBaseUrl();
	        this._url = utils.urlPathJoin(options.baseUrl, SESSION_SERVICE_URL, this._id);
	        this._uuid = utils.uuid();
	        Private.runningSessions[this._uuid] = this;
	        this.setupKernel(kernel);
	        this._options = utils.copy(options);
	    }
	    Object.defineProperty(NotebookSession.prototype, "sessionDied", {
	        /**
	         * A signal emitted when the session dies.
	         */
	        get: function () {
	            return Private.sessionDiedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookSession.prototype, "kernelChanged", {
	        /**
	         * A signal emitted when the kernel changes.
	         */
	        get: function () {
	            return Private.kernelChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookSession.prototype, "statusChanged", {
	        /**
	         * A signal emitted when the kernel status changes.
	         */
	        get: function () {
	            return Private.statusChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookSession.prototype, "iopubMessage", {
	        /**
	         * A signal emitted for a kernel messages.
	         */
	        get: function () {
	            return Private.iopubMessageSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookSession.prototype, "unhandledMessage", {
	        /**
	         * A signal emitted for an unhandled kernel message.
	         */
	        get: function () {
	            return Private.unhandledMessageSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookSession.prototype, "notebookPathChanged", {
	        /**
	         * A signal emitted when the notebook path changes.
	         */
	        get: function () {
	            return Private.notebookPathChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookSession.prototype, "id", {
	        /**
	         * Get the session id.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._id;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookSession.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(NotebookSession.prototype, "notebookPath", {
	        /**
	         * Get the notebook path.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._notebookPath;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookSession.prototype, "status", {
	        /**
	         * The current status of the session.
	         *
	         * #### Notes
	         * This is a read-only property, and is a delegate to the kernel status.
	         */
	        get: function () {
	            return this._kernel ? this._kernel.status : ikernel_1.KernelStatus.Dead;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookSession.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(NotebookSession.prototype, "isDisposed", {
	        /**
	         * Test whether the session has been disposed.
	         *
	         * #### Notes
	         * This is a read-only property which is always safe to access.
	         */
	        get: function () {
	            return this._options === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Clone the current session with a new clientId.
	     */
	    NotebookSession.prototype.clone = function () {
	        var _this = this;
	        var options = this._getKernelOptions();
	        return kernel_1.connectToKernel(this.kernel.id, options).then(function (kernel) {
	            var options = utils.copy(_this._options);
	            options.ajaxSettings = _this.ajaxSettings;
	            return new NotebookSession(options, _this._id, kernel);
	        });
	    };
	    /**
	     * Update the session based on a session model from the server.
	     */
	    NotebookSession.prototype.update = function (id) {
	        var _this = this;
	        // Avoid a race condition if we are waiting for a REST call return.
	        if (this._updating) {
	            return Promise.resolve(void 0);
	        }
	        if (this._notebookPath !== id.notebook.path) {
	            this.notebookPathChanged.emit(id.notebook.path);
	        }
	        this._notebookPath = id.notebook.path;
	        if (id.kernel.id !== this._kernel.id) {
	            var options = this._getKernelOptions();
	            options.name = id.kernel.name;
	            return kernel_1.connectToKernel(id.kernel.id, options).then(function (kernel) {
	                _this.setupKernel(kernel);
	                _this.kernelChanged.emit(kernel);
	            });
	        }
	        return Promise.resolve(void 0);
	    };
	    /**
	     * Dispose of the resources held by the session.
	     */
	    NotebookSession.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        if (this._kernel) {
	            this._kernel.dispose();
	        }
	        this._options = null;
	        delete Private.runningSessions[this._uuid];
	        this._kernel = null;
	        phosphor_signaling_1.clearSignalData(this);
	    };
	    /**
	     * Rename or move a notebook.
	     *
	     * @param path - The new notebook path.
	     *
	     * #### Notes
	     * This uses the Notebook REST API, and the response is validated.
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     */
	    NotebookSession.prototype.renameNotebook = 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 notebook path.
	     */
	    NotebookSession.prototype.changeKernel = function (options) {
	        var _this = this;
	        if (this.isDisposed) {
	            return Promise.reject(new Error('Session is disposed'));
	        }
	        this._kernel.dispose();
	        var data = JSON.stringify({ kernel: options });
	        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.
	     */
	    NotebookSession.prototype.shutdown = function () {
	        var _this = this;
	        if (this.isDisposed) {
	            return Promise.reject(new Error('Session is disposed'));
	        }
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'DELETE';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(this._url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 204) {
	                throw Error('Invalid Status: ' + success.xhr.status);
	            }
	            _this._kernel.dispose();
	            _this._kernel = null;
	            _this.sessionDied.emit(void 0);
	        }, function (rejected) {
	            if (rejected.xhr.status === 410) {
	                throw Error('The kernel was deleted but the session was not');
	            }
	            Private.onSessionError(rejected);
	        });
	    };
	    /**
	     * Handle connections to a kernel.
	     */
	    NotebookSession.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.
	     */
	    NotebookSession.prototype.onKernelStatus = function (sender, state) {
	        this.statusChanged.emit(state);
	    };
	    /**
	     * Handle iopub kernel messages.
	     */
	    NotebookSession.prototype.onIopubMessage = function (sender, msg) {
	        this.iopubMessage.emit(msg);
	    };
	    /**
	     * Handle unhandled kernel messages.
	     */
	    NotebookSession.prototype.onUnhandledMessage = function (sender, msg) {
	        this.unhandledMessage.emit(msg);
	    };
	    /**
	     * Get the options used to create a new kernel.
	     */
	    NotebookSession.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 notebook path or the kernel.
	     */
	    NotebookSession.prototype._patch = function (data) {
	        var _this = this;
	        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(this._url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw Error('Invalid Status: ' + success.xhr.status);
	            }
	            var data = success.data;
	            validate.validateSessionId(data);
	            _this._updating = false;
	            return Private.updateById(data);
	        }, function (error) {
	            _this._updating = false;
	            return Private.onSessionError(error);
	        });
	    };
	    return NotebookSession;
	}());
	/**
	 * A namespace for notebook session private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when the session is shut down.
	     */
	    Private.sessionDiedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when the kernel changes.
	     */
	    Private.kernelChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when the session kernel status changes.
	     */
	    Private.statusChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted for iopub kernel messages.
	     */
	    Private.iopubMessageSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted for an unhandled kernel message.
	     */
	    Private.unhandledMessageSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when the notebook path changes.
	     */
	    Private.notebookPathChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * The running sessions.
	     */
	    Private.runningSessions = Object.create(null);
	    /**
	     * Create a new session, or return an existing session if a session if
	     * the notebook 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.notebookPath }
	        };
	        var ajaxSettings = utils.copy(options.ajaxSettings) || {};
	        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 Error('Invalid Status: ' + success.xhr.status);
	            }
	            validate.validateSessionId(success.data);
	            var data = success.data;
	            return updateById(data);
	        }, onSessionError);
	    }
	    Private.startSession = startSession;
	    /**
	     * Create a Promise for a kernel object given a sessionId and options.
	     */
	    function createKernel(sessionId, options) {
	        var kernelOptions = {
	            name: sessionId.kernel.name,
	            baseUrl: options.baseUrl || utils.getBaseUrl(),
	            wsUrl: options.wsUrl,
	            username: options.username,
	            clientId: options.clientId,
	            ajaxSettings: options.ajaxSettings
	        };
	        return kernel_1.connectToKernel(sessionId.kernel.id, kernelOptions);
	    }
	    Private.createKernel = createKernel;
	    /**
	     * Create a NotebookSession object.
	     *
	     * @returns - A promise that resolves with a started session.
	     */
	    function createSession(sessionId, options) {
	        return createKernel(sessionId, options).then(function (kernel) {
	            return new NotebookSession(options, sessionId.id, kernel);
	        }).catch(function (error) {
	            return typedThrow('Session failed to start: ' + error.message);
	        });
	    }
	    Private.createSession = createSession;
	    /**
	     * Get a full session id model from the server by session id string.
	     */
	    function getSessionId(id, options) {
	        options = options || {};
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var url = utils.urlPathJoin(baseUrl, SESSION_SERVICE_URL, id);
	        var ajaxSettings = options.ajaxSettings || {};
	        ajaxSettings.method = 'GET';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw Error('Invalid Status: ' + success.xhr.status);
	            }
	            var data = success.data;
	            validate.validateSessionId(data);
	            return updateById(data);
	        }, Private.onSessionError);
	    }
	    Private.getSessionId = getSessionId;
	    /**
	     * Update the running sessions based on new data from the server.
	     */
	    function updateRunningSessions(sessions) {
	        var promises = [];
	        for (var uuid in Private.runningSessions) {
	            var session = Private.runningSessions[uuid];
	            var updated = false;
	            for (var _i = 0, sessions_1 = sessions; _i < sessions_1.length; _i++) {
	                var sId = sessions_1[_i];
	                if (sId.id === session.id) {
	                    promises.push(session.update(sId));
	                    updated = true;
	                    break;
	                }
	            }
	            // If session is no longer running on disk, emit dead signal.
	            if (!updated && session.status !== ikernel_1.KernelStatus.Dead) {
	                session.sessionDied.emit(void 0);
	            }
	        }
	        return Promise.all(promises).then(function () { return sessions; });
	    }
	    Private.updateRunningSessions = updateRunningSessions;
	    /**
	     * Update the running sessions given an updated session Id.
	     */
	    function updateById(sessionId) {
	        var promises = [];
	        for (var uuid in Private.runningSessions) {
	            var session = Private.runningSessions[uuid];
	            if (session.id === sessionId.id) {
	                promises.push(session.update(sessionId));
	            }
	        }
	        return Promise.all(promises).then(function () { return sessionId; });
	    }
	    Private.updateById = updateById;
	    /**
	     * Handle an error on a session Ajax call.
	     */
	    function onSessionError(error) {
	        var text = (error.statusText ||
	            error.error.message ||
	            error.xhr.responseText);
	        console.error("API request failed (" + error.xhr.status + "):  " + text);
	        throw Error(text);
	    }
	    Private.onSessionError = onSessionError;
	    /**
	     * Throw a typed error.
	     */
	    function typedThrow(msg) {
	        throw new Error(msg);
	    }
	    Private.typedThrow = typedThrow;
	})(Private || (Private = {}));


/***/ },
/* 115 */
/***/ function(module, exports) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	/**
	 * The class name added to dialog instances.
	 */
	var DIALOG_CLASS = 'jp-Dialog';
	/**
	 * The class name added to dialog content node.
	 */
	var CONTENT_CLASS = 'jp-Dialog-content';
	/**
	 * The class name added to dialog header node.
	 */
	var HEADER_CLASS = 'jp-Dialog-header';
	/**
	 * The class name added to dialog title node.
	 */
	var TITLE_CLASS = 'jp-Dialog-title';
	/**
	 * The class name added to dialog body node.
	 */
	var BODY_CLASS = 'jp-Dialog-body';
	/**
	 * The class name added to a dialog body content node.
	 */
	var BODY_CONTENT_CLASS = 'jp-Dialog-bodyContent';
	/**
	 * The class name added to a dialog content node.
	 */
	var FOOTER_CLASS = 'jp-Dialog-footer';
	/**
	 * The class name added to a dialog button node.
	 */
	var BUTTON_CLASS = 'jp-Dialog-button';
	/**
	 * The class name added to a dialog button icon node.
	 */
	var BUTTON_ICON_CLASS = 'jp-Dialog-buttonIcon';
	/**
	 * The class name added to a dialog button text node.
	 */
	var BUTTON_TEXT_CLASS = 'jp-Dialog-buttonText';
	/*
	 * The class name added to dialog Confirm buttons.
	 */
	var OK_BUTTON_CLASS = 'jp-Dialog-okButton';
	/**
	 * The class name added to dialog Cancel buttons.
	 */
	var CANCEL_BUTTON_CLASS = 'jp-Dialog-cancelButton';
	/**
	 * The class name added to dialog input field wrappers.
	 */
	var INPUT_WRAPPER_CLASS = 'jp-Dialog-inputWrapper';
	/**
	 * The class name added to dialog input fields.
	 */
	var INPUT_CLASS = 'jp-Dialog-input';
	/**
	 * The class name added to dialog select wrappers.
	 */
	var SELECT_WRAPPER_CLASS = 'jp-Dialog-selectWrapper';
	/**
	 * The class anem added to dialog select nodes.
	 */
	var SELECT_CLASS = 'jp-Dialog-select';
	/**
	 * A default confirmation button.
	 */
	exports.okButton = {
	    text: 'OK',
	    className: OK_BUTTON_CLASS
	};
	/**
	 * A default cancel button.
	 */
	exports.cancelButton = {
	    text: 'CANCEL',
	    className: CANCEL_BUTTON_CLASS
	};
	/**
	 * Create a dialog and show it.
	 *
	 * @param options - The dialog setup options.
	 *
	 * @returns The button item that was selected.
	 */
	function showDialog(options) {
	    options = options || {};
	    var host = options.host || document.body;
	    options.host = host;
	    options.body = options.body || '';
	    exports.okButton.text = options.okText ? options.okText : 'OK';
	    var buttons = options.buttons || [exports.cancelButton, exports.okButton];
	    var buttonNodes = buttons.map(createButton);
	    var dialog = createDialog(options, buttonNodes);
	    host.appendChild(dialog);
	    // Focus the ok button if given.
	    var index = buttons.indexOf(exports.okButton);
	    if (index !== -1) {
	        buttonNodes[index].focus();
	    }
	    return new Promise(function (resolve, reject) {
	        buttonNodes.map(function (node) {
	            node.addEventListener('click', function (evt) {
	                if (node.contains(evt.target)) {
	                    host.removeChild(dialog);
	                    var button = buttons[buttonNodes.indexOf(node)];
	                    resolve(button);
	                }
	            });
	        });
	        dialog.addEventListener('keydown', function (evt) {
	            // Check for escape key
	            if (evt.keyCode === 27) {
	                host.removeChild(dialog);
	                resolve(null);
	            }
	        }, true);
	        dialog.addEventListener('contextmenu', function (evt) {
	            evt.preventDefault();
	            evt.stopPropagation();
	        }, true);
	    });
	}
	exports.showDialog = showDialog;
	/**
	 * Create the dialog node.
	 */
	function createDialog(options, buttonNodes) {
	    // Create the dialog nodes (except for the buttons).
	    var node = document.createElement('div');
	    var content = document.createElement('div');
	    var header = document.createElement('div');
	    var body = document.createElement('div');
	    var footer = document.createElement('div');
	    var title = document.createElement('span');
	    node.className = DIALOG_CLASS;
	    content.className = CONTENT_CLASS;
	    header.className = HEADER_CLASS;
	    body.className = BODY_CLASS;
	    footer.className = FOOTER_CLASS;
	    title.className = TITLE_CLASS;
	    node.appendChild(content);
	    content.appendChild(header);
	    content.appendChild(body);
	    content.appendChild(footer);
	    header.appendChild(title);
	    // Populate the nodes.
	    title.textContent = options.title || '';
	    var child;
	    if (typeof options.body === 'string') {
	        child = document.createElement('span');
	        child.innerHTML = options.body;
	    }
	    else if (options.body) {
	        child = options.body;
	        switch (child.tagName) {
	            case 'INPUT':
	                child = wrapInput(child);
	                break;
	            case 'SELECT':
	                child = wrapSelect(child);
	                break;
	            default:
	                child = styleElements(child);
	                break;
	        }
	    }
	    child.classList.add(BODY_CONTENT_CLASS);
	    body.appendChild(child);
	    buttonNodes.map(function (buttonNode) { footer.appendChild(buttonNode); });
	    return node;
	}
	/**
	 * Style the child elements of a parent element.
	 */
	function styleElements(element) {
	    for (var i = 0; i < element.children.length; i++) {
	        var child = element.children[i];
	        var next = child.nextSibling;
	        switch (child.tagName) {
	            case 'INPUT':
	                child = wrapInput(child);
	                element.insertBefore(child, next);
	                break;
	            case 'SELECT':
	                child = wrapSelect(child);
	                element.insertBefore(child, next);
	                break;
	        }
	    }
	    return element;
	}
	/**
	 * Create a node for a button item.
	 */
	function createButton(item) {
	    var button = document.createElement('button');
	    button.className = BUTTON_CLASS;
	    button.tabIndex = -1;
	    if (item.className) {
	        button.classList.add(item.className);
	    }
	    var icon = document.createElement('span');
	    icon.className = BUTTON_ICON_CLASS;
	    if (item.icon) {
	        icon.classList.add(item.icon);
	    }
	    var text = document.createElement('span');
	    text.className = BUTTON_TEXT_CLASS;
	    text.textContent = item.text;
	    button.appendChild(icon);
	    button.appendChild(text);
	    return button;
	}
	/**
	 * Wrap and style an input node.
	 */
	function wrapInput(input) {
	    var wrapper = document.createElement('div');
	    wrapper.className = INPUT_WRAPPER_CLASS;
	    wrapper.appendChild(input);
	    input.classList.add(INPUT_CLASS);
	    return wrapper;
	}
	/**
	 * Wrap and style a select node.
	 */
	function wrapSelect(select) {
	    var wrapper = document.createElement('div');
	    wrapper.className = SELECT_WRAPPER_CLASS;
	    wrapper.appendChild(select);
	    select.classList.add(SELECT_CLASS);
	    return wrapper;
	}


/***/ },
/* 116 */
/***/ function(module, exports, __webpack_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];
	}
	__export(__webpack_require__(117));
	__export(__webpack_require__(128));


/***/ },
/* 117 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var utils = __webpack_require__(106);
	var phosphor_signaling_1 = __webpack_require__(22);
	var json_1 = __webpack_require__(118);
	var metadata_1 = __webpack_require__(119);
	var output_area_1 = __webpack_require__(120);
	/**
	 * An implementation of the cell model.
	 */
	var CellModel = (function () {
	    /**
	     * Construct a cell model from optional cell content.
	     */
	    function CellModel(cell) {
	        this._metadata = Object.create(null);
	        this._cursors = Object.create(null);
	        this._source = '';
	        if (!cell) {
	            return;
	        }
	        this.source = cell.source;
	        var metadata = utils.copy(cell.metadata);
	        if (this.type !== 'raw') {
	            delete metadata['format'];
	        }
	        if (this.type !== 'code') {
	            delete metadata['collapsed'];
	            delete metadata['scrolled'];
	        }
	        this._metadata = metadata;
	    }
	    Object.defineProperty(CellModel.prototype, "contentChanged", {
	        /**
	         * A signal emitted when the state of the model changes.
	         */
	        get: function () {
	            return Private.contentChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CellModel.prototype, "stateChanged", {
	        /**
	         * A signal emitted when a model state changes.
	         */
	        get: function () {
	            return Private.stateChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CellModel.prototype, "metadataChanged", {
	        /**
	         * A signal emitted when a metadata field changes.
	         */
	        get: function () {
	            return Private.metadataChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CellModel.prototype, "source", {
	        /**
	         * The input content of the cell.
	         */
	        get: function () {
	            return this._source;
	        },
	        set: function (newValue) {
	            if (this._source === newValue) {
	                return;
	            }
	            var oldValue = this._source;
	            this._source = newValue;
	            this.contentChanged.emit(void 0);
	            this.stateChanged.emit({ name: 'source', oldValue: oldValue, newValue: newValue });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CellModel.prototype, "isDisposed", {
	        /**
	         * Get whether the model is disposed.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._metadata === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the model.
	     */
	    CellModel.prototype.dispose = function () {
	        // Do nothing if already disposed.
	        if (this.isDisposed) {
	            return;
	        }
	        phosphor_signaling_1.clearSignalData(this);
	        for (var key in this._cursors) {
	            this._cursors[key].dispose();
	        }
	        this._cursors = null;
	        this._metadata = null;
	    };
	    /**
	     * Serialize the model to JSON.
	     */
	    CellModel.prototype.toJSON = function () {
	        return {
	            cell_type: this.type,
	            source: this.source,
	            metadata: utils.copy(this._metadata)
	        };
	    };
	    /**
	     * Get a metadata cursor for the cell.
	     *
	     * #### Notes
	     * Metadata associated with the nbformat spec are set directly
	     * on the model.  This method is used to interact with a namespaced
	     * set of metadata on the cell.
	     */
	    CellModel.prototype.getMetadata = function (name) {
	        var _this = this;
	        if (name in this._cursors) {
	            return this._cursors[name];
	        }
	        var cursor = new metadata_1.MetadataCursor(name, function () {
	            return _this._metadata[name];
	        }, function (value) {
	            _this.setCursorData(name, value);
	        });
	        this._cursors[name] = cursor;
	        return cursor;
	    };
	    /**
	     * List the metadata namespace keys for the notebook.
	     *
	     * #### Notes
	     * Metadata associated with the nbformat are not included.
	     */
	    CellModel.prototype.listMetadata = function () {
	        return Object.keys(this._metadata);
	    };
	    /**
	     * Set the cursor data for a given field.
	     */
	    CellModel.prototype.setCursorData = function (name, newValue) {
	        var oldValue = this._metadata[name];
	        if (json_1.deepEqual(oldValue, newValue)) {
	            return;
	        }
	        this._metadata[name] = newValue;
	        this.contentChanged.emit(void 0);
	        this.metadataChanged.emit({ name: name, oldValue: oldValue, newValue: newValue });
	    };
	    return CellModel;
	}());
	exports.CellModel = CellModel;
	/**
	 * An implementation of a raw cell model.
	 */
	var RawCellModel = (function (_super) {
	    __extends(RawCellModel, _super);
	    function RawCellModel() {
	        _super.apply(this, arguments);
	    }
	    Object.defineProperty(RawCellModel.prototype, "type", {
	        /**
	         * The type of the cell.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return 'raw';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return RawCellModel;
	}(CellModel));
	exports.RawCellModel = RawCellModel;
	/**
	 * An implementation of a markdown cell model.
	 */
	var MarkdownCellModel = (function (_super) {
	    __extends(MarkdownCellModel, _super);
	    function MarkdownCellModel() {
	        _super.apply(this, arguments);
	    }
	    Object.defineProperty(MarkdownCellModel.prototype, "type", {
	        /**
	         * The type of the cell.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return 'markdown';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return MarkdownCellModel;
	}(CellModel));
	exports.MarkdownCellModel = MarkdownCellModel;
	/**
	 * An implementation of a code cell Model.
	 */
	var CodeCellModel = (function (_super) {
	    __extends(CodeCellModel, _super);
	    /**
	     * Construct a new code cell with optional original cell content.
	     */
	    function CodeCellModel(cell) {
	        var _this = this;
	        _super.call(this, cell);
	        this._outputs = null;
	        this._executionCount = null;
	        this._outputs = new output_area_1.ObservableOutputs();
	        if (cell && cell.cell_type === 'code') {
	            this.executionCount = cell.execution_count;
	            this._outputs.assign(cell.outputs);
	        }
	        this._outputs.changed.connect(function () {
	            _this.contentChanged.emit(void 0);
	        });
	    }
	    Object.defineProperty(CodeCellModel.prototype, "type", {
	        /**
	         * The type of the cell.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return 'code';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeCellModel.prototype, "executionCount", {
	        /**
	         * The execution count of the cell.
	         */
	        get: function () {
	            return this._executionCount;
	        },
	        set: function (newValue) {
	            if (newValue === this._executionCount) {
	                return;
	            }
	            var oldValue = this.executionCount;
	            this._executionCount = newValue;
	            this.contentChanged.emit(void 0);
	            this.stateChanged.emit({ name: 'executionCount', oldValue: oldValue, newValue: newValue });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeCellModel.prototype, "outputs", {
	        /**
	         * The cell outputs.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._outputs;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the model.
	     */
	    CodeCellModel.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._outputs.clear(false);
	        this._outputs = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Serialize the model to JSON.
	     */
	    CodeCellModel.prototype.toJSON = function () {
	        var cell = _super.prototype.toJSON.call(this);
	        cell.execution_count = this.executionCount;
	        var outputs = this.outputs;
	        cell.outputs = [];
	        for (var i = 0; i < outputs.length; i++) {
	            cell.outputs.push(outputs.get(i));
	        }
	        return cell;
	    };
	    return CodeCellModel;
	}(CellModel));
	exports.CodeCellModel = CodeCellModel;
	/**
	 * A namespace for cell private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when the state of the model changes.
	     */
	    Private.contentChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when a model state changes.
	     */
	    Private.stateChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when a metadata field changes.
	     */
	    Private.metadataChangedSignal = new phosphor_signaling_1.Signal();
	})(Private || (Private = {}));


/***/ },
/* 118 */
/***/ function(module, exports) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	"use strict";
	/**
	 * Test whether a JSON value is a primitive.
	 *
	 * @param value - The JSON value of interest.
	 *
	 * @returns `true` if the value is a primitive or `null`,
	 *   `false` otherwise.
	 */
	function isPrimitive(value) {
	    return (value === null ||
	        typeof value === 'boolean' ||
	        typeof value === 'number' ||
	        typeof value === 'string');
	}
	exports.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);
	}
	exports.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);
	}
	exports.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;
	    }
	    // Bail if either is `undefined`.
	    if (!first || !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 Private.arrayEqual(first, second);
	    }
	    // At this point, they must both be objects.
	    return Private.objectEqual(first, second);
	}
	exports.deepEqual = deepEqual;
	/**
	 * The namespace for the private module data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Compare two JSON arrays for deep equality.
	     */
	    function arrayEqual(first, second) {
	        // 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;
	    }
	    Private.arrayEqual = arrayEqual;
	    /**
	     * Compare two JSON objects for deep equality.
	     */
	    function objectEqual(first, second) {
	        // Get the keys for each object.
	        var k1 = Object.keys(first);
	        var k2 = Object.keys(second);
	        // Test the keys for equal length.
	        if (k1.length !== k2.length) {
	            return false;
	        }
	        // Sort the keys for equivalent order.
	        k1.sort();
	        k2.sort();
	        // Compare the keys for equality.
	        for (var i = 0, n = k1.length; i < n; ++i) {
	            if (k1[i] !== k2[i]) {
	                return false;
	            }
	        }
	        // Compare the values for equality.
	        for (var i = 0, n = k1.length; i < n; ++i) {
	            if (!deepEqual(first[k1[i]], second[k1[i]])) {
	                return false;
	            }
	        }
	        // At this point, the objects are equal.
	        return true;
	    }
	    Private.objectEqual = objectEqual;
	})(Private || (Private = {}));


/***/ },
/* 119 */
/***/ function(module, exports) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	/**
	 * An implementation of a metadata cursor.
	 */
	var MetadataCursor = (function () {
	    /**
	     * Construct a new metadata cursor.
	     *
	     * @param name - The metadata namespace key.
	     *
	     * @param read - The read callback.
	     *
	     * @param write - The write callback.
	     */
	    function MetadataCursor(name, read, write) {
	        this._name = '';
	        this._read = null;
	        this._write = null;
	        this._name = name;
	        this._read = read;
	        this._write = write;
	    }
	    Object.defineProperty(MetadataCursor.prototype, "name", {
	        /**
	         * Get the namespace key of the metadata.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._name;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources used by the cursor.
	     *
	     * #### Notes
	     * This is not meant to be called by user code.
	     */
	    MetadataCursor.prototype.dispose = function () {
	        this._read = null;
	        this._write = null;
	    };
	    /**
	     * Get the value of the namespace data.
	     */
	    MetadataCursor.prototype.getValue = function () {
	        var read = this._read;
	        return read();
	    };
	    /**
	     * Set the value of the namespace data.
	     */
	    MetadataCursor.prototype.setValue = function (value) {
	        var write = this._write;
	        write(value);
	    };
	    return MetadataCursor;
	}());
	exports.MetadataCursor = MetadataCursor;


/***/ },
/* 120 */
/***/ function(module, exports, __webpack_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];
	}
	__export(__webpack_require__(121));
	__export(__webpack_require__(124));


/***/ },
/* 121 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_observablelist_1 = __webpack_require__(122);
	var nbformat_1 = __webpack_require__(123);
	/**
	 * An observable list that handles output area data.
	 */
	var ObservableOutputs = (function (_super) {
	    __extends(ObservableOutputs, _super);
	    function ObservableOutputs() {
	        _super.apply(this, arguments);
	        this._clearNext = false;
	    }
	    /**
	     * Add an output, which may be combined with previous output
	     * (e.g. for streams).
	     */
	    ObservableOutputs.prototype.add = function (output) {
	        // If we received a delayed clear message, then clear now.
	        if (this._clearNext) {
	            this.clear();
	            this._clearNext = false;
	        }
	        // Consolidate outputs if they are stream outputs of the same kind.
	        var index = this.length - 1;
	        var lastOutput = this.get(index);
	        if (nbformat_1.nbformat.isStream(output)
	            && lastOutput && nbformat_1.nbformat.isStream(lastOutput)
	            && output.name === lastOutput.name) {
	            // 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.
	            var text = output.text;
	            output.text = lastOutput.text + text;
	            this.set(index, output);
	            return index;
	        }
	        else {
	            switch (output.output_type) {
	                case 'stream':
	                case 'execute_result':
	                case 'display_data':
	                case 'error':
	                    return _super.prototype.add.call(this, output);
	                default:
	                    break;
	            }
	        }
	        return -1;
	    };
	    /**
	     * Clear all of the output.
	     *
	     * @param wait Delay clearing the output until the next message is added.
	     */
	    ObservableOutputs.prototype.clear = function (wait) {
	        if (wait === void 0) { wait = false; }
	        if (wait) {
	            this._clearNext = true;
	            return [];
	        }
	        return _super.prototype.clear.call(this);
	    };
	    return ObservableOutputs;
	}(phosphor_observablelist_1.ObservableList));
	exports.ObservableOutputs = ObservableOutputs;
	/**
	 * Execute code on a kernel and send outputs to an observable output.
	 */
	function executeCode(code, kernel, outputs) {
	    var exRequest = {
	        code: code,
	        silent: false,
	        store_history: true,
	        stop_on_error: true,
	        allow_stdin: true
	    };
	    outputs.clear();
	    return new Promise(function (resolve, reject) {
	        var future = kernel.execute(exRequest);
	        future.onIOPub = (function (msg) {
	            var model = msg.content;
	            if (model !== void 0) {
	                model.output_type = msg.header.msg_type;
	                outputs.add(model);
	            }
	        });
	        future.onReply = (function (msg) {
	            resolve(msg.content);
	        });
	    });
	}
	exports.executeCode = executeCode;


/***/ },
/* 122 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var arrays = __webpack_require__(3);
	var phosphor_signaling_1 = __webpack_require__(22);
	/**
	 * An enum of the change types which occur on an observable list.
	 */
	(function (ListChangeType) {
	    /**
	     * An item was added to the list.
	     */
	    ListChangeType[ListChangeType["Add"] = 0] = "Add";
	    /**
	     * An item was moved in the list.
	     */
	    ListChangeType[ListChangeType["Move"] = 1] = "Move";
	    /**
	     * An item was removed from the list.
	     */
	    ListChangeType[ListChangeType["Remove"] = 2] = "Remove";
	    /**
	     * Items were replaced in the list.
	     */
	    ListChangeType[ListChangeType["Replace"] = 3] = "Replace";
	    /**
	     * An item was set in the list.
	     */
	    ListChangeType[ListChangeType["Set"] = 4] = "Set";
	})(exports.ListChangeType || (exports.ListChangeType = {}));
	var ListChangeType = exports.ListChangeType;
	/**
	 * A concrete implementation of [[IObservableList]].
	 */
	var ObservableList = (function () {
	    /**
	     * Construct a new observable list.
	     *
	     * @param items - The initial items for the list.
	     */
	    function ObservableList(items) {
	        this.internal = items ? items.slice() : [];
	    }
	    Object.defineProperty(ObservableList.prototype, "changed", {
	        /**
	         * A signal emitted when the list has changed.
	         *
	         * #### Notes
	         * This is a pure delegate to the [[changedSignal]].
	         */
	        get: function () {
	            return ObservableList.changedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ObservableList.prototype, "length", {
	        /**
	         * The number of items in the list.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this.internal.length;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the item at a specific index in the list.
	     *
	     * @param index - The index of the item of interest. If this is
	     *   negative, it is offset from the end of the list.
	     *
	     * @returns The item at the specified index, or `undefined` if the
	     *   index is out of range.
	     */
	    ObservableList.prototype.get = function (index) {
	        return this.internal[this._norm(index)];
	    };
	    /**
	     * Test whether the list contains a specific item.
	     *
	     * @param item - The item of interest.
	     *
	     * @returns `true` if the list contains the item, `false` otherwise.
	     */
	    ObservableList.prototype.contains = function (item) {
	        return this.internal.indexOf(item) !== -1;
	    };
	    /**
	     * Get the index of the first occurence of an item in the list.
	     *
	     * @param item - The item of interest.
	     *
	     * @returns The index of the specified item or `-1` if the item is
	     *   not contained in the list.
	     */
	    ObservableList.prototype.indexOf = function (item) {
	        return this.internal.indexOf(item);
	    };
	    /**
	     * Get a shallow copy of a portion of the list.
	     *
	     * @param start - The start index of the slice, inclusive. If this is
	     *   negative, it is offset from the end of the list. If this is not
	     *   provided, it defaults to `0`. In all cases, it is clamped to the
	     *   bounds of the list.
	     *
	     * @param end - The end index of the slice, exclusive. If this is
	     *   negative, it is offset from the end of the list. If this is not
	     *   provided, it defaults to `length`. In all cases, it is clamped
	     *   to the bounds of the list.
	     *
	     * @returns A new array containing the specified range of items.
	     */
	    ObservableList.prototype.slice = function (start, end) {
	        return this.internal.slice(start, end);
	    };
	    /**
	     * Set the item at a specific index.
	     *
	     * @param index - The index of interest. If this is negative, it is
	     *   offset from the end of the list.
	     *
	     * @param item - The item to set at the index.
	     *
	     * @returns The item which occupied the index, or `undefined` if the
	     *   index is out of range.
	     */
	    ObservableList.prototype.set = function (index, item) {
	        var i = this._norm(index);
	        if (!this._check(i))
	            return void 0;
	        return this.setItem(i, item);
	    };
	    /**
	     * Replace the contents of the list with the specified items.
	     *
	     * @param items - The items to assign to the list.
	     *
	     * @returns An array of the previous list items.
	     *
	     * #### Notes
	     * This is equivalent to `list.replace(0, list.length, items)`.
	     */
	    ObservableList.prototype.assign = function (items) {
	        return this.replaceItems(0, this.internal.length, items);
	    };
	    /**
	     * Add an item to the end of the list.
	     *
	     * @param item - The item to add to the list.
	     *
	     * @returns The index at which the item was added.
	     */
	    ObservableList.prototype.add = function (item) {
	        return this.addItem(this.internal.length, item);
	    };
	    /**
	     * Insert an item into the list at a specific index.
	     *
	     * @param index - The index at which to insert the item. If this is
	     *   negative, it is offset from the end of the list. In all cases,
	     *   it is clamped to the bounds of the list.
	     *
	     * @param item - The item to insert into the list.
	     *
	     * @returns The index at which the item was inserted.
	     */
	    ObservableList.prototype.insert = function (index, item) {
	        return this.addItem(this._clamp(index), item);
	    };
	    /**
	     * Move an item from one index to another.
	     *
	     * @param fromIndex - The index of the item of interest. If this is
	     *   negative, it is offset from the end of the list.
	     *
	     * @param toIndex - The desired index for the item. If this is
	     *   negative, it is offset from the end of the list.
	     *
	     * @returns `true` if the item was moved, `false` otherwise.
	     */
	    ObservableList.prototype.move = function (fromIndex, toIndex) {
	        var i = this._norm(fromIndex);
	        if (!this._check(i))
	            return false;
	        var j = this._norm(toIndex);
	        if (!this._check(j))
	            return false;
	        return this.moveItem(i, j);
	    };
	    /**
	     * Remove the first occurrence of a specific item from the list.
	     *
	     * @param item - The item to remove from the list.
	     *
	     * @return The index occupied by the item, or `-1` if the item is
	     *   not contained in the list.
	     */
	    ObservableList.prototype.remove = function (item) {
	        var i = this.internal.indexOf(item);
	        if (i !== -1)
	            this.removeItem(i);
	        return i;
	    };
	    /**
	     * Remove the item at a specific index.
	     *
	     * @param index - The index of the item of interest. If this is
	     *   negative, it is offset from the end of the list.
	     *
	     * @returns The item at the specified index, or `undefined` if the
	     *   index is out of range.
	     */
	    ObservableList.prototype.removeAt = function (index) {
	        var i = this._norm(index);
	        if (!this._check(i))
	            return void 0;
	        return this.removeItem(i);
	    };
	    /**
	     * Replace items at a specific location in the list.
	     *
	     * @param index - The index at which to modify the list. If this is
	     *   negative, it is offset from the end of the list. In all cases,
	     *   it is clamped to the bounds of the list.
	     *
	     * @param count - The number of items to remove at the given index.
	     *   This is clamped to the length of the list.
	     *
	     * @param items - The items to insert at the specified index.
	     *
	     * @returns An array of the items removed from the list.
	     */
	    ObservableList.prototype.replace = function (index, count, items) {
	        return this.replaceItems(this._norm(index), this._limit(count), items);
	    };
	    /**
	     * Remove all items from the list.
	     *
	     * @returns An array of the items removed from the list.
	     *
	     * #### Notes
	     * This is equivalent to `list.replace(0, list.length, [])`.
	     */
	    ObservableList.prototype.clear = function () {
	        return this.replaceItems(0, this.internal.length, []);
	    };
	    /**
	     * Add an item to the list at the specified index.
	     *
	     * @param index - The index at which to add the item. This must be
	     *   an integer in the range `[0, internal.length]`.
	     *
	     * @param item - The item to add at the specified index.
	     *
	     * @returns The index at which the item was added.
	     *
	     * #### Notes
	     * This may be reimplemented by subclasses to customize the behavior.
	     */
	    ObservableList.prototype.addItem = function (index, item) {
	        var i = arrays.insert(this.internal, index, item);
	        this.changed.emit({
	            type: ListChangeType.Add,
	            newIndex: i,
	            newValue: item,
	            oldIndex: -1,
	            oldValue: void 0,
	        });
	        return i;
	    };
	    /**
	     * Move an item in the list from one index to another.
	     *
	     * @param fromIndex - The initial index of the item. This must be
	     *   an integer in the range `[0, internal.length)`.
	     *
	     * @param toIndex - The desired index for the item. This must be
	     *   an integer in the range `[0, internal.length)`.
	     *
	     * @returns `true` if the item was moved, `false` otherwise.
	     *
	     * #### Notes
	     * This may be reimplemented by subclasses to customize the behavior.
	     */
	    ObservableList.prototype.moveItem = function (fromIndex, toIndex) {
	        if (!arrays.move(this.internal, fromIndex, toIndex)) {
	            return false;
	        }
	        var item = this.internal[toIndex];
	        this.changed.emit({
	            type: ListChangeType.Move,
	            newIndex: toIndex,
	            newValue: item,
	            oldIndex: fromIndex,
	            oldValue: item,
	        });
	        return true;
	    };
	    /**
	     * Remove the item from the list at the specified index.
	     *
	     * @param index - The index of the item to remove. This must be
	     *   an integer in the range `[0, internal.length)`.
	     *
	     * @returns The item removed from the list.
	     *
	     * #### Notes
	     * This may be reimplemented by subclasses to customize the behavior.
	     */
	    ObservableList.prototype.removeItem = function (index) {
	        var item = arrays.removeAt(this.internal, index);
	        this.changed.emit({
	            type: ListChangeType.Remove,
	            newIndex: -1,
	            newValue: void 0,
	            oldIndex: index,
	            oldValue: item,
	        });
	        return item;
	    };
	    /**
	     * Replace items at a specific location in the list.
	     *
	     * @param index - The index at which to modify the list. This must
	     *   be an integer in the range `[0, internal.length]`.
	     *
	     * @param count - The number of items to remove from the list. This
	     *   must be an integer in the range `[0, internal.length]`.
	     *
	     * @param items - The items to insert at the specified index.
	     *
	     * @returns An array of the items removed from the list.
	     *
	     * #### Notes
	     * This may be reimplemented by subclasses to customize the behavior.
	     */
	    ObservableList.prototype.replaceItems = function (index, count, items) {
	        var old = (_a = this.internal).splice.apply(_a, [index, count].concat(items));
	        this.changed.emit({
	            type: ListChangeType.Replace,
	            newIndex: index,
	            newValue: items,
	            oldIndex: index,
	            oldValue: old,
	        });
	        return old;
	        var _a;
	    };
	    /**
	     * Set the item at a specific index in the list.
	     *
	     * @param index - The index of interest. This must be an integer in
	     *   the range `[0, internal.length)`.
	     *
	     * @param item - The item to set at the index.
	     *
	     * @returns The item which previously occupied the specified index.
	     *
	     * #### Notes
	     * This may be reimplemented by subclasses to customize the behavior.
	     */
	    ObservableList.prototype.setItem = function (index, item) {
	        var old = this.internal[index];
	        this.internal[index] = item;
	        this.changed.emit({
	            type: ListChangeType.Set,
	            newIndex: index,
	            newValue: item,
	            oldIndex: index,
	            oldValue: old,
	        });
	        return old;
	    };
	    /**
	     * Normalize an index and offset negative values from the list end.
	     */
	    ObservableList.prototype._norm = function (i) {
	        return i < 0 ? Math.floor(i) + this.internal.length : Math.floor(i);
	    };
	    /**
	     * Check whether a normalized index is in range.
	     */
	    ObservableList.prototype._check = function (i) {
	        return i >= 0 && i < this.internal.length;
	    };
	    /**
	     * Normalize and clamp an index to the list bounds.
	     */
	    ObservableList.prototype._clamp = function (i) {
	        return Math.max(0, Math.min(this._norm(i), this.internal.length));
	    };
	    /**
	     * Normalize and limit a count to the length of the list.
	     */
	    ObservableList.prototype._limit = function (c) {
	        return Math.max(0, Math.min(Math.floor(c), this.internal.length));
	    };
	    /**
	     * A signal emitted when the list has changed.
	     *
	     * **See also:** [[changed]]
	     */
	    ObservableList.changedSignal = new phosphor_signaling_1.Signal();
	    return ObservableList;
	})();
	exports.ObservableList = ObservableList;
	//# sourceMappingURL=index.js.map

/***/ },
/* 123 */
/***/ function(module, exports) {

	// Notebook format interfaces
	// https://nbformat.readthedocs.org/en/latest/format_description.html
	// https://github.com/jupyter/nbformat/blob/master/nbformat/v4/nbformat.v4.schema.json
	"use strict";
	/**
	 * 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 = 0;
	    /**
	     * Check if cell is of markdown type.
	     */
	    function isMarkdownCell(d) {
	        return d.cell_type === 'markdown';
	    }
	    nbformat.isMarkdownCell = isMarkdownCell;
	    /**
	     * Check if cell is of code type.
	     */
	    function isCodeCell(d) {
	        return d.cell_type === 'code';
	    }
	    nbformat.isCodeCell = isCodeCell;
	    /**
	     * Check if cell is of raw type.
	     */
	    function isRawCell(d) {
	        return d.cell_type === 'raw';
	    }
	    nbformat.isRawCell = isRawCell;
	    /**
	     * Check if output is an `execute_result`.
	     */
	    function isExecuteResult(d) {
	        return d.output_type === 'execute_result';
	    }
	    nbformat.isExecuteResult = isExecuteResult;
	    /**
	     * Check if output is a `display_data`.
	     */
	    function isDisplayData(d) {
	        return d.output_type === 'display_data';
	    }
	    nbformat.isDisplayData = isDisplayData;
	    /**
	     * Check if output is `stream`.
	     */
	    function isStream(d) {
	        return d.output_type === 'stream';
	    }
	    nbformat.isStream = isStream;
	    /**
	     * Check if output is `error`.
	     */
	    function isError(d) {
	        return d.output_type === 'error';
	    }
	    nbformat.isError = isError;
	})(nbformat = exports.nbformat || (exports.nbformat = {}));


/***/ },
/* 124 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_observablelist_1 = __webpack_require__(122);
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_widget_1 = __webpack_require__(20);
	var sanitizer_1 = __webpack_require__(125);
	/**
	 * The class name added to an output area widget.
	 */
	var OUTPUT_AREA_CLASS = 'jp-OutputArea';
	/**
	 * The class name added to an output area output.
	 */
	var OUTPUT_CLASS = 'jp-OutputArea-output';
	/**
	 * The class name added to an execute result.
	 */
	var EXECUTE_CLASS = 'jp-OutputArea-executeResult';
	/**
	 * The class name added to display data.
	 */
	var DISPLAY_CLASS = 'jp-OutputArea-displayData';
	/**
	 * The class name added to stdout data.
	 */
	var STDOUT_CLASS = 'jp-OutputArea-stdout';
	/**
	 * The class name added to stderr data.
	 */
	var STDERR_CLASS = 'jp-OutputArea-stderr';
	/**
	 * The class anme added to error data.
	 */
	var ERROR_CLASS = 'jp-Output-error';
	/**
	 * 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';
	/**
	 * The class name added to output area prompts.
	 */
	var PROMPT_CLASS = 'jp-OutputArea-prompt';
	/**
	 * The class name added to output area results.
	 */
	var RESULT_CLASS = 'jp-OutputArea-result';
	/**
	 * A list of outputs considered safe.
	 */
	var safeOutputs = ['text/plain', 'text/latex', 'image/png', 'image/jpeg',
	    'application/vnd.jupyter.console-text'];
	/**
	 * A list of outputs that are sanitizable.
	 */
	var sanitizable = ['text/svg', 'text/html'];
	/**
	 * An output area widget.
	 */
	var OutputAreaWidget = (function (_super) {
	    __extends(OutputAreaWidget, _super);
	    /**
	     * Construct an output area widget.
	     */
	    function OutputAreaWidget(outputs, rendermime) {
	        _super.call(this);
	        this._sanitized = false; // true if sanitized outputs are displayed
	        this._trusted = false;
	        this._fixedHeight = false;
	        this._collapsed = false;
	        this._outputs = null;
	        this._rendermime = null;
	        this.addClass(OUTPUT_AREA_CLASS);
	        this._rendermime = rendermime;
	        this.layout = new phosphor_panel_1.PanelLayout();
	        for (var i = 0; i < outputs.length; i++) {
	            var widget = this.createOutput(outputs.get(i));
	            this.layout.addChild(widget);
	        }
	        outputs.changed.connect(this.outputsChanged, this);
	        this._outputs = outputs;
	    }
	    Object.defineProperty(OutputAreaWidget.prototype, "trusted", {
	        /**
	         * The trusted state of the widget.
	         */
	        get: function () {
	            return this._trusted;
	        },
	        set: function (value) {
	            if (this._trusted === value) {
	                return;
	            }
	            this._trusted = value;
	            // Re-render only if necessary.
	            if ((this._sanitized && value) || (!value)) {
	                var layout = this.layout;
	                for (var i = 0; i < layout.childCount(); i++) {
	                    layout.childAt(0).dispose();
	                }
	                var outputs = this._outputs;
	                for (var i = 0; i < outputs.length; i++) {
	                    layout.addChild(this.createOutput(outputs.get(i)));
	                }
	            }
	        },
	        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
	    });
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    OutputAreaWidget.prototype.dispose = function () {
	        // Do nothing if already disposed.
	        if (this.isDisposed) {
	            return;
	        }
	        this._outputs = null;
	        this._rendermime = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Create an output node from an output model.
	     */
	    OutputAreaWidget.prototype.createOutput = function (output) {
	        var widget = new phosphor_panel_1.Panel();
	        widget.addClass(OUTPUT_CLASS);
	        var bundle;
	        this._sanitized = false;
	        switch (output.output_type) {
	            case 'execute_result':
	                bundle = output.data;
	                widget.addClass(EXECUTE_CLASS);
	                var prompt_1 = new phosphor_widget_1.Widget();
	                prompt_1.addClass(PROMPT_CLASS);
	                var count = output.execution_count;
	                prompt_1.node.textContent = "Out[" + (count === null ? ' ' : count) + "]:";
	                widget.addChild(prompt_1);
	                break;
	            case 'display_data':
	                bundle = output.data;
	                widget.addClass(DISPLAY_CLASS);
	                break;
	            case 'stream':
	                bundle = { 'application/vnd.jupyter.console-text': output.text };
	                if (output.name === 'stdout') {
	                    widget.addClass(STDOUT_CLASS);
	                }
	                else {
	                    widget.addClass(STDERR_CLASS);
	                }
	                break;
	            case 'error':
	                var out = output;
	                var traceback = out.traceback.join('\n');
	                bundle = { 'application/vnd.jupyter.console-text': traceback || out.ename + ": " + out.evalue };
	                widget.addClass(ERROR_CLASS);
	                break;
	            default:
	                console.error("Unrecognized output type: " + output.output_type);
	                bundle = {};
	        }
	        // Sanitize outputs as needed.
	        if (!this.trusted) {
	            var keys = Object.keys(bundle);
	            for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
	                var key = keys_1[_i];
	                if (safeOutputs.indexOf(key) !== -1) {
	                    continue;
	                }
	                else if (sanitizable.indexOf(key) !== -1) {
	                    this._sanitized = true;
	                    var out = bundle[key];
	                    if (typeof out === 'string') {
	                        bundle[key] = sanitizer_1.sanitize(out);
	                    }
	                    else {
	                        console.log('Ignoring unsanitized ' + key + ' output; could not sanitize because output is not a string.');
	                        delete bundle[key];
	                    }
	                }
	                else {
	                    this._sanitized = true;
	                    // Don't display if we don't know how to sanitize it.
	                    console.log('Ignoring untrusted ' + key + ' output.');
	                    delete bundle[key];
	                }
	            }
	        }
	        if (bundle) {
	            var child = this._rendermime.render(bundle);
	            if (child) {
	                child.addClass(RESULT_CLASS);
	                widget.addChild(child);
	            }
	            else {
	                console.log('Did not find renderer for output mimebundle.');
	                console.log(bundle);
	            }
	        }
	        return widget;
	    };
	    /**
	     * Follow changes to the outputs list.
	     */
	    OutputAreaWidget.prototype.outputsChanged = function (sender, args) {
	        var layout = this.layout;
	        var widget;
	        switch (args.type) {
	            case phosphor_observablelist_1.ListChangeType.Add:
	                var value = args.newValue;
	                layout.insertChild(args.newIndex, this.createOutput(value));
	                break;
	            case phosphor_observablelist_1.ListChangeType.Move:
	                layout.insertChild(args.newIndex, layout.childAt(args.oldIndex));
	                break;
	            case phosphor_observablelist_1.ListChangeType.Remove:
	                widget = layout.childAt(args.oldIndex);
	                layout.removeChild(widget);
	                widget.dispose();
	                break;
	            case phosphor_observablelist_1.ListChangeType.Replace:
	                var oldValues = args.oldValue;
	                for (var i = args.oldIndex; i < oldValues.length; i++) {
	                    widget = layout.childAt(args.oldIndex);
	                    layout.removeChild(widget);
	                    widget.dispose();
	                }
	                var newValues = args.newValue;
	                for (var i = newValues.length; i < 0; i--) {
	                    layout.insertChild(args.newIndex, this.createOutput(newValues[i]));
	                }
	                break;
	            case phosphor_observablelist_1.ListChangeType.Set:
	                widget = layout.childAt(args.newIndex);
	                layout.removeChild(widget);
	                widget.dispose();
	                widget = this.createOutput(args.newValue);
	                layout.insertChild(args.newIndex, widget);
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle `update_request` messages.
	     */
	    OutputAreaWidget.prototype.onUpdateRequest = function (msg) {
	        _super.prototype.onUpdateRequest.call(this, msg);
	        if (this.collapsed) {
	            this.addClass(COLLAPSED_CLASS);
	        }
	        else {
	            this.removeClass(COLLAPSED_CLASS);
	        }
	        if (this.fixedHeight) {
	            this.addClass(FIXED_HEIGHT_CLASS);
	        }
	        else {
	            this.removeClass(FIXED_HEIGHT_CLASS);
	        }
	    };
	    return OutputAreaWidget;
	}(phosphor_widget_1.Widget));
	exports.OutputAreaWidget = OutputAreaWidget;


/***/ },
/* 125 */
/***/ function(module, exports, __webpack_require__) {

	var html4 = __webpack_require__(126);
	var URI = __webpack_require__(127);
	
	// Copyright (C) 2006 Google Inc.
	//
	// Licensed under the Apache License, Version 2.0 (the "License");
	// you may not use this file except in compliance with the License.
	// You may obtain a copy of the License at
	//
	//      http://www.apache.org/licenses/LICENSE-2.0
	//
	// Unless required by applicable law or agreed to in writing, software
	// distributed under the License is distributed on an "AS IS" BASIS,
	// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	// See the License for the specific language governing permissions and
	// limitations under the License.
	
	/**
	 * @fileoverview
	 * An HTML sanitizer that can satisfy a variety of security policies.
	 *
	 * <p>
	 * The HTML sanitizer is built around a SAX parser and HTML element and
	 * attributes schemas.
	 *
	 * If the cssparser is loaded, inline styles are sanitized using the
	 * css property and value schemas.  Else they are remove during
	 * sanitization.
	 *
	 * If it exists, uses parseCssDeclarations, sanitizeCssProperty,  cssSchema
	 *
	 * @author mikesamuel@gmail.com
	 * @author jasvir@gmail.com
	 * \@requires html4, URI
	 * \@overrides window
	 * \@provides html, html_sanitize
	 */
	
	// The Turkish i seems to be a non-issue, but abort in case it is.
	if ('I'.toLowerCase() !== 'i') { throw 'I/i problem'; }
	
	/**
	 * \@namespace
	 */
	var html = (function(html4) {
	
	    // For closure compiler
	    var parseCssDeclarations, sanitizeCssProperty, cssSchema;
	    if ('undefined' !== typeof window) {
	        parseCssDeclarations = window['parseCssDeclarations'];
	        sanitizeCssProperty = window['sanitizeCssProperty'];
	        cssSchema = window['cssSchema'];
	    }
	
	    // The keys of this object must be 'quoted' or JSCompiler will mangle them!
	    // This is a partial list -- lookupEntity() uses the host browser's parser
	    // (when available) to implement full entity lookup.
	    // Note that entities are in general case-sensitive; the uppercase ones are
	    // explicitly defined by HTML5 (presumably as compatibility).
	    var ENTITIES = {
	        'lt': '<',
	        'LT': '<',
	        'gt': '>',
	        'GT': '>',
	        'amp': '&',
	        'AMP': '&',
	        'quot': '"',
	        'apos': '\'',
	        'nbsp': '\u00a0'
	    };
	
	    // Patterns for types of entity/character reference names.
	    var decimalEscapeRe = /^#(\d+)$/;
	    var hexEscapeRe = /^#x([0-9A-Fa-f]+)$/;
	    // contains every entity per http://www.w3.org/TR/2011/WD-html5-20110113/named-character-references.html
	    var safeEntityNameRe = /^[A-Za-z][A-za-z0-9]+$/;
	    // Used as a hook to invoke the browser's entity parsing. <textarea> is used
	    // because its content is parsed for entities but not tags.
	    // TODO(kpreid): This retrieval is a kludge and leads to silent loss of
	    // functionality if the document isn't available.
	    var entityLookupElement =
	        ('undefined' !== typeof window && window['document'])
	            ? window['document'].createElement('textarea') : null;
	    /**
	     * Decodes an HTML entity.
	     *
	     * {\@updoc
	     * $ lookupEntity('lt')
	     * # '<'
	     * $ lookupEntity('GT')
	     * # '>'
	     * $ lookupEntity('amp')
	     * # '&'
	     * $ lookupEntity('nbsp')
	     * # '\xA0'
	     * $ lookupEntity('apos')
	     * # "'"
	     * $ lookupEntity('quot')
	     * # '"'
	     * $ lookupEntity('#xa')
	     * # '\n'
	     * $ lookupEntity('#10')
	     * # '\n'
	     * $ lookupEntity('#x0a')
	     * # '\n'
	     * $ lookupEntity('#010')
	     * # '\n'
	     * $ lookupEntity('#x00A')
	     * # '\n'
	     * $ lookupEntity('Pi')      // Known failure
	     * # '\u03A0'
	     * $ lookupEntity('pi')      // Known failure
	     * # '\u03C0'
	     * }
	     *
	     * @param {string} name the content between the '&' and the ';'.
	     * @return {string} a single unicode code-point as a string.
	     */
	    function lookupEntity(name) {
	        // TODO: entity lookup as specified by HTML5 actually depends on the
	        // presence of the ";".
	        if (ENTITIES.hasOwnProperty(name)) { return ENTITIES[name]; }
	        var m = name.match(decimalEscapeRe);
	        if (m) {
	            return String.fromCharCode(parseInt(m[1], 10));
	        } else if (!!(m = name.match(hexEscapeRe))) {
	            return String.fromCharCode(parseInt(m[1], 16));
	        } else if (entityLookupElement && safeEntityNameRe.test(name)) {
	            entityLookupElement.innerHTML = '&' + name + ';';
	            var text = entityLookupElement.textContent;
	            ENTITIES[name] = text;
	            return text;
	        } else {
	            return '&' + name + ';';
	        }
	    }
	
	    function decodeOneEntity(_, name) {
	        return lookupEntity(name);
	    }
	
	    var nulRe = /\0/g;
	    function stripNULs(s) {
	        return s.replace(nulRe, '');
	    }
	
	    var ENTITY_RE_1 = /&(#[0-9]+|#[xX][0-9A-Fa-f]+|\w+);/g;
	    var ENTITY_RE_2 = /^(#[0-9]+|#[xX][0-9A-Fa-f]+|\w+);/;
	    /**
	     * The plain text of a chunk of HTML CDATA which possibly containing.
	     *
	     * {\@updoc
	     * $ unescapeEntities('')
	     * # ''
	     * $ unescapeEntities('hello World!')
	     * # 'hello World!'
	     * $ unescapeEntities('1 &lt; 2 &amp;&AMP; 4 &gt; 3&#10;')
	     * # '1 < 2 && 4 > 3\n'
	     * $ unescapeEntities('&lt;&lt <- unfinished entity&gt;')
	     * # '<&lt <- unfinished entity>'
	     * $ unescapeEntities('/foo?bar=baz&copy=true')  // & often unescaped in URLS
	     * # '/foo?bar=baz&copy=true'
	     * $ unescapeEntities('pi=&pi;&#x3c0;, Pi=&Pi;\u03A0') // FIXME: known failure
	     * # 'pi=\u03C0\u03c0, Pi=\u03A0\u03A0'
	     * }
	     *
	     * @param {string} s a chunk of HTML CDATA.  It must not start or end inside
	     *     an HTML entity.
	     */
	    function unescapeEntities(s) {
		if(s) {
		    return s.replace(ENTITY_RE_1, decodeOneEntity);
		}
		else {
		    return s;
		}
	    }
	
	    var ampRe = /&/g;
	    var looseAmpRe = /&([^a-z#]|#(?:[^0-9x]|x(?:[^0-9a-f]|$)|$)|$)/gi;
	    var ltRe = /[<]/g;
	    var gtRe = />/g;
	    var quotRe = /\"/g;
	
	    /**
	     * Escapes HTML special characters in attribute values.
	     *
	     * {\@updoc
	     * $ escapeAttrib('')
	     * # ''
	     * $ escapeAttrib('"<<&==&>>"')  // Do not just escape the first occurrence.
	     * # '&#34;&lt;&lt;&amp;&#61;&#61;&amp;&gt;&gt;&#34;'
	     * $ escapeAttrib('Hello <World>!')
	     * # 'Hello &lt;World&gt;!'
	     * }
	     */
	    function escapeAttrib(s) {
		if(s) {
		    return ('' + s).replace(ampRe, '&amp;').replace(ltRe, '&lt;')
	            .replace(gtRe, '&gt;').replace(quotRe, '&#34;');
		}
		else {
		    return s;
		}
	        
	    }
	
	    /**
	     * Escape entities in RCDATA that can be escaped without changing the meaning.
	     * {\@updoc
	     * $ normalizeRCData('1 < 2 &&amp; 3 > 4 &amp;& 5 &lt; 7&8')
	     * # '1 &lt; 2 &amp;&amp; 3 &gt; 4 &amp;&amp; 5 &lt; 7&amp;8'
	     * }
	     */
	    function normalizeRCData(rcdata) {
		if(rcdata) {
		    return rcdata
	                .replace(looseAmpRe, '&amp;$1')
	                .replace(ltRe, '&lt;')
	                .replace(gtRe, '&gt;');
		}
		else {
		    return rcdata;
		}
	    }
	
	    // TODO(felix8a): validate sanitizer regexs against the HTML5 grammar at
	    // http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html
	    // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html
	    // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html
	    // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html
	
	    // We initially split input so that potentially meaningful characters
	    // like '<' and '>' are separate tokens, using a fast dumb process that
	    // ignores quoting.  Then we walk that token stream, and when we see a
	    // '<' that's the start of a tag, we use ATTR_RE to extract tag
	    // attributes from the next token.  That token will never have a '>'
	    // character.  However, it might have an unbalanced quote character, and
	    // when we see that, we combine additional tokens to balance the quote.
	
	    var ATTR_RE = new RegExp(
	        '^\\s*' +
	            '([-.:\\w]+)' +             // 1 = Attribute name
	            '(?:' + (
	            '\\s*(=)\\s*' +           // 2 = Is there a value?
	                '(' + (                   // 3 = Attribute value
	                // TODO(felix8a): maybe use backref to match quotes
	                '(\")[^\"]*(\"|$)' +    // 4, 5 = Double-quoted string
	                    '|' +
	                    '(\')[^\']*(\'|$)' +    // 6, 7 = Single-quoted string
	                    '|' +
	                    // Positive lookahead to prevent interpretation of
	                    // <foo a= b=c> as <foo a='b=c'>
	                    // TODO(felix8a): might be able to drop this case
	                    '(?=[a-z][-\\w]*\\s*=)' +
	                    '|' +
	                    // Unquoted value that isn't an attribute name
	                    // (since we didn't match the positive lookahead above)
	                    '[^\"\'\\s]*' ) +
	                ')' ) +
	            ')?',
	        'i');
	
	    // false on IE<=8, true on most other browsers
	    var splitWillCapture = ('a,b'.split(/(,)/).length === 3);
	
	    // bitmask for tags with special parsing, like <script> and <textarea>
	    var EFLAGS_TEXT = html4.eflags['CDATA'] | html4.eflags['RCDATA'];
	
	    /**
	     * Given a SAX-like event handler, produce a function that feeds those
	     * events and a parameter to the event handler.
	     *
	     * The event handler has the form:{@code
	     * {
	   *   // Name is an upper-case HTML tag name.  Attribs is an array of
	   *   // alternating upper-case attribute names, and attribute values.  The
	   *   // attribs array is reused by the parser.  Param is the value passed to
	   *   // the saxParser.
	   *   startTag: function (name, attribs, param) { ... },
	   *   endTag:   function (name, param) { ... },
	   *   pcdata:   function (text, param) { ... },
	   *   rcdata:   function (text, param) { ... },
	   *   cdata:    function (text, param) { ... },
	   *   startDoc: function (param) { ... },
	   *   endDoc:   function (param) { ... }
	   * }}
	     *
	     * @param {Object} handler a record containing event handlers.
	     * @return {function(string, Object)} A function that takes a chunk of HTML
	     *     and a parameter.  The parameter is passed on to the handler methods.
	     */
	    function makeSaxParser(handler) {
	        // Accept quoted or unquoted keys (Closure compat)
	        var hcopy = {
	            cdata: handler.cdata || handler['cdata'],
	            comment: handler.comment || handler['comment'],
	            endDoc: handler.endDoc || handler['endDoc'],
	            endTag: handler.endTag || handler['endTag'],
	            pcdata: handler.pcdata || handler['pcdata'],
	            rcdata: handler.rcdata || handler['rcdata'],
	            startDoc: handler.startDoc || handler['startDoc'],
	            startTag: handler.startTag || handler['startTag']
	        };
	        return function(htmlText, param) {
	            return parse(htmlText, hcopy, param);
	        };
	    }
	
	    // Parsing strategy is to split input into parts that might be lexically
	    // meaningful (every ">" becomes a separate part), and then recombine
	    // parts if we discover they're in a different context.
	
	    // TODO(felix8a): Significant performance regressions from -legacy,
	    // tested on
	    //    Chrome 18.0
	    //    Firefox 11.0
	    //    IE 6, 7, 8, 9
	    //    Opera 11.61
	    //    Safari 5.1.3
	    // Many of these are unusual patterns that are linearly slower and still
	    // pretty fast (eg 1ms to 5ms), so not necessarily worth fixing.
	
	    // TODO(felix8a): "<script> && && && ... <\/script>" is slower on all
	    // browsers.  The hotspot is htmlSplit.
	
	    // TODO(felix8a): "<p title='>>>>...'><\/p>" is slower on all browsers.
	    // This is partly htmlSplit, but the hotspot is parseTagAndAttrs.
	
	    // TODO(felix8a): "<a><\/a><a><\/a>..." is slower on IE9.
	    // "<a>1<\/a><a>1<\/a>..." is faster, "<a><\/a>2<a><\/a>2..." is faster.
	
	    // TODO(felix8a): "<p<p<p..." is slower on IE[6-8]
	
	    var continuationMarker = {};
	    function parse(htmlText, handler, param) {
	        var m, p, tagName;
	        var parts = htmlSplit(htmlText);
	        var state = {
	            noMoreGT: false,
	            noMoreEndComments: false
	        };
	        parseCPS(handler, parts, 0, state, param);
	    }
	
	    function continuationMaker(h, parts, initial, state, param) {
	        return function () {
	            parseCPS(h, parts, initial, state, param);
	        };
	    }
	
	    function parseCPS(h, parts, initial, state, param) {
	        try {
	            if (h.startDoc && initial == 0) { h.startDoc(param); }
	            var m, p, tagName;
	            for (var pos = initial, end = parts.length; pos < end;) {
	                var current = parts[pos++];
	                var next = parts[pos];
	                switch (current) {
	                    case '&':
	                        if (ENTITY_RE_2.test(next)) {
	                            if (h.pcdata) {
	                                h.pcdata('&' + next, param, continuationMarker,
	                                    continuationMaker(h, parts, pos, state, param));
	                            }
	                            pos++;
	                        } else {
	                            if (h.pcdata) { h.pcdata("&amp;", param, continuationMarker,
	                                continuationMaker(h, parts, pos, state, param));
	                            }
	                        }
	                        break;
	                    case '<\/':
	                        if ((m = /^([-\w:]+)[^\'\"]*/.exec(next))) {
	                            if (m[0].length === next.length && parts[pos + 1] === '>') {
	                                // fast case, no attribute parsing needed
	                                pos += 2;
	                                tagName = m[1].toLowerCase();
	                                if (h.endTag) {
	                                    h.endTag(tagName, param, continuationMarker,
	                                        continuationMaker(h, parts, pos, state, param));
	                                }
	                            } else {
	                                // slow case, need to parse attributes
	                                // TODO(felix8a): do we really care about misparsing this?
	                                pos = parseEndTag(
	                                    parts, pos, h, param, continuationMarker, state);
	                            }
	                        } else {
	                            if (h.pcdata) {
	                                h.pcdata('&lt;/', param, continuationMarker,
	                                    continuationMaker(h, parts, pos, state, param));
	                            }
	                        }
	                        break;
	                    case '<':
	                        if (m = /^([-\w:]+)\s*\/?/.exec(next)) {
	                            if (m[0].length === next.length && parts[pos + 1] === '>') {
	                                // fast case, no attribute parsing needed
	                                pos += 2;
	                                tagName = m[1].toLowerCase();
	                                if (h.startTag) {
	                                    h.startTag(tagName, [], param, continuationMarker,
	                                        continuationMaker(h, parts, pos, state, param));
	                                }
	                                // tags like <script> and <textarea> have special parsing
	                                var eflags = html4.ELEMENTS[tagName];
	                                if (eflags & EFLAGS_TEXT) {
	                                    var tag = { name: tagName, next: pos, eflags: eflags };
	                                    pos = parseText(
	                                        parts, tag, h, param, continuationMarker, state);
	                                }
	                            } else {
	                                // slow case, need to parse attributes
	                                pos = parseStartTag(
	                                    parts, pos, h, param, continuationMarker, state);
	                            }
	                        } else {
	                            if (h.pcdata) {
	                                h.pcdata('&lt;', param, continuationMarker,
	                                    continuationMaker(h, parts, pos, state, param));
	                            }
	                        }
	                        break;
	                    case '<\!--':
	                        // The pathological case is n copies of '<\!--' without '-->', and
	                        // repeated failure to find '-->' is quadratic.  We avoid that by
	                        // remembering when search for '-->' fails.
	                        if (!state.noMoreEndComments) {
	                            // A comment <\!--x--> is split into three tokens:
	                            //   '<\!--', 'x--', '>'
	                            // We want to find the next '>' token that has a preceding '--'.
	                            // pos is at the 'x--'.
	                            for (p = pos + 1; p < end; p++) {
	                                if (parts[p] === '>' && /--$/.test(parts[p - 1])) { break; }
	                            }
	                            if (p < end) {
	                                if (h.comment) {
	                                    var comment = parts.slice(pos, p).join('');
	                                    h.comment(
	                                        comment.substr(0, comment.length - 2), param,
	                                        continuationMarker,
	                                        continuationMaker(h, parts, p + 1, state, param));
	                                }
	                                pos = p + 1;
	                            } else {
	                                state.noMoreEndComments = true;
	                            }
	                        }
	                        if (state.noMoreEndComments) {
	                            if (h.pcdata) {
	                                h.pcdata('&lt;!--', param, continuationMarker,
	                                    continuationMaker(h, parts, pos, state, param));
	                            }
	                        }
	                        break;
	                    case '<\!':
	                        if (!/^\w/.test(next)) {
	                            if (h.pcdata) {
	                                h.pcdata('&lt;!', param, continuationMarker,
	                                    continuationMaker(h, parts, pos, state, param));
	                            }
	                        } else {
	                            // similar to noMoreEndComment logic
	                            if (!state.noMoreGT) {
	                                for (p = pos + 1; p < end; p++) {
	                                    if (parts[p] === '>') { break; }
	                                }
	                                if (p < end) {
	                                    pos = p + 1;
	                                } else {
	                                    state.noMoreGT = true;
	                                }
	                            }
	                            if (state.noMoreGT) {
	                                if (h.pcdata) {
	                                    h.pcdata('&lt;!', param, continuationMarker,
	                                        continuationMaker(h, parts, pos, state, param));
	                                }
	                            }
	                        }
	                        break;
	                    case '<?':
	                        // similar to noMoreEndComment logic
	                        if (!state.noMoreGT) {
	                            for (p = pos + 1; p < end; p++) {
	                                if (parts[p] === '>') { break; }
	                            }
	                            if (p < end) {
	                                pos = p + 1;
	                            } else {
	                                state.noMoreGT = true;
	                            }
	                        }
	                        if (state.noMoreGT) {
	                            if (h.pcdata) {
	                                h.pcdata('&lt;?', param, continuationMarker,
	                                    continuationMaker(h, parts, pos, state, param));
	                            }
	                        }
	                        break;
	                    case '>':
	                        if (h.pcdata) {
	                            h.pcdata("&gt;", param, continuationMarker,
	                                continuationMaker(h, parts, pos, state, param));
	                        }
	                        break;
	                    case '':
	                        break;
	                    default:
	                        if (h.pcdata) {
	                            h.pcdata(current, param, continuationMarker,
	                                continuationMaker(h, parts, pos, state, param));
	                        }
	                        break;
	                }
	            }
	            if (h.endDoc) { h.endDoc(param); }
	        } catch (e) {
	            if (e !== continuationMarker) { throw e; }
	        }
	    }
	
	    // Split str into parts for the html parser.
	    function htmlSplit(str) {
	        // can't hoist this out of the function because of the re.exec loop.
	        var re = /(<\/|<\!--|<[!?]|[&<>])/g;
	        str += '';
	        if (splitWillCapture) {
	            return str.split(re);
	        } else {
	            var parts = [];
	            var lastPos = 0;
	            var m;
	            while ((m = re.exec(str)) !== null) {
	                parts.push(str.substring(lastPos, m.index));
	                parts.push(m[0]);
	                lastPos = m.index + m[0].length;
	            }
	            parts.push(str.substring(lastPos));
	            return parts;
	        }
	    }
	
	    function parseEndTag(parts, pos, h, param, continuationMarker, state) {
	        var tag = parseTagAndAttrs(parts, pos);
	        // drop unclosed tags
	        if (!tag) { return parts.length; }
	        if (h.endTag) {
	            h.endTag(tag.name, param, continuationMarker,
	                continuationMaker(h, parts, pos, state, param));
	        }
	        return tag.next;
	    }
	
	    function parseStartTag(parts, pos, h, param, continuationMarker, state) {
	        var tag = parseTagAndAttrs(parts, pos);
	        // drop unclosed tags
	        if (!tag) { return parts.length; }
	        if (h.startTag) {
	            h.startTag(tag.name, tag.attrs, param, continuationMarker,
	                continuationMaker(h, parts, tag.next, state, param));
	        }
	        // tags like <script> and <textarea> have special parsing
	        if (tag.eflags & EFLAGS_TEXT) {
	            return parseText(parts, tag, h, param, continuationMarker, state);
	        } else {
	            return tag.next;
	        }
	    }
	
	    var endTagRe = {};
	
	    // Tags like <script> and <textarea> are flagged as CDATA or RCDATA,
	    // which means everything is text until we see the correct closing tag.
	    function parseText(parts, tag, h, param, continuationMarker, state) {
	        var end = parts.length;
	        if (!endTagRe.hasOwnProperty(tag.name)) {
	            endTagRe[tag.name] = new RegExp('^' + tag.name + '(?:[\\s\\/]|$)', 'i');
	        }
	        var re = endTagRe[tag.name];
	        var first = tag.next;
	        var p = tag.next + 1;
	        for (; p < end; p++) {
	            if (parts[p - 1] === '<\/' && re.test(parts[p])) { break; }
	        }
	        if (p < end) { p -= 1; }
	        var buf = parts.slice(first, p).join('');
	        if (tag.eflags & html4.eflags['CDATA']) {
	            if (h.cdata) {
	                h.cdata(buf, param, continuationMarker,
	                    continuationMaker(h, parts, p, state, param));
	            }
	        } else if (tag.eflags & html4.eflags['RCDATA']) {
	            if (h.rcdata) {
	                h.rcdata(normalizeRCData(buf), param, continuationMarker,
	                    continuationMaker(h, parts, p, state, param));
	            }
	        } else {
	            throw new Error('bug');
	        }
	        return p;
	    }
	
	    // at this point, parts[pos-1] is either "<" or "<\/".
	    function parseTagAndAttrs(parts, pos) {
	        var m = /^([-\w:]+)/.exec(parts[pos]);
	        var tag = {};
	        tag.name = m[1].toLowerCase();
	        tag.eflags = html4.ELEMENTS[tag.name];
	        var buf = parts[pos].substr(m[0].length);
	        // Find the next '>'.  We optimistically assume this '>' is not in a
	        // quoted context, and further down we fix things up if it turns out to
	        // be quoted.
	        var p = pos + 1;
	        var end = parts.length;
	        for (; p < end; p++) {
	            if (parts[p] === '>') { break; }
	            buf += parts[p];
	        }
	        if (end <= p) { return void 0; }
	        var attrs = [];
	        while (buf !== '') {
	            m = ATTR_RE.exec(buf);
	            if (!m) {
	                // No attribute found: skip garbage
	                buf = buf.replace(/^[\s\S][^a-z\s]*/, '');
	
	            } else if ((m[4] && !m[5]) || (m[6] && !m[7])) {
	                // Unterminated quote: slurp to the next unquoted '>'
	                var quote = m[4] || m[6];
	                var sawQuote = false;
	                var abuf = [buf, parts[p++]];
	                for (; p < end; p++) {
	                    if (sawQuote) {
	                        if (parts[p] === '>') { break; }
	                    } else if (0 <= parts[p].indexOf(quote)) {
	                        sawQuote = true;
	                    }
	                    abuf.push(parts[p]);
	                }
	                // Slurp failed: lose the garbage
	                if (end <= p) { break; }
	                // Otherwise retry attribute parsing
	                buf = abuf.join('');
	                continue;
	
	            } else {
	                // We have an attribute
	                var aName = m[1].toLowerCase();
	                var aValue = m[2] ? decodeValue(m[3]) : '';
	                attrs.push(aName, aValue);
	                buf = buf.substr(m[0].length);
	            }
	        }
	        tag.attrs = attrs;
	        tag.next = p + 1;
	        return tag;
	    }
	
	    function decodeValue(v) {
	        var q = v.charCodeAt(0);
	        if (q === 0x22 || q === 0x27) { // " or '
	            v = v.substr(1, v.length - 2);
	        }
	        return unescapeEntities(stripNULs(v));
	    }
	
	    /**
	     * Returns a function that strips unsafe tags and attributes from html.
	     * @param {function(string, Array.<string>): ?Array.<string>} tagPolicy
	     *     A function that takes (tagName, attribs[]), where tagName is a key in
	     *     html4.ELEMENTS and attribs is an array of alternating attribute names
	     *     and values.  It should return a record (as follows), or null to delete
	     *     the element.  It's okay for tagPolicy to modify the attribs array,
	     *     but the same array is reused, so it should not be held between calls.
	     *     Record keys:
	     *        attribs: (required) Sanitized attributes array.
	     *        tagName: Replacement tag name.
	     * @return {function(string, Array)} A function that sanitizes a string of
	     *     HTML and appends result strings to the second argument, an array.
	     */
	    function makeHtmlSanitizer(tagPolicy) {
	        var stack;
	        var ignoring;
	        var emit = function (text, out) {
	            if (!ignoring) { out.push(text); }
	        };
	        return makeSaxParser({
	            'startDoc': function(_) {
	                stack = [];
	                ignoring = false;
	            },
	            'startTag': function(tagNameOrig, attribs, out) {
	                if (ignoring) { return; }
	                if (!html4.ELEMENTS.hasOwnProperty(tagNameOrig)) { return; }
	                var eflagsOrig = html4.ELEMENTS[tagNameOrig];
	                if (eflagsOrig & html4.eflags['FOLDABLE']) {
	                    return;
	                }
	
	                var decision = tagPolicy(tagNameOrig, attribs);
	                if (!decision) {
	                    ignoring = !(eflagsOrig & html4.eflags['EMPTY']);
	                    return;
	                } else if (typeof decision !== 'object') {
	                    throw new Error('tagPolicy did not return object (old API?)');
	                }
	                if ('attribs' in decision) {
	                    attribs = decision['attribs'];
	                } else {
	                    throw new Error('tagPolicy gave no attribs');
	                }
	                var eflagsRep;
	                var tagNameRep;
	                if ('tagName' in decision) {
	                    tagNameRep = decision['tagName'];
	                    eflagsRep = html4.ELEMENTS[tagNameRep];
	                } else {
	                    tagNameRep = tagNameOrig;
	                    eflagsRep = eflagsOrig;
	                }
	                // TODO(mikesamuel): relying on tagPolicy not to insert unsafe
	                // attribute names.
	
	                // If this is an optional-end-tag element and either this element or its
	                // previous like sibling was rewritten, then insert a close tag to
	                // preserve structure.
	                if (eflagsOrig & html4.eflags['OPTIONAL_ENDTAG']) {
	                    var onStack = stack[stack.length - 1];
	                    if (onStack && onStack.orig === tagNameOrig &&
	                        (onStack.rep !== tagNameRep || tagNameOrig !== tagNameRep)) {
	                        out.push('<\/', onStack.rep, '>');
	                    }
	                }
	
	                if (!(eflagsOrig & html4.eflags['EMPTY'])) {
	                    stack.push({orig: tagNameOrig, rep: tagNameRep});
	                }
	
	                out.push('<', tagNameRep);
	                for (var i = 0, n = attribs.length; i < n; i += 2) {
	                    var attribName = attribs[i],
	                        value = attribs[i + 1];
	                    if (value !== null && value !== void 0) {
	                        out.push(' ', attribName, '="', escapeAttrib(value), '"');
	                    }
	                }
	                out.push('>');
	
	                if ((eflagsOrig & html4.eflags['EMPTY'])
	                    && !(eflagsRep & html4.eflags['EMPTY'])) {
	                    // replacement is non-empty, synthesize end tag
	                    out.push('<\/', tagNameRep, '>');
	                }
	            },
	            'endTag': function(tagName, out) {
	                if (ignoring) {
	                    ignoring = false;
	                    return;
	                }
	                if (!html4.ELEMENTS.hasOwnProperty(tagName)) { return; }
	                var eflags = html4.ELEMENTS[tagName];
	                if (!(eflags & (html4.eflags['EMPTY'] | html4.eflags['FOLDABLE']))) {
	                    var index;
	                    if (eflags & html4.eflags['OPTIONAL_ENDTAG']) {
	                        for (index = stack.length; --index >= 0;) {
	                            var stackElOrigTag = stack[index].orig;
	                            if (stackElOrigTag === tagName) { break; }
	                            if (!(html4.ELEMENTS[stackElOrigTag] &
	                                html4.eflags['OPTIONAL_ENDTAG'])) {
	                                // Don't pop non optional end tags looking for a match.
	                                return;
	                            }
	                        }
	                    } else {
	                        for (index = stack.length; --index >= 0;) {
	                            if (stack[index].orig === tagName) { break; }
	                        }
	                    }
	                    if (index < 0) { return; }  // Not opened.
	                    for (var i = stack.length; --i > index;) {
	                        var stackElRepTag = stack[i].rep;
	                        if (!(html4.ELEMENTS[stackElRepTag] &
	                            html4.eflags['OPTIONAL_ENDTAG'])) {
	                            out.push('<\/', stackElRepTag, '>');
	                        }
	                    }
	                    if (index < stack.length) {
	                        tagName = stack[index].rep;
	                    }
	                    stack.length = index;
	                    out.push('<\/', tagName, '>');
	                }
	            },
	            'pcdata': emit,
	            'rcdata': emit,
	            'cdata': emit,
	            'endDoc': function(out) {
	                for (; stack.length; stack.length--) {
	                    out.push('<\/', stack[stack.length - 1].rep, '>');
	                }
	            }
	        });
	    }
	
	    var ALLOWED_URI_SCHEMES = /^(?:https?|mailto)$/i;
	
	    function safeUri(uri, effect, ltype, hints, naiveUriRewriter) {
	        if (!naiveUriRewriter) { return null; }
	        try {
	            var parsed = URI.parse('' + uri);
	            if (parsed) {
	                if (!parsed.hasScheme() ||
	                    ALLOWED_URI_SCHEMES.test(parsed.getScheme())) {
	                    var safe = naiveUriRewriter(parsed, effect, ltype, hints);
	                    return safe ? safe.toString() : null;
	                }
	            }
	        } catch (e) {
	            return null;
	        }
	        return null;
	    }
	
	    function log(logger, tagName, attribName, oldValue, newValue) {
	        if (!attribName) {
	            logger(tagName + " removed", {
	                change: "removed",
	                tagName: tagName
	            });
	        }
	        if (oldValue !== newValue) {
	            var changed = "changed";
	            if (oldValue && !newValue) {
	                changed = "removed";
	            } else if (!oldValue && newValue)  {
	                changed = "added";
	            }
	            logger(tagName + "." + attribName + " " + changed, {
	                change: changed,
	                tagName: tagName,
	                attribName: attribName,
	                oldValue: oldValue,
	                newValue: newValue
	            });
	        }
	    }
	
	    function lookupAttribute(map, tagName, attribName) {
	        var attribKey;
	        attribKey = tagName + '::' + attribName;
	        if (map.hasOwnProperty(attribKey)) {
	            return map[attribKey];
	        }
	        attribKey = '*::' + attribName;
	        if (map.hasOwnProperty(attribKey)) {
	            return map[attribKey];
	        }
	        return void 0;
	    }
	    function getAttributeType(tagName, attribName) {
	        return lookupAttribute(html4.ATTRIBS, tagName, attribName);
	    }
	    function getLoaderType(tagName, attribName) {
	        return lookupAttribute(html4.LOADERTYPES, tagName, attribName);
	    }
	    function getUriEffect(tagName, attribName) {
	        return lookupAttribute(html4.URIEFFECTS, tagName, attribName);
	    }
	
	    /**
	     * Sanitizes attributes on an HTML tag.
	     * @param {string} tagName An HTML tag name in lowercase.
	     * @param {Array.<?string>} attribs An array of alternating names and values.
	     * @param {?function(?string): ?string} opt_naiveUriRewriter A transform to
	     *     apply to URI attributes; it can return a new string value, or null to
	     *     delete the attribute.  If unspecified, URI attributes are deleted.
	     * @param {function(?string): ?string} opt_nmTokenPolicy A transform to apply
	     *     to attributes containing HTML names, element IDs, and space-separated
	     *     lists of classes; it can return a new string value, or null to delete
	     *     the attribute.  If unspecified, these attributes are kept unchanged.
	     * @return {Array.<?string>} The sanitized attributes as a list of alternating
	     *     names and values, where a null value means to omit the attribute.
	     */
	    function sanitizeAttribs(tagName, attribs,
	        opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) {
	        // TODO(felix8a): it's obnoxious that domado duplicates much of this
	        // TODO(felix8a): maybe consistently enforce constraints like target=
	        for (var i = 0; i < attribs.length; i += 2) {
	            var attribName = attribs[i];
	            var value = attribs[i + 1];
	            var oldValue = value;
	            var atype = null, attribKey;
	            if ((attribKey = tagName + '::' + attribName,
	                html4.ATTRIBS.hasOwnProperty(attribKey)) ||
	                (attribKey = '*::' + attribName,
	                    html4.ATTRIBS.hasOwnProperty(attribKey))) {
	                atype = html4.ATTRIBS[attribKey];
	            }
	            if (atype !== null) {
	                switch (atype) {
	                    case html4.atype['NONE']: break;
	                    case html4.atype['SCRIPT']:
	                        value = null;
	                        if (opt_logger) {
	                            log(opt_logger, tagName, attribName, oldValue, value);
	                        }
	                        break;
	                    case html4.atype['STYLE']:
	                        if ('undefined' === typeof parseCssDeclarations) {
	                            value = null;
	                            if (opt_logger) {
	                                log(opt_logger, tagName, attribName, oldValue, value);
	                            }
	                            break;
	                        }
	                        var sanitizedDeclarations = [];
	                        parseCssDeclarations(
	                            value,
	                            {
	                                'declaration': function (property, tokens) {
	                                    var normProp = property.toLowerCase();
	                                    sanitizeCssProperty(
	                                        normProp, tokens,
	                                        opt_naiveUriRewriter
	                                            ? function (url) {
	                                            return safeUri(
	                                                url, html4.ueffects.SAME_DOCUMENT,
	                                                html4.ltypes.SANDBOXED,
	                                                {
	                                                    "TYPE": "CSS",
	                                                    "CSS_PROP": normProp
	                                                }, opt_naiveUriRewriter);
	                                        }
	                                            : null);
	                                    if (tokens.length) {
	                                        sanitizedDeclarations.push(
	                                            normProp + ': ' + tokens.join(' '));
	                                    }
	                                }
	                            });
	                        value = sanitizedDeclarations.length > 0 ?
	                            sanitizedDeclarations.join(' ; ') : null;
	                        if (opt_logger) {
	                            log(opt_logger, tagName, attribName, oldValue, value);
	                        }
	                        break;
	                    case html4.atype['ID']:
	                    case html4.atype['IDREF']:
	                    case html4.atype['IDREFS']:
	                    case html4.atype['GLOBAL_NAME']:
	                    case html4.atype['LOCAL_NAME']:
	                    case html4.atype['CLASSES']:
	                        value = opt_nmTokenPolicy ? opt_nmTokenPolicy(value) : value;
	                        if (opt_logger) {
	                            log(opt_logger, tagName, attribName, oldValue, value);
	                        }
	                        break;
	                    case html4.atype['URI']:
	                        value = safeUri(value,
	                            getUriEffect(tagName, attribName),
	                            getLoaderType(tagName, attribName),
	                            {
	                                "TYPE": "MARKUP",
	                                "XML_ATTR": attribName,
	                                "XML_TAG": tagName
	                            }, opt_naiveUriRewriter);
	                        if (opt_logger) {
	                            log(opt_logger, tagName, attribName, oldValue, value);
	                        }
	                        break;
	                    case html4.atype['URI_FRAGMENT']:
	                        if (value && '#' === value.charAt(0)) {
	                            value = value.substring(1);  // remove the leading '#'
	                            value = opt_nmTokenPolicy ? opt_nmTokenPolicy(value) : value;
	                            if (value !== null && value !== void 0) {
	                                value = '#' + value;  // restore the leading '#'
	                            }
	                        } else {
	                            value = null;
	                        }
	                        if (opt_logger) {
	                            log(opt_logger, tagName, attribName, oldValue, value);
	                        }
	                        break;
	                    default:
	                        value = null;
	                        if (opt_logger) {
	                            log(opt_logger, tagName, attribName, oldValue, value);
	                        }
	                        break;
	                }
	            } else {
	                value = null;
	                if (opt_logger) {
	                    log(opt_logger, tagName, attribName, oldValue, value);
	                }
	            }
	            attribs[i + 1] = value;
	        }
	        return attribs;
	    }
	
	    /**
	     * Creates a tag policy that omits all tags marked UNSAFE in html4-defs.js
	     * and applies the default attribute sanitizer with the supplied policy for
	     * URI attributes and NMTOKEN attributes.
	     * @param {?function(?string): ?string} opt_naiveUriRewriter A transform to
	     *     apply to URI attributes.  If not given, URI attributes are deleted.
	     * @param {function(?string): ?string} opt_nmTokenPolicy A transform to apply
	     *     to attributes containing HTML names, element IDs, and space-separated
	     *     lists of classes.  If not given, such attributes are left unchanged.
	     * @return {function(string, Array.<?string>)} A tagPolicy suitable for
	     *     passing to html.sanitize.
	     */
	    function makeTagPolicy(
	        opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) {
	        return function(tagName, attribs) {
	            if (!(html4.ELEMENTS[tagName] & html4.eflags['UNSAFE'])) {
	                return {
	                    'attribs': sanitizeAttribs(tagName, attribs,
	                        opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger)
	                };
	            } else {
	                if (opt_logger) {
	                    log(opt_logger, tagName, undefined, undefined, undefined);
	                }
	            }
	        };
	    }
	
	    /**
	     * Sanitizes HTML tags and attributes according to a given policy.
	     * @param {string} inputHtml The HTML to sanitize.
	     * @param {function(string, Array.<?string>)} tagPolicy A function that
	     *     decides which tags to accept and sanitizes their attributes (see
	     *     makeHtmlSanitizer above for details).
	     * @return {string} The sanitized HTML.
	     */
	    function sanitizeWithPolicy(inputHtml, tagPolicy) {
	        var outputArray = [];
	        makeHtmlSanitizer(tagPolicy)(inputHtml, outputArray);
	        return outputArray.join('');
	    }
	
	    /**
	     * Strips unsafe tags and attributes from HTML.
	     * @param {string} inputHtml The HTML to sanitize.
	     * @param {?function(?string): ?string} opt_naiveUriRewriter A transform to
	     *     apply to URI attributes.  If not given, URI attributes are deleted.
	     * @param {function(?string): ?string} opt_nmTokenPolicy A transform to apply
	     *     to attributes containing HTML names, element IDs, and space-separated
	     *     lists of classes.  If not given, such attributes are left unchanged.
	     */
	    function sanitize(inputHtml,
	        opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) {
	        var tagPolicy = makeTagPolicy(
	            opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger);
	        return sanitizeWithPolicy(inputHtml, tagPolicy);
	    }
	
	    // Export both quoted and unquoted names for Closure linkage.
	    var html = {};
	    html.escapeAttrib = html['escapeAttrib'] = escapeAttrib;
	    html.makeHtmlSanitizer = html['makeHtmlSanitizer'] = makeHtmlSanitizer;
	    html.makeSaxParser = html['makeSaxParser'] = makeSaxParser;
	    html.makeTagPolicy = html['makeTagPolicy'] = makeTagPolicy;
	    html.normalizeRCData = html['normalizeRCData'] = normalizeRCData;
	    html.sanitize = html['sanitize'] = sanitize;
	    html.sanitizeAttribs = html['sanitizeAttribs'] = sanitizeAttribs;
	    html.sanitizeWithPolicy = html['sanitizeWithPolicy'] = sanitizeWithPolicy;
	    html.unescapeEntities = html['unescapeEntities'] = unescapeEntities;
	    return html;
	})(html4);
	
	var html_sanitize = html['sanitize'];
	
	// Exports for Closure compiler.  Note this file is also cajoled
	// for domado and run in an environment without 'window'
	if (typeof window !== 'undefined') {
	    window['html'] = html;
	    window['html_sanitize'] = html_sanitize;
	}
	
	var Sanitizer = {};
	
	// Ensure backwards compatibility
	Sanitizer.escapeAttrib = html.escapeAttrib;
	Sanitizer.makeHtmlSanitizer = html.makeHtmlSanitizer;
	Sanitizer.makeSaxParser = html.makeSaxParser;
	Sanitizer.makeTagPolicy = html.makeTagPolicy;
	Sanitizer.normalizeRCData = html.normalizeRCData
	Sanitizer.sanitizeAttribs = html.sanitizeAttribs
	Sanitizer.sanitizeWithPolicy = html.sanitizeWithPolicy
	Sanitizer.unescapeEntities = html.unescapeEntities
	Sanitizer.escape = html.escapeAttrib;
	
	// https://github.com/theSmaw/Caja-HTML-Sanitizer/issues/8
	Sanitizer.sanitize = function(inputHtml, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) {
	    if (typeof(inputHtml) === "string") {
	        inputHtml = inputHtml.replace(/<([a-zA-Z]+)([^>]*)\/>/g, '<$1$2></$1>');
	    }
	    
	    if (inputHtml) {
	        return html.sanitize(inputHtml, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger);
	    }
	    else {
	        return inputHtml;
	    }
	    
	}
	
	// the browser, add 'Sanitizer' as a global object via a string identifier,
	// for Closure Compiler "advanced" mode.
	if (true) {
	    if (typeof module !== 'undefined' && module.exports) {
	        exports = module.exports = Sanitizer;
	    }
	    exports.Sanitizer = Sanitizer;
	} else {
	    this.Sanitizer = Sanitizer;
	}


/***/ },
/* 126 */
/***/ function(module, exports, __webpack_require__) {

	/* Copyright Google Inc.
	 * Licensed under the Apache Licence Version 2.0
	 * Autogenerated at Fri Aug 13 11:26:55 PDT 2010
	 * @provides html4
	 */
	var html4 = {};
	html4 .atype = {
	    'NONE': 0,
	    'URI': 1,
	    'URI_FRAGMENT': 11,
	    'SCRIPT': 2,
	    'STYLE': 3,
	    'ID': 4,
	    'IDREF': 5,
	    'IDREFS': 6,
	    'GLOBAL_NAME': 7,
	    'LOCAL_NAME': 8,
	    'CLASSES': 9,
	    'FRAME_TARGET': 10
	};
	html4 .ATTRIBS = {
	    '*::class': 9,
	    '*::dir': 0,
	    '*::id': 4,
	    '*::lang': 0,
	    '*::onclick': 2,
	    '*::ondblclick': 2,
	    '*::onkeydown': 2,
	    '*::onkeypress': 2,
	    '*::onkeyup': 2,
	    '*::onload': 2,
	    '*::onmousedown': 2,
	    '*::onmousemove': 2,
	    '*::onmouseout': 2,
	    '*::onmouseover': 2,
	    '*::onmouseup': 2,
	    '*::style': 3,
	    '*::title': 0,
	    'a::accesskey': 0,
	    'a::coords': 0,
	    'a::href': 1,
	    'a::hreflang': 0,
	    'a::name': 7,
	    'a::onblur': 2,
	    'a::onfocus': 2,
	    'a::rel': 0,
	    'a::rev': 0,
	    'a::shape': 0,
	    'a::tabindex': 0,
	    'a::target': 10,
	    'a::type': 0,
	    'area::accesskey': 0,
	    'area::alt': 0,
	    'area::coords': 0,
	    'area::href': 1,
	    'area::nohref': 0,
	    'area::onblur': 2,
	    'area::onfocus': 2,
	    'area::shape': 0,
	    'area::tabindex': 0,
	    'area::target': 10,
	    'bdo::dir': 0,
	    'blockquote::cite': 1,
	    'br::clear': 0,
	    'button::accesskey': 0,
	    'button::disabled': 0,
	    'button::name': 8,
	    'button::onblur': 2,
	    'button::onfocus': 2,
	    'button::tabindex': 0,
	    'button::type': 0,
	    'button::value': 0,
	    'caption::align': 0,
	    'col::align': 0,
	    'col::char': 0,
	    'col::charoff': 0,
	    'col::span': 0,
	    'col::valign': 0,
	    'col::width': 0,
	    'colgroup::align': 0,
	    'colgroup::char': 0,
	    'colgroup::charoff': 0,
	    'colgroup::span': 0,
	    'colgroup::valign': 0,
	    'colgroup::width': 0,
	    'del::cite': 1,
	    'del::datetime': 0,
	    'dir::compact': 0,
	    'div::align': 0,
	    'dl::compact': 0,
	    'font::color': 0,
	    'font::face': 0,
	    'font::size': 0,
	    'form::accept': 0,
	    'form::action': 1,
	    'form::autocomplete': 0,
	    'form::enctype': 0,
	    'form::method': 0,
	    'form::name': 7,
	    'form::onreset': 2,
	    'form::onsubmit': 2,
	    'form::target': 10,
	    'h1::align': 0,
	    'h2::align': 0,
	    'h3::align': 0,
	    'h4::align': 0,
	    'h5::align': 0,
	    'h6::align': 0,
	    'hr::align': 0,
	    'hr::noshade': 0,
	    'hr::size': 0,
	    'hr::width': 0,
	    'iframe::align': 0,
	    'iframe::frameborder': 0,
	    'iframe::height': 0,
	    'iframe::marginheight': 0,
	    'iframe::marginwidth': 0,
	    'iframe::width': 0,
	    'img::align': 0,
	    'img::alt': 0,
	    'img::border': 0,
	    'img::height': 0,
	    'img::hspace': 0,
	    'img::ismap': 0,
	    'img::name': 7,
	    'img::src': 1,
	    'img::usemap': 11,
	    'img::vspace': 0,
	    'img::width': 0,
	    'input::accept': 0,
	    'input::accesskey': 0,
	    'input::align': 0,
	    'input::alt': 0,
	    'input::autocomplete': 0,
	    'input::checked': 0,
	    'input::disabled': 0,
	    'input::ismap': 0,
	    'input::maxlength': 0,
	    'input::name': 8,
	    'input::onblur': 2,
	    'input::onchange': 2,
	    'input::onfocus': 2,
	    'input::onselect': 2,
	    'input::readonly': 0,
	    'input::size': 0,
	    'input::src': 1,
	    'input::tabindex': 0,
	    'input::type': 0,
	    'input::usemap': 11,
	    'input::value': 0,
	    'ins::cite': 1,
	    'ins::datetime': 0,
	    'label::accesskey': 0,
	    'label::for': 5,
	    'label::onblur': 2,
	    'label::onfocus': 2,
	    'legend::accesskey': 0,
	    'legend::align': 0,
	    'li::type': 0,
	    'li::value': 0,
	    'map::name': 7,
	    'menu::compact': 0,
	    'ol::compact': 0,
	    'ol::start': 0,
	    'ol::type': 0,
	    'optgroup::disabled': 0,
	    'optgroup::label': 0,
	    'option::disabled': 0,
	    'option::label': 0,
	    'option::selected': 0,
	    'option::value': 0,
	    'p::align': 0,
	    'pre::width': 0,
	    'q::cite': 1,
	    'select::disabled': 0,
	    'select::multiple': 0,
	    'select::name': 8,
	    'select::onblur': 2,
	    'select::onchange': 2,
	    'select::onfocus': 2,
	    'select::size': 0,
	    'select::tabindex': 0,
	    'table::align': 0,
	    'table::bgcolor': 0,
	    'table::border': 0,
	    'table::cellpadding': 0,
	    'table::cellspacing': 0,
	    'table::frame': 0,
	    'table::rules': 0,
	    'table::summary': 0,
	    'table::width': 0,
	    'tbody::align': 0,
	    'tbody::char': 0,
	    'tbody::charoff': 0,
	    'tbody::valign': 0,
	    'td::abbr': 0,
	    'td::align': 0,
	    'td::axis': 0,
	    'td::bgcolor': 0,
	    'td::char': 0,
	    'td::charoff': 0,
	    'td::colspan': 0,
	    'td::headers': 6,
	    'td::height': 0,
	    'td::nowrap': 0,
	    'td::rowspan': 0,
	    'td::scope': 0,
	    'td::valign': 0,
	    'td::width': 0,
	    'textarea::accesskey': 0,
	    'textarea::cols': 0,
	    'textarea::disabled': 0,
	    'textarea::name': 8,
	    'textarea::onblur': 2,
	    'textarea::onchange': 2,
	    'textarea::onfocus': 2,
	    'textarea::onselect': 2,
	    'textarea::readonly': 0,
	    'textarea::rows': 0,
	    'textarea::tabindex': 0,
	    'tfoot::align': 0,
	    'tfoot::char': 0,
	    'tfoot::charoff': 0,
	    'tfoot::valign': 0,
	    'th::abbr': 0,
	    'th::align': 0,
	    'th::axis': 0,
	    'th::bgcolor': 0,
	    'th::char': 0,
	    'th::charoff': 0,
	    'th::colspan': 0,
	    'th::headers': 6,
	    'th::height': 0,
	    'th::nowrap': 0,
	    'th::rowspan': 0,
	    'th::scope': 0,
	    'th::valign': 0,
	    'th::width': 0,
	    'thead::align': 0,
	    'thead::char': 0,
	    'thead::charoff': 0,
	    'thead::valign': 0,
	    'tr::align': 0,
	    'tr::bgcolor': 0,
	    'tr::char': 0,
	    'tr::charoff': 0,
	    'tr::valign': 0,
	    'ul::compact': 0,
	    'ul::type': 0
	};
	html4 .eflags = {
	    'OPTIONAL_ENDTAG': 1,
	    'EMPTY': 2,
	    'CDATA': 4,
	    'RCDATA': 8,
	    'UNSAFE': 16,
	    'FOLDABLE': 32,
	    'SCRIPT': 64,
	    'STYLE': 128
	};
	html4 .ELEMENTS = {
	    'a': 0,
	    'abbr': 0,
	    'acronym': 0,
	    'address': 0,
	    'applet': 16,
	    'area': 2,
	    'b': 0,
	    'base': 18,
	    'basefont': 18,
	    'bdo': 0,
	    'big': 0,
	    'blockquote': 0,
	    'body': 49,
	    'br': 2,
	    'button': 0,
	    'caption': 0,
	    'center': 0,
	    'cite': 0,
	    'code': 0,
	    'col': 2,
	    'colgroup': 1,
	    'dd': 1,
	    'del': 0,
	    'dfn': 0,
	    'dir': 0,
	    'div': 0,
	    'dl': 0,
	    'dt': 1,
	    'em': 0,
	    'fieldset': 0,
	    'font': 0,
	    'form': 0,
	    'frame': 18,
	    'frameset': 16,
	    'h1': 0,
	    'h2': 0,
	    'h3': 0,
	    'h4': 0,
	    'h5': 0,
	    'h6': 0,
	    'head': 49,
	    'hr': 2,
	    'html': 49,
	    'i': 0,
	    'iframe': 4,
	    'img': 2,
	    'input': 2,
	    'ins': 0,
	    'isindex': 18,
	    'kbd': 0,
	    'label': 0,
	    'legend': 0,
	    'li': 1,
	    'link': 18,
	    'map': 0,
	    'menu': 0,
	    'meta': 18,
	    'noframes': 20,
	    'noscript': 20,
	    'object': 16,
	    'ol': 0,
	    'optgroup': 0,
	    'option': 1,
	    'p': 1,
	    'param': 18,
	    'pre': 0,
	    'q': 0,
	    's': 0,
	    'samp': 0,
	    'script': 84,
	    'select': 0,
	    'small': 0,
	    'span': 0,
	    'strike': 0,
	    'strong': 0,
	    'style': 148,
	    'sub': 0,
	    'sup': 0,
	    'table': 0,
	    'tbody': 1,
	    'td': 1,
	    'textarea': 8,
	    'tfoot': 1,
	    'th': 1,
	    'thead': 1,
	    'title': 24,
	    'tr': 1,
	    'tt': 0,
	    'u': 0,
	    'ul': 0,
	    'var': 0
	};
	
	html4 .URIEFFECTS = {
	
	};
	html4 .LOADERTYPES = {}
	
	if (true) {
	    if (typeof module !== 'undefined' && module.exports) {
	        exports = module.exports = html4;
	    }
	    exports.URI = html4;
	} else {
	
	    // Exports for closure compiler.
	    if (typeof window !== 'undefined') {
	        window['html4'] = html4;
	    }
	}


/***/ },
/* 127 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (C) 2010 Google Inc.
	//
	// Licensed under the Apache License, Version 2.0 (the "License");
	// you may not use this file except in compliance with the License.
	// You may obtain a copy of the License at
	//
	//      http://www.apache.org/licenses/LICENSE-2.0
	//
	// Unless required by applicable law or agreed to in writing, software
	// distributed under the License is distributed on an "AS IS" BASIS,
	// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	// See the License for the specific language governing permissions and
	// limitations under the License.
	
	/**
	 * @fileoverview
	 * Implements RFC 3986 for parsing/formatting URIs.
	 *
	 * @author mikesamuel@gmail.com
	 * \@provides URI
	 * \@overrides window
	 */
	
	var URI = (function () {
	
	    /**
	     * creates a uri from the string form.  The parser is relaxed, so special
	     * characters that aren't escaped but don't cause ambiguities will not cause
	     * parse failures.
	     *
	     * @return {URI|null}
	     */
	    function parse(uriStr) {
	        var m = ('' + uriStr).match(URI_RE_);
	        if (!m) { return null; }
	        return new URI(
	            nullIfAbsent(m[1]),
	            nullIfAbsent(m[2]),
	            nullIfAbsent(m[3]),
	            nullIfAbsent(m[4]),
	            nullIfAbsent(m[5]),
	            nullIfAbsent(m[6]),
	            nullIfAbsent(m[7]));
	    }
	
	
	    /**
	     * creates a uri from the given parts.
	     *
	     * @param scheme {string} an unencoded scheme such as "http" or null
	     * @param credentials {string} unencoded user credentials or null
	     * @param domain {string} an unencoded domain name or null
	     * @param port {number} a port number in [1, 32768].
	     *    -1 indicates no port, as does null.
	     * @param path {string} an unencoded path
	     * @param query {Array.<string>|string|null} a list of unencoded cgi
	     *   parameters where even values are keys and odds the corresponding values
	     *   or an unencoded query.
	     * @param fragment {string} an unencoded fragment without the "#" or null.
	     * @return {URI}
	     */
	    function create(scheme, credentials, domain, port, path, query, fragment) {
	        var uri = new URI(
	            encodeIfExists2(scheme, URI_DISALLOWED_IN_SCHEME_OR_CREDENTIALS_),
	            encodeIfExists2(
	                credentials, URI_DISALLOWED_IN_SCHEME_OR_CREDENTIALS_),
	            encodeIfExists(domain),
	            port > 0 ? port.toString() : null,
	            encodeIfExists2(path, URI_DISALLOWED_IN_PATH_),
	            null,
	            encodeIfExists(fragment));
	        if (query) {
	            if ('string' === typeof query) {
	                uri.setRawQuery(query.replace(/[^?&=0-9A-Za-z_\-~.%]/g, encodeOne));
	            } else {
	                uri.setAllParameters(query);
	            }
	        }
	        return uri;
	    }
	    function encodeIfExists(unescapedPart) {
	        if ('string' == typeof unescapedPart) {
	            return encodeURIComponent(unescapedPart);
	        }
	        return null;
	    };
	    /**
	     * if unescapedPart is non null, then escapes any characters in it that aren't
	     * valid characters in a url and also escapes any special characters that
	     * appear in extra.
	     *
	     * @param unescapedPart {string}
	     * @param extra {RegExp} a character set of characters in [\01-\177].
	     * @return {string|null} null iff unescapedPart == null.
	     */
	    function encodeIfExists2(unescapedPart, extra) {
	        if ('string' == typeof unescapedPart) {
	            return encodeURI(unescapedPart).replace(extra, encodeOne);
	        }
	        return null;
	    };
	    /** converts a character in [\01-\177] to its url encoded equivalent. */
	    function encodeOne(ch) {
	        var n = ch.charCodeAt(0);
	        return '%' + '0123456789ABCDEF'.charAt((n >> 4) & 0xf) +
	            '0123456789ABCDEF'.charAt(n & 0xf);
	    }
	
	    /**
	     * {@updoc
	     *  $ normPath('foo/./bar')
	     *  # 'foo/bar'
	     *  $ normPath('./foo')
	     *  # 'foo'
	     *  $ normPath('foo/.')
	     *  # 'foo'
	     *  $ normPath('foo//bar')
	     *  # 'foo/bar'
	     * }
	     */
	    function normPath(path) {
	        return path.replace(/(^|\/)\.(?:\/|$)/g, '$1').replace(/\/{2,}/g, '/');
	    }
	
	    var PARENT_DIRECTORY_HANDLER = new RegExp(
	        ''
	            // A path break
	            + '(/|^)'
	            // followed by a non .. path element
	            // (cannot be . because normPath is used prior to this RegExp)
	            + '(?:[^./][^/]*|\\.{2,}(?:[^./][^/]*)|\\.{3,}[^/]*)'
	            // followed by .. followed by a path break.
	            + '/\\.\\.(?:/|$)');
	
	    var PARENT_DIRECTORY_HANDLER_RE = new RegExp(PARENT_DIRECTORY_HANDLER);
	
	    var EXTRA_PARENT_PATHS_RE = /^(?:\.\.\/)*(?:\.\.$)?/;
	
	    /**
	     * Normalizes its input path and collapses all . and .. sequences except for
	     * .. sequences that would take it above the root of the current parent
	     * directory.
	     * {@updoc
	     *  $ collapse_dots('foo/../bar')
	     *  # 'bar'
	     *  $ collapse_dots('foo/./bar')
	     *  # 'foo/bar'
	     *  $ collapse_dots('foo/../bar/./../../baz')
	     *  # 'baz'
	     *  $ collapse_dots('../foo')
	     *  # '../foo'
	     *  $ collapse_dots('../foo').replace(EXTRA_PARENT_PATHS_RE, '')
	     *  # 'foo'
	     * }
	     */
	    function collapse_dots(path) {
	        if (path === null) { return null; }
	        var p = normPath(path);
	        // Only /../ left to flatten
	        var r = PARENT_DIRECTORY_HANDLER_RE;
	        // We replace with $1 which matches a / before the .. because this
	        // guarantees that:
	        // (1) we have at most 1 / between the adjacent place,
	        // (2) always have a slash if there is a preceding path section, and
	        // (3) we never turn a relative path into an absolute path.
	        for (var q; (q = p.replace(r, '$1')) != p; p = q) {};
	        return p;
	    }
	
	    /**
	     * resolves a relative url string to a base uri.
	     * @return {URI}
	     */
	    function resolve(baseUri, relativeUri) {
	        // there are several kinds of relative urls:
	        // 1. //foo - replaces everything from the domain on.  foo is a domain name
	        // 2. foo - replaces the last part of the path, the whole query and fragment
	        // 3. /foo - replaces the the path, the query and fragment
	        // 4. ?foo - replace the query and fragment
	        // 5. #foo - replace the fragment only
	
	        var absoluteUri = baseUri.clone();
	        // we satisfy these conditions by looking for the first part of relativeUri
	        // that is not blank and applying defaults to the rest
	
	        var overridden = relativeUri.hasScheme();
	
	        if (overridden) {
	            absoluteUri.setRawScheme(relativeUri.getRawScheme());
	        } else {
	            overridden = relativeUri.hasCredentials();
	        }
	
	        if (overridden) {
	            absoluteUri.setRawCredentials(relativeUri.getRawCredentials());
	        } else {
	            overridden = relativeUri.hasDomain();
	        }
	
	        if (overridden) {
	            absoluteUri.setRawDomain(relativeUri.getRawDomain());
	        } else {
	            overridden = relativeUri.hasPort();
	        }
	
	        var rawPath = relativeUri.getRawPath();
	        var simplifiedPath = collapse_dots(rawPath);
	        if (overridden) {
	            absoluteUri.setPort(relativeUri.getPort());
	            simplifiedPath = simplifiedPath
	                && simplifiedPath.replace(EXTRA_PARENT_PATHS_RE, '');
	        } else {
	            overridden = !!rawPath;
	            if (overridden) {
	                // resolve path properly
	                if (simplifiedPath.charCodeAt(0) !== 0x2f /* / */) {  // path is relative
	                    var absRawPath = collapse_dots(absoluteUri.getRawPath() || '')
	                        .replace(EXTRA_PARENT_PATHS_RE, '');
	                    var slash = absRawPath.lastIndexOf('/') + 1;
	                    simplifiedPath = collapse_dots(
	                        (slash ? absRawPath.substring(0, slash) : '')
	                            + collapse_dots(rawPath))
	                        .replace(EXTRA_PARENT_PATHS_RE, '');
	                }
	            } else {
	                simplifiedPath = simplifiedPath
	                    && simplifiedPath.replace(EXTRA_PARENT_PATHS_RE, '');
	                if (simplifiedPath !== rawPath) {
	                    absoluteUri.setRawPath(simplifiedPath);
	                }
	            }
	        }
	
	        if (overridden) {
	            absoluteUri.setRawPath(simplifiedPath);
	        } else {
	            overridden = relativeUri.hasQuery();
	        }
	
	        if (overridden) {
	            absoluteUri.setRawQuery(relativeUri.getRawQuery());
	        } else {
	            overridden = relativeUri.hasFragment();
	        }
	
	        if (overridden) {
	            absoluteUri.setRawFragment(relativeUri.getRawFragment());
	        }
	
	        return absoluteUri;
	    }
	
	    /**
	     * a mutable URI.
	     *
	     * This class contains setters and getters for the parts of the URI.
	     * The <tt>getXYZ</tt>/<tt>setXYZ</tt> methods return the decoded part -- so
	     * <code>uri.parse('/foo%20bar').getPath()</code> will return the decoded path,
	     * <tt>/foo bar</tt>.
	     *
	     * <p>The raw versions of fields are available too.
	     * <code>uri.parse('/foo%20bar').getRawPath()</code> will return the raw path,
	     * <tt>/foo%20bar</tt>.  Use the raw setters with care, since
	     * <code>URI::toString</code> is not guaranteed to return a valid url if a
	     * raw setter was used.
	     *
	     * <p>All setters return <tt>this</tt> and so may be chained, a la
	     * <code>uri.parse('/foo').setFragment('part').toString()</code>.
	     *
	     * <p>You should not use this constructor directly -- please prefer the factory
	     * functions {@link uri.parse}, {@link uri.create}, {@link uri.resolve}
	     * instead.</p>
	     *
	     * <p>The parameters are all raw (assumed to be properly escaped) parts, and
	     * any (but not all) may be null.  Undefined is not allowed.</p>
	     *
	     * @constructor
	     */
	    function URI(
	        rawScheme,
	        rawCredentials, rawDomain, port,
	        rawPath, rawQuery, rawFragment) {
	        this.scheme_ = rawScheme;
	        this.credentials_ = rawCredentials;
	        this.domain_ = rawDomain;
	        this.port_ = port;
	        this.path_ = rawPath;
	        this.query_ = rawQuery;
	        this.fragment_ = rawFragment;
	        /**
	         * @type {Array|null}
	         */
	        this.paramCache_ = null;
	    }
	
	    /** returns the string form of the url. */
	    URI.prototype.toString = function () {
	        var out = [];
	        if (null !== this.scheme_) { out.push(this.scheme_, ':'); }
	        if (null !== this.domain_) {
	            out.push('//');
	            if (null !== this.credentials_) { out.push(this.credentials_, '@'); }
	            out.push(this.domain_);
	            if (null !== this.port_) { out.push(':', this.port_.toString()); }
	        }
	        if (null !== this.path_) { out.push(this.path_); }
	        if (null !== this.query_) { out.push('?', this.query_); }
	        if (null !== this.fragment_) { out.push('#', this.fragment_); }
	        return out.join('');
	    };
	
	    URI.prototype.clone = function () {
	        return new URI(this.scheme_, this.credentials_, this.domain_, this.port_,
	            this.path_, this.query_, this.fragment_);
	    };
	
	    URI.prototype.getScheme = function () {
	        // HTML5 spec does not require the scheme to be lowercased but
	        // all common browsers except Safari lowercase the scheme.
	        return this.scheme_ && decodeURIComponent(this.scheme_).toLowerCase();
	    };
	    URI.prototype.getRawScheme = function () {
	        return this.scheme_;
	    };
	    URI.prototype.setScheme = function (newScheme) {
	        this.scheme_ = encodeIfExists2(
	            newScheme, URI_DISALLOWED_IN_SCHEME_OR_CREDENTIALS_);
	        return this;
	    };
	    URI.prototype.setRawScheme = function (newScheme) {
	        this.scheme_ = newScheme ? newScheme : null;
	        return this;
	    };
	    URI.prototype.hasScheme = function () {
	        return null !== this.scheme_;
	    };
	
	
	    URI.prototype.getCredentials = function () {
	        return this.credentials_ && decodeURIComponent(this.credentials_);
	    };
	    URI.prototype.getRawCredentials = function () {
	        return this.credentials_;
	    };
	    URI.prototype.setCredentials = function (newCredentials) {
	        this.credentials_ = encodeIfExists2(
	            newCredentials, URI_DISALLOWED_IN_SCHEME_OR_CREDENTIALS_);
	
	        return this;
	    };
	    URI.prototype.setRawCredentials = function (newCredentials) {
	        this.credentials_ = newCredentials ? newCredentials : null;
	        return this;
	    };
	    URI.prototype.hasCredentials = function () {
	        return null !== this.credentials_;
	    };
	
	
	    URI.prototype.getDomain = function () {
	        return this.domain_ && decodeURIComponent(this.domain_);
	    };
	    URI.prototype.getRawDomain = function () {
	        return this.domain_;
	    };
	    URI.prototype.setDomain = function (newDomain) {
	        return this.setRawDomain(newDomain && encodeURIComponent(newDomain));
	    };
	    URI.prototype.setRawDomain = function (newDomain) {
	        this.domain_ = newDomain ? newDomain : null;
	        // Maintain the invariant that paths must start with a slash when the URI
	        // is not path-relative.
	        return this.setRawPath(this.path_);
	    };
	    URI.prototype.hasDomain = function () {
	        return null !== this.domain_;
	    };
	
	
	    URI.prototype.getPort = function () {
	        return this.port_ && decodeURIComponent(this.port_);
	    };
	    URI.prototype.setPort = function (newPort) {
	        if (newPort) {
	            newPort = Number(newPort);
	            if (newPort !== (newPort & 0xffff)) {
	                throw new Error('Bad port number ' + newPort);
	            }
	            this.port_ = '' + newPort;
	        } else {
	            this.port_ = null;
	        }
	        return this;
	    };
	    URI.prototype.hasPort = function () {
	        return null !== this.port_;
	    };
	
	
	    URI.prototype.getPath = function () {
	        return this.path_ && decodeURIComponent(this.path_);
	    };
	    URI.prototype.getRawPath = function () {
	        return this.path_;
	    };
	    URI.prototype.setPath = function (newPath) {
	        return this.setRawPath(encodeIfExists2(newPath, URI_DISALLOWED_IN_PATH_));
	    };
	    URI.prototype.setRawPath = function (newPath) {
	        if (newPath) {
	            newPath = String(newPath);
	            this.path_ =
	                // Paths must start with '/' unless this is a path-relative URL.
	                (!this.domain_ || /^\//.test(newPath)) ? newPath : '/' + newPath;
	        } else {
	            this.path_ = null;
	        }
	        return this;
	    };
	    URI.prototype.hasPath = function () {
	        return null !== this.path_;
	    };
	
	
	    URI.prototype.getQuery = function () {
	        // From http://www.w3.org/Addressing/URL/4_URI_Recommentations.html
	        // Within the query string, the plus sign is reserved as shorthand notation
	        // for a space.
	        return this.query_ && decodeURIComponent(this.query_).replace(/\+/g, ' ');
	    };
	    URI.prototype.getRawQuery = function () {
	        return this.query_;
	    };
	    URI.prototype.setQuery = function (newQuery) {
	        this.paramCache_ = null;
	        this.query_ = encodeIfExists(newQuery);
	        return this;
	    };
	    URI.prototype.setRawQuery = function (newQuery) {
	        this.paramCache_ = null;
	        this.query_ = newQuery ? newQuery : null;
	        return this;
	    };
	    URI.prototype.hasQuery = function () {
	        return null !== this.query_;
	    };
	
	    /**
	     * sets the query given a list of strings of the form
	     * [ key0, value0, key1, value1, ... ].
	     *
	     * <p><code>uri.setAllParameters(['a', 'b', 'c', 'd']).getQuery()</code>
	     * will yield <code>'a=b&c=d'</code>.
	     */
	    URI.prototype.setAllParameters = function (params) {
	        if (typeof params === 'object') {
	            if (!(params instanceof Array)
	                && (params instanceof Object
	                || Object.prototype.toString.call(params) !== '[object Array]')) {
	                var newParams = [];
	                var i = -1;
	                for (var k in params) {
	                    var v = params[k];
	                    if ('string' === typeof v) {
	                        newParams[++i] = k;
	                        newParams[++i] = v;
	                    }
	                }
	                params = newParams;
	            }
	        }
	        this.paramCache_ = null;
	        var queryBuf = [];
	        var separator = '';
	        for (var j = 0; j < params.length;) {
	            var k = params[j++];
	            var v = params[j++];
	            queryBuf.push(separator, encodeURIComponent(k.toString()));
	            separator = '&';
	            if (v) {
	                queryBuf.push('=', encodeURIComponent(v.toString()));
	            }
	        }
	        this.query_ = queryBuf.join('');
	        return this;
	    };
	    URI.prototype.checkParameterCache_ = function () {
	        if (!this.paramCache_) {
	            var q = this.query_;
	            if (!q) {
	                this.paramCache_ = [];
	            } else {
	                var cgiParams = q.split(/[&\?]/);
	                var out = [];
	                var k = -1;
	                for (var i = 0; i < cgiParams.length; ++i) {
	                    var m = cgiParams[i].match(/^([^=]*)(?:=(.*))?$/);
	                    // From http://www.w3.org/Addressing/URL/4_URI_Recommentations.html
	                    // Within the query string, the plus sign is reserved as shorthand
	                    // notation for a space.
	                    out[++k] = decodeURIComponent(m[1]).replace(/\+/g, ' ');
	                    out[++k] = decodeURIComponent(m[2] || '').replace(/\+/g, ' ');
	                }
	                this.paramCache_ = out;
	            }
	        }
	    };
	    /**
	     * sets the values of the named cgi parameters.
	     *
	     * <p>So, <code>uri.parse('foo?a=b&c=d&e=f').setParameterValues('c', ['new'])
	     * </code> yields <tt>foo?a=b&c=new&e=f</tt>.</p>
	     *
	     * @param key {string}
	     * @param values {Array.<string>} the new values.  If values is a single string
	     *   then it will be treated as the sole value.
	     */
	    URI.prototype.setParameterValues = function (key, values) {
	        // be nice and avoid subtle bugs where [] operator on string performs charAt
	        // on some browsers and crashes on IE
	        if (typeof values === 'string') {
	            values = [ values ];
	        }
	
	        this.checkParameterCache_();
	        var newValueIndex = 0;
	        var pc = this.paramCache_;
	        var params = [];
	        for (var i = 0, k = 0; i < pc.length; i += 2) {
	            if (key === pc[i]) {
	                if (newValueIndex < values.length) {
	                    params.push(key, values[newValueIndex++]);
	                }
	            } else {
	                params.push(pc[i], pc[i + 1]);
	            }
	        }
	        while (newValueIndex < values.length) {
	            params.push(key, values[newValueIndex++]);
	        }
	        this.setAllParameters(params);
	        return this;
	    };
	    URI.prototype.removeParameter = function (key) {
	        return this.setParameterValues(key, []);
	    };
	    /**
	     * returns the parameters specified in the query part of the uri as a list of
	     * keys and values like [ key0, value0, key1, value1, ... ].
	     *
	     * @return {Array.<string>}
	     */
	    URI.prototype.getAllParameters = function () {
	        this.checkParameterCache_();
	        return this.paramCache_.slice(0, this.paramCache_.length);
	    };
	    /**
	     * returns the value<b>s</b> for a given cgi parameter as a list of decoded
	     * query parameter values.
	     * @return {Array.<string>}
	     */
	    URI.prototype.getParameterValues = function (paramNameUnescaped) {
	        this.checkParameterCache_();
	        var values = [];
	        for (var i = 0; i < this.paramCache_.length; i += 2) {
	            if (paramNameUnescaped === this.paramCache_[i]) {
	                values.push(this.paramCache_[i + 1]);
	            }
	        }
	        return values;
	    };
	    /**
	     * returns a map of cgi parameter names to (non-empty) lists of values.
	     * @return {Object.<string,Array.<string>>}
	     */
	    URI.prototype.getParameterMap = function (paramNameUnescaped) {
	        this.checkParameterCache_();
	        var paramMap = {};
	        for (var i = 0; i < this.paramCache_.length; i += 2) {
	            var key = this.paramCache_[i++],
	                value = this.paramCache_[i++];
	            if (!(key in paramMap)) {
	                paramMap[key] = [value];
	            } else {
	                paramMap[key].push(value);
	            }
	        }
	        return paramMap;
	    };
	    /**
	     * returns the first value for a given cgi parameter or null if the given
	     * parameter name does not appear in the query string.
	     * If the given parameter name does appear, but has no '<tt>=</tt>' following
	     * it, then the empty string will be returned.
	     * @return {string|null}
	     */
	    URI.prototype.getParameterValue = function (paramNameUnescaped) {
	        this.checkParameterCache_();
	        for (var i = 0; i < this.paramCache_.length; i += 2) {
	            if (paramNameUnescaped === this.paramCache_[i]) {
	                return this.paramCache_[i + 1];
	            }
	        }
	        return null;
	    };
	
	    URI.prototype.getFragment = function () {
	        return this.fragment_ && decodeURIComponent(this.fragment_);
	    };
	    URI.prototype.getRawFragment = function () {
	        return this.fragment_;
	    };
	    URI.prototype.setFragment = function (newFragment) {
	        this.fragment_ = newFragment ? encodeURIComponent(newFragment) : null;
	        return this;
	    };
	    URI.prototype.setRawFragment = function (newFragment) {
	        this.fragment_ = newFragment ? newFragment : null;
	        return this;
	    };
	    URI.prototype.hasFragment = function () {
	        return null !== this.fragment_;
	    };
	
	    function nullIfAbsent(matchPart) {
	        return ('string' == typeof matchPart) && (matchPart.length > 0)
	            ? matchPart
	            : null;
	    }
	
	
	
	
	    /**
	     * a regular expression for breaking a URI into its component parts.
	     *
	     * <p>http://www.gbiv.com/protocols/uri/rfc/rfc3986.html#RFC2234 says
	     * As the "first-match-wins" algorithm is identical to the "greedy"
	     * disambiguation method used by POSIX regular expressions, it is natural and
	     * commonplace to use a regular expression for parsing the potential five
	     * components of a URI reference.
	     *
	     * <p>The following line is the regular expression for breaking-down a
	     * well-formed URI reference into its components.
	     *
	     * <pre>
	     * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
	     *  12            3  4          5       6  7        8 9
	     * </pre>
	     *
	     * <p>The numbers in the second line above are only to assist readability; they
	     * indicate the reference points for each subexpression (i.e., each paired
	     * parenthesis). We refer to the value matched for subexpression <n> as $<n>.
	     * For example, matching the above expression to
	     * <pre>
	     *     http://www.ics.uci.edu/pub/ietf/uri/#Related
	     * </pre>
	     * results in the following subexpression matches:
	     * <pre>
	     *    $1 = http:
	     *    $2 = http
	     *    $3 = //www.ics.uci.edu
	     *    $4 = www.ics.uci.edu
	     *    $5 = /pub/ietf/uri/
	     *    $6 = <undefined>
	     *    $7 = <undefined>
	     *    $8 = #Related
	     *    $9 = Related
	     * </pre>
	     * where <undefined> indicates that the component is not present, as is the
	     * case for the query component in the above example. Therefore, we can
	     * determine the value of the five components as
	     * <pre>
	     *    scheme    = $2
	     *    authority = $4
	     *    path      = $5
	     *    query     = $7
	     *    fragment  = $9
	     * </pre>
	     *
	     * <p>msamuel: I have modified the regular expression slightly to expose the
	     * credentials, domain, and port separately from the authority.
	     * The modified version yields
	     * <pre>
	     *    $1 = http              scheme
	     *    $2 = <undefined>       credentials -\
	     *    $3 = www.ics.uci.edu   domain       | authority
	     *    $4 = <undefined>       port        -/
	     *    $5 = /pub/ietf/uri/    path
	     *    $6 = <undefined>       query without ?
	     *    $7 = Related           fragment without #
	     * </pre>
	     */
	    var URI_RE_ = new RegExp(
	        "^" +
	            "(?:" +
	            "([^:/?#]+)" +         // scheme
	            ":)?" +
	            "(?://" +
	            "(?:([^/?#]*)@)?" +    // credentials
	            "([^/?#:@]*)" +        // domain
	            "(?::([0-9]+))?" +     // port
	            ")?" +
	            "([^?#]+)?" +            // path
	            "(?:\\?([^#]*))?" +      // query
	            "(?:#(.*))?" +           // fragment
	            "$"
	    );
	
	    var URI_DISALLOWED_IN_SCHEME_OR_CREDENTIALS_ = /[#\/\?@]/g;
	    var URI_DISALLOWED_IN_PATH_ = /[\#\?]/g;
	
	    URI.parse = parse;
	    URI.create = create;
	    URI.resolve = resolve;
	    URI.collapse_dots = collapse_dots;  // Visible for testing.
	
	// lightweight string-based api for loadModuleMaker
	    URI.utils = {
	        mimeTypeOf: function (uri) {
	            var uriObj = parse(uri);
	            if (/\.html$/.test(uriObj.getPath())) {
	                return 'text/html';
	            } else {
	                return 'application/javascript';
	            }
	        },
	        resolve: function (base, uri) {
	            if (base) {
	                return resolve(parse(base), parse(uri)).toString();
	            } else {
	                return '' + uri;
	            }
	        }
	    };
	
	
	    return URI;
	})();
	
	if (true) {
	    if (typeof module !== 'undefined' && module.exports) {
	        exports = module.exports = URI;
	    }
	    exports.URI = URI;
	} else {
	
	    // Exports for closure compiler.
	    if (typeof window !== 'undefined') {
	        window['URI'] = URI;
	    }
	}


/***/ },
/* 128 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var codemirror_1 = __webpack_require__(129);
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_widget_1 = __webpack_require__(20);
	var output_area_1 = __webpack_require__(120);
	var sanitizer_1 = __webpack_require__(125);
	var editor_1 = __webpack_require__(263);
	/**
	 * The class name added to cell widgets.
	 */
	var CELL_CLASS = 'jp-Cell';
	/**
	 * The class name added to input area widgets.
	 */
	var INPUT_CLASS = 'jp-InputArea';
	/**
	 * The class name added to the prompt area of cell.
	 */
	var PROMPT_CLASS = 'jp-InputArea-prompt';
	/**
	 * The class name added to the editor area of the cell.
	 */
	var EDITOR_CLASS = 'jp-InputArea-editor';
	/**
	 * The class name added to the cell when collapsed.
	 */
	var COLLAPSED_CLASS = 'jp-mod-collapsed';
	/**
	 * The class name added to the cell when readonly.
	 */
	var READONLY_CLASS = 'jp-mod-readOnly';
	/**
	 * The class name added to code cells.
	 */
	var CODE_CELL_CLASS = 'jp-CodeCell';
	/**
	 * The class name added to markdown cells.
	 */
	var MARKDOWN_CELL_CLASS = 'jp-MarkdownCell';
	/**
	 * The class name added to the markdown cell renderer widget.
	 */
	var RENDERER_CLASS = 'jp-MarkdownCell-renderer';
	/**
	 * The class name added to raw cells.
	 */
	var RAW_CELL_CLASS = 'jp-RawCell';
	/**
	 * The class name added to a rendered markdown cell.
	 */
	var RENDERED_CLASS = 'jp-mod-rendered';
	/**
	 * The text applied to an empty markdown cell.
	 */
	var DEFAULT_MARKDOWN_TEXT = 'Type Markdown and LaTeX: $ α^2 $';
	/**
	 * A base cell widget.
	 */
	var BaseCellWidget = (function (_super) {
	    __extends(BaseCellWidget, _super);
	    /**
	     * Construct a new base cell widget.
	     */
	    function BaseCellWidget(model) {
	        _super.call(this);
	        this._input = null;
	        this._editor = null;
	        this._model = null;
	        this._mimetype = 'text/plain';
	        this._readOnly = false;
	        this._trustedCursor = null;
	        this._trusted = false;
	        this.addClass(CELL_CLASS);
	        this._model = model;
	        var ctor = this.constructor;
	        this._editor = ctor.createCellEditor(model);
	        this._input = ctor.createInputArea(this._editor);
	        // Set the editor mode to be the default MIME type.
	        codemirror_1.loadModeByMIME(this._editor.editor, this._mimetype);
	        this.layout = new phosphor_panel_1.PanelLayout();
	        this.layout.addChild(this._input);
	        model.metadataChanged.connect(this.onMetadataChanged, this);
	        this._trustedCursor = model.getMetadata('trusted');
	        this._trusted = this._trustedCursor.getValue();
	    }
	    /**
	     * Create a new cell editor for the widget.
	     */
	    BaseCellWidget.createCellEditor = function (model) {
	        return new editor_1.CellEditorWidget(model);
	    };
	    /**
	     * Create a new input area for the widget.
	     */
	    BaseCellWidget.createInputArea = function (editor) {
	        return new InputAreaWidget(editor);
	    };
	    Object.defineProperty(BaseCellWidget.prototype, "model", {
	        /**
	         * Get the model used by the widget.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._model;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(BaseCellWidget.prototype, "editor", {
	        /**
	         * Get the editor widget used by the cell.
	         *
	         * #### Notes
	         * This is a ready-only property.
	         */
	        get: function () {
	            return this._editor;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(BaseCellWidget.prototype, "mimetype", {
	        /**
	         * The mimetype used by the cell.
	         */
	        get: function () {
	            return this._mimetype;
	        },
	        set: function (value) {
	            if (!value) {
	                return;
	            }
	            if (this._mimetype === value) {
	                return;
	            }
	            this._mimetype = value;
	            codemirror_1.loadModeByMIME(this.editor.editor, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(BaseCellWidget.prototype, "readOnly", {
	        /**
	         * The read only state of the cell.
	         */
	        get: function () {
	            return this._readOnly;
	        },
	        set: function (value) {
	            if (value === this._readOnly) {
	                return;
	            }
	            this._readOnly = value;
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(BaseCellWidget.prototype, "trusted", {
	        /**
	         * The trusted state of the cell.
	         */
	        get: function () {
	            return this._trusted;
	        },
	        set: function (value) {
	            this._trustedCursor.setValue(value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Focus the widget.
	     */
	    BaseCellWidget.prototype.focus = function () {
	        this.editor.editor.focus();
	    };
	    /**
	     * Set the prompt for the widget.
	     */
	    BaseCellWidget.prototype.setPrompt = function (value) {
	        this._input.setPrompt(value);
	    };
	    /**
	     * Toggle whether the input area is shown.
	     */
	    BaseCellWidget.prototype.toggleInput = function (value) {
	        if (value) {
	            this._input.show();
	            this.focus();
	        }
	        else {
	            this._input.hide();
	        }
	    };
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    BaseCellWidget.prototype.dispose = function () {
	        // Do nothing if already disposed.
	        if (this.isDisposed) {
	            return;
	        }
	        this._model = null;
	        this._input = null;
	        this._editor = null;
	        this._trustedCursor = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Handle `after-attach` messages.
	     */
	    BaseCellWidget.prototype.onAfterAttach = function (msg) {
	        this.update();
	    };
	    /**
	     * Handle `update_request` messages.
	     */
	    BaseCellWidget.prototype.onUpdateRequest = function (message) {
	        // Handle read only state.
	        var option = this._readOnly ? 'nocursor' : false;
	        this.editor.editor.setOption('readOnly', option);
	        this.toggleClass(READONLY_CLASS, this._readOnly);
	    };
	    /**
	     * Handle changes in the model.
	     */
	    BaseCellWidget.prototype.onMetadataChanged = function (model, args) {
	        switch (args.name) {
	            case 'trusted':
	                this._trusted = this._trustedCursor.getValue();
	                this.update();
	                break;
	            default:
	                break;
	        }
	    };
	    return BaseCellWidget;
	}(phosphor_widget_1.Widget));
	exports.BaseCellWidget = BaseCellWidget;
	/**
	 * A widget for a code cell.
	 */
	var CodeCellWidget = (function (_super) {
	    __extends(CodeCellWidget, _super);
	    /**
	     * Construct a code cell widget.
	     */
	    function CodeCellWidget(model, rendermime) {
	        _super.call(this, model);
	        this._output = null;
	        this._rendermime = null;
	        this._collapsedCursor = null;
	        this._scrolledCursor = null;
	        this._rendermime = rendermime;
	        this.addClass(CODE_CELL_CLASS);
	        var constructor = this.constructor;
	        this._output = constructor.createOutput(model.outputs, rendermime);
	        this._output.trusted = this.trusted;
	        this.layout.addChild(this._output);
	        this._collapsedCursor = model.getMetadata('collapsed');
	        this._scrolledCursor = model.getMetadata('scrolled');
	        this.setPrompt(String(model.executionCount));
	        model.stateChanged.connect(this.onModelChanged, this);
	    }
	    /**
	     * Create an output area widget.
	     */
	    CodeCellWidget.createOutput = function (outputs, rendermime) {
	        return new output_area_1.OutputAreaWidget(outputs, rendermime);
	    };
	    /**
	     * Dispose of the resources used by the widget.
	     */
	    CodeCellWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._rendermime = null;
	        this._collapsedCursor = null;
	        this._scrolledCursor = null;
	        this._output = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Execute the cell given a kernel.
	     */
	    CodeCellWidget.prototype.execute = function (kernel) {
	        var model = this.model;
	        var code = model.source;
	        if (!code.trim()) {
	            model.executionCount = null;
	            return Promise.resolve(void 0);
	        }
	        model.executionCount = null;
	        this.setPrompt('*');
	        this.trusted = true;
	        var outputs = model.outputs;
	        return output_area_1.executeCode(code, kernel, outputs).then(function (reply) {
	            model.executionCount = reply.execution_count;
	        });
	    };
	    /**
	     * Handle `update_request` messages.
	     */
	    CodeCellWidget.prototype.onUpdateRequest = function (message) {
	        this.toggleClass(COLLAPSED_CLASS, this._collapsedCursor.getValue());
	        // TODO: handle scrolled state.
	        this._output.trusted = this.trusted;
	        _super.prototype.onUpdateRequest.call(this, message);
	    };
	    /**
	     * Handle changes in the model.
	     */
	    CodeCellWidget.prototype.onModelChanged = function (model, args) {
	        switch (args.name) {
	            case 'executionCount':
	                this.setPrompt(String(model.executionCount));
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle changes in the metadata.
	     */
	    CodeCellWidget.prototype.onMetadataChanged = function (model, args) {
	        switch (args.name) {
	            case 'collapsed':
	            case 'scrolled':
	                this.update();
	                break;
	            default:
	                break;
	        }
	        _super.prototype.onMetadataChanged.call(this, model, args);
	    };
	    return CodeCellWidget;
	}(BaseCellWidget));
	exports.CodeCellWidget = CodeCellWidget;
	/**
	 * A widget for a Markdown cell.
	 *
	 * #### Notes
	 * Things get complicated if we want the rendered text to update
	 * any time the text changes, the text editor model changes,
	 * or the input area model changes.  We don't support automatically
	 * updating the rendered text in all of these cases.
	 */
	var MarkdownCellWidget = (function (_super) {
	    __extends(MarkdownCellWidget, _super);
	    /**
	     * Construct a Markdown cell widget.
	     */
	    function MarkdownCellWidget(model, rendermime) {
	        _super.call(this, model);
	        this._rendermime = null;
	        this._renderer = null;
	        this._rendered = true;
	        this._prev = '';
	        this._rendermime = rendermime;
	        this.addClass(MARKDOWN_CELL_CLASS);
	        // Insist on the Github-flavored markdown mode.
	        this.mimetype = 'text/x-ipythongfm';
	        this._renderer = new phosphor_widget_1.Widget();
	        this._renderer.addClass(RENDERER_CLASS);
	        this.layout.addChild(this._renderer);
	    }
	    Object.defineProperty(MarkdownCellWidget.prototype, "rendered", {
	        /**
	         * Whether the cell is rendered.
	         */
	        get: function () {
	            return this._rendered;
	        },
	        set: function (value) {
	            if (value === this._rendered) {
	                return;
	            }
	            this._rendered = value;
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resource held by the widget.
	     */
	    MarkdownCellWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._renderer = null;
	        this._rendermime = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Handle `update_request` messages.
	     */
	    MarkdownCellWidget.prototype.onUpdateRequest = function (message) {
	        var model = this.model;
	        if (this.rendered) {
	            var text = model.source || DEFAULT_MARKDOWN_TEXT;
	            // Do not re-render if the text has not changed.
	            if (text !== this._prev) {
	                text = sanitizer_1.sanitize(text);
	                var bundle = { 'text/markdown': text };
	                this._renderer.dispose();
	                this._renderer = this._rendermime.render(bundle) || new phosphor_widget_1.Widget();
	                this._renderer.addClass(RENDERER_CLASS);
	                this.layout.addChild(this._renderer);
	            }
	            this._prev = text;
	            this._renderer.show();
	            this.toggleInput(false);
	            this.addClass(RENDERED_CLASS);
	        }
	        else {
	            this._renderer.hide();
	            this.toggleInput(true);
	            this.removeClass(RENDERED_CLASS);
	        }
	        _super.prototype.onUpdateRequest.call(this, message);
	    };
	    return MarkdownCellWidget;
	}(BaseCellWidget));
	exports.MarkdownCellWidget = MarkdownCellWidget;
	/**
	 * A widget for a raw cell.
	 */
	var RawCellWidget = (function (_super) {
	    __extends(RawCellWidget, _super);
	    /**
	     * Construct a raw cell widget.
	     */
	    function RawCellWidget(model) {
	        _super.call(this, model);
	        this.addClass(RAW_CELL_CLASS);
	    }
	    return RawCellWidget;
	}(BaseCellWidget));
	exports.RawCellWidget = RawCellWidget;
	/**
	 * An input area widget, which hosts a prompt and an editor widget.
	 */
	var InputAreaWidget = (function (_super) {
	    __extends(InputAreaWidget, _super);
	    /**
	     * Construct an input area widget.
	     */
	    function InputAreaWidget(editor) {
	        _super.call(this);
	        this.addClass(INPUT_CLASS);
	        editor.addClass(EDITOR_CLASS);
	        this.layout = new phosphor_panel_1.PanelLayout();
	        var prompt = new phosphor_widget_1.Widget();
	        prompt.addClass(PROMPT_CLASS);
	        var layout = this.layout;
	        layout.addChild(prompt);
	        layout.addChild(editor);
	    }
	    /**
	     * Set the prompt of the input area.
	     */
	    InputAreaWidget.prototype.setPrompt = function (value) {
	        var prompt = this.layout.childAt(0);
	        if (value === 'null') {
	            value = ' ';
	        }
	        var text = "In [" + (value || ' ') + "]:";
	        prompt.node.textContent = text;
	    };
	    return InputAreaWidget;
	}(phosphor_widget_1.Widget));
	exports.InputAreaWidget = InputAreaWidget;


/***/ },
/* 129 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var CodeMirror = __webpack_require__(130);
	__webpack_require__(131);
	__webpack_require__(134);
	// Bundle other common modes
	__webpack_require__(141);
	__webpack_require__(142);
	__webpack_require__(143);
	__webpack_require__(144);
	__webpack_require__(137);
	/**
	 * 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;
	/**
	 * Load a CodeMirror mode based on a mode spec.
	 */
	function loadInfo(editor, info) {
	    if (!info) {
	        editor.setOption('mode', 'null');
	        return;
	    }
	    if (CodeMirror.modes.hasOwnProperty(info.mode)) {
	        editor.setOption('mode', info.mime);
	    }
	    else {
	        __webpack_require__.e/* require */(1, function(__webpack_require__) { var __WEBPACK_AMD_REQUIRE_ARRAY__ = [(__webpack_require__(145)("./" + info.mode + "/" + info.mode))]; (function () {
	            editor.setOption('mode', info.mime);
	        }.apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__));});
	    }
	}


/***/ },
/* 130 */
/***/ function(module, exports, __webpack_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(mod) {
	  if (true) // CommonJS
	    module.exports = mod();
	  else if (typeof define == "function" && define.amd) // AMD
	    return define([], mod);
	  else // Plain browser env
	    (this || window).CodeMirror = mod();
	})(function() {
	  "use strict";
	
	  // BROWSER SNIFFING
	
	  // 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 ie = ie_upto10 || ie_11up;
	  var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);
	  var webkit = /WebKit\//.test(userAgent);
	  var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent);
	  var chrome = /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 = /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.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);
	
	  // Optimize some code when these features are not used.
	  var sawReadOnlySpans = false, sawCollapsedSpans = false;
	
	  // EDITOR CONSTRUCTOR
	
	  // A CodeMirror instance represents an editor. This is the object
	  // that user code is usually dealing with.
	
	  function CodeMirror(place, options) {
	    if (!(this instanceof CodeMirror)) return new CodeMirror(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);
	    this.doc = doc;
	
	    var input = new CodeMirror.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";
	    if (options.autofocus && !mobile) display.input.focus();
	    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
	    };
	
	    var cm = this;
	
	    // Override magic textarea content restore that IE sometimes does
	    // on our hidden textarea on reload
	    if (ie && ie_version < 11) setTimeout(function() { cm.display.input.reset(true); }, 20);
	
	    registerEventHandlers(this);
	    ensureGlobalHandlers();
	
	    startOperation(this);
	    this.curOp.forceUpdate = true;
	    attachDoc(this, doc);
	
	    if ((options.autofocus && !mobile) || cm.hasFocus())
	      setTimeout(bind(onFocus, this), 20);
	    else
	      onBlur(this);
	
	    for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
	      optionHandlers[opt](this, options[opt], Init);
	    maybeUpdateLineNumberWidth(this);
	    if (options.finishInit) options.finishInit(this);
	    for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
	    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";
	  }
	
	  // DISPLAY CONSTRUCTOR
	
	  // 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 = elt("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 = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
	                      null, "position: relative; outline: none");
	    // Moved around its parent to cover visible view.
	    d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-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);
	  }
	
	  // STATE UPDATES
	
	  // Used to get the editor into a consistent state again when options change.
	
	  function loadMode(cm) {
	    cm.doc.mode = CodeMirror.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.frontier = cm.doc.first;
	    startWorker(cm, 100);
	    cm.state.modeGen++;
	    if (cm.curOp) regChange(cm);
	  }
	
	  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(){updateScrollbars(cm);}, 100);
	  }
	
	  // 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);
	    });
	  }
	
	  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);
	  }
	
	  function guttersChanged(cm) {
	    updateGutters(cm);
	    regChange(cm);
	    setTimeout(function(){alignHorizontally(cm);}, 20);
	  }
	
	  // 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);
	    for (var i = 0; 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);
	  }
	
	  function updateGutterSpace(cm) {
	    var width = cm.display.gutters.offsetWidth;
	    cm.display.sizer.style.marginLeft = width + "px";
	  }
	
	  // 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 = merged.find(0, true);
	      len -= cur.text.length - found.from.ch;
	      cur = found.to.line;
	      len += cur.text.length - found.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;
	      }
	    });
	  }
	
	  // 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);
	    }
	  }
	
	  // 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
	    };
	  }
	
	  function NativeScrollbars(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 = copyObj({
	    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 =
	          (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};
	    },
	    setScrollLeft: function(pos) {
	      if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos;
	      if (this.disableHoriz) this.enableZeroWidthBar(this.horiz, this.disableHoriz);
	    },
	    setScrollTop: function(pos) {
	      if (this.vert.scrollTop != pos) this.vert.scrollTop = pos;
	      if (this.disableVert) this.enableZeroWidthBar(this.vert, this.disableVert);
	    },
	    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;
	    },
	    enableZeroWidthBar: function(bar, delay) {
	      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
	        // left 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 = document.elementFromPoint(box.left + 1, box.bottom - 1);
	        if (elt != bar) bar.style.pointerEvents = "none";
	        else delay.set(1000, maybeDisable);
	      }
	      delay.set(1000, maybeDisable);
	    },
	    clear: function() {
	      var parent = this.horiz.parentNode;
	      parent.removeChild(this.horiz);
	      parent.removeChild(this.vert);
	    }
	  }, NativeScrollbars.prototype);
	
	  function NullScrollbars() {}
	
	  NullScrollbars.prototype = copyObj({
	    update: function() { return {bottom: 0, right: 0}; },
	    setScrollLeft: function() {},
	    setScrollTop: function() {},
	    clear: function() {}
	  }, NullScrollbars.prototype);
	
	  CodeMirror.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 CodeMirror.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() { cm.display.input.focus(); }, 0);
	      });
	      node.setAttribute("cm-not-content", "true");
	    }, function(pos, axis) {
	      if (axis == "horizontal") setScrollLeft(cm, pos);
	      else setScrollTop(cm, pos);
	    }, cm);
	    if (cm.display.scrollbars.addClass)
	      addClass(cm.display.wrapper, cm.display.scrollbars.addClass);
	  }
	
	  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 = "";
	  }
	
	  // 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)};
	  }
	
	  // LINE NUMBERS
	
	  // 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 && view[i].gutter)
	        view[i].gutter.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;
	  }
	
	  function lineNumberFor(options, i) {
	    return String(options.lineNumberFormatter(i + options.firstLineNumber));
	  }
	
	  // 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;
	  }
	
	  // DISPLAY DRAWING
	
	  function DisplayUpdate(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() {
	    for (var i = 0; i < this.events.length; i++)
	      signal.apply(null, this.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;
	    }
	  }
	
	  // 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 focused = activeElt();
	    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.
	    if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();
	
	    // 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.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();
	    }
	  }
	
	  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";
	  }
	
	  // 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;
	      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;
	  }
	
	  // 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};
	  }
	
	  // 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);
	  }
	
	  // 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(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(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);
	    }
	  }
	
	  // 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(lineView);
	    } else if (cls) {
	      lineView.text.className = cls;
	    }
	  }
	
	  function updateLineClasses(lineView) {
	    updateLineBackground(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");
	      wrap.insertBefore(lineView.gutterBackground, lineView.text);
	    }
	    var markers = lineView.line.gutterMarkers;
	    if (cm.options.lineNumbers || markers) {
	      var wrap = 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.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; node; node = next) {
	      var 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(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";
	    }
	  }
	
	  // POSITION OBJECT
	
	  // A Pos instance represents a position within the text.
	  var Pos = CodeMirror.Pos = function(line, ch) {
	    if (!(this instanceof Pos)) return new Pos(line, ch);
	    this.line = line; this.ch = ch;
	  };
	
	  // Compare two positions, return 0 if they are the same, a negative
	  // number when a is less, and a positive number otherwise.
	  var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; };
	
	  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; }
	
	  // INPUT HANDLING
	
	  function ensureFocus(cm) {
	    if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
	  }
	
	  // 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 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 = doc.splitLines(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) {
	        multiPaste = map(textLines, function(l) { return [l]; });
	      }
	    }
	
	    // Normal behavior is to insert the new text into every selection
	    for (var i = sel.ranges.length - 1; i >= 0; i--) {
	      var range = sel.ranges[i];
	      var from = range.from(), to = range.to();
	      if (range.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)
	      }
	      var updateInput = cm.curOp.updateInput;
	      var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % 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/plain");
	    if (pasted) {
	      e.preventDefault();
	      if (!cm.isReadOnly() && !cm.options.disableInput)
	        runInOp(cm, function() { 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 = sel.ranges[i];
	      if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue;
	      var mode = cm.getModeAt(range.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.head.line, "smart");
	            break;
	          }
	      } else if (mode.electricInput) {
	        if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch)))
	          indented = indentLine(cm, range.head.line, "smart");
	      }
	      if (indented) signalLater(cm, "electricInput", cm, range.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) {
	    field.setAttribute("autocorrect", "off");
	    field.setAttribute("autocapitalize", "off");
	    field.setAttribute("spellcheck", "false");
	  }
	
	  // TEXTAREA INPUT STYLE
	
	  function TextareaInput(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;
	  };
	
	  function hiddenTextarea() {
	    var te = elt("textarea", null, null, "position: absolute; 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;
	  }
	
	  TextareaInput.prototype = copyObj({
	    init: function(display) {
	      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 && input.hasSelection) input.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()) {
	          lastCopied = {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);
	          lastCopied = {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;
	        }
	      });
	    },
	
	    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;
	    },
	
	    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)
	    reset: function(typing) {
	      if (this.contextMenuPending) return;
	      var minimal, selected, cm = this.cm, doc = cm.doc;
	      if (cm.somethingSelected()) {
	        this.prevInput = "";
	        var range = doc.sel.primary();
	        minimal = hasCopyEvent &&
	          (range.to().line - range.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;
	    },
	
	    getField: function() { return this.textarea; },
	
	    supportsTouch: function() { return false; },
	
	    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
	      }
	    },
	
	    blur: function() { this.textarea.blur(); },
	
	    resetPosition: function() {
	      this.wrapper.style.top = this.wrapper.style.left = 0;
	    },
	
	    receivedFocus: function() { this.slowPoll(); },
	
	    // Poll for input changes, using the normal rate of polling. This
	    // runs as long as the editor is focused.
	    slowPoll: function() {
	      var input = this;
	      if (input.pollingFast) return;
	      input.polling.set(this.cm.options.pollInterval, function() {
	        input.poll();
	        if (input.cm.state.focused) input.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.
	    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).
	    poll: function() {
	      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;
	
	      var self = this;
	      runInOp(cm, function() {
	        applyTextInput(cm, text.slice(same), prevInput.length - same,
	                       null, self.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 = self.prevInput = "";
	        else self.prevInput = text;
	
	        if (self.composing) {
	          self.composing.range.clear();
	          self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"),
	                                             {className: "CodeMirror-composing"});
	        }
	      });
	      return true;
	    },
	
	    ensurePolled: function() {
	      if (this.pollingFast && this.poll()) this.pollingFast = false;
	    },
	
	    onKeyPress: function() {
	      if (ie && ie_version >= 9) this.hasSelection = null;
	      this.fastPoll();
	    },
	
	    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; top: " + (e.clientY - wrapperBox.top - 5) +
	        "px; left: " + (e.clientX - wrapperBox.left - 5) + "px; z-index: 1000; background: " +
	        (ie ? "rgba(255, 255, 255, .05)" : "transparent") +
	        "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
	      if (webkit) var 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, commands.selectAll)(cm);
	            else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);
	            else 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);
	      }
	    },
	
	    readOnlyChanged: function(val) {
	      if (!val) this.reset();
	    },
	
	    setUneditable: nothing,
	
	    needsContentAttribute: false
	  }, TextareaInput.prototype);
	
	  // CONTENTEDITABLE INPUT STYLE
	
	  function ContentEditableInput(cm) {
	    this.cm = cm;
	    this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null;
	    this.polling = new Delayed();
	    this.gracePeriod = false;
	  }
	
	  ContentEditableInput.prototype = copyObj({
	    init: function(display) {
	      var input = this, cm = input.cm;
	      var div = input.div = display.lineDiv;
	      disableBrowserMagic(div);
	
	      on(div, "paste", function(e) {
	        if (!signalDOMEvent(cm, e)) handlePaste(e, cm);
	      })
	
	      on(div, "compositionstart", function(e) {
	        var data = e.data;
	        input.composing = {sel: cm.doc.sel, data: data, startData: data};
	        if (!data) return;
	        var prim = cm.doc.sel.primary();
	        var line = cm.getLine(prim.head.line);
	        var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length));
	        if (found > -1 && found <= prim.head.ch)
	          input.composing.sel = simpleSelection(Pos(prim.head.line, found),
	                                                Pos(prim.head.line, found + data.length));
	      });
	      on(div, "compositionupdate", function(e) {
	        input.composing.data = e.data;
	      });
	      on(div, "compositionend", function(e) {
	        var ours = input.composing;
	        if (!ours) return;
	        if (e.data != ours.startData && !/\u200b/.test(e.data))
	          ours.data = e.data;
	        // Need a small delay to prevent other code (input event,
	        // selection polling) from doing damage when fired right after
	        // compositionend.
	        setTimeout(function() {
	          if (!ours.handled)
	            input.applyComposition(ours);
	          if (input.composing == ours)
	            input.composing = null;
	        }, 50);
	      });
	
	      on(div, "touchstart", function() {
	        input.forceCompositionEnd();
	      });
	
	      on(div, "input", function() {
	        if (input.composing) return;
	        if (cm.isReadOnly() || !input.pollContent())
	          runInOp(input.cm, function() {regChange(cm);});
	      });
	
	      function onCopyCut(e) {
	        if (signalDOMEvent(cm, e)) return
	        if (cm.somethingSelected()) {
	          lastCopied = {lineWise: false, text: cm.getSelections()};
	          if (e.type == "cut") cm.replaceSelection("", null, "cut");
	        } else if (!cm.options.lineWiseCopyCut) {
	          return;
	        } else {
	          var ranges = copyableRanges(cm);
	          lastCopied = {lineWise: true, text: ranges.text};
	          if (e.type == "cut") {
	            cm.operation(function() {
	              cm.setSelections(ranges.ranges, 0, sel_dontScroll);
	              cm.replaceSelection("", null, "cut");
	            });
	          }
	        }
	        // iOS exposes the clipboard API, but seems to discard content inserted into it
	        if (e.clipboardData && !ios) {
	          e.preventDefault();
	          e.clipboardData.clearData();
	          e.clipboardData.setData("text/plain", lastCopied.text.join("\n"));
	        } else {
	          // 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();
	          }, 50);
	        }
	      }
	      on(div, "copy", onCopyCut);
	      on(div, "cut", onCopyCut);
	    },
	
	    prepareSelection: function() {
	      var result = prepareSelection(this.cm, false);
	      result.focus = this.cm.state.focused;
	      return result;
	    },
	
	    showSelection: function(info, takeFocus) {
	      if (!info || !this.cm.display.view.length) return;
	      if (info.focus || takeFocus) this.showPrimarySelection();
	      this.showMultipleSelections(info);
	    },
	
	    showPrimarySelection: function() {
	      var sel = window.getSelection(), prim = this.cm.doc.sel.primary();
	      var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset);
	      var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset);
	      if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&
	          cmp(minPos(curAnchor, curFocus), prim.from()) == 0 &&
	          cmp(maxPos(curAnchor, curFocus), prim.to()) == 0)
	        return;
	
	      var start = posToDOM(this.cm, prim.from());
	      var end = posToDOM(this.cm, prim.to());
	      if (!start && !end) return;
	
	      var view = this.cm.display.view;
	      var old = sel.rangeCount && sel.getRangeAt(0);
	      if (!start) {
	        start = {node: view[0].measure.map[2], offset: 0};
	      } else if (!end) { // FIXME dangerously hacky
	        var measure = view[view.length - 1].measure;
	        var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map;
	        end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]};
	      }
	
	      try { var 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 && this.cm.state.focused) {
	          sel.collapse(start.node, start.offset);
	          if (!rng.collapsed) sel.addRange(rng);
	        } else {
	          sel.removeAllRanges();
	          sel.addRange(rng);
	        }
	        if (old && sel.anchorNode == null) sel.addRange(old);
	        else if (gecko) this.startGracePeriod();
	      }
	      this.rememberSelection();
	    },
	
	    startGracePeriod: function() {
	      var input = this;
	      clearTimeout(this.gracePeriod);
	      this.gracePeriod = setTimeout(function() {
	        input.gracePeriod = false;
	        if (input.selectionChanged())
	          input.cm.operation(function() { input.cm.curOp.selectionChanged = true; });
	      }, 20);
	    },
	
	    showMultipleSelections: function(info) {
	      removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors);
	      removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection);
	    },
	
	    rememberSelection: function() {
	      var sel = window.getSelection();
	      this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset;
	      this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset;
	    },
	
	    selectionInEditor: function() {
	      var sel = window.getSelection();
	      if (!sel.rangeCount) return false;
	      var node = sel.getRangeAt(0).commonAncestorContainer;
	      return contains(this.div, node);
	    },
	
	    focus: function() {
	      if (this.cm.options.readOnly != "nocursor") this.div.focus();
	    },
	    blur: function() { this.div.blur(); },
	    getField: function() { return this.div; },
	
	    supportsTouch: function() { return true; },
	
	    receivedFocus: function() {
	      var input = this;
	      if (this.selectionInEditor())
	        this.pollSelection();
	      else
	        runInOp(this.cm, function() { 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);
	    },
	
	    selectionChanged: function() {
	      var sel = window.getSelection();
	      return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||
	        sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset;
	    },
	
	    pollSelection: function() {
	      if (!this.composing && !this.gracePeriod && this.selectionChanged()) {
	        var sel = window.getSelection(), cm = this.cm;
	        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;
	        });
	      }
	    },
	
	    pollContent: function() {
	      var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary();
	      var from = sel.from(), to = sel.to();
	      if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false;
	
	      var fromIndex;
	      if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) {
	        var fromLine = lineNo(display.view[0].line);
	        var fromNode = display.view[0].node;
	      } else {
	        var fromLine = lineNo(display.view[fromIndex].line);
	        var fromNode = display.view[fromIndex - 1].node.nextSibling;
	      }
	      var toIndex = findViewIndex(cm, to.line);
	      if (toIndex == display.view.length - 1) {
	        var toLine = display.viewTo - 1;
	        var toNode = display.lineDiv.lastChild;
	      } else {
	        var toLine = lineNo(display.view[toIndex + 1].line) - 1;
	        var toNode = display.view[toIndex + 1].node.previousSibling;
	      }
	
	      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;
	
	      newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd);
	      newText[0] = newText[0].slice(cutFront);
	
	      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;
	      }
	    },
	
	    ensurePolled: function() {
	      this.forceCompositionEnd();
	    },
	    reset: function() {
	      this.forceCompositionEnd();
	    },
	    forceCompositionEnd: function() {
	      if (!this.composing || this.composing.handled) return;
	      this.applyComposition(this.composing);
	      this.composing.handled = true;
	      this.div.blur();
	      this.div.focus();
	    },
	    applyComposition: function(composing) {
	      if (this.cm.isReadOnly())
	        operation(this.cm, regChange)(this.cm)
	      else if (composing.data && composing.data != composing.startData)
	        operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel);
	    },
	
	    setUneditable: function(node) {
	      node.contentEditable = "false"
	    },
	
	    onKeyPress: function(e) {
	      e.preventDefault();
	      if (!this.cm.isReadOnly())
	        operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0);
	    },
	
	    readOnlyChanged: function(val) {
	      this.div.contentEditable = String(val != "nocursor")
	    },
	
	    onContextMenu: nothing,
	    resetPosition: nothing,
	
	    needsContentAttribute: true
	  }, ContentEditableInput.prototype);
	
	  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), 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 badPos(pos, bad) { if (bad) pos.bad = true; return pos; }
	
	  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 = i < 0 ? measure.map : maps[i];
	        for (var j = 0; j < map.length; j += 3) {
	          var curNode = map[j + 2];
	          if (curNode == textNode || curNode == topNode) {
	            var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]);
	            var ch = map[j] + offset;
	            if (offset < 0 || curNode != textNode) ch = map[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 = offset; before; before = before.previousSibling) {
	      found = find(before, before.firstChild, -1);
	      if (found)
	        return badPos(Pos(found.line, found.ch + dist), bad);
	      else
	        dist += after.textContent.length;
	    }
	  }
	
	  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 walk(node) {
	      if (node.nodeType == 1) {
	        var cmText = node.getAttribute("cm-text");
	        if (cmText != null) {
	          if (cmText == "") cmText = node.textContent.replace(/\u200b/g, "");
	          text += cmText;
	          return;
	        }
	        var markerID = node.getAttribute("cm-marker"), range;
	        if (markerID) {
	          var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID));
	          if (found.length && (range = found[0].find()))
	            text += getBetween(cm.doc, range.from, range.to).join(lineSep);
	          return;
	        }
	        if (node.getAttribute("contenteditable") == "false") return;
	        for (var i = 0; i < node.childNodes.length; i++)
	          walk(node.childNodes[i]);
	        if (/^(pre|div|p)$/i.test(node.nodeName))
	          closing = true;
	      } else if (node.nodeType == 3) {
	        var val = node.nodeValue;
	        if (!val) return;
	        if (closing) {
	          text += lineSep;
	          closing = false;
	        }
	        text += val;
	      }
	    }
	    for (;;) {
	      walk(from);
	      if (from == to) break;
	      from = from.nextSibling;
	    }
	    return text;
	  }
	
	  CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput};
	
	  // SELECTION / CURSOR
	
	  // 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).
	  function Selection(ranges, primIndex) {
	    this.ranges = ranges;
	    this.primIndex = primIndex;
	  }
	
	  Selection.prototype = {
	    primary: function() { return this.ranges[this.primIndex]; },
	    equals: function(other) {
	      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.ranges[i], there = other.ranges[i];
	        if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false;
	      }
	      return true;
	    },
	    deepCopy: function() {
	      for (var out = [], i = 0; i < this.ranges.length; i++)
	        out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head));
	      return new Selection(out, this.primIndex);
	    },
	    somethingSelected: function() {
	      for (var i = 0; i < this.ranges.length; i++)
	        if (!this.ranges[i].empty()) return true;
	      return false;
	    },
	    contains: function(pos, end) {
	      if (!end) end = pos;
	      for (var i = 0; i < this.ranges.length; i++) {
	        var range = this.ranges[i];
	        if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
	          return i;
	      }
	      return -1;
	    }
	  };
	
	  function Range(anchor, head) {
	    this.anchor = anchor; this.head = head;
	  }
	
	  Range.prototype = {
	    from: function() { return minPos(this.anchor, this.head); },
	    to: function() { return maxPos(this.anchor, this.head); },
	    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);
	  }
	
	  // 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 isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
	  function clipPosArray(doc, array) {
	    for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]);
	    return out;
	  }
	
	  // SELECTION UPDATES
	
	  // 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(doc, range, head, other) {
	    if (doc.cm && doc.cm.display.shift || doc.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) {
	    setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options);
	  }
	
	  // Extend all selections (pos is an array of selections with length
	  // equal the number of selections)
	  function extendSelections(doc, heads, options) {
	    for (var out = [], i = 0; i < doc.sel.ranges.length; i++)
	      out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null);
	    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) {
	        this.ranges = [];
	        for (var i = 0; i < ranges.length; i++)
	          this.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), sel_dontScroll);
	  }
	
	  // 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;
	          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);
	    }
	  }
	
	  // SELECTION DRAWING
	
	  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 = doc.sel.ranges[i];
	      if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) continue;
	      var collapsed = range.empty();
	      if (collapsed || cm.options.showCursorWhenSelecting)
	        drawSelectionCursor(cm, range.head, curFragment);
	      if (!collapsed)
	        drawSelectionRange(cm, range, 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, 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; top: " + top + "px; width: " + (width == null ? rightSide - left : width) +
	                               "px; 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), 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.from(), sTo = range.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() {
	        display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden";
	      }, cm.options.cursorBlinkRate);
	    else if (cm.options.cursorBlinkRate < 0)
	      display.cursorDiv.style.visibility = "hidden";
	  }
	
	  // HIGHLIGHT WORKER
	
	  function startWorker(cm, time) {
	    if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo)
	      cm.state.highlight.set(time, bind(highlightWorker, cm));
	  }
	
	  function highlightWorker(cm) {
	    var doc = cm.doc;
	    if (doc.frontier < doc.first) doc.frontier = doc.first;
	    if (doc.frontier >= cm.display.viewTo) return;
	    var end = +new Date + cm.options.workTime;
	    var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
	    var changedLines = [];
	
	    doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {
	      if (doc.frontier >= cm.display.viewFrom) { // Visible
	        var oldStyles = line.styles, tooLong = line.text.length > cm.options.maxHighlightLength;
	        var highlighted = highlightLine(cm, line, tooLong ? copyState(doc.mode, state) : state, true);
	        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(doc.frontier);
	        line.stateAfter = tooLong ? state : copyState(doc.mode, state);
	      } else {
	        if (line.text.length <= cm.options.maxHighlightLength)
	          processLine(cm, line.text, state);
	        line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
	      }
	      ++doc.frontier;
	      if (+new Date > end) {
	        startWorker(cm, cm.options.workDelay);
	        return true;
	      }
	    });
	    if (changedLines.length) runInOp(cm, function() {
	      for (var i = 0; i < changedLines.length; i++)
	        regLineChange(cm, changedLines[i], "text");
	    });
	  }
	
	  // 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);
	      if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
	      var indented = countColumn(line.text, null, cm.options.tabSize);
	      if (minline == null || minindent > indented) {
	        minline = search - 1;
	        minindent = indented;
	      }
	    }
	    return minline;
	  }
	
	  function getStateBefore(cm, n, precise) {
	    var doc = cm.doc, display = cm.display;
	    if (!doc.mode.startState) return true;
	    var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
	    if (!state) state = startState(doc.mode);
	    else state = copyState(doc.mode, state);
	    doc.iter(pos, n, function(line) {
	      processLine(cm, line.text, state);
	      var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo;
	      line.stateAfter = save ? copyState(doc.mode, state) : null;
	      ++pos;
	    });
	    if (precise) doc.frontier = pos;
	    return state;
	  }
	
	  // 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 = 0; i < lineView.rest.length; i++)
	      if (lineNo(lineView.rest[i]) > lineN)
	        return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], 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, ch, bias) {
	    var node, start, end, collapse;
	    // First, search the line map for the text node corresponding to,
	    // or closest to, the target character.
	    for (var i = 0; i < map.length; i += 3) {
	      var mStart = map[i], mEnd = map[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.length - 3 || ch == mEnd && map[i + 3] > ch) {
	        end = mEnd - mStart;
	        start = end - 1;
	        if (ch >= mEnd) collapse = "right";
	      }
	      if (start != null) {
	        node = map[i + 2];
	        if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
	          collapse = bias;
	        if (bias == "left" && start == 0)
	          while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {
	            node = map[(i -= 3) + 2];
	            collapse = "left";
	          }
	        if (bias == "right" && start == mEnd - mStart)
	          while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {
	            node = map[(i += 3) + 2];
	            collapse = "right";
	          }
	        break;
	      }
	    }
	    return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd};
	  }
	
	  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 = 0; i < 4; i++) { // 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 if (ie && cm.options.lineWrapping) {
	          var rects = range(node, start, end).getClientRects();
	          if (rects.length)
	            rect = rects[bias == "right" ? rects.length - 1 : 0];
	          else
	            rect = nullRect;
	        } else {
	          rect = range(node, start, end).getBoundingClientRect() || nullRect;
	        }
	        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;
	    for (var i = 0; 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() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
	  function pageScrollY() { 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) {
	    if (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.
	  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);
	    }
	    function getBidi(ch, partPos) {
	      var part = order[partPos], right = part.level % 2;
	      if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
	        part = order[--partPos];
	        ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
	        right = true;
	      } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
	        part = order[++partPos];
	        ch = bidiLeft(part) - part.level % 2;
	        right = false;
	      }
	      if (right && ch == part.to && ch > part.from) return get(ch - 1);
	      return get(ch, right);
	    }
	    var order = getOrder(lineObj), ch = pos.ch;
	    if (!order) return get(ch);
	    var partPos = getBidiPartAt(order, ch);
	    var val = getBidi(ch, partPos);
	    if (bidiOther != null) val.other = getBidi(ch, bidiOther);
	    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, outside, xRel) {
	    var pos = Pos(line, ch);
	    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, 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, 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 coordsCharInner(cm, lineObj, lineNo, x, y) {
	    var innerOff = y - heightAtLine(lineObj);
	    var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
	    var preparedMeasure = prepareMeasureForLine(cm, lineObj);
	
	    function getX(ch) {
	      var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure);
	      wrongLine = true;
	      if (innerOff > sp.bottom) return sp.left - adjust;
	      else if (innerOff < sp.top) return sp.left + adjust;
	      else wrongLine = false;
	      return sp.left;
	    }
	
	    var bidi = getOrder(lineObj), dist = lineObj.text.length;
	    var from = lineLeft(lineObj), to = lineRight(lineObj);
	    var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
	
	    if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
	    // Do a binary search between these bounds.
	    for (;;) {
	      if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
	        var ch = x < fromX || x - fromX <= toX - x ? from : to;
	        var xDiff = x - (ch == from ? fromX : toX);
	        while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;
	        var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
	                              xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0);
	        return pos;
	      }
	      var step = Math.ceil(dist / 2), middle = from + step;
	      if (bidi) {
	        middle = from;
	        for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
	      }
	      var middleX = getX(middle);
	      if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
	      else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
	    }
	  }
	
	  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;
	  }
	
	  // OPERATIONS
	
	  // 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 operationGroup = null;
	
	  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
	    };
	    if (operationGroup) {
	      operationGroup.ops.push(cm.curOp);
	    } else {
	      cm.curOp.ownsGroup = operationGroup = {
	        ops: [cm.curOp],
	        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);
	  }
	
	  // Finish an operation, updating the display and signalling delayed events
	  function endOperation(cm) {
	    var op = cm.curOp, group = op.ownsGroup;
	    if (!group) return;
	
	    try { fireCallbacksForOps(group); }
	    finally {
	      operationGroup = null;
	      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 = 0; i < ops.length; i++) // Write DOM (maybe)
	      endOperation_W1(ops[i]);
	    for (var i = 0; i < ops.length; i++) // Read DOM
	      endOperation_R2(ops[i]);
	    for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
	      endOperation_W2(ops[i]);
	    for (var i = 0; i < ops.length; i++) // Read DOM
	      endOperation_finish(ops[i]);
	  }
	
	  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 && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) {
	      doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
	      display.scrollbars.setScrollTop(doc.scrollTop);
	      display.scroller.scrollTop = doc.scrollTop;
	    }
	    if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) {
	      doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft));
	      display.scrollbars.setScrollLeft(doc.scrollLeft);
	      display.scroller.scrollLeft = doc.scrollLeft;
	      alignHorizontally(cm);
	    }
	    // If we need to scroll a specific position into view, do so.
	    if (op.scrollToPos) {
	      var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
	                                     clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);
	      if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords);
	    }
	
	    // 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 = 0; i < unhidden.length; ++i)
	      if (unhidden[i].lines.length) signal(unhidden[i], "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); }
	    };
	  }
	
	  // VIEW TRACKING
	
	  // 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;
	  }
	
	  // 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 = viewCuttingPoint(cm, from, from, -1);
	      if (cut) {
	        display.view = display.view.slice(0, cut.index);
	        display.viewTo = cut.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;
	  }
	
	  // 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 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};
	    for (var i = 0, n = cm.display.viewFrom; 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;
	  }
	
	  // EVENT HANDLERS
	
	  // 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) { 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) {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() {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)) {
	        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) {
	        setScrollTop(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){onScrollWheel(cm, e);});
	    on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
	
	    // Prevent wrapper from ever scrolling
	    on(d.wrapper, "scroll", function() { 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){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) { onKeyUp.call(cm, e); });
	    on(inp, "keydown", operation(cm, onKeyDown));
	    on(inp, "keypress", operation(cm, onKeyPress));
	    on(inp, "focus", bind(onFocus, cm));
	    on(inp, "blur", bind(onBlur, cm));
	  }
	
	  function dragDropChanged(cm, value, old) {
	    var wasOn = old && old != CodeMirror.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);
	    }
	  }
	
	  // 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();
	  }
	
	  // MOUSE EVENTS
	
	  // 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;
	    }
	  }
	
	  // 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;
	  }
	
	  // 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.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(){display.scroller.draggable = true;}, 100);
	      }
	      return;
	    }
	    if (clickInGutter(cm, e)) return;
	    var start = posFromMouse(cm, e);
	    window.focus();
	
	    switch (e_button(e)) {
	    case 1:
	      // #3261: make sure, that we're not starting a second selection
	      if (cm.state.selectingText)
	        cm.state.selectingText(e);
	      else if (start)
	        leftButtonDown(cm, e, start);
	      else if (e_target(e) == display.scroller)
	        e_preventDefault(e);
	      break;
	    case 2:
	      if (webkit) cm.state.lastMiddleDown = +new Date;
	      if (start) extendSelection(cm.doc, start);
	      setTimeout(function() {display.input.focus();}, 20);
	      e_preventDefault(e);
	      break;
	    case 3:
	      if (captureRightClick) onContextMenu(cm, e);
	      else delayBlurEvent(cm);
	      break;
	    }
	  }
	
	  var lastClick, lastDoubleClick;
	  function leftButtonDown(cm, e, start) {
	    if (ie) setTimeout(bind(ensureFocus, cm), 0);
	    else cm.curOp.focus = activeElt();
	
	    var now = +new Date, type;
	    if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {
	      type = "triple";
	    } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) {
	      type = "double";
	      lastDoubleClick = {time: now, pos: start};
	    } else {
	      type = "single";
	      lastClick = {time: now, pos: start};
	    }
	
	    var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained;
	    if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() &&
	        type == "single" && (contained = sel.contains(start)) > -1 &&
	        (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) &&
	        (cmp(contained.to(), start) > 0 || start.xRel < 0))
	      leftButtonStartDrag(cm, e, start, modifier);
	    else
	      leftButtonSelect(cm, e, start, type, modifier);
	  }
	
	  // 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, e, start, modifier) {
	    var display = cm.display, startTime = +new Date;
	    var dragEnd = operation(cm, function(e2) {
	      if (webkit) display.scroller.draggable = false;
	      cm.state.draggingText = false;
	      off(document, "mouseup", dragEnd);
	      off(display.scroller, "drop", dragEnd);
	      if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
	        e_preventDefault(e2);
	        if (!modifier && +new Date - 200 < startTime)
	          extendSelection(cm.doc, start);
	        // 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();
	      }
	    });
	    // Let the drag handler handle this.
	    if (webkit) display.scroller.draggable = true;
	    cm.state.draggingText = dragEnd;
	    // IE's approach to draggable
	    if (display.scroller.dragDrop) display.scroller.dragDrop();
	    on(document, "mouseup", dragEnd);
	    on(display.scroller, "drop", dragEnd);
	  }
	
	  // Normal selection, as opposed to text dragging.
	  function leftButtonSelect(cm, e, start, type, addNew) {
	    var display = cm.display, doc = cm.doc;
	    e_preventDefault(e);
	
	    var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges;
	    if (addNew && !e.shiftKey) {
	      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 (chromeOS ? e.shiftKey && e.metaKey : e.altKey) {
	      type = "rect";
	      if (!addNew) ourRange = new Range(start, start);
	      start = posFromMouse(cm, e, true, true);
	      ourIndex = -1;
	    } else if (type == "double") {
	      var word = cm.findWordAt(start);
	      if (cm.display.shift || doc.extend)
	        ourRange = extendRange(doc, ourRange, word.anchor, word.head);
	      else
	        ourRange = word;
	    } else if (type == "triple") {
	      var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0)));
	      if (cm.display.shift || doc.extend)
	        ourRange = extendRange(doc, ourRange, line.anchor, line.head);
	      else
	        ourRange = line;
	    } else {
	      ourRange = extendRange(doc, ourRange, start);
	    }
	
	    if (!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() && type == "single" && !e.shiftKey) {
	      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 (type == "rect") {
	        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 anchor = oldRange.anchor, head = pos;
	        if (type != "single") {
	          if (type == "double")
	            var range = cm.findWordAt(pos);
	          else
	            var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));
	          if (cmp(range.anchor, anchor) > 0) {
	            head = range.head;
	            anchor = minPos(oldRange.from(), range.anchor);
	          } else {
	            head = range.anchor;
	            anchor = maxPos(oldRange.to(), range.head);
	          }
	        }
	        var ranges = startSel.ranges.slice(0);
	        ranges[ourIndex] = new Range(clipPos(doc, anchor), head);
	        setSelection(doc, normalizeSelection(ranges, 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, type == "rect");
	      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) {
	    try { var 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);
	  }
	
	  // 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() {cm.display.input.focus();}, 20);
	        return;
	      }
	      try {
	        var text = e.dataTransfer.getData("Text");
	        if (text) {
	          if (cm.state.draggingText && !(mac ? e.altKey : e.ctrlKey))
	            var selected = cm.listSelections();
	          setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
	          if (selected) for (var i = 0; i < selected.length; ++i)
	            replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag");
	          cm.replaceSelection(text, "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;
	    }
	  }
	
	  // SCROLL EVENTS
	
	  // Sync the scrollable area and scrollbars, ensure the viewport
	  // covers the visible area.
	  function setScrollTop(cm, val) {
	    if (Math.abs(cm.doc.scrollTop - val) < 2) return;
	    cm.doc.scrollTop = val;
	    if (!gecko) updateDisplaySimple(cm, {top: val});
	    if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
	    cm.display.scrollbars.setScrollTop(val);
	    if (gecko) updateDisplaySimple(cm);
	    startWorker(cm, 100);
	  }
	  // Sync scroller and scrollbar, ensure the gutter elements are
	  // aligned.
	  function setScrollLeft(cm, val, isScroller) {
	    if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
	    val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
	    cm.doc.scrollLeft = val;
	    alignHorizontally(cm);
	    if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
	    cm.display.scrollbars.setScrollLeft(val);
	  }
	
	  // 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, 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;
	
	  var wheelEventDelta = function(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};
	  };
	  CodeMirror.wheelEventPixels = function(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)
	        setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
	      setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
	      // 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;
	      }
	    }
	  }
	
	  // KEY EVENTS
	
	  // 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);
	  }
	
	  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);
	    if (handleCharBinding(cm, e, ch)) return;
	    cm.display.input.onKeyPress(e);
	  }
	
	  // FOCUS/BLUR EVENTS
	
	  function delayBlurEvent(cm) {
	    cm.state.delayingBlurEvent = true;
	    setTimeout(function() {
	      if (cm.state.delayingBlurEvent) {
	        cm.state.delayingBlurEvent = false;
	        onBlur(cm);
	      }
	    }, 100);
	  }
	
	  function onFocus(cm) {
	    if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false;
	
	    if (cm.options.readOnly == "nocursor") return;
	    if (!cm.state.focused) {
	      signal(cm, "focus", cm);
	      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() { cm.display.input.reset(true); }, 20); // Issue #1730
	      }
	      cm.display.input.receivedFocus();
	    }
	    restartBlink(cm);
	  }
	  function onBlur(cm) {
	    if (cm.state.delayingBlurEvent) return;
	
	    if (cm.state.focused) {
	      signal(cm, "blur", cm);
	      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);
	  }
	
	  // 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);
	  }
	
	  // UPDATING
	
	  // Compute the position of the end of a change (its 'to' property
	  // refers to the pre-change end).
	  var changeEnd = CodeMirror.changeEnd = function(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);
	  }
	
	  // 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() { this.canceled = true; }
	    };
	    if (update) obj.update = function(from, to, text, origin) {
	      if (from) this.from = clipPos(doc, from);
	      if (to) this.to = clipPos(doc, to);
	      if (text) this.text = text;
	      if (origin !== undefined) this.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) 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)
	    for (var i = 0; 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");
	
	    for (var i = event.changes.length - 1; i >= 0; --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));
	      });
	    }
	  }
	
	  // 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;
	    }
	
	    // Adjust frontier, schedule worker
	    doc.frontier = Math.min(doc.frontier, 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});
	  }
	
	  // 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, coords) {
	    if (signalDOMEvent(cm, "scrollCursorIntoView")) return;
	
	    var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
	    if (coords.top + box.top < 0) doScroll = true;
	    else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
	    if (doScroll != null && !phantom) {
	      var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " +
	                           (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " +
	                           (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " +
	                           coords.left + "px; width: 2px;");
	      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;
	    for (var limit = 0; limit < 5; limit++) {
	      var changed = false, coords = cursorCoords(cm, pos);
	      var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
	      var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),
	                                         Math.min(coords.top, endCoords.top) - margin,
	                                         Math.max(coords.left, endCoords.left),
	                                         Math.max(coords.bottom, endCoords.bottom) + margin);
	      var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
	      if (scrollPos.scrollTop != null) {
	        setScrollTop(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 coords;
	  }
	
	  // Scroll a given set of coordinates into view (immediately).
	  function scrollIntoView(cm, x1, y1, x2, y2) {
	    var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
	    if (scrollPos.scrollTop != null) setScrollTop(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, x1, y1, x2, y2) {
	    var display = cm.display, snapMargin = textHeight(cm.display);
	    if (y1 < 0) y1 = 0;
	    var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
	    var screen = displayHeight(cm), result = {};
	    if (y2 - y1 > screen) y2 = y1 + screen;
	    var docBottom = cm.doc.height + paddingVert(display);
	    var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
	    if (y1 < screentop) {
	      result.scrollTop = atTop ? 0 : y1;
	    } else if (y2 > screentop + screen) {
	      var newTop = Math.min(y1, (atBottom ? docBottom : y2) - 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 = x2 - x1 > screenw;
	    if (tooWide) x2 = x1 + screenw;
	    if (x1 < 10)
	      result.scrollLeft = 0;
	    else if (x1 < screenleft)
	      result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10));
	    else if (x2 > screenw + screenleft - 3)
	      result.scrollLeft = x2 + (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 addToScrollPos(cm, left, top) {
	    if (left != null || top != null) resolveScrollToPos(cm);
	    if (left != null)
	      cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left;
	    if (top != null)
	      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, isCursor: true};
	  }
	
	  // 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 = cm.curOp.scrollToPos;
	    if (range) {
	      cm.curOp.scrollToPos = null;
	      var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to);
	      var sPos = calculateScrollPos(cm, Math.min(from.left, to.left),
	                                    Math.min(from.top, to.top) - range.margin,
	                                    Math.max(from.right, to.right),
	                                    Math.max(from.bottom, to.bottom) + range.margin);
	      cm.scrollTo(sPos.scrollLeft, sPos.scrollTop);
	    }
	  }
	
	  // API UTILITIES
	
	  // 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 = getStateBefore(cm, n);
	    }
	
	    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 = 0; i < doc.sel.ranges.length; i++) {
	        var range = doc.sel.ranges[i];
	        if (range.head.line == n && range.head.ch < curSpaceString.length) {
	          var pos = Pos(n, curSpaceString.length);
	          replaceOneSelection(doc, i, new Range(pos, pos));
	          break;
	        }
	      }
	    }
	  }
	
	  // 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;
	  }
	
	  // 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);
	    });
	  }
	
	  // 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 line = pos.line, ch = pos.ch, origDir = dir;
	    var lineObj = getLine(doc, line);
	    function findNextLine() {
	      var l = line + dir;
	      if (l < doc.first || l >= doc.first + doc.size) return false
	      line = l;
	      return lineObj = getLine(doc, l);
	    }
	    function moveOnce(boundToLine) {
	      var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
	      if (next == null) {
	        if (!boundToLine && findNextLine()) {
	          if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
	          else ch = dir < 0 ? lineObj.text.length : 0;
	        } else return false
	      } else ch = 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(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();}
	          break;
	        }
	
	        if (type) sawType = type;
	        if (dir > 0 && !moveOnce(!first)) break;
	      }
	    }
	    var result = skipAtomic(doc, Pos(line, ch), pos, origDir, true);
	    if (!cmp(pos, 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);
	      y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
	    } else if (unit == "line") {
	      y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
	    }
	    for (;;) {
	      var 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;
	  }
	
	  // EDITOR METHODS
	
	  // 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.
	
	  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);
	    },
	
	    getOption: function(option) {return this.options[option];},
	    getDoc: function() {return this.doc;},
	
	    addKeyMap: function(map, bottom) {
	      this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map));
	    },
	    removeKeyMap: function(map) {
	      var maps = this.state.keyMaps;
	      for (var i = 0; i < maps.length; ++i)
	        if (maps[i] == map || maps[i].name == map) {
	          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.");
	      this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
	      this.state.modeGen++;
	      regChange(this);
	    }),
	    removeOverlay: methodOp(function(spec) {
	      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.state.modeGen++;
	          regChange(this);
	          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 ranges = this.doc.sel.ranges, end = -1;
	      for (var i = 0; i < ranges.length; i++) {
	        var range = ranges[i];
	        if (!range.empty()) {
	          var from = range.from(), to = range.to();
	          var start = Math.max(end, from.line);
	          end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
	          for (var j = start; j < end; ++j)
	            indentLine(this, j, how);
	          var newRanges = this.doc.sel.ranges;
	          if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)
	            replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll);
	        } else if (range.head.line > end) {
	          indentLine(this, range.head.line, how, true);
	          end = range.head.line;
	          if (i == this.doc.sel.primIndex) ensureCursorVisible(this);
	        }
	      }
	    }),
	
	    // 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("cm-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 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 = 0; i < help._global.length; i++) {
	        var cur = help._global[i];
	        if (cur.pred(mode, this) && 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 getStateBefore(this, line + 1, precise);
	    },
	
	    cursorCoords: function(start, mode) {
	      var pos, range = this.doc.sel.primary();
	      if (start == null) pos = range.head;
	      else if (typeof start == "object") pos = clipPos(this.doc, start);
	      else pos = start ? range.from() : range.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) {
	      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").top +
	        (end ? this.doc.height - heightAtLine(lineObj) : 0);
	    },
	
	    defaultTextHeight: function() { return textHeight(this.display); },
	    defaultCharWidth: function() { return charWidth(this.display); },
	
	    setGutterMarker: methodOp(function(line, gutterID, value) {
	      return changeLine(this.doc, line, "gutter", function(line) {
	        var markers = line.gutterMarkers || (line.gutterMarkers = {});
	        markers[gutterID] = value;
	        if (!value && isEmpty(markers)) line.gutterMarkers = null;
	        return true;
	      });
	    }),
	
	    clearGutter: methodOp(function(gutterID) {
	      var cm = this, doc = cm.doc, i = doc.first;
	      doc.iter(function(line) {
	        if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
	          line.gutterMarkers[gutterID] = null;
	          regLineChange(cm, i, "gutter");
	          if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
	        }
	        ++i;
	      });
	    }),
	
	    lineInfo: function(line) {
	      if (typeof line == "number") {
	        if (!isLine(this.doc, line)) return null;
	        var n = line;
	        line = getLine(this.doc, line);
	        if (!line) return null;
	      } else {
	        var 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};
	    },
	
	    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, top, left + node.offsetWidth, top + node.offsetHeight);
	    },
	
	    triggerOnKeyDown: methodOp(onKeyDown),
	    triggerOnKeyPress: methodOp(onKeyPress),
	    triggerOnKeyUp: onKeyUp,
	
	    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 dir = 1;
	      if (amount < 0) { dir = -1; amount = -amount; }
	      for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
	        cur = findPosH(this.doc, cur, dir, unit, visually);
	        if (cur.hitSide) break;
	      }
	      return cur;
	    },
	
	    moveH: methodOp(function(dir, unit) {
	      var cm = this;
	      cm.extendSelectionsBy(function(range) {
	        if (cm.display.shift || cm.doc.extend || range.empty())
	          return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually);
	        else
	          return dir < 0 ? range.from() : range.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) {
	          var other = findPosH(doc, range.head, dir, unit, false);
	          return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other};
	        });
	    }),
	
	    findPosV: function(from, amount, unit, goalColumn) {
	      var dir = 1, x = goalColumn;
	      if (amount < 0) { dir = -1; amount = -amount; }
	      for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
	        var coords = cursorCoords(this, cur, "div");
	        if (x == null) x = coords.left;
	        else coords.left = x;
	        cur = findPosV(this, coords, dir, unit);
	        if (cur.hitSide) break;
	      }
	      return cur;
	    },
	
	    moveV: methodOp(function(dir, unit) {
	      var cm = this, doc = this.doc, goals = [];
	      var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected();
	      doc.extendSelectionsBy(function(range) {
	        if (collapse)
	          return dir < 0 ? range.from() : range.to();
	        var headPos = cursorCoords(cm, range.head, "div");
	        if (range.goalColumn != null) headPos.left = range.goalColumn;
	        goals.push(headPos.left);
	        var pos = findPosV(cm, headPos, dir, unit);
	        if (unit == "page" && range == doc.sel.primary())
	          addToScrollPos(cm, null, charCoords(cm, 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.xRel < 0 || 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) {
	      if (x != null || y != null) resolveScrollToPos(this);
	      if (x != null) this.curOp.scrollLeft = x;
	      if (y != null) this.curOp.scrollTop = 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, margin) {
	      if (range == null) {
	        range = {from: this.doc.sel.primary().head, to: null};
	        if (margin == null) margin = this.options.cursorScrollMargin;
	      } else if (typeof range == "number") {
	        range = {from: Pos(range, 0), to: null};
	      } else if (range.from == null) {
	        range = {from: range, to: null};
	      }
	      if (!range.to) range.to = range.from;
	      range.margin = margin || 0;
	
	      if (range.from.line != null) {
	        resolveScrollToPos(this);
	        this.curOp.scrollToPos = range;
	      } else {
	        var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left),
	                                      Math.min(range.from.top, range.to.top) - range.margin,
	                                      Math.max(range.from.right, range.to.right),
	                                      Math.max(range.from.bottom, range.to.bottom) + range.margin);
	        this.scrollTo(sPos.scrollLeft, sPos.scrollTop);
	      }
	    }),
	
	    setSize: methodOp(function(width, height) {
	      var cm = this;
	      function interpret(val) {
	        return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
	      }
	      if (width != null) cm.display.wrapper.style.width = interpret(width);
	      if (height != null) cm.display.wrapper.style.height = interpret(height);
	      if (cm.options.lineWrapping) clearLineMeasurementCache(this);
	      var lineNo = cm.display.viewFrom;
	      cm.doc.iter(lineNo, cm.display.viewTo, function(line) {
	        if (line.widgets) for (var i = 0; i < line.widgets.length; i++)
	          if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; }
	        ++lineNo;
	      });
	      cm.curOp.forceUpdate = true;
	      signal(cm, "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);
	      this.scrollTo(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();
	      this.scrollTo(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);
	
	  // OPTION DEFAULTS
	
	  // The default configuration options.
	  var defaults = CodeMirror.defaults = {};
	  // Functions to run when options are changed.
	  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;
	  }
	
	  // Passed to option handlers when there is no old value.
	  var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.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) {
	    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\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val, old) {
	    cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
	    if (old != CodeMirror.Init) cm.refresh();
	  });
	  option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {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("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 != CodeMirror.Init && getKeyMap(old);
	    if (prev && prev.detach) prev.detach(cm, next);
	    if (next.attach) next.attach(cm, prev || null);
	  });
	  option("extraKeys", 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) {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("readOnly", false, function(cm, val) {
	    if (val == "nocursor") {
	      onBlur(cm);
	      cm.display.input.blur();
	      cm.display.disabled = true;
	    } else {
	      cm.display.disabled = false;
	    }
	    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){cm.doc.history.undoDepth = val;});
	  option("historyEventDelay", 1250);
	  option("viewportMargin", 10, function(cm){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) {
	    cm.display.input.getField().tabIndex = val || "";
	  });
	  option("autofocus", null);
	
	  // MODE DEFINITION AND QUERYING
	
	  // Known modes, by name and by MIME
	  var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.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.)
	  CodeMirror.defineMode = function(name, mode) {
	    if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
	    if (arguments.length > 2)
	      mode.dependencies = Array.prototype.slice.call(arguments, 2);
	    modes[name] = mode;
	  };
	
	  CodeMirror.defineMIME = function(mime, spec) {
	    mimeModes[mime] = spec;
	  };
	
	  // Given a MIME type, a {name, ...options} config object, or a name
	  // string, return a mode config object.
	  CodeMirror.resolveMode = function(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 CodeMirror.resolveMode("application/xml");
	    }
	    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.
	  CodeMirror.getMode = function(options, spec) {
	    var spec = CodeMirror.resolveMode(spec);
	    var mfactory = modes[spec.name];
	    if (!mfactory) return CodeMirror.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 in spec.modeProps)
	      modeObj[prop] = spec.modeProps[prop];
	
	    return modeObj;
	  };
	
	  // Minimal default mode.
	  CodeMirror.defineMode("null", function() {
	    return {token: function(stream) {stream.skipToEnd();}};
	  });
	  CodeMirror.defineMIME("text/plain", "null");
	
	  // This can be used to attach properties to mode objects from
	  // outside the actual mode definition.
	  var modeExtensions = CodeMirror.modeExtensions = {};
	  CodeMirror.extendMode = function(mode, properties) {
	    var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
	    copyObj(properties, exts);
	  };
	
	  // EXTENSIONS
	
	  CodeMirror.defineExtension = function(name, func) {
	    CodeMirror.prototype[name] = func;
	  };
	  CodeMirror.defineDocExtension = function(name, func) {
	    Doc.prototype[name] = func;
	  };
	  CodeMirror.defineOption = option;
	
	  var initHooks = [];
	  CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
	
	  var helpers = CodeMirror.helpers = {};
	  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});
	  };
	
	  // MODE STATE HANDLING
	
	  // Utility functions for working with state. Exported because nested
	  // modes need to do this for their inner modes.
	
	  var copyState = CodeMirror.copyState = function(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;
	  };
	
	  var startState = CodeMirror.startState = function(mode, a1, a2) {
	    return mode.startState ? mode.startState(a1, a2) : true;
	  };
	
	  // Given a mode and a state (for that mode), find the inner mode and
	  // state at the position that the state refers to.
	  CodeMirror.innerMode = function(mode, state) {
	    while (mode.innerMode) {
	      var info = mode.innerMode(state);
	      if (!info || info.mode == mode) break;
	      state = info.state;
	      mode = info.mode;
	    }
	    return info || {mode: mode, state: state};
	  };
	
	  // STANDARD COMMANDS
	
	  // Commands are parameter-less actions that can be performed on an
	  // editor, mostly used for keybindings.
	  var commands = CodeMirror.commands = {
	    selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);},
	    singleSelection: function(cm) {
	      cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll);
	    },
	    killLine: function(cm) {
	      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) {
	      deleteNearSelection(cm, function(range) {
	        return {from: Pos(range.from().line, 0),
	                to: clipPos(cm.doc, Pos(range.to().line + 1, 0))};
	      });
	    },
	    delLineLeft: function(cm) {
	      deleteNearSelection(cm, function(range) {
	        return {from: Pos(range.from().line, 0), to: range.from()};
	      });
	    },
	    delWrappedLineLeft: function(cm) {
	      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) {
	      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) {cm.undo();},
	    redo: function(cm) {cm.redo();},
	    undoSelection: function(cm) {cm.undoSelection();},
	    redoSelection: function(cm) {cm.redoSelection();},
	    goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
	    goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
	    goLineStart: function(cm) {
	      cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); },
	                            {origin: "+move", bias: 1});
	    },
	    goLineStartSmart: function(cm) {
	      cm.extendSelectionsBy(function(range) {
	        return lineStartSmart(cm, range.head);
	      }, {origin: "+move", bias: 1});
	    },
	    goLineEnd: function(cm) {
	      cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); },
	                            {origin: "+move", bias: -1});
	    },
	    goLineRight: function(cm) {
	      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) {
	      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) {
	      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) {cm.moveV(-1, "line");},
	    goLineDown: function(cm) {cm.moveV(1, "line");},
	    goPageUp: function(cm) {cm.moveV(-1, "page");},
	    goPageDown: function(cm) {cm.moveV(1, "page");},
	    goCharLeft: function(cm) {cm.moveH(-1, "char");},
	    goCharRight: function(cm) {cm.moveH(1, "char");},
	    goColumnLeft: function(cm) {cm.moveH(-1, "column");},
	    goColumnRight: function(cm) {cm.moveH(1, "column");},
	    goWordLeft: function(cm) {cm.moveH(-1, "word");},
	    goGroupRight: function(cm) {cm.moveH(1, "group");},
	    goGroupLeft: function(cm) {cm.moveH(-1, "group");},
	    goWordRight: function(cm) {cm.moveH(1, "word");},
	    delCharBefore: function(cm) {cm.deleteH(-1, "char");},
	    delCharAfter: function(cm) {cm.deleteH(1, "char");},
	    delWordBefore: function(cm) {cm.deleteH(-1, "word");},
	    delWordAfter: function(cm) {cm.deleteH(1, "word");},
	    delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
	    delGroupAfter: function(cm) {cm.deleteH(1, "group");},
	    indentAuto: function(cm) {cm.indentSelection("smart");},
	    indentMore: function(cm) {cm.indentSelection("add");},
	    indentLess: function(cm) {cm.indentSelection("subtract");},
	    insertTab: function(cm) {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");
	    },
	    transposeChars: function(cm) {
	      runInOp(cm, function() {
	        var ranges = cm.listSelections(), newSel = [];
	        for (var i = 0; i < ranges.length; i++) {
	          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)
	                cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() +
	                                prev.charAt(prev.length - 1),
	                                Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
	            }
	          }
	          newSel.push(new Range(cur, cur));
	        }
	        cm.setSelections(newSel);
	      });
	    },
	    newlineAndIndent: function(cm) {
	      runInOp(cm, function() {
	        var len = cm.listSelections().length;
	        for (var i = 0; i < len; i++) {
	          var range = cm.listSelections()[i];
	          cm.replaceRange(cm.doc.lineSeparator(), range.anchor, range.head, "+input");
	          cm.indentLine(range.from().line + 1, null, true);
	        }
	        ensureCursorVisible(cm);
	      });
	    },
	    openLine: function(cm) {cm.replaceSelection("\n", "start")},
	    toggleOverwrite: function(cm) {cm.toggleOverwrite();}
	  };
	
	
	  // STANDARD KEYMAPS
	
	  var keyMap = CodeMirror.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.
	  CodeMirror.normalizeKeyMap = function(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, name;
	        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;
	  };
	
	  var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) {
	    map = getKeyMap(map);
	    var found = map.call ? map.call(key, context) : map[key];
	    if (found === false) return "nothing";
	    if (found === "...") return "multi";
	    if (found != null && handle(found)) return "handled";
	
	    if (map.fallthrough) {
	      if (Object.prototype.toString.call(map.fallthrough) != "[object Array]")
	        return lookupKey(key, map.fallthrough, handle, context);
	      for (var i = 0; i < map.fallthrough.length; i++) {
	        var result = lookupKey(key, map.fallthrough[i], handle, context);
	        if (result) return result;
	      }
	    }
	  };
	
	  // Modifier key presses don't count as 'real' key presses for the
	  // purpose of keymap fallthrough.
	  var isModifierKey = CodeMirror.isModifierKey = function(value) {
	    var name = typeof value == "string" ? value : keyNames[value.keyCode];
	    return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
	  };
	
	  // Look up the name of a key as indicated by an event object.
	  var keyName = CodeMirror.keyName = function(event, noShift) {
	    if (presto && event.keyCode == 34 && event["char"]) return false;
	    var base = keyNames[event.keyCode], name = base;
	    if (name == null || event.altGraphKey) return false;
	    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;
	  };
	
	  function getKeyMap(val) {
	    return typeof val == "string" ? keyMap[val] : val;
	  }
	
	  // FROMTEXTAREA
	
	  CodeMirror.fromTextArea = function(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();}
	    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(function(node) {
	      textarea.parentNode.insertBefore(node, textarea.nextSibling);
	    }, options);
	    return cm;
	  };
	
	  // STRING STREAM
	
	  // Fed to the mode parsers, provides helper functions to make
	  // parsers more succinct.
	
	  var StringStream = CodeMirror.StringStream = function(string, tabSize) {
	    this.pos = this.start = 0;
	    this.string = string;
	    this.tabSize = tabSize || 8;
	    this.lastColumnPos = this.lastColumnValue = 0;
	    this.lineStart = 0;
	  };
	
	  StringStream.prototype = {
	    eol: function() {return this.pos >= this.string.length;},
	    sol: function() {return this.pos == this.lineStart;},
	    peek: function() {return this.string.charAt(this.pos) || undefined;},
	    next: function() {
	      if (this.pos < this.string.length)
	        return this.string.charAt(this.pos++);
	    },
	    eat: function(match) {
	      var ch = this.string.charAt(this.pos);
	      if (typeof match == "string") var ok = ch == match;
	      else var ok = ch && (match.test ? match.test(ch) : match(ch));
	      if (ok) {++this.pos; return ch;}
	    },
	    eatWhile: function(match) {
	      var start = this.pos;
	      while (this.eat(match)){}
	      return this.pos > start;
	    },
	    eatSpace: function() {
	      var start = this.pos;
	      while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
	      return this.pos > start;
	    },
	    skipToEnd: function() {this.pos = this.string.length;},
	    skipTo: function(ch) {
	      var found = this.string.indexOf(ch, this.pos);
	      if (found > -1) {this.pos = found; return true;}
	    },
	    backUp: function(n) {this.pos -= n;},
	    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);
	    },
	    indentation: function() {
	      return countColumn(this.string, null, this.tabSize) -
	        (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
	    },
	    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;
	      }
	    },
	    current: function(){return this.string.slice(this.start, this.pos);},
	    hideFirstChars: function(n, inner) {
	      this.lineStart += n;
	      try { return inner(); }
	      finally { this.lineStart -= n; }
	    }
	  };
	
	  // 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.
	
	  var nextMarkerId = 0;
	
	  var TextMarker = CodeMirror.TextMarker = function(doc, type) {
	    this.lines = [];
	    this.type = type;
	    this.doc = doc;
	    this.id = ++nextMarkerId;
	  };
	  eventMixin(TextMarker);
	
	  // Clear the marker.
	  TextMarker.prototype.clear = function() {
	    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.lines[i];
	      var span = getMarkedSpanFor(line.markedSpans, this);
	      if (cm && !this.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.collapsed && !lineIsHidden(this.doc, line) && cm)
	        updateLineHeight(line, textHeight(cm.display));
	    }
	    if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
	      var visual = visualLine(this.lines[i]), 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);
	    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) {
	    if (side == null && this.type == "bookmark") side = 1;
	    var from, to;
	    for (var i = 0; i < this.lines.length; ++i) {
	      var line = this.lines[i];
	      var span = getMarkedSpanFor(line.markedSpans, this);
	      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 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);
	      }
	    });
	  };
	
	  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);
	    }
	  };
	
	  // 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;
	
	  // 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 = elt("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");
	      sawCollapsedSpans = true;
	    }
	
	    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() { marker.clear(); });
	
	    if (marker.readOnly) {
	      sawReadOnlySpans = true;
	      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 = CodeMirror.SharedTextMarker = function(markers, primary) {
	    this.markers = markers;
	    this.primary = primary;
	    for (var i = 0; i < markers.length; ++i)
	      markers[i].parent = this;
	  };
	  eventMixin(SharedTextMarker);
	
	  SharedTextMarker.prototype.clear = function() {
	    if (this.explicitlyCleared) return;
	    this.explicitlyCleared = true;
	    for (var i = 0; i < this.markers.length; ++i)
	      this.markers[i].clear();
	    signalLater(this, "clear");
	  };
	  SharedTextMarker.prototype.find = function(side, lineObj) {
	    return this.primary.find(side, lineObj);
	  };
	
	  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) {
	    for (var i = 0; i < markers.length; i++) {
	      var marker = markers[i], linked = [marker.primary.doc];;
	      linkedDocs(marker.primary.doc, function(d) { 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);
	        }
	      }
	    }
	  }
	
	  // 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) {
	    for (var r, 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) {
	    if (old) for (var i = 0, nw; 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) {
	    if (old) for (var i = 0, nw; 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 = 0; i < last.length; ++i) {
	        var span = last[i];
	        if (span.to != null) span.to += offset;
	        if (span.from == null) {
	          var found = getMarkedSpanFor(first, span.marker);
	          if (!found) {
	            span.from = offset;
	            if (sameLine) (first || (first = [])).push(span);
	          }
	        } else {
	          span.from += offset;
	          if (sameLine) (first || (first = [])).push(span);
	        }
	      }
	    }
	    // 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 = 0; i < first.length; ++i)
	          if (first[i].to == null)
	            (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null));
	      for (var i = 0; i < gap; ++i)
	        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 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 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 - 1;
	      }
	    }
	    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, 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, from, to, marker) {
	    var line = getLine(doc, lineNo);
	    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;
	  }
	
	  // 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, 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, 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;
	    }
	  }
	
	  // LINE WIDGETS
	
	  // Line widgets are block elements displayed above or below a line.
	
	  var LineWidget = CodeMirror.LineWidget = function(doc, node, options) {
	    if (options) for (var opt in options) if (options.hasOwnProperty(opt))
	      this[opt] = options[opt];
	    this.doc = doc;
	    this.node = node;
	  };
	  eventMixin(LineWidget);
	
	  function adjustScrollWhenAboveVisible(cm, line, diff) {
	    if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
	      addToScrollPos(cm, null, diff);
	  }
	
	  LineWidget.prototype.clear = function() {
	    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) 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");
	    });
	  };
	  LineWidget.prototype.changed = function() {
	    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);
	    });
	  };
	
	  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;
	  }
	
	  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) addToScrollPos(cm, null, widget.height);
	        cm.curOp.forceUpdate = true;
	      }
	      return true;
	    });
	    return widget;
	  }
	
	  // LINE DATA STRUCTURE
	
	  // Line objects. These hold state related to a line, including
	  // highlighting info (the styles array).
	  var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
	    this.text = text;
	    attachMarkedSpans(this, markedSpans);
	    this.height = estimateHeight ? estimateHeight(this) : 1;
	  };
	  eventMixin(Line);
	  Line.prototype.lineNo = function() { return lineNo(this); };
	
	  // 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);
	  }
	
	  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;
	  }
	
	  function callBlankLine(mode, state) {
	    if (mode.blankLine) return mode.blankLine(state);
	    if (!mode.innerMode) return;
	    var inner = CodeMirror.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] = CodeMirror.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.");
	  }
	
	  // Utility for getTokenAt and getLineTokens
	  function takeToken(cm, pos, precise, asArray) {
	    function getObj(copy) {
	      return {start: stream.start, end: stream.pos,
	              string: stream.current(),
	              type: style || null,
	              state: copy ? copyState(doc.mode, state) : state};
	    }
	
	    var doc = cm.doc, mode = doc.mode, style;
	    pos = clipPos(doc, pos);
	    var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise);
	    var stream = new StringStream(line.text, cm.options.tabSize), tokens;
	    if (asArray) tokens = [];
	    while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
	      stream.start = stream.pos;
	      style = readToken(mode, stream, state);
	      if (asArray) tokens.push(getObj(true));
	    }
	    return asArray ? tokens : getObj();
	  }
	
	  // Run the given mode's parser over a line, calling f for each token.
	  function runMode(cm, text, mode, state, 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), style;
	    var inner = cm.options.addModeClass && [null];
	    if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses);
	    while (!stream.eol()) {
	      if (stream.pos > cm.options.maxHighlightLength) {
	        flattenSpans = false;
	        if (forceToEnd) processLine(cm, text, state, stream.pos);
	        stream.pos = text.length;
	        style = null;
	      } else {
	        style = extractLineClasses(readToken(mode, stream, 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 + 50000);
	          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
	      var pos = Math.min(stream.pos, curStart + 50000);
	      f(pos, curStyle);
	      curStart = pos;
	    }
	  }
	
	  // 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, state, 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, state, function(end, style) {
	      st.push(end, style);
	    }, lineClasses, forceToEnd);
	
	    // Run overlays, adjust style array.
	    for (var o = 0; o < cm.state.overlays.length; ++o) {
	      var overlay = cm.state.overlays[o], i = 1, at = 0;
	      runMode(cm, line.text, overlay.mode, true, 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, "cm-overlay " + style);
	          i = start + 2;
	        } else {
	          for (; start < i; start += 2) {
	            var cur = st[start+1];
	            st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style;
	          }
	        }
	      }, lineClasses);
	    }
	
	    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 state = getStateBefore(cm, lineNo(line));
	      var result = highlightLine(cm, line, line.text.length > cm.options.maxHighlightLength ? copyState(cm.doc.mode, state) : state);
	      line.stateAfter = state;
	      line.styles = result.styles;
	      if (result.classes) line.styleClasses = result.classes;
	      else if (line.styleClasses) line.styleClasses = null;
	      if (updateFrontier === cm.doc.frontier) cm.doc.frontier++;
	    }
	    return line.styles;
	  }
	
	  // 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, state, startAt) {
	    var mode = cm.doc.mode;
	    var stream = new StringStream(text, cm.options.tabSize);
	    stream.start = stream.pos = startAt || 0;
	    if (text == "") callBlankLine(mode, state);
	    while (!stream.eol()) {
	      readToken(mode, stream, state);
	      stream.start = stream.pos;
	    }
	  }
	
	  // 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 = {}, 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 = elt("span", null, null, webkit ? "padding-right: .1px" : null);
	    var builder = {pre: elt("pre", [content], "CodeMirror-line"), content: content,
	                   col: 0, pos: 0, cm: cm,
	                   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;
	      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)))
	        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 ? text.replace(/ {3,}/g, splitSpaces) : text;
	    var special = builder.cm.state.specialChars, mustWrap = false;
	    if (!special.test(text)) {
	      builder.col += text.length;
	      var 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 {
	      var content = document.createDocumentFragment(), 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;
	        if (m[0] == "\t") {
	          var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
	          var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
	          txt.setAttribute("role", "presentation");
	          txt.setAttribute("cm-text", "\t");
	          builder.col += tabWidth;
	        } else if (m[0] == "\r" || m[0] == "\n") {
	          var txt = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar"));
	          txt.setAttribute("cm-text", m[0]);
	          builder.col += 1;
	        } else {
	          var txt = builder.cm.options.specialCharPlaceholder(m[0]);
	          txt.setAttribute("cm-text", m[0]);
	          if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
	          else content.appendChild(txt);
	          builder.col += 1;
	        }
	        builder.map.push(builder.pos, builder.pos + 1, txt);
	        builder.pos++;
	      }
	    }
	    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(old) {
	    var out = " ";
	    for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
	    out += " ";
	    return out;
	  }
	
	  // 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
	        for (var i = 0; i < order.length; i++) {
	          var 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;
	  }
	
	  // 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; i < styles.length; i+=2)
	        builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+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
	        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 = 0; j < endStyles.length; j += 2)
	          if (endStyles[j + 1] == nextChange) spanEndStyle += " " + endStyles[j]
	
	        if (!collapsed || collapsed.from == pos) for (var j = 0; j < foundBookmarks.length; ++j)
	          buildCollapsedSpan(builder, 0, foundBookmarks[j]);
	        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);
	      }
	    }
	  }
	
	  // 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) {
	    function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
	    function update(line, text, spans) {
	      updateLine(line, text, spans, estimateHeight);
	      signalLater(line, "change", line, change);
	    }
	    function linesFor(start, end) {
	      for (var i = start, result = []; i < end; ++i)
	        result.push(new Line(text[i], spansFor(i), estimateHeight));
	      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 = linesFor(1, text.length - 1);
	        added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
	        update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
	        doc.insert(from.line + 1, added);
	      }
	    } 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 = linesFor(1, text.length - 1);
	      if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
	      doc.insert(from.line + 1, added);
	    }
	
	    signalLater(doc, "change", doc, change);
	  }
	
	  // 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) {
	    this.lines = lines;
	    this.parent = null;
	    for (var i = 0, height = 0; i < lines.length; ++i) {
	      lines[i].parent = this;
	      height += lines[i].height;
	    }
	    this.height = height;
	  }
	
	  LeafChunk.prototype = {
	    chunkSize: function() { return this.lines.length; },
	    // Remove the n lines at offset 'at'.
	    removeInner: function(at, n) {
	      for (var i = at, e = at + n; i < e; ++i) {
	        var line = this.lines[i];
	        this.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(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(at, lines, height) {
	      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;
	    },
	    // Used to iterate over a part of the tree.
	    iterN: function(at, n, op) {
	      for (var e = at + n; at < e; ++at)
	        if (op(this.lines[at])) return true;
	    }
	  };
	
	  function BranchChunk(children) {
	    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;
	    }
	    this.size = size;
	    this.height = height;
	    this.parent = null;
	  }
	
	  BranchChunk.prototype = {
	    chunkSize: function() { return this.size; },
	    removeInner: function(at, n) {
	      this.size -= n;
	      for (var i = 0; i < this.children.length; ++i) {
	        var child = this.children[i], sz = child.chunkSize();
	        if (at < sz) {
	          var rm = Math.min(n, sz - at), oldHeight = child.height;
	          child.removeInner(at, rm);
	          this.height -= oldHeight - child.height;
	          if (sz == rm) { this.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(lines) {
	      for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines);
	    },
	    insertInner: function(at, lines, height) {
	      this.size += lines.length;
	      this.height += height;
	      for (var i = 0; i < this.children.length; ++i) {
	        var child = this.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.children.splice(++i, 0, leaf);
	              leaf.parent = this;
	            }
	            child.lines = child.lines.slice(0, remaining);
	            this.maybeSpill();
	          }
	          break;
	        }
	        at -= sz;
	      }
	    },
	    // When a node has grown, check whether it should be split.
	    maybeSpill: function() {
	      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(at, n, op) {
	      for (var i = 0; i < this.children.length; ++i) {
	        var child = this.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;
	      }
	    }
	  };
	
	  var nextDocId = 0;
	  var Doc = CodeMirror.Doc = function(text, mode, firstLine, lineSep) {
	    if (!(this instanceof Doc)) return new Doc(text, mode, firstLine, lineSep);
	    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.frontier = 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.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);
	      setSelection(this, simpleSelection(top));
	    }),
	    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 = this.sel.primary(), pos;
	      if (start == null || start == "head") pos = range.head;
	      else if (start == "anchor") pos = range.anchor;
	      else if (start == "end" || start == "to" || start === false) pos = range.to();
	      else pos = range.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) {
	      if (!ranges.length) return;
	      for (var i = 0, out = []; i < ranges.length; i++)
	        out[i] = new Range(clipPos(this, ranges[i].anchor),
	                           clipPos(this, 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 ranges = this.sel.ranges, lines;
	      for (var i = 0; i < ranges.length; i++) {
	        var sel = getBetween(this, 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 parts = [], ranges = this.sel.ranges;
	      for (var i = 0; i < ranges.length; i++) {
	        var sel = getBetween(this, ranges[i].from(), ranges[i].to());
	        if (lineSep !== false) sel = sel.join(lineSep || this.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 changes = [], sel = this.sel;
	      for (var i = 0; i < sel.ranges.length; i++) {
	        var range = sel.ranges[i];
	        changes[i] = {from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin};
	      }
	      var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
	      for (var i = changes.length - 1; i >= 0; i--)
	        makeChange(this, changes[i]);
	      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 = 0; i < hist.undone.length; i++) if (!hist.undone[i].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);
	    },
	
	    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 = 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 == from.line && from.ch >= span.to ||
	                span.from == null && lineNo != from.line ||
	                span.from != null && lineNo == to.line && span.from >= to.ch) &&
	              (!filter || filter(span.marker)))
	            found.push(span.marker.parent || span.marker);
	        }
	        ++lineNo;
	      });
	      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 = 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;
	      });
	      return clipPos(this, Pos(lineNo, 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) {
	        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);
	      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);
	      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) {
	      if (other instanceof CodeMirror) other = other.doc;
	      if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
	        var link = this.linked[i];
	        if (link.doc != other) continue;
	        this.linked.splice(i, 1);
	        other.unlinkDoc(this);
	        detachSharedMarkers(findSharedMarkers(this));
	        break;
	      }
	      // If the histories were shared, split them again
	      if (other.history == this.history) {
	        var splitIds = [other.id];
	        linkedDocs(other, function(doc) {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"; }
	  });
	
	  // Public alias.
	  Doc.prototype.eachLine = Doc.prototype.iter;
	
	  // 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.prototype[prop] = (function(method) {
	      return function() {return method.apply(this.doc, arguments);};
	    })(Doc.prototype[prop]);
	
	  eventMixin(Doc);
	
	  // 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);
	    if (!cm.options.lineWrapping) findMaxLine(cm);
	    cm.options.mode = doc.modeOption;
	    regChange(cm);
	  }
	
	  // LINE UTILITIES
	
	  // 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.");
	    for (var chunk = doc; !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); });
	    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 = 0; i < chunk.children.length; ++i) {
	        var child = chunk.children[i], ch = child.height;
	        if (h < ch) { chunk = child; continue outer; }
	        h -= ch;
	        n += child.chunkSize();
	      }
	      return n;
	    } while (!chunk.lines);
	    for (var i = 0; i < chunk.lines.length; ++i) {
	      var line = chunk.lines[i], lh = line.height;
	      if (h < lh) break;
	      h -= lh;
	    }
	    return n + i;
	  }
	
	
	  // 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 = 0; i < p.children.length; ++i) {
	        var cur = p.children[i];
	        if (cur == chunk) break;
	        else h += cur.height;
	      }
	    }
	    return h;
	  }
	
	  // 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) {
	    var order = line.order;
	    if (order == null) order = line.order = bidiOrdering(line.text);
	    return order;
	  }
	
	  // HISTORY
	
	  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) {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, ore 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;
	
	    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
	      var 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;
	    for (var i = 0, out; 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;
	    for (var i = 0, nw = []; i < change.text.length; ++i)
	      nw.push(removeClearedSpans(found[i]));
	    return nw;
	  }
	
	  // 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) {
	    for (var i = 0, copy = []; 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;
	        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;
	  }
	
	  // 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 = 0; j < sub.changes.length; ++j) {
	        var cur = sub.changes[j];
	        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);
	  }
	
	  // EVENT UTILITIES
	
	  // Due to the fact that we still support jurassic IE versions, some
	  // compatibility wrappers are needed.
	
	  var e_preventDefault = CodeMirror.e_preventDefault = function(e) {
	    if (e.preventDefault) e.preventDefault();
	    else e.returnValue = false;
	  };
	  var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) {
	    if (e.stopPropagation) e.stopPropagation();
	    else e.cancelBubble = true;
	  };
	  function e_defaultPrevented(e) {
	    return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
	  }
	  var e_stop = CodeMirror.e_stop = function(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;
	  }
	
	  // EVENT HANDLING
	
	  // Lightweight event framework. on/off also work on DOM nodes,
	  // registering native DOM handlers.
	
	  var on = CodeMirror.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 = emitter._handlers || (emitter._handlers = {});
	      var arr = map[type] || (map[type] = []);
	      arr.push(f);
	    }
	  };
	
	  var noHandlers = []
	  function getHandlers(emitter, type, copy) {
	    var arr = emitter._handlers && emitter._handlers[type]
	    if (copy) return arr && arr.length > 0 ? arr.slice() : noHandlers
	    else return arr || noHandlers
	  }
	
	  var off = CodeMirror.off = function(emitter, type, f) {
	    if (emitter.removeEventListener)
	      emitter.removeEventListener(type, f, false);
	    else if (emitter.detachEvent)
	      emitter.detachEvent("on" + type, f);
	    else {
	      var handlers = getHandlers(emitter, type, false)
	      for (var i = 0; i < handlers.length; ++i)
	        if (handlers[i] == f) { handlers.splice(i, 1); break; }
	    }
	  };
	
	  var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {
	    var handlers = getHandlers(emitter, type, true)
	    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);
	  };
	
	  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, false)
	    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);
	    }
	    function bnd(f) {return function(){f.apply(null, args);};};
	    for (var i = 0; i < arr.length; ++i)
	      list.push(bnd(arr[i]));
	  }
	
	  function fireOrphanDelayed() {
	    var delayed = orphanDelayedCallbacks;
	    orphanDelayedCallbacks = null;
	    for (var i = 0; i < delayed.length; ++i) delayed[i]();
	  }
	
	  // 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);};
	  }
	
	  // MISC UTILITIES
	
	  // 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 = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
	
	  // Reused option objects for setSelection & friends
	  var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"};
	
	  function Delayed() {this.id = null;}
	  Delayed.prototype.set = function(ms, f) {
	    clearTimeout(this.id);
	    this.id = setTimeout(f, ms);
	  };
	
	  // Counts the column offset in a string, taking tabs into account.
	  // Used mostly to find indentation.
	  var countColumn = CodeMirror.countColumn = function(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;
	    }
	  };
	
	  // The inverse of countColumn -- find the offset that corresponds to
	  // a particular column.
	  var findColumn = CodeMirror.findColumn = function(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]; }
	
	  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 indexOf(array, elt) {
	    for (var i = 0; i < array.length; ++i)
	      if (array[i] == elt) return i;
	    return -1;
	  }
	  function map(array, f) {
	    var out = [];
	    for (var i = 0; i < array.length; i++) out[i] = f(array[i], i);
	    return out;
	  }
	
	  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;
	  };
	
	  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;
	  }
	
	  function bind(f) {
	    var args = Array.prototype.slice.call(arguments, 1);
	    return function(){return f.apply(null, args);};
	  }
	
	  var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
	  var isWordCharBasic = CodeMirror.isWordChar = function(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); }
	
	  // DOM UTILITIES
	
	  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;
	  }
	
	  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 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);
	  }
	
	  var contains = CodeMirror.contains = function(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() {
	    var activeElement = document.activeElement;
	    while (activeElement && activeElement.root && activeElement.root.activeElement)
	      activeElement = activeElement.root.activeElement;
	    return activeElement;
	  }
	  // Older versions of IE throws unspecified error when touching
	  // document.activeElement in some cases (during loading, in iframe)
	  if (ie && ie_version < 11) activeElt = function() {
	    try { return document.activeElement; }
	    catch(e) { return document.body; }
	  };
	
	  function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); }
	  var rmClass = CodeMirror.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 : "");
	    }
	  };
	  var addClass = CodeMirror.addClass = function(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;
	  }
	
	  // WINDOW-WIDE EVENTS
	
	  // 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.body.getElementsByClassName) return;
	    var byClass = document.body.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() {
	      forEachCodeMirror(onBlur);
	    });
	  }
	
	  // FEATURE DETECTION
	
	  // 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();
	    if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780)
	    var r1 = range(txt, 1, 2).getBoundingClientRect();
	    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 = CodeMirror.splitLines = "\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) {
	    try {var range = te.ownerDocument.selection.createRange();}
	    catch(e) {}
	    if (!range || range.parentElement() != te) return false;
	    return range.compareEndPoints("StartToEnd", range) != 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;
	  }
	
	  // KEY NAMES
	
	  var keyNames = CodeMirror.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"
	  };
	  (function() {
	    // Number keys
	    for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);
	    // Alphabetic keys
	    for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
	    // Function keys
	    for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
	  })();
	
	  // 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");
	  }
	
	  function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
	  function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
	
	  function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
	  function lineRight(line) {
	    var order = getOrder(line);
	    if (!order) return line.text.length;
	    return bidiRight(lst(order));
	  }
	
	  function lineStart(cm, lineN) {
	    var line = getLine(cm.doc, lineN);
	    var visual = visualLine(line);
	    if (visual != line) lineN = lineNo(visual);
	    var order = getOrder(visual);
	    var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
	    return Pos(lineN, ch);
	  }
	  function lineEnd(cm, lineN) {
	    var merged, line = getLine(cm.doc, lineN);
	    while (merged = collapsedSpanAtEnd(line)) {
	      line = merged.find(1, true).line;
	      lineN = null;
	    }
	    var order = getOrder(line);
	    var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
	    return Pos(lineN == null ? lineNo(line) : lineN, ch);
	  }
	  function lineStartSmart(cm, pos) {
	    var start = lineStart(cm, pos.line);
	    var line = getLine(cm.doc, start.line);
	    var order = getOrder(line);
	    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);
	    }
	    return start;
	  }
	
	  function compareBidiLevel(order, a, b) {
	    var linedir = order[0].level;
	    if (a == linedir) return true;
	    if (b == linedir) return false;
	    return a < b;
	  }
	  var bidiOther;
	  function getBidiPartAt(order, pos) {
	    bidiOther = null;
	    for (var i = 0, found; i < order.length; ++i) {
	      var cur = order[i];
	      if (cur.from < pos && cur.to > pos) return i;
	      if ((cur.from == pos || cur.to == pos)) {
	        if (found == null) {
	          found = i;
	        } else if (compareBidiLevel(order, cur.level, order[found].level)) {
	          if (cur.from != cur.to) bidiOther = found;
	          return i;
	        } else {
	          if (cur.from != cur.to) bidiOther = i;
	          return found;
	        }
	      }
	    }
	    return found;
	  }
	
	  function moveInLine(line, pos, dir, byUnit) {
	    if (!byUnit) return pos + dir;
	    do pos += dir;
	    while (pos > 0 && isExtendingChar(line.text.charAt(pos)));
	    return pos;
	  }
	
	  // This is needed in order to move 'visually' through bi-directional
	  // text -- i.e., pressing left should make the cursor go left, even
	  // when in RTL text. The tricky part is the 'jumps', where RTL and
	  // LTR text touch each other. This often requires the cursor offset
	  // to move more than one unit, in order to visually move one unit.
	  function moveVisually(line, start, dir, byUnit) {
	    var bidi = getOrder(line);
	    if (!bidi) return moveLogically(line, start, dir, byUnit);
	    var pos = getBidiPartAt(bidi, start), part = bidi[pos];
	    var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);
	
	    for (;;) {
	      if (target > part.from && target < part.to) return target;
	      if (target == part.from || target == part.to) {
	        if (getBidiPartAt(bidi, target) == pos) return target;
	        part = bidi[pos += dir];
	        return (dir > 0) == part.level % 2 ? part.to : part.from;
	      } else {
	        part = bidi[pos += dir];
	        if (!part) return null;
	        if ((dir > 0) == part.level % 2)
	          target = moveInLine(line, part.to, -1, byUnit);
	        else
	          target = moveInLine(line, part.from, 1, byUnit);
	      }
	    }
	  }
	
	  function moveLogically(line, start, dir, byUnit) {
	    var target = start + dir;
	    if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir;
	    return target < 0 || target > line.text.length ? null : target;
	  }
	
	  // 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 0x6ff
	    var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm";
	    function charType(code) {
	      if (code <= 0xf7) return lowTypes.charAt(code);
	      else if (0x590 <= code && code <= 0x5f4) return "R";
	      else if (0x600 <= code && code <= 0x6ed) 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]/;
	    // Browsers seem to always treat the boundaries of block elements as being L.
	    var outerType = "L";
	
	    function BidiSpan(level, from, to) {
	      this.level = level;
	      this.from = from; this.to = to;
	    }
	
	    return function(str) {
	      if (!bidiRE.test(str)) return false;
	      var len = str.length, types = [];
	      for (var i = 0, type; i < len; ++i)
	        types.push(type = 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 = 0, prev = outerType; i < len; ++i) {
	        var type = types[i];
	        if (type == "m") types[i] = 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 = 0, cur = outerType; i < len; ++i) {
	        var type = types[i];
	        if (type == "1" && cur == "r") types[i] = "n";
	        else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "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 = 1, prev = types[0]; i < len - 1; ++i) {
	        var type = types[i];
	        if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
	        else if (type == "," && prev == types[i+1] &&
	                 (prev == "1" || prev == "n")) types[i] = prev;
	        prev = type;
	      }
	
	      // 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 = 0; i < len; ++i) {
	        var type = types[i];
	        if (type == ",") types[i] = "N";
	        else if (type == "%") {
	          for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
	          var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
	          for (var j = i; j < end; ++j) types[j] = replace;
	          i = 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 = 0, cur = outerType; i < len; ++i) {
	        var type = types[i];
	        if (cur == "L" && type == "1") types[i] = "L";
	        else if (isStrong.test(type)) cur = type;
	      }
	
	      // 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 = 0; i < len; ++i) {
	        if (isNeutral.test(types[i])) {
	          for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
	          var before = (i ? types[i-1] : outerType) == "L";
	          var after = (end < len ? types[end] : outerType) == "L";
	          var replace = before || after ? "L" : "R";
	          for (var j = i; j < end; ++j) types[j] = replace;
	          i = end - 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 = 0; i < len;) {
	        if (countsAsLeft.test(types[i])) {
	          var start = i;
	          for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
	          order.push(new BidiSpan(0, start, i));
	        } else {
	          var pos = i, at = order.length;
	          for (++i; i < len && types[i] != "L"; ++i) {}
	          for (var j = pos; j < i;) {
	            if (countsAsNum.test(types[j])) {
	              if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j));
	              var nstart = j;
	              for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
	              order.splice(at, 0, new BidiSpan(2, nstart, j));
	              pos = j;
	            } else ++j;
	          }
	          if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i));
	        }
	      }
	      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));
	      }
	      if (order[0].level == 2)
	        order.unshift(new BidiSpan(1, order[0].to, order[0].to));
	      if (order[0].level != lst(order).level)
	        order.push(new BidiSpan(order[0].level, len, len));
	
	      return order;
	    };
	  })();
	
	  // THE END
	
	  CodeMirror.version = "5.15.2";
	
	  return CodeMirror;
	});


/***/ },
/* 131 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var CodeMirror = __webpack_require__(130);
	__webpack_require__(132);
	__webpack_require__(133);
	/**
	 * 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);
	});
	CodeMirror.defineMIME('text/x-ipython', 'ipython');
	CodeMirror.modeInfo.push({
	    ext: [],
	    mime: 'text/x-ipython',
	    mode: 'ipython',
	    name: 'ipython'
	});


/***/ },
/* 132 */
/***/ function(module, exports, __webpack_require__) {

	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__webpack_require__(130));
	  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"]},
	    {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: "Jade", mime: "text/x-jade", mode: "jade", ext: ["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"], 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: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]},
	    {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: "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: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd"], 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", mime: "text/x-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;
	    }
	  };
	
	  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;
	    }
	  };
	});


/***/ },
/* 133 */
/***/ function(module, exports, __webpack_require__) {

	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__webpack_require__(130));
	  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 && parseInt(parserConf.version, 10) == 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("^(([rub]|(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))
	            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 ("rub".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 (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")
	  });
	
	});


/***/ },
/* 134 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var CodeMirror = __webpack_require__(130);
	__webpack_require__(135);
	__webpack_require__(136);
	__webpack_require__(140);
	/**
	 * 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 gfm_mode = CodeMirror.getMode(config, 'gfm');
	    var tex_mode = CodeMirror.getMode(config, 'stex');
	    return CodeMirror.multiplexingMode(gfm_mode, {
	        open: '$', close: '$',
	        mode: tex_mode,
	        delimStyle: 'delimit'
	    }, {
	        // not sure this works as $$ is interpreted at (opening $, closing $, as defined just above)
	        open: '$$', close: '$$',
	        mode: tex_mode,
	        delimStyle: 'delimit'
	    }, {
	        open: '\\(', close: '\\)',
	        mode: tex_mode,
	        delimStyle: 'delimit'
	    }, {
	        open: '\\[', close: '\\]',
	        mode: tex_mode,
	        delimStyle: 'delimit'
	    });
	});
	CodeMirror.defineMIME('text/x-ipythongfm', 'ipythongfm');


/***/ },
/* 135 */
/***/ function(module, exports, __webpack_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(__webpack_require__(130));
	  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");
	
	});


/***/ },
/* 136 */
/***/ function(module, exports, __webpack_require__) {

	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__webpack_require__(130), __webpack_require__(137), __webpack_require__(139));
	  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 = {
	    underscoresBreakWords: false,
	    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");
	});


/***/ },
/* 137 */
/***/ function(module, exports, __webpack_require__) {

	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__webpack_require__(130), __webpack_require__(138), __webpack_require__(132));
	  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;
	
	  // Should underscores in words open/close em/strong?
	  if (modeCfg.underscoresBreakWords === undefined)
	    modeCfg.underscoresBreakWords = true;
	
	  // 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: "tag",
	    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*$/
	  ,   ulRE = /^[*\-+]\s+/
	  ,   olRE = /^[0-9]+([.)])\s+/
	  ,   taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
	  ,   atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
	  ,   setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
	  ,   textRE = /^[^#!\[\]*_\\<>` "'(~]+/
	  ,   fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
	                                ")[ \\t]*([\\w+#\-]*)");
	
	  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 (htmlModeMissing && 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) {
	      stream.skipToEnd();
	      if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) {
	        state.indentation -= 4;
	        state.indentedCode = true;
	        return tokenTypes.code;
	      } else {
	        return null;
	      }
	    } 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 ((lineIsEmpty(state.prevLine) || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
	      var listType = null;
	      if (stream.match(ulRE, true)) {
	        listType = 'ul';
	      } else {
	        stream.match(olRE, true);
	        listType = 'ol';
	      }
	      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, false)) {
	      state.localMode = state.localState = null;
	      state.f = state.block = leavingLocal;
	      return null;
	    } else if (state.localMode) {
	      return state.localMode.token(stream, state.localState);
	    } else {
	      stream.skipToEnd();
	      return tokenTypes.code;
	    }
	  }
	
	  function leavingLocal(stream, state) {
	    stream.match(state.fencedChars);
	    state.block = blockNormal;
	    state.f = inlineNormal;
	    state.fencedChars = null;
	    if (modeCfg.highlightFormatting) state.formatting = "code-block";
	    state.code = 1
	    var returnType = getType(state);
	    state.code = 0
	    return returnType;
	  }
	
	  // 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.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);
	    }
	
	    // Get sol() value now, before character is consumed
	    var sol = stream.sol();
	
	    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)) {
	      stream.match(/\[[^\]]*\]/);
	      state.inline = state.f = linkHref;
	      return tokenTypes.image;
	    }
	
	    if (ch === '[' && stream.match(/[^\]]*\](\(.*\)| ?\[.*?\])/, false)) {
	      state.linkText = true;
	      if (modeCfg.highlightFormatting) state.formatting = "link";
	      return getType(state);
	    }
	
	    if (ch === ']' && state.linkText && stream.match(/\(.*?\)| ?\[.*?\]/, false)) {
	      if (modeCfg.highlightFormatting) state.formatting = "link";
	      var type = getType(state);
	      state.linkText = false;
	      state.inline = state.f = linkHref;
	      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(/^(!--|\w)/, 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";
	    }
	
	    var ignoreUnderscore = false;
	    if (!modeCfg.underscoresBreakWords) {
	      if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
	        var prevPos = stream.pos - 2;
	        if (prevPos >= 0) {
	          var prevCh = stream.string.charAt(prevPos);
	          if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
	            ignoreUnderscore = true;
	          }
	        }
	      }
	    }
	    if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
	      if (sol && stream.peek() === ' ') {
	        // Do nothing, surrounded by newline and space
	      } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
	        if (modeCfg.highlightFormatting) state.formatting = "strong";
	        var t = getType(state);
	        state.strong = false;
	        return t;
	      } else if (!state.strong && stream.eat(ch)) { // Add STRONG
	        state.strong = ch;
	        if (modeCfg.highlightFormatting) state.formatting = "strong";
	        return getType(state);
	      } else if (state.em === ch) { // Remove EM
	        if (modeCfg.highlightFormatting) state.formatting = "em";
	        var t = getType(state);
	        state.em = false;
	        return t;
	      } else if (!state.em) { // Add EM
	        state.em = ch;
	        if (modeCfg.highlightFormatting) state.formatting = "em";
	        return getType(state);
	      }
	    } 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 === "(" ? ")" : "]", 0);
	      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,
	        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,
	
	    fold: "markdown"
	  };
	  return mode;
	}, "xml");
	
	CodeMirror.defineMIME("text/x-markdown", "markdown");
	
	});


/***/ },
/* 138 */
/***/ function(module, exports, __webpack_require__) {

	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__webpack_require__(130));
	  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});
	
	});


/***/ },
/* 139 */
/***/ function(module, exports, __webpack_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(__webpack_require__(130));
	  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) {
	      if (base.blankLine) base.blankLine(state.base);
	      if (overlay.blankLine) overlay.blankLine(state.overlay);
	    }
	  };
	};
	
	});


/***/ },
/* 140 */
/***/ function(module, exports, __webpack_require__) {

	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__webpack_require__(130));
	  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};
	    }
	  };
	};
	
	});


/***/ },
/* 141 */
/***/ function(module, exports, __webpack_require__) {

	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	// TODO actually recognize syntax of TypeScript constructs
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__webpack_require__(130));
	  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|[\[{}\(,;:]|=>)$/.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, "async": kw("async")
	    };
	
	    // Extend the 'normal' keywords with the TypeScript language extensions
	    if (isTS) {
	      var type = {type: "variable", style: "variable-3"};
	      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"),
	
	        // operators
	        "as": operator,
	
	        // 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)) {
	      stream.eatWhile(isOperatorChar);
	      return ret("operator", "operator", stream.current());
	    } else if (wordRE.test(ch)) {
	      stream.eatWhile(wordRE);
	      var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
	      return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
	                     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;
	
	    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) 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"), expression, 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"), expression, statement, poplex, maybeelse);
	    }
	    if (type == "function") return cont(functiondef);
	    if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
	    if (type == "variable") return cont(pushlex("stat"), maybelabel);
	    if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
	                                      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, pushlex("}"), expect("{"), block, poplex, poplex)
	    if (type == "async") return cont(statement)
	    return pass(pushlex("stat"), expression, expect(";"), poplex);
	  }
	  function expression(type) {
	    return expressionInner(type, false);
	  }
	  function expressionNoComma(type) {
	    return expressionInner(type, true);
	  }
	  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 == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
	    if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, 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);
	  }
	  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 == "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);
	    }
	  }
	  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) {
	    function proceed(type, value) {
	      if (type == ",") {
	        var lex = cx.state.lexical;
	        if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
	        return cont(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) {
	    if (isTS && type == ":") return cont(typeexpr);
	  }
	  function maybedefault(_, value) {
	    if (value == "=") return cont(expressionNoComma);
	  }
	  function typeexpr(type) {
	    if (type == "variable") {cx.marked = "variable-3"; return cont(afterType);}
	  }
	  function afterType(type, value) {
	    if (value == "<") return cont(commasep(typeexpr, ">"), afterType)
	    if (type == "[") return cont(expect("]"), afterType)
	  }
	  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);
	  }
	  function funarg(type) {
	    if (type == "spread") return cont(funarg);
	    return pass(pattern, maybetype, maybedefault);
	  }
	  function className(type, value) {
	    if (type == "variable") {register(value); return cont(classNameAfter);}
	  }
	  function classNameAfter(type, value) {
	    if (value == "extends") return cont(expression, classNameAfter);
	    if (type == "{") return cont(pushlex("}"), classBody, poplex);
	  }
	  function classBody(type, value) {
	    if (type == "variable" || cx.style == "keyword") {
	      if (value == "static") {
	        cx.marked = "keyword";
	        return cont(classBody);
	      }
	      cx.marked = "property";
	      if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
	      return cont(functiondef, classBody);
	    }
	    if (value == "*") {
	      cx.marked = "keyword";
	      return cont(classBody);
	    }
	    if (type == ";") return cont(classBody);
	    if (type == "}") return cont();
	  }
	  function classGetterSetter(type) {
	    if (type != "variable") return pass();
	    cx.marked = "property";
	    return cont();
	  }
	  function afterExport(_type, value) {
	    if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
	    if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
	    return pass(statement);
	  }
	  function afterImport(type) {
	    if (type == "string") return cont();
	    return pass(importSpec, maybeFrom);
	  }
	  function importSpec(type, value) {
	    if (type == "{") return contCommasep(importSpec, "}");
	    if (type == "variable") register(value);
	    if (value == "*") cx.marked = "keyword";
	    return cont(maybeAs);
	  }
	  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(expressionNoComma, maybeArrayComprehension);
	  }
	  function maybeArrayComprehension(type) {
	    if (type == "for") return pass(comprehension, expect("]"));
	    if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
	    return pass(commasep(expressionNoComma, "]"));
	  }
	  function comprehension(type) {
	    if (type == "for") return cont(forspec, comprehension);
	    if (type == "if") return cont(expression, comprehension);
	  }
	
	  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;
	      // 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;
	      }
	      if (lexical.type == "stat" && firstChar == "}") 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 });
	
	});


/***/ },
/* 142 */
/***/ function(module, exports, __webpack_require__) {

	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__webpack_require__(130));
	  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,
	      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 == "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);
	          cx = cx.prev;
	        }
	      }
	      return indent;
	    },
	
	    electricChars: "}",
	    blockCommentStart: "/*",
	    blockCommentEnd: "*/",
	    fold: "brace"
	  };
	});
	
	  function keySet(array) {
	    var keys = {};
	    for (var i = 0; i < array.length; ++i) {
	      keys[array[i]] = 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", "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", "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",
	    "marker-offset", "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", "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",
	    "vertical-align", "visibility", "voice-balance", "voice-duration",
	    "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
	    "voice-volume", "volume", "white-space", "widows", "width", "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", "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",
	    "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", "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", "se-resize", "searchfield",
	    "searchfield-cancel-button", "searchfield-decoration",
	    "searchfield-results-button", "searchfield-results-decoration",
	    "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", "spell-out", "square",
	    "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
	    "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "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",
	    "translate", "translate3d", "translateX", "translateY", "translateZ",
	    "transparent", "ultra-condensed", "ultra-expanded", "underline", "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,
	    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*\{/))
	          return [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,
	    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"
	  });
	
	});


/***/ },
/* 143 */
/***/ function(module, exports, __webpack_require__) {

	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__webpack_require__(130));
	  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(_conf, parserConf) {
	  var ERRORCLASS = 'error';
	
	  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 specialChar = "\\\\[abfnrtv0%?'\"\\\\]";
	  var singleChar = "([^\\u0027\\u005C\\uD800-\\uDFFF]|[\\uD800-\\uDFFF][\\uDC00-\\uDFFF])";
	  var operators = parserConf.operators || /^\.?[|&^\\%*+\-<>!=\/]=?|\?|~|:|\$|\.[<>]|<<=?|>>>?=?|\.[<>=]=|->?|\/\/|\bin\b(?!\()|[\u2208\u2209](?!\()/;
	  var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
	  var identifiers = parserConf.identifiers || /^[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
	  var charsList = [octChar, hexChar, specialChar, singleChar];
	  var blockOpeners = ["begin", "function", "type", "immutable", "let", "macro", "for", "while", "quote", "if", "else", "elseif", "try", "finally", "catch", "do"];
	  var blockClosers = ["end", "else", "elseif", "catch", "finally"];
	  var keywordList = ['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 builtinList = ['true', 'false', 'nothing', 'NaN', 'Inf'];
	
	  //var stringPrefixes = new RegExp("^[br]?('|\")")
	  var stringPrefixes = /^(`|"{3}|([brv]?"))/;
	  var chars = wordRegexp(charsList, "'");
	  var keywords = wordRegexp(keywordList);
	  var builtins = wordRegexp(builtinList);
	  var openers = wordRegexp(blockOpeners);
	  var closers = wordRegexp(blockClosers);
	  var macro = /^@[_A-Za-z][\w]*/;
	  var symbol = /^:[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
	  var typeAnnotation = /^::[^,;"{()=$\s]+({[^}]*}+)*/;
	
	  function inArray(state) {
	    var ch = currentScope(state);
	    if (ch == '[') {
	      return true;
	    }
	    return false;
	  }
	
	  function currentScope(state) {
	    if (state.scopes.length == 0) {
	      return null;
	    }
	    return state.scopes[state.scopes.length - 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 (scope == '[' && ch === ']') {
	      state.scopes.pop();
	      state.leavingExpr = true;
	    }
	
	    if (scope == '(' && ch === ')') {
	      state.scopes.pop();
	      state.leavingExpr = true;
	    }
	
	    var match;
	    if (!inArray(state) && (match=stream.match(openers, false))) {
	      state.scopes.push(match);
	    }
	
	    if (!inArray(state) && stream.match(closers, false)) {
	      state.scopes.pop();
	    }
	
	    if (inArray(state)) {
	      if (state.lastToken == 'end' && stream.match(/^:/)) {
	        return 'operator';
	      }
	      if (stream.match(/^end/)) {
	        return 'number';
	      }
	    }
	
	    if (stream.match(/^=>/)) {
	      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';
	      }
	    }
	
	    if (stream.match(/^<:/)) {
	      return 'operator';
	    }
	
	    if (stream.match(typeAnnotation)) {
	      return 'builtin';
	    }
	
	    // 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 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 ERRORCLASS;
	  }
	
	  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 tokenComment(stream, state) {
	    if (stream.match(/^#=/)) {
	      state.weakScopes++;
	    }
	    if (!stream.match(/.*?(?=(#=|=#))/)) {
	      stream.skipToEnd();
	    }
	    if (stream.match(/^=#/)) {
	      state.weakScopes--;
	      if (state.weakScopes == 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 ERRORCLASS;
	  }
	
	  function tokenStringFactory(delimiter) {
	    while ('bruv'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
	      delimiter = delimiter.substr(1);
	    }
	    var OUTCLASS = 'string';
	
	    function tokenString(stream, state) {
	      while (!stream.eol()) {
	        stream.eatWhile(/[^"\\]/);
	        if (stream.eat('\\')) {
	            stream.next();
	        } else if (stream.match(delimiter)) {
	            state.tokenize = tokenBase;
	            state.leavingExpr = true;
	            return OUTCLASS;
	        } else {
	            stream.eat(/["]/);
	        }
	      }
	      return OUTCLASS;
	    }
	    tokenString.isString = true;
	    return tokenString;
	  }
	
	  var external = {
	    startState: function() {
	      return {
	        tokenize: tokenBase,
	        scopes: [],
	        weakScopes: 0,
	        lastToken: null,
	        leavingExpr: false,
	        isDefinition: false,
	        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' : ERRORCLASS;
	      }
	      return style;
	    },
	
	    indent: function(state, textAfter) {
	      var delta = 0;
	      if (textAfter == "]" || textAfter == ")" || textAfter == "end" || textAfter == "else" || textAfter == "elseif" || textAfter == "catch" || textAfter == "finally") {
	        delta = -1;
	      }
	      return (state.scopes.length + delta) * _conf.indentUnit;
	    },
	
	    electricInput: /(end|else(if)?|catch|finally)$/,
	    lineComment: "#",
	    fold: "indent"
	  };
	  return external;
	});
	
	
	CodeMirror.defineMIME("text/x-julia", "julia");
	
	});


/***/ },
/* 144 */
/***/ function(module, exports, __webpack_require__) {

	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__webpack_require__(130));
	  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(/.[.\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 "variable-2";
	    } else if (ch == "<" && stream.eat("-")) {
	      return "arrow";
	    } else if (ch == "=" && state.ctx.argList) {
	      return "arg-is";
	    } else if (opChars.test(ch)) {
	      if (ch == "$") return "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";
	      }
	    };
	  }
	
	  function push(state, type, stream) {
	    state.ctx = {type: type,
	                 indent: state.indent,
	                 align: null,
	                 column: stream.column(),
	                 prev: state.ctx};
	  }
	  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,
	                    align: false},
	              indent: 0,
	              afterIdent: false};
	    },
	
	    token: function(stream, state) {
	      if (stream.sol()) {
	        if (state.ctx.align == null) state.ctx.align = false;
	        state.indent = stream.indentation();
	      }
	      if (stream.eatSpace()) return null;
	      var style = state.tokenize(stream, state);
	      if (style != "comment" && state.ctx.align == null) state.ctx.align = true;
	
	      var ctype = state.ctx.type;
	      if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && ctype == "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 == ctype) pop(state);
	      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.type == "block") return ctx.indent + (firstChar == "{" ? 0 : config.indentUnit);
	      else if (ctx.align) return ctx.column + (closing ? 0 : 1);
	      else return ctx.indent + (closing ? 0 : config.indentUnit);
	    },
	
	    lineComment: "#"
	  };
	});
	
	CodeMirror.defineMIME("text/x-rsrc", "r");
	
	});


/***/ },
/* 145 */,
/* 146 */,
/* 147 */,
/* 148 */,
/* 149 */,
/* 150 */,
/* 151 */,
/* 152 */,
/* 153 */,
/* 154 */,
/* 155 */,
/* 156 */,
/* 157 */,
/* 158 */,
/* 159 */,
/* 160 */,
/* 161 */,
/* 162 */,
/* 163 */,
/* 164 */,
/* 165 */,
/* 166 */,
/* 167 */,
/* 168 */,
/* 169 */,
/* 170 */,
/* 171 */,
/* 172 */,
/* 173 */,
/* 174 */,
/* 175 */,
/* 176 */,
/* 177 */,
/* 178 */,
/* 179 */,
/* 180 */,
/* 181 */,
/* 182 */,
/* 183 */,
/* 184 */,
/* 185 */,
/* 186 */,
/* 187 */,
/* 188 */,
/* 189 */,
/* 190 */,
/* 191 */,
/* 192 */,
/* 193 */,
/* 194 */,
/* 195 */,
/* 196 */,
/* 197 */,
/* 198 */,
/* 199 */,
/* 200 */,
/* 201 */,
/* 202 */,
/* 203 */,
/* 204 */,
/* 205 */,
/* 206 */,
/* 207 */,
/* 208 */,
/* 209 */,
/* 210 */,
/* 211 */,
/* 212 */,
/* 213 */,
/* 214 */,
/* 215 */,
/* 216 */,
/* 217 */,
/* 218 */,
/* 219 */,
/* 220 */,
/* 221 */,
/* 222 */,
/* 223 */,
/* 224 */,
/* 225 */,
/* 226 */,
/* 227 */,
/* 228 */,
/* 229 */,
/* 230 */,
/* 231 */,
/* 232 */,
/* 233 */,
/* 234 */,
/* 235 */,
/* 236 */,
/* 237 */,
/* 238 */,
/* 239 */,
/* 240 */,
/* 241 */,
/* 242 */,
/* 243 */,
/* 244 */,
/* 245 */,
/* 246 */,
/* 247 */,
/* 248 */,
/* 249 */,
/* 250 */,
/* 251 */,
/* 252 */,
/* 253 */,
/* 254 */,
/* 255 */,
/* 256 */,
/* 257 */,
/* 258 */,
/* 259 */,
/* 260 */,
/* 261 */,
/* 262 */,
/* 263 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var CodeMirror = __webpack_require__(130);
	var widget_1 = __webpack_require__(264);
	var phosphor_signaling_1 = __webpack_require__(22);
	/**
	 * The key code for the up arrow key.
	 */
	var UP_ARROW = 38;
	/**
	 * The key code for the down arrow key.
	 */
	var DOWN_ARROW = 40;
	/**
	 * The key code for the tab key.
	 */
	var TAB = 9;
	/**
	 * The class name added to cell editor widget nodes.
	 */
	var CELL_EDITOR_CLASS = 'jp-CellEditor';
	/**
	 * A widget for a cell editor.
	 */
	var CellEditorWidget = (function (_super) {
	    __extends(CellEditorWidget, _super);
	    /**
	     * Construct a new cell editor widget.
	     */
	    function CellEditorWidget(model) {
	        var _this = this;
	        _super.call(this);
	        this._model = null;
	        this.addClass(CELL_EDITOR_CLASS);
	        this._model = model;
	        var editor = this.editor;
	        var doc = editor.getDoc();
	        if (model.source) {
	            doc.setValue(model.source);
	        }
	        CodeMirror.on(doc, 'change', function (instance, change) {
	            _this.onDocChange(instance, change);
	        });
	        CodeMirror.on(editor, 'keydown', function (instance, evt) {
	            _this.onEditorKeydown(instance, evt);
	        });
	        model.stateChanged.connect(this.onModelChanged, this);
	    }
	    Object.defineProperty(CellEditorWidget.prototype, "edgeRequested", {
	        /**
	         * A signal emitted when either the top or bottom edge is requested.
	         */
	        get: function () {
	            return Private.edgeRequestedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CellEditorWidget.prototype, "textChanged", {
	        /**
	         * A signal emitted when a text change is completed.
	         */
	        get: function () {
	            return Private.textChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CellEditorWidget.prototype, "completionRequested", {
	        /**
	         * A signal emitted when a tab (text) completion is requested.
	         */
	        get: function () {
	            return Private.completionRequestedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CellEditorWidget.prototype, "model", {
	        /**
	         * Get the cell model used by the editor.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._model;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the editor.
	     */
	    CellEditorWidget.prototype.dispose = function () {
	        this._model = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Get the current cursor position of the editor.
	     */
	    CellEditorWidget.prototype.getCursorPosition = function () {
	        var doc = this.editor.getDoc();
	        var position = doc.getCursor();
	        return doc.indexFromPos(position);
	    };
	    /**
	     * Set the current cursor position of the editor.
	     */
	    CellEditorWidget.prototype.setCursorPosition = function (position) {
	        var doc = this.editor.getDoc();
	        doc.setCursor(doc.posFromIndex(position));
	    };
	    /**
	     * Handle changes in the model.
	     */
	    CellEditorWidget.prototype.onModelChanged = function (model, args) {
	        switch (args.name) {
	            case 'source':
	                var doc = this.editor.getDoc();
	                if (doc.getValue() !== args.newValue) {
	                    doc.setValue(args.newValue);
	                }
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle change events from the document.
	     */
	    CellEditorWidget.prototype.onDocChange = function (doc, change) {
	        if (change.origin === 'setValue') {
	            return;
	        }
	        var model = this.model;
	        var editor = this.editor;
	        var oldValue = model.source;
	        var newValue = doc.getValue();
	        if (oldValue === newValue) {
	            return;
	        }
	        model.source = newValue;
	        var cursor = doc.getCursor();
	        var line = cursor.line;
	        var ch = cursor.ch;
	        var chHeight = editor.defaultTextHeight();
	        var chWidth = editor.defaultCharWidth();
	        var coords = editor.charCoords({ line: line, ch: ch }, 'page');
	        this.textChanged.emit({
	            line: line, ch: ch, chHeight: chHeight, chWidth: chWidth, coords: coords, oldValue: oldValue, newValue: newValue
	        });
	    };
	    /**
	     * Handle keydown events from the editor.
	     */
	    CellEditorWidget.prototype.onEditorKeydown = function (editor, event) {
	        var doc = editor.getDoc();
	        var cursor = doc.getCursor();
	        var line = cursor.line;
	        var ch = cursor.ch;
	        if (event.keyCode === TAB) {
	            return this.onTabEvent(event, ch, line);
	        }
	        if (line === 0 && ch === 0 && event.keyCode === UP_ARROW) {
	            this.edgeRequested.emit('top');
	            return;
	        }
	        var lastLine = doc.lastLine();
	        var lastCh = doc.getLineHandle(lastLine).text.length;
	        if (line === lastLine && ch === lastCh && event.keyCode === DOWN_ARROW) {
	            this.edgeRequested.emit('bottom');
	            return;
	        }
	    };
	    /**
	     * Handle a tab key press.
	     */
	    CellEditorWidget.prototype.onTabEvent = function (event, ch, line) {
	        var editor = this.editor;
	        var currentValue = editor.getDoc().getValue();
	        var currentLine = currentValue.split('\n')[line];
	        var chHeight = editor.defaultTextHeight();
	        var chWidth = editor.defaultCharWidth();
	        var coords = editor.charCoords({ line: line, ch: ch }, 'page');
	        // A completion request signal should only be emitted if the final
	        // character of the current line is not whitespace. Otherwise, the
	        // default tab action of creating a tab character should be allowed to
	        // propagate.
	        if (currentLine.match(/\S$/)) {
	            var data = { line: line, ch: ch, chHeight: chHeight, chWidth: chWidth, coords: coords, currentValue: currentValue };
	            this.completionRequested.emit(data);
	            event.preventDefault();
	            event.stopPropagation();
	        }
	    };
	    return CellEditorWidget;
	}(widget_1.CodeMirrorWidget));
	exports.CellEditorWidget = CellEditorWidget;
	/**
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when either the top or bottom edge is requested.
	     */
	    Private.edgeRequestedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when a text change is completed.
	     */
	    Private.textChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when a tab (text) completion is requested.
	     */
	    Private.completionRequestedSignal = new phosphor_signaling_1.Signal();
	})(Private || (Private = {}));


/***/ },
/* 264 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var CodeMirror = __webpack_require__(130);
	__webpack_require__(132);
	__webpack_require__(265);
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * The class name added to CodeMirrorWidget instances.
	 */
	var EDITOR_CLASS = 'jp-CodeMirrorWidget';
	/**
	 * A widget which hosts a CodeMirror editor.
	 */
	var CodeMirrorWidget = (function (_super) {
	    __extends(CodeMirrorWidget, _super);
	    /**
	     * Construct a CodeMirror widget.
	     */
	    function CodeMirrorWidget(options) {
	        _super.call(this);
	        this._editor = null;
	        this._needsRefresh = true;
	        this.addClass(EDITOR_CLASS);
	        this._editor = CodeMirror(this.node, options);
	    }
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    CodeMirrorWidget.prototype.dispose = function () {
	        this._editor = null;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(CodeMirrorWidget.prototype, "editor", {
	        /**
	         * Get the editor wrapped by the widget.
	         *
	         * #### Notes
	         * This is a ready-only property.
	         */
	        get: function () {
	            return this._editor;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    CodeMirrorWidget.prototype.onAfterAttach = function (msg) {
	        if (!this.isVisible) {
	            this._needsRefresh = true;
	            return;
	        }
	        this._editor.refresh();
	        this._needsRefresh = false;
	    };
	    /**
	     * A message handler invoked on an `'after-show'` message.
	     */
	    CodeMirrorWidget.prototype.onAfterShow = function (msg) {
	        if (this._needsRefresh) {
	            this._editor.refresh();
	            this._needsRefresh = false;
	        }
	    };
	    /**
	     * A message handler invoked on an `'resize'` message.
	     */
	    CodeMirrorWidget.prototype.onResize = function (msg) {
	        if (msg.width < 0 || msg.height < 0) {
	            this._editor.refresh();
	        }
	        else {
	            this._editor.setSize(msg.width, msg.height);
	        }
	        this._needsRefresh = false;
	    };
	    return CodeMirrorWidget;
	}(phosphor_widget_1.Widget));
	exports.CodeMirrorWidget = CodeMirrorWidget;


/***/ },
/* 265 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(266);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../css-loader/index.js!./codemirror.css", function() {
				var newContent = require("!!./../../css-loader/index.js!./codemirror.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 266 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/* BASICS */\n\n.CodeMirror {\n  /* Set height, width, borders, and global font properties here */\n  font-family: monospace;\n  height: 300px;\n  color: black;\n}\n\n/* PADDING */\n\n.CodeMirror-lines {\n  padding: 4px 0; /* Vertical padding around content */\n}\n.CodeMirror pre {\n  padding: 0 4px; /* Horizontal padding of content */\n}\n\n.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {\n  background-color: white; /* The little square between H and V scrollbars */\n}\n\n/* GUTTER */\n\n.CodeMirror-gutters {\n  border-right: 1px solid #ddd;\n  background-color: #f7f7f7;\n  white-space: nowrap;\n}\n.CodeMirror-linenumbers {}\n.CodeMirror-linenumber {\n  padding: 0 3px 0 5px;\n  min-width: 20px;\n  text-align: right;\n  color: #999;\n  white-space: nowrap;\n}\n\n.CodeMirror-guttermarker { color: black; }\n.CodeMirror-guttermarker-subtle { color: #999; }\n\n/* CURSOR */\n\n.CodeMirror-cursor {\n  border-left: 1px solid black;\n  border-right: none;\n  width: 0;\n}\n/* Shown when moving in bi-directional text */\n.CodeMirror div.CodeMirror-secondarycursor {\n  border-left: 1px solid silver;\n}\n.cm-fat-cursor .CodeMirror-cursor {\n  width: auto;\n  border: 0 !important;\n  background: #7e7;\n}\n.cm-fat-cursor div.CodeMirror-cursors {\n  z-index: 1;\n}\n\n.cm-animate-fat-cursor {\n  width: auto;\n  border: 0;\n  -webkit-animation: blink 1.06s steps(1) infinite;\n  -moz-animation: blink 1.06s steps(1) infinite;\n  animation: blink 1.06s steps(1) infinite;\n  background-color: #7e7;\n}\n@-moz-keyframes blink {\n  0% {}\n  50% { background-color: transparent; }\n  100% {}\n}\n@-webkit-keyframes blink {\n  0% {}\n  50% { background-color: transparent; }\n  100% {}\n}\n@keyframes blink {\n  0% {}\n  50% { background-color: transparent; }\n  100% {}\n}\n\n/* Can style cursor different in overwrite (non-insert) mode */\n.CodeMirror-overwrite .CodeMirror-cursor {}\n\n.cm-tab { display: inline-block; text-decoration: inherit; }\n\n.CodeMirror-ruler {\n  border-left: 1px solid #ccc;\n  position: absolute;\n}\n\n/* DEFAULT THEME */\n\n.cm-s-default .cm-header {color: blue;}\n.cm-s-default .cm-quote {color: #090;}\n.cm-negative {color: #d44;}\n.cm-positive {color: #292;}\n.cm-header, .cm-strong {font-weight: bold;}\n.cm-em {font-style: italic;}\n.cm-link {text-decoration: underline;}\n.cm-strikethrough {text-decoration: line-through;}\n\n.cm-s-default .cm-keyword {color: #708;}\n.cm-s-default .cm-atom {color: #219;}\n.cm-s-default .cm-number {color: #164;}\n.cm-s-default .cm-def {color: #00f;}\n.cm-s-default .cm-variable,\n.cm-s-default .cm-punctuation,\n.cm-s-default .cm-property,\n.cm-s-default .cm-operator {}\n.cm-s-default .cm-variable-2 {color: #05a;}\n.cm-s-default .cm-variable-3 {color: #085;}\n.cm-s-default .cm-comment {color: #a50;}\n.cm-s-default .cm-string {color: #a11;}\n.cm-s-default .cm-string-2 {color: #f50;}\n.cm-s-default .cm-meta {color: #555;}\n.cm-s-default .cm-qualifier {color: #555;}\n.cm-s-default .cm-builtin {color: #30a;}\n.cm-s-default .cm-bracket {color: #997;}\n.cm-s-default .cm-tag {color: #170;}\n.cm-s-default .cm-attribute {color: #00c;}\n.cm-s-default .cm-hr {color: #999;}\n.cm-s-default .cm-link {color: #00c;}\n\n.cm-s-default .cm-error {color: #f00;}\n.cm-invalidchar {color: #f00;}\n\n.CodeMirror-composing { border-bottom: 2px solid; }\n\n/* Default styles for common addons */\n\ndiv.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}\ndiv.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}\n.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }\n.CodeMirror-activeline-background {background: #e8f2ff;}\n\n/* STOP */\n\n/* The rest of this file contains styles related to the mechanics of\n   the editor. You probably shouldn't touch them. */\n\n.CodeMirror {\n  position: relative;\n  overflow: hidden;\n  background: white;\n}\n\n.CodeMirror-scroll {\n  overflow: scroll !important; /* Things will break if this is overridden */\n  /* 30px is the magic margin used to hide the element's real scrollbars */\n  /* See overflow: hidden in .CodeMirror */\n  margin-bottom: -30px; margin-right: -30px;\n  padding-bottom: 30px;\n  height: 100%;\n  outline: none; /* Prevent dragging from highlighting the element */\n  position: relative;\n}\n.CodeMirror-sizer {\n  position: relative;\n  border-right: 30px solid transparent;\n}\n\n/* The fake, visible scrollbars. Used to force redraw during scrolling\n   before actual scrolling happens, thus preventing shaking and\n   flickering artifacts. */\n.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {\n  position: absolute;\n  z-index: 6;\n  display: none;\n}\n.CodeMirror-vscrollbar {\n  right: 0; top: 0;\n  overflow-x: hidden;\n  overflow-y: scroll;\n}\n.CodeMirror-hscrollbar {\n  bottom: 0; left: 0;\n  overflow-y: hidden;\n  overflow-x: scroll;\n}\n.CodeMirror-scrollbar-filler {\n  right: 0; bottom: 0;\n}\n.CodeMirror-gutter-filler {\n  left: 0; bottom: 0;\n}\n\n.CodeMirror-gutters {\n  position: absolute; left: 0; top: 0;\n  min-height: 100%;\n  z-index: 3;\n}\n.CodeMirror-gutter {\n  white-space: normal;\n  height: 100%;\n  display: inline-block;\n  vertical-align: top;\n  margin-bottom: -30px;\n  /* Hack to make IE7 behave */\n  *zoom:1;\n  *display:inline;\n}\n.CodeMirror-gutter-wrapper {\n  position: absolute;\n  z-index: 4;\n  background: none !important;\n  border: none !important;\n}\n.CodeMirror-gutter-background {\n  position: absolute;\n  top: 0; bottom: 0;\n  z-index: 4;\n}\n.CodeMirror-gutter-elt {\n  position: absolute;\n  cursor: default;\n  z-index: 4;\n}\n.CodeMirror-gutter-wrapper {\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  user-select: none;\n}\n\n.CodeMirror-lines {\n  cursor: text;\n  min-height: 1px; /* prevents collapsing before first draw */\n}\n.CodeMirror pre {\n  /* Reset some styles that the rest of the page might have set */\n  -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;\n  border-width: 0;\n  background: transparent;\n  font-family: inherit;\n  font-size: inherit;\n  margin: 0;\n  white-space: pre;\n  word-wrap: normal;\n  line-height: inherit;\n  color: inherit;\n  z-index: 2;\n  position: relative;\n  overflow: visible;\n  -webkit-tap-highlight-color: transparent;\n  -webkit-font-variant-ligatures: none;\n  font-variant-ligatures: none;\n}\n.CodeMirror-wrap pre {\n  word-wrap: break-word;\n  white-space: pre-wrap;\n  word-break: normal;\n}\n\n.CodeMirror-linebackground {\n  position: absolute;\n  left: 0; right: 0; top: 0; bottom: 0;\n  z-index: 0;\n}\n\n.CodeMirror-linewidget {\n  position: relative;\n  z-index: 2;\n  overflow: auto;\n}\n\n.CodeMirror-widget {}\n\n.CodeMirror-code {\n  outline: none;\n}\n\n/* Force content-box sizing for the elements where we expect it */\n.CodeMirror-scroll,\n.CodeMirror-sizer,\n.CodeMirror-gutter,\n.CodeMirror-gutters,\n.CodeMirror-linenumber {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n}\n\n.CodeMirror-measure {\n  position: absolute;\n  width: 100%;\n  height: 0;\n  overflow: hidden;\n  visibility: hidden;\n}\n\n.CodeMirror-cursor { position: absolute; }\n.CodeMirror-measure pre { position: static; }\n\ndiv.CodeMirror-cursors {\n  visibility: hidden;\n  position: relative;\n  z-index: 3;\n}\ndiv.CodeMirror-dragcursors {\n  visibility: visible;\n}\n\n.CodeMirror-focused div.CodeMirror-cursors {\n  visibility: visible;\n}\n\n.CodeMirror-selected { background: #d9d9d9; }\n.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }\n.CodeMirror-crosshair { cursor: crosshair; }\n.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }\n.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }\n\n.cm-searching {\n  background: #ffa;\n  background: rgba(255, 255, 0, .4);\n}\n\n/* IE7 hack to prevent it from returning funny offsetTops on the spans */\n.CodeMirror span { *vertical-align: text-bottom; }\n\n/* Used to force a border model for a node */\n.cm-force-border { padding-right: .1px; }\n\n@media print {\n  /* Hide the cursor when printing */\n  .CodeMirror div.CodeMirror-cursors {\n    visibility: hidden;\n  }\n}\n\n/* See issue #2901 */\n.cm-tab-wrap-hack:after { content: ''; }\n\n/* Help users use markselection to safely style text background */\nspan.CodeMirror-selectedtext { background: none; }\n", ""]);
	
	// exports


/***/ },
/* 267 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var CodeMirror = __webpack_require__(130);
	__webpack_require__(132);
	/**
	 * Get the appropriate codemirror mimetype given language info.
	 */
	function mimetypeForLanguage(info) {
	    // Use the codemirror mode if given since some kernels rely on it.
	    var mode = info.codemirror_mode;
	    var mime = 'text/plain';
	    if (mode) {
	        if (typeof mode === 'string') {
	            mode = CodeMirror.findModeByName(mode);
	        }
	        else if (mode.mime) {
	        }
	        else if (mode.name) {
	            var name_1 = mode.name;
	            mode = CodeMirror.findModeByName(name_1);
	        }
	        if (mode) {
	            mime = mode.mime;
	        }
	    }
	    else if (info.mimetype) {
	        mime = info.mimetype;
	    }
	    return mime;
	}
	exports.mimetypeForLanguage = mimetypeForLanguage;


/***/ },
/* 268 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * The class name added to tooltip widgets.
	 */
	var TOOLTIP_CLASS = 'jp-ConsoleTooltip';
	/**
	 * A tooltip widget for a console.
	 */
	var ConsoleTooltip = (function (_super) {
	    __extends(ConsoleTooltip, _super);
	    /**
	     * Construct a console tooltip widget.
	     */
	    function ConsoleTooltip() {
	        _super.call(this);
	        this._reference = null;
	        this._content = null;
	        this.addClass(TOOLTIP_CLASS);
	        this.layout = new phosphor_panel_1.PanelLayout();
	        this.hide();
	    }
	    Object.defineProperty(ConsoleTooltip.prototype, "reference", {
	        /**
	         * The semantic parent of the tooltip, its reference widget.
	         */
	        get: function () {
	            return this._reference;
	        },
	        set: function (widget) {
	            this._reference = widget;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ConsoleTooltip.prototype, "content", {
	        /**
	         * The text of the tooltip.
	         */
	        get: function () {
	            return this._content;
	        },
	        set: function (newValue) {
	            if (newValue === this._content) {
	                return;
	            }
	            if (this._content) {
	                this._content.dispose();
	            }
	            this._content = newValue;
	            if (this._content) {
	                var layout = this.layout;
	                layout.addChild(this._content);
	            }
	        },
	        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 dock panel's node. It should
	     * not be called directly by user code.
	     */
	    ConsoleTooltip.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'keydown':
	                this._evtKeydown(event);
	                break;
	            case 'mousedown':
	                this._evtMousedown(event);
	                break;
	            case 'scroll':
	                this._evtScroll(event);
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle `after_attach` messages for the widget.
	     *
	     * #### Notes
	     * Captures window events in capture phase to dismiss the tooltip widget.
	     *
	     * Because its parent (reference) widgets use window listeners instead of
	     * document listeners, the tooltip widget must also use window listeners
	     * in the capture phase.
	     */
	    ConsoleTooltip.prototype.onAfterAttach = function (msg) {
	        window.addEventListener('keydown', this, true);
	        window.addEventListener('mousedown', this, true);
	        window.addEventListener('scroll', this, true);
	    };
	    /**
	     * Handle `before_detach` messages for the widget.
	     */
	    ConsoleTooltip.prototype.onBeforeDetach = function (msg) {
	        window.removeEventListener('keydown', this);
	        window.removeEventListener('mousedown', this);
	        window.removeEventListener('scroll', this);
	    };
	    /**
	     * Handle `update_request` messages.
	     */
	    ConsoleTooltip.prototype.onUpdateRequest = function (msg) {
	        this.show();
	    };
	    /**
	     * Handle keydown events for the widget.
	     *
	     * #### Notes
	     * Hides the tooltip if a keydown happens anywhere on the document outside
	     * of either the tooltip or its parent.
	     */
	    ConsoleTooltip.prototype._evtKeydown = function (event) {
	        var target = event.target;
	        if (!this._reference) {
	            this.hide();
	            return;
	        }
	        if (this.isHidden) {
	            return;
	        }
	        while (target !== document.documentElement) {
	            if (target === this._reference.node) {
	                if (event.keyCode === 27) {
	                    this.hide();
	                }
	                return;
	            }
	            target = target.parentElement;
	        }
	        this.hide();
	    };
	    /**
	     * Handle mousedown events for the widget.
	     *
	     * #### Notes
	     * Hides the tooltip if a mousedown happens anywhere outside the tooltip.
	     */
	    ConsoleTooltip.prototype._evtMousedown = function (event) {
	        var target = event.target;
	        while (target !== document.documentElement) {
	            if (target === this.node) {
	                return;
	            }
	            target = target.parentElement;
	        }
	        this.hide();
	    };
	    /**
	     * Handle scroll events for the widget
	     */
	    ConsoleTooltip.prototype._evtScroll = function (event) {
	        if (!this._reference || this.isHidden) {
	            this.hide();
	            return;
	        }
	        var target = event.target;
	        while (target !== document.documentElement) {
	            // If the scroll event happened in the tooltip widget, allow it.
	            if (target === this.node) {
	                return;
	            }
	            target = target.parentElement;
	        }
	        this.hide();
	    };
	    return ConsoleTooltip;
	}(phosphor_widget_1.Widget));
	exports.ConsoleTooltip = ConsoleTooltip;


/***/ },
/* 269 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var phosphor_signaling_1 = __webpack_require__(22);
	/**
	 * A console history manager object.
	 */
	var ConsoleHistory = (function () {
	    /**
	     * Construct a new console history object.
	     */
	    function ConsoleHistory(kernel) {
	        this._cursor = 0;
	        this._history = null;
	        this._kernel = null;
	        this._history = [];
	        if (kernel) {
	            this.kernel = kernel;
	        }
	    }
	    Object.defineProperty(ConsoleHistory.prototype, "isDisposed", {
	        /**
	         * Get whether the console history manager is disposed.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._history === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ConsoleHistory.prototype, "kernel", {
	        /**
	         * The current kernel supplying navigation history.
	         */
	        get: function () {
	            return this._kernel;
	        },
	        set: function (newValue) {
	            var _this = this;
	            if (newValue === this._kernel) {
	                return;
	            }
	            var contents = Private.initialRequest;
	            this._kernel = newValue;
	            this._kernel.history(contents).then(function (value) {
	                _this._history = [];
	                var last = '';
	                var current = '';
	                for (var i = 0; i < value.history.length; i++) {
	                    // History entries have the shape:
	                    // [session: number, line: number, input: string]
	                    // Contiguous duplicates are stripped out of the API response.
	                    current = value.history[i][2];
	                    if (current !== last) {
	                        _this._history.push(last = current);
	                    }
	                }
	                // Reset the history navigation cursor back to the bottom.
	                _this._cursor = _this._history.length;
	            });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the previous item in the console history.
	     *
	     * @returns A Promise for console command text or `undefined` if unavailable.
	     */
	    ConsoleHistory.prototype.back = function () {
	        var content = this._history[--this._cursor];
	        this._cursor = Math.max(0, this._cursor);
	        return Promise.resolve(content);
	    };
	    /**
	     * Dispose of the resources held by the console history manager.
	     */
	    ConsoleHistory.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        phosphor_signaling_1.clearSignalData(this);
	        this._history.length = 0;
	        this._history = null;
	    };
	    /**
	     * Get the next item in the console history.
	     *
	     * @returns A Promise for console command text or `undefined` if unavailable.
	     */
	    ConsoleHistory.prototype.forward = function () {
	        var content = this._history[++this._cursor];
	        this._cursor = Math.min(this._history.length, this._cursor);
	        return Promise.resolve(content);
	    };
	    /**
	     * Add a new item to the bottom of history.
	     *
	     * @param item The item being added to the bottom of history.
	     *
	     * #### Notes
	     * If the item being added is undefined or empty, it is ignored. If the item
	     * being added is the same as the last item in history, it is ignored as well
	     * so that the console's history will consist of no contiguous repetitions.
	     * This behavior varies from some shells, but the Jupyter Qt Console is
	     * implemented this way.
	     */
	    ConsoleHistory.prototype.push = function (item) {
	        if (item && item !== this._history[this._history.length - 1]) {
	            this._history.push(item);
	        }
	        // Reset the history navigation cursor back to the bottom.
	        this._cursor = this._history.length;
	    };
	    return ConsoleHistory;
	}());
	exports.ConsoleHistory = ConsoleHistory;
	/**
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    Private.initialRequest = {
	        output: false,
	        raw: true,
	        hist_access_type: 'tail',
	        n: 500
	    };
	})(Private || (Private = {}));


/***/ },
/* 270 */
/***/ function(module, exports, __webpack_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];
	}
	__export(__webpack_require__(271));
	__export(__webpack_require__(272));


/***/ },
/* 271 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var phosphor_signaling_1 = __webpack_require__(22);
	/**
	 * An implementation of a completion model.
	 */
	var CompletionModel = (function () {
	    function CompletionModel() {
	        this._isDisposed = false;
	        this._options = null;
	        this._original = null;
	        this._current = null;
	        this._query = '';
	        this._cursor = null;
	    }
	    Object.defineProperty(CompletionModel.prototype, "isDisposed", {
	        /**
	         * Get whether the model is disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CompletionModel.prototype, "stateChanged", {
	        /**
	         * A signal emitted when state of the completion menu changes.
	         */
	        get: function () {
	            return Private.stateChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CompletionModel.prototype, "cursor", {
	        /**
	         * The cursor details that the API has used to return matching options.
	         */
	        get: function () {
	            return this._cursor;
	        },
	        set: function (cursor) {
	            this._cursor = cursor;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CompletionModel.prototype, "items", {
	        /**
	         * The list of visible items in the completion menu.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._filter();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CompletionModel.prototype, "options", {
	        /**
	         * The unfiltered list of all available options in a completion menu.
	         */
	        get: function () {
	            return this._options;
	        },
	        set: function (newValue) {
	            if (newValue) {
	                this._options = [];
	                (_a = this._options).push.apply(_a, newValue);
	            }
	            else {
	                this._options = null;
	            }
	            this.stateChanged.emit(void 0);
	            var _a;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CompletionModel.prototype, "original", {
	        /**
	         * The original completion request details.
	         */
	        get: function () {
	            return this._original;
	        },
	        set: function (request) {
	            this._original = request;
	            this._current = null;
	            this.stateChanged.emit(void 0);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CompletionModel.prototype, "current", {
	        /**
	         * The current text change details.
	         */
	        get: function () {
	            return this._current;
	        },
	        set: function (newValue) {
	            this._current = newValue;
	            var original = this._original;
	            var current = this._current;
	            var originalLine = original.currentValue.split('\n')[original.line];
	            var currentLine = current.newValue.split('\n')[current.line];
	            // If the text change means that the original start point has been preceded,
	            // then the completion is no longer valid and should be reset.
	            if (currentLine.length < originalLine.length) {
	                console.log('A');
	                this.reset();
	            }
	            else {
	                var _a = this._cursor, start = _a.start, end = _a.end;
	                // Clip the front of the current line.
	                var query = currentLine.substring(start);
	                // Clip the back of the current line.
	                var ending = originalLine.substring(end);
	                query = query.substring(0, query.lastIndexOf(ending));
	                this._query = query;
	            }
	            this.stateChanged.emit(void 0);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create a resolved patch between the original state and a patch string.
	     *
	     * @param patch - The patch string to apply to the original value.
	     *
	     * @returns A patched text change or null if original value did not exist.
	     *
	     * #### Notes
	     * The coords field is set to null because it is calculated by the editor, so
	     * a patched version cannot reliably produce accurate coordinates for the
	     * cursor.
	     */
	    CompletionModel.prototype.createPatch = function (patch) {
	        var original = this._original;
	        var cursor = this._cursor;
	        if (!original || !cursor) {
	            return null;
	        }
	        var start = cursor.start, end = cursor.end;
	        var lines = original.currentValue.split('\n');
	        var line = lines[original.line];
	        var prefix = line.substring(0, start);
	        var suffix = line.substring(end);
	        lines[original.line] = prefix + patch + suffix;
	        var text = lines.join('\n');
	        // Add current line to position.
	        var position = prefix.length + patch.length;
	        // Add all the preceding lines lengths to position.
	        for (var i = 0; i < original.line; i++) {
	            // Add an extra character for the line break.
	            position += lines[i].length + 1;
	        }
	        return { position: position, text: text };
	    };
	    /**
	     * Dispose of the resources held by the model.
	     */
	    CompletionModel.prototype.dispose = function () {
	        // Do nothing if already disposed.
	        if (this.isDisposed) {
	            return;
	        }
	        phosphor_signaling_1.clearSignalData(this);
	        this._isDisposed = true;
	    };
	    /**
	     * Reset the state of the model.
	     */
	    CompletionModel.prototype.reset = function () {
	        this.original = null;
	        this.options = null;
	        this._query = '';
	        this._cursor = null;
	    };
	    /**
	     * Apply the query to the complete options list to return the matching subset.
	     */
	    CompletionModel.prototype._filter = function () {
	        var options = this._options || [];
	        var query = this._query;
	        if (!query) {
	            return options.map(function (option) { return ({ raw: option, text: option }); });
	        }
	        var results = [];
	        for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
	            var option = options_1[_i];
	            var match = StringSearch.sumOfSquares(option, query);
	            if (match) {
	                results.push({
	                    raw: option,
	                    score: match.score,
	                    text: StringSearch.highlight(option, match.indices)
	                });
	            }
	        }
	        return results.sort(function (a, b) { return a.score - b.score; })
	            .map(function (result) { return ({ text: result.text, raw: result.raw }); });
	    };
	    return CompletionModel;
	}());
	exports.CompletionModel = CompletionModel;
	/**
	 * A namespace for completion model private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when state of the completion menu changes.
	     */
	    Private.stateChangedSignal = new phosphor_signaling_1.Signal();
	})(Private || (Private = {}));
	/**
	 * A namespace which holds string searching functionality.
	 *
	 * #### Notes
	 * This functionality comes from phosphor-core and can be removed from this file
	 * once newer versions of phosphor libraries are used throughout
	 * jupyter-js-notebook.
	 */
	var StringSearch;
	(function (StringSearch) {
	    /**
	     * Compute the sum-of-squares match for the given search text.
	     *
	     * @param sourceText - The text which should be searched.
	     *
	     * @param queryText - The query text to locate in the source text.
	     *
	     * @returns The match result object, or `null` if there is no 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 `queryText` **must** appear in `sourceText` 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.
	     *
	     * The character match is performed with strict equality. It is case
	     * sensitive and does not ignore whitespace. If those behaviors are
	     * required, the text should be transformed before scoring.
	     */
	    function sumOfSquares(sourceText, queryText) {
	        var score = 0;
	        var indices = new Array(queryText.length);
	        for (var i = 0, j = 0, n = queryText.length; i < n; ++i, ++j) {
	            j = sourceText.indexOf(queryText[i], j);
	            if (j === -1) {
	                return null;
	            }
	            indices[i] = j;
	            score += j * j;
	        }
	        return { score: score, indices: indices };
	    }
	    StringSearch.sumOfSquares = sumOfSquares;
	    /**
	     * Highlight the matched characters of a source string.
	     *
	     * @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.
	     *
	     * @returns A string with interpolated `<mark>` tags.
	     */
	    function highlight(sourceText, indices) {
	        var k = 0;
	        var last = 0;
	        var result = '';
	        var n = indices.length;
	        while (k < n) {
	            var i = indices[k];
	            var j = indices[k];
	            while (++k < n && indices[k] === j + 1) {
	                j++;
	            }
	            var head = sourceText.slice(last, i);
	            var chunk = sourceText.slice(i, j + 1);
	            result += head + "<mark>" + chunk + "</mark>";
	            last = j + 1;
	        }
	        return result + sourceText.slice(last);
	    }
	    StringSearch.highlight = highlight;
	})(StringSearch || (StringSearch = {}));


/***/ },
/* 272 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_signaling_1 = __webpack_require__(22);
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * The class name added to completion menu widgets.
	 */
	var COMPLETION_CLASS = 'jp-Completion';
	/**
	 * The class name added to completion menu items.
	 */
	var ITEM_CLASS = 'jp-Completion-item';
	/**
	 * The class name added to an active completion menu item.
	 */
	var ACTIVE_CLASS = 'jp-mod-active';
	/**
	 * The maximum height of a completion widget.
	 */
	var MAX_HEIGHT = 250;
	/**
	 * A widget that enables text completion.
	 */
	var CompletionWidget = (function (_super) {
	    __extends(CompletionWidget, _super);
	    /**
	     * Construct a text completion menu widget.
	     */
	    function CompletionWidget(model) {
	        var _this = this;
	        _super.call(this);
	        this._activeIndex = 0;
	        this._model = null;
	        this._reference = null;
	        this._model = model;
	        this._model.stateChanged.connect(function () { return _this.update(); }, this);
	        this.addClass(COMPLETION_CLASS);
	        this.update();
	    }
	    /**
	     * Create the DOM node for a text completion menu.
	     */
	    CompletionWidget.createNode = function () {
	        var node = document.createElement('ul');
	        return node;
	    };
	    /**
	     * Create an item node for a text completion menu.
	     */
	    CompletionWidget.createItemNode = function (item) {
	        var li = document.createElement('li');
	        var code = document.createElement('code');
	        // Set the raw, un-marked up value as a data attribute.
	        li.dataset['value'] = item.raw;
	        // Use innerHTML because search results include <mark> tags.
	        code.innerHTML = item.text;
	        li.className = ITEM_CLASS;
	        li.appendChild(code);
	        return li;
	    };
	    Object.defineProperty(CompletionWidget.prototype, "selected", {
	        /**
	         * A signal emitted when a selection is made from the completion menu.
	         */
	        get: function () {
	            return Private.selectedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CompletionWidget.prototype, "model", {
	        /**
	         * The model used by the completion widget.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._model;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CompletionWidget.prototype, "reference", {
	        /**
	         * The semantic parent of the completion widget, its reference widget.
	         */
	        get: function () {
	            return this._reference;
	        },
	        set: function (widget) {
	            this._reference = widget;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the completion widget.
	     */
	    CompletionWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._model.dispose();
	        this._model = null;
	        phosphor_signaling_1.clearSignalData(this);
	        _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.
	     */
	    CompletionWidget.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'keydown':
	                this._evtKeydown(event);
	                break;
	            case 'mousedown':
	                this._evtMousedown(event);
	                break;
	            case 'scroll':
	                this._evtScroll(event);
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle `after_attach` messages for the widget.
	     *
	     * #### Notes
	     * Captures window events in capture phase to dismiss or navigate the
	     * completion widget.
	     *
	     * Because its parent (reference) widgets use window listeners instead of
	     * document listeners, the completion widget must also use window listeners
	     * in the capture phase.
	     */
	    CompletionWidget.prototype.onAfterAttach = function (msg) {
	        window.addEventListener('keydown', this, true);
	        window.addEventListener('mousedown', this, true);
	        window.addEventListener('scroll', this, true);
	    };
	    /**
	     * Handle `before_detach` messages for the widget.
	     */
	    CompletionWidget.prototype.onBeforeDetach = function (msg) {
	        window.removeEventListener('keydown', this);
	        window.removeEventListener('mousedown', this);
	        window.removeEventListener('scroll', this);
	    };
	    /**
	     * Handle `update_request` messages.
	     */
	    CompletionWidget.prototype.onUpdateRequest = function (msg) {
	        var node = this.node;
	        var items = this._model.items;
	        var constructor = this.constructor;
	        node.textContent = '';
	        // All repaints reset the index back to 0.
	        this._activeIndex = 0;
	        if (!items || !items.length) {
	            this.hide();
	            return;
	        }
	        for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
	            var item = items_1[_i];
	            node.appendChild(constructor.createItemNode(item));
	        }
	        var active = node.querySelectorAll("." + ITEM_CLASS)[this._activeIndex];
	        active.classList.add(ACTIVE_CLASS);
	        if (this.isHidden) {
	            this.show();
	        }
	        var coords = this._model.current ? this._model.current.coords
	            : this._model.original.coords;
	        var availableHeight = coords.top;
	        var maxHeight = Math.min(availableHeight, MAX_HEIGHT);
	        node.style.maxHeight = maxHeight + "px";
	        // Account for 1px border width.
	        var left = Math.floor(coords.left) + 1;
	        var rect = node.getBoundingClientRect();
	        var top = availableHeight - rect.height;
	        node.style.left = left + "px";
	        node.style.top = top + "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) + "px";
	            node.scrollTop = 0;
	        }
	    };
	    /**
	     * Handle mousedown events for the widget.
	     */
	    CompletionWidget.prototype._evtMousedown = function (event) {
	        if (!this._reference || this.isHidden || Private.nonstandardClick(event)) {
	            this.hide();
	            return;
	        }
	        var target = event.target;
	        while (target !== document.documentElement) {
	            // If the user has made a selection, emit its value and reset the model.
	            if (target.classList.contains(ITEM_CLASS)) {
	                event.preventDefault();
	                event.stopPropagation();
	                event.stopImmediatePropagation();
	                this.selected.emit(target.dataset['value']);
	                this._model.reset();
	                return;
	            }
	            // If the mouse event happened anywhere else in the widget, bail.
	            if (target === this.node) {
	                event.preventDefault();
	                event.stopPropagation();
	                event.stopImmediatePropagation();
	                return;
	            }
	            target = target.parentElement;
	        }
	        this._model.reset();
	    };
	    /**
	     * Handle keydown events for the widget.
	     */
	    CompletionWidget.prototype._evtKeydown = function (event) {
	        if (!this._reference || this.isHidden) {
	            this.hide();
	            return;
	        }
	        var target = event.target;
	        var node = this.node;
	        var active;
	        while (target !== document.documentElement) {
	            if (target === this._reference.node) {
	                switch (event.keyCode) {
	                    case 13: // Enter key
	                    case 9:
	                        event.preventDefault();
	                        event.stopPropagation();
	                        event.stopImmediatePropagation();
	                        active = node.querySelector("." + ACTIVE_CLASS);
	                        this.selected.emit(active.dataset['value']);
	                        this._model.reset();
	                        return;
	                    case 27:
	                        event.preventDefault();
	                        event.stopPropagation();
	                        event.stopImmediatePropagation();
	                        this._model.reset();
	                        return;
	                    case 38: // Up arrow key
	                    case 40:
	                        event.preventDefault();
	                        event.stopPropagation();
	                        event.stopImmediatePropagation();
	                        var items = this.node.querySelectorAll("." + ITEM_CLASS);
	                        active = node.querySelector("." + ACTIVE_CLASS);
	                        active.classList.remove(ACTIVE_CLASS);
	                        this._activeIndex = event.keyCode === 38 ?
	                            Math.max(--this._activeIndex, 0)
	                            : Math.min(++this._activeIndex, items.length - 1);
	                        active = items[this._activeIndex];
	                        active.classList.add(ACTIVE_CLASS);
	                        Private.scrollIfNeeded(this.node, active);
	                        return;
	                    default:
	                        return;
	                }
	            }
	            target = target.parentElement;
	        }
	        this.hide();
	    };
	    /**
	     * Handle scroll events for the widget
	     */
	    CompletionWidget.prototype._evtScroll = function (event) {
	        if (!this._reference || this.isHidden) {
	            this.hide();
	            return;
	        }
	        var target = event.target;
	        while (target !== document.documentElement) {
	            // If the scroll event happened in the completion widget, allow it.
	            if (target === this.node) {
	                return;
	            }
	            target = target.parentElement;
	        }
	        this.hide();
	    };
	    return CompletionWidget;
	}(phosphor_widget_1.Widget));
	exports.CompletionWidget = CompletionWidget;
	/**
	 * A namespace for completion widget private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when state of the completion menu changes.
	     */
	    Private.selectedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * Returns true for any modified click event (i.e., not a left-click).
	     */
	    function nonstandardClick(event) {
	        return event.button !== 0 ||
	            event.altKey ||
	            event.ctrlKey ||
	            event.shiftKey ||
	            event.metaKey;
	    }
	    Private.nonstandardClick = nonstandardClick;
	    /**
	     * Scroll an element into view if needed.
	     *
	     * @param area - The scroll area element.
	     *
	     * @param elem - The element of interest.
	     */
	    function scrollIfNeeded(area, elem) {
	        var ar = area.getBoundingClientRect();
	        var er = elem.getBoundingClientRect();
	        if (er.top < ar.top - 10) {
	            area.scrollTop -= ar.top - er.top + 10;
	        }
	        else if (er.bottom > ar.bottom + 10) {
	            area.scrollTop += er.bottom - ar.bottom + 10;
	        }
	    }
	    Private.scrollIfNeeded = scrollIfNeeded;
	})(Private || (Private = {}));


/***/ },
/* 273 */
/***/ function(module, exports) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	/**
	 * A composite renderer.
	 *
	 * #### Notes
	 * When rendering a mimebundle, a mimetype is selected from the mimetypes by
	 * searching through the `this.order` list. The first mimetype found in the bundle
	 * determines the renderer that will be used.
	 *
	 * You can add a renderer by adding it to the `renderers` object and registering
	 * the mimetype in the `order` array.
	 */
	var RenderMime = (function () {
	    /**
	     * Construct a renderer.
	     *
	     * @param renderers - a map of mimetypes to renderers.
	     * @param order - a list of mimetypes in order of precedence (earliest one has precedence).
	     */
	    function RenderMime(renderers, order) {
	        this._renderers = {};
	        for (var i in renderers) {
	            this._renderers[i] = renderers[i];
	        }
	        this._order = order.slice();
	    }
	    /**
	     * Render a mimebundle.
	     *
	     * @param bundle - the mimebundle to render.
	     */
	    RenderMime.prototype.render = function (bundle) {
	        var mimetype = this.preferredMimetype(bundle);
	        if (mimetype) {
	            return this._renderers[mimetype].render(mimetype, bundle[mimetype]);
	        }
	    };
	    /**
	     * Find the preferred mimetype in a mimebundle.
	     *
	     * @param bundle - the mimebundle giving available mimetype content.
	     */
	    RenderMime.prototype.preferredMimetype = function (bundle) {
	        for (var _i = 0, _a = this.order; _i < _a.length; _i++) {
	            var m = _a[_i];
	            if (bundle.hasOwnProperty(m)) {
	                return m;
	            }
	        }
	    };
	    /**
	     * Clone the rendermime instance with shallow copies of data.
	     */
	    RenderMime.prototype.clone = function () {
	        return new RenderMime(this._renderers, this.order);
	    };
	    /**
	     * Get a renderer by mimetype.
	     */
	    RenderMime.prototype.getRenderer = function (mimetype) {
	        return this._renderers[mimetype];
	    };
	    /**
	     * Add a renderer by mimetype.
	     *
	     * @param mimetype - The mimetype of the renderer.
	     * @param renderer - The renderer instance.
	     * @param index - The optional order index.
	     *
	     * ####Notes
	     * Negative indices count from the end, so -1 refers to the penultimate 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.
	     */
	    RenderMime.prototype.addRenderer = function (mimetype, renderer, index) {
	        if (index === void 0) { index = 0; }
	        this._renderers[mimetype] = renderer;
	        this._order.splice(index, 0, mimetype);
	    };
	    /**
	     * Remove a renderer by mimetype.
	     */
	    RenderMime.prototype.removeRenderer = function (mimetype) {
	        delete this._renderers[mimetype];
	        var index = this._order.indexOf(mimetype);
	        if (index !== -1) {
	            this._order.splice(index, 1);
	        }
	    };
	    Object.defineProperty(RenderMime.prototype, "order", {
	        /**
	         * Get the ordered list of mimetypes.
	         *
	         * #### Notes
	         * These mimetypes are searched from beginning to end, and the first matching
	         * mimetype is used.
	         */
	        get: function () {
	            return this._order.slice();
	        },
	        /**
	         * Set the ordered list of mimetypes.
	         */
	        set: function (value) {
	            this._order = value.slice();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return RenderMime;
	}());
	exports.RenderMime = RenderMime;


/***/ },
/* 274 */
/***/ function(module, exports, __webpack_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];
	}
	__export(__webpack_require__(275));
	__export(__webpack_require__(276));
	__export(__webpack_require__(277));
	__export(__webpack_require__(278));
	__export(__webpack_require__(279));
	__export(__webpack_require__(281));


/***/ },
/* 275 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var CodeMirror = __webpack_require__(130);
	var phosphor_signaling_1 = __webpack_require__(22);
	/**
	 * The default implementation of a document model.
	 */
	var DocumentModel = (function () {
	    /**
	     * Construct a new document model.
	     */
	    function DocumentModel(languagePreference) {
	        this._text = '';
	        this._defaultLang = '';
	        this._dirty = false;
	        this._readOnly = false;
	        this._isDisposed = false;
	        this._defaultLang = languagePreference;
	    }
	    Object.defineProperty(DocumentModel.prototype, "isDisposed", {
	        /**
	         * Get whether the model factory has been disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentModel.prototype, "contentChanged", {
	        /**
	         * A signal emitted when the document content changes.
	         */
	        get: function () {
	            return Private.contentChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentModel.prototype, "stateChanged", {
	        /**
	         * A signal emitted when the document state changes.
	         */
	        get: function () {
	            return Private.stateChangedSignal.bind(this);
	        },
	        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.stateChanged.emit({ 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.stateChanged.emit({ 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
	    });
	    /**
	     * Dispose of the resources held by the document manager.
	     */
	    DocumentModel.prototype.dispose = function () {
	        this._isDisposed = true;
	    };
	    /**
	     * Serialize the model to a string.
	     */
	    DocumentModel.prototype.toString = function () {
	        return this._text;
	    };
	    /**
	     * Deserialize the model from a string.
	     *
	     * #### Notes
	     * Should emit a [contentChanged] signal.
	     */
	    DocumentModel.prototype.fromString = function (value) {
	        if (this._text === value) {
	            return;
	        }
	        this._text = value;
	        this.contentChanged.emit(void 0);
	        this.dirty = true;
	    };
	    /**
	     * Serialize the model to JSON.
	     */
	    DocumentModel.prototype.toJSON = function () {
	        return JSON.stringify(this._text);
	    };
	    /**
	     * Deserialize the model from JSON.
	     *
	     * #### Notes
	     * Should emit a [contentChanged] signal.
	     */
	    DocumentModel.prototype.fromJSON = function (value) {
	        this.fromString(JSON.parse(value));
	    };
	    /**
	     * Initialize the model state.
	     */
	    DocumentModel.prototype.initialize = function () {
	        // No action necessary.
	    };
	    return DocumentModel;
	}());
	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.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return 'text';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TextModelFactory.prototype, "contentsOptions", {
	        /**
	         * The contents options used to fetch/save files.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return { type: 'file', format: '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 document manager.
	     */
	    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) {
	        return new DocumentModel(languagePreference);
	    };
	    /**
	     * Get the preferred kernel language given an extension.
	     */
	    TextModelFactory.prototype.preferredLanguage = function (ext) {
	        var mode = CodeMirror.findModeByExtension(ext.slice(1));
	        if (mode) {
	            return mode.mode;
	        }
	    };
	    return TextModelFactory;
	}());
	exports.TextModelFactory = TextModelFactory;
	/**
	 * An implementation of a model factory for base64 files.
	 */
	var Base64ModelFactory = (function (_super) {
	    __extends(Base64ModelFactory, _super);
	    function Base64ModelFactory() {
	        _super.apply(this, arguments);
	    }
	    Object.defineProperty(Base64ModelFactory.prototype, "name", {
	        /**
	         * The name of the model.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return 'base64';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Base64ModelFactory.prototype, "contentsOptions", {
	        /**
	         * The contents options used to fetch/save files.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return { type: 'file', format: 'base64' };
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return Base64ModelFactory;
	}(TextModelFactory));
	exports.Base64ModelFactory = Base64ModelFactory;
	/**
	 * The default implemetation of a widget factory.
	 */
	var ABCWidgetFactory = (function () {
	    function ABCWidgetFactory() {
	        this._isDisposed = false;
	    }
	    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;
	    };
	    /**
	     * Take an action on a widget before closing it.
	     *
	     * @returns A promise that resolves to true if the document should close
	     *   and false otherwise.
	     */
	    ABCWidgetFactory.prototype.beforeClose = function (model, context, widget) {
	        // There is nothing specific to do.
	        return Promise.resolve(true);
	    };
	    return ABCWidgetFactory;
	}());
	exports.ABCWidgetFactory = ABCWidgetFactory;
	/**
	 * A private namespace for data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when a document content changes.
	     */
	    Private.contentChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when a document dirty state changes.
	     */
	    Private.stateChangedSignal = new phosphor_signaling_1.Signal();
	})(Private || (Private = {}));


/***/ },
/* 276 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var dialog_1 = __webpack_require__(115);
	/**
	 * Bring up a dialog to select a kernel.
	 */
	function selectKernel(options) {
	    var specs = options.specs;
	    var kernel = options.kernel;
	    // Create the dialog body.
	    var body = document.createElement('div');
	    var text = document.createElement('pre');
	    text.textContent = "Select kernel for\n\"" + options.name + "\"";
	    body.appendChild(text);
	    if (kernel) {
	        var displayName = specs.kernelspecs[kernel.name].spec.display_name;
	        text.textContent += "\nCurrent: " + displayName;
	        text.title = ("Kernel Name: " + displayName + "\n") +
	            ("Kernel Id: " + kernel.id);
	    }
	    var selector = document.createElement('select');
	    body.appendChild(selector);
	    // Get the current sessions, populate the kernels, and show the dialog.
	    var lang = options.preferredLanguage;
	    populateKernels(selector, specs, options.sessions, lang);
	    return dialog_1.showDialog({
	        title: 'Select Kernel',
	        body: body,
	        host: options.host,
	        okText: 'SELECT'
	    }).then(function (result) {
	        // Change the kernel if a kernel was selected.
	        if (result.text === 'SELECT') {
	            return JSON.parse(selector.value);
	        }
	        return void 0;
	    });
	}
	exports.selectKernel = selectKernel;
	/**
	 * Change the kernel on a context.
	 */
	function selectKernelForContext(context, host) {
	    return context.listSessions().then(function (sessions) {
	        var options = {
	            name: context.path.split('/').pop(),
	            specs: context.kernelspecs,
	            sessions: sessions,
	            preferredLanguage: context.model.defaultKernelLanguage,
	            kernel: context.kernel,
	            host: host
	        };
	        return selectKernel(options);
	    }).then(function (kernel) {
	        context.changeKernel(kernel);
	    });
	}
	exports.selectKernelForContext = selectKernelForContext;
	/**
	 * Get the appropriate kernel name.
	 */
	function findKernel(kernelName, language, specs) {
	    if (kernelName === 'unknown') {
	        return specs.default;
	    }
	    // Look for an exact match.
	    for (var specName in specs.kernelspecs) {
	        if (specName === kernelName) {
	            return kernelName;
	        }
	    }
	    // Next try to match the language name.
	    if (language === 'unknown') {
	        return specs.default;
	    }
	    for (var specName in specs.kernelspecs) {
	        var kernelLanguage = specs.kernelspecs[specName].spec.language;
	        if (language === kernelLanguage) {
	            console.log('No exact match found for ' + specName +
	                ', using kernel ' + specName + ' that matches ' +
	                'language=' + language);
	            return specName;
	        }
	    }
	    // Finally, use the default kernel.
	    console.log(("No matching kernel found for " + kernelName + ", ") +
	        ("using default kernel " + specs.default));
	    return specs.default;
	}
	exports.findKernel = findKernel;
	/**
	 * Populate a kernel dropdown list.
	 *
	 * @param node - The host html element.
	 *
	 * @param specs - The available kernel spec information.
	 *
	 * @param running - The list of running session ids.
	 *
	 * @param preferredLanguage - The preferred language for the kernel.
	 *
	 * #### 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 populateKernels(node, specs, running, preferredLanguage) {
	    // Clear any existing options.
	    while (node.firstChild) {
	        node.removeChild(node.firstChild);
	    }
	    var maxLength = 10;
	    // 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) {
	        displayNames[name_1] = specs.kernelspecs[name_1].spec.display_name;
	        maxLength = Math.max(maxLength, displayNames[name_1].length);
	        languages[name_1] = specs.kernelspecs[name_1].spec.language;
	    }
	    // Handle a preferred kernel language in order of display name.
	    var names = [];
	    if (preferredLanguage) {
	        for (var name_2 in specs.kernelspecs) {
	            if (languages[name_2] === preferredLanguage) {
	                names.push(name_2);
	            }
	        }
	        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_3 = names_1[_i];
	            node.appendChild(optionForName(name_3, displayNames[name_3]));
	        }
	    }
	    // Use the default kernel if no preferred language or none were found.
	    if (!names.length) {
	        var name_4 = specs.default;
	        node.appendChild(optionForName(name_4, displayNames[name_4]));
	    }
	    // Add a separator.
	    node.appendChild(createSeparatorOption(maxLength));
	    // Add the option to have no kernel.
	    var option = document.createElement('option');
	    option.text = 'None';
	    option.value = 'null';
	    node.appendChild(option);
	    node.appendChild(createSeparatorOption(maxLength));
	    // Add the rest of the kernel names in alphabetical order.
	    var otherNames = [];
	    for (var name_5 in specs.kernelspecs) {
	        if (names.indexOf(name_5) !== -1) {
	            continue;
	        }
	        otherNames.push(name_5);
	    }
	    otherNames.sort(function (a, b) { return displayNames[a].localeCompare(displayNames[b]); });
	    for (var _a = 0, otherNames_1 = otherNames; _a < otherNames_1.length; _a++) {
	        var name_6 = otherNames_1[_a];
	        node.appendChild(optionForName(name_6, displayNames[name_6]));
	    }
	    // Add a separator option if there were any other names.
	    if (otherNames.length) {
	        node.appendChild(createSeparatorOption(maxLength));
	    }
	    // Add the sessions using the preferred language first.
	    var matchingSessions = [];
	    if (preferredLanguage) {
	        for (var _b = 0, running_1 = running; _b < running_1.length; _b++) {
	            var session = running_1[_b];
	            if (languages[session.kernel.name] === preferredLanguage) {
	                matchingSessions.push(session);
	            }
	        }
	        if (matchingSessions) {
	            matchingSessions.sort(function (a, b) {
	                return a.notebook.path.localeCompare(b.notebook.path);
	            });
	            for (var _c = 0, matchingSessions_1 = matchingSessions; _c < matchingSessions_1.length; _c++) {
	                var session = matchingSessions_1[_c];
	                var name_7 = displayNames[session.kernel.name];
	                node.appendChild(optionForSession(session, name_7, maxLength));
	            }
	            node.appendChild(createSeparatorOption(maxLength));
	        }
	    }
	    // Add the other remaining sessions.
	    var otherSessions = [];
	    for (var _d = 0, running_2 = running; _d < running_2.length; _d++) {
	        var session = running_2[_d];
	        if (matchingSessions.indexOf(session) === -1) {
	            otherSessions.push(session);
	        }
	    }
	    if (otherSessions) {
	        otherSessions.sort(function (a, b) {
	            return a.notebook.path.localeCompare(b.notebook.path);
	        });
	        for (var _e = 0, otherSessions_1 = otherSessions; _e < otherSessions_1.length; _e++) {
	            var session = otherSessions_1[_e];
	            var name_8 = displayNames[session.kernel.name];
	            node.appendChild(optionForSession(session, name_8, maxLength));
	        }
	    }
	    node.selectedIndex = 0;
	}
	exports.populateKernels = populateKernels;
	/**
	 * Create a separator option.
	 */
	function createSeparatorOption(length) {
	    var option = document.createElement('option');
	    option.disabled = true;
	    option.text = Array(length).join('─');
	    return option;
	}
	/**
	 * 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 element for a session.
	 */
	function optionForSession(session, displayName, maxLength) {
	    var option = document.createElement('option');
	    var sessionName = session.notebook.path.split('/').pop();
	    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;
	}


/***/ },
/* 277 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var CodeMirror = __webpack_require__(130);
	__webpack_require__(132);
	var codemirror_1 = __webpack_require__(129);
	var widget_1 = __webpack_require__(264);
	var default_1 = __webpack_require__(275);
	/**
	 * The class name added to a dirty widget.
	 */
	var DIRTY_CLASS = 'jp-mod-dirty';
	/**
	 * The class name added to a jupyter code mirror widget.
	 */
	var EDITOR_CLASS = 'jp-EditorWidget';
	/**
	 * A document widget for codemirrors.
	 */
	var EditorWidget = (function (_super) {
	    __extends(EditorWidget, _super);
	    /**
	     * Construct a new editor widget.
	     */
	    function EditorWidget(model, context) {
	        var _this = this;
	        _super.call(this);
	        this.addClass(EDITOR_CLASS);
	        var editor = this.editor;
	        editor.setOption('lineNumbers', true);
	        var doc = editor.getDoc();
	        doc.setValue(model.toString());
	        this.title.text = context.path.split('/').pop();
	        codemirror_1.loadModeByFileName(editor, context.path);
	        model.stateChanged.connect(function (m, args) {
	            if (args.name === 'dirty') {
	                if (args.newValue) {
	                    _this.title.className += " " + DIRTY_CLASS;
	                }
	                else {
	                    _this.title.className = _this.title.className.replace(DIRTY_CLASS, '');
	                }
	            }
	        });
	        context.pathChanged.connect(function (c, path) {
	            codemirror_1.loadModeByFileName(editor, path);
	            _this.title.text = path.split('/').pop();
	        });
	        model.contentChanged.connect(function () {
	            var old = doc.getValue();
	            var text = model.toString();
	            if (old !== text) {
	                doc.setValue(text);
	            }
	        });
	        CodeMirror.on(doc, 'change', function (instance, change) {
	            if (change.origin !== 'setValue') {
	                model.fromString(instance.getValue());
	            }
	        });
	    }
	    return EditorWidget;
	}(widget_1.CodeMirrorWidget));
	exports.EditorWidget = EditorWidget;
	/**
	 * A widget factory for editors.
	 */
	var EditorWidgetFactory = (function (_super) {
	    __extends(EditorWidgetFactory, _super);
	    function EditorWidgetFactory() {
	        _super.apply(this, arguments);
	    }
	    /**
	     * Create a new widget given a document model and a context.
	     */
	    EditorWidgetFactory.prototype.createNew = function (model, context, kernel) {
	        if (kernel) {
	            context.changeKernel(kernel);
	        }
	        return new EditorWidget(model, context);
	    };
	    return EditorWidgetFactory;
	}(default_1.ABCWidgetFactory));
	exports.EditorWidgetFactory = EditorWidgetFactory;


/***/ },
/* 278 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_widget_1 = __webpack_require__(20);
	var default_1 = __webpack_require__(275);
	/**
	 * A widget for images.
	 */
	var ImageWidget = (function (_super) {
	    __extends(ImageWidget, _super);
	    /**
	     * Construct a new image widget.
	     */
	    function ImageWidget(model, context) {
	        var _this = this;
	        _super.call(this);
	        this._model = model;
	        this._context = context;
	        this.node.tabIndex = -1;
	        this.node.style.overflowX = 'auto';
	        this.node.style.overflowY = 'auto';
	        if (model.toString()) {
	            this.update();
	        }
	        context.pathChanged.connect(function () {
	            _this.update();
	        });
	        model.contentChanged.connect(function () {
	            _this.update();
	        });
	    }
	    /**
	     * Create the node for the image widget.
	     */
	    ImageWidget.createNode = function () {
	        return document.createElement('img');
	    };
	    /**
	     * Dispose of the resources used by the widget.
	     */
	    ImageWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._model = null;
	        this._context = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Handle `update-request` messages for the widget.
	     */
	    ImageWidget.prototype.onUpdateRequest = function (msg) {
	        this.title.text = this._context.path.split('/').pop();
	        var node = this.node;
	        var content = this._model.toString();
	        var model = this._context.contentsModel;
	        node.src = "data:" + model.mimetype + ";" + model.format + "," + content;
	    };
	    return ImageWidget;
	}(phosphor_widget_1.Widget));
	exports.ImageWidget = ImageWidget;
	/**
	 * A widget factory for images.
	 */
	var ImageWidgetFactory = (function (_super) {
	    __extends(ImageWidgetFactory, _super);
	    function ImageWidgetFactory() {
	        _super.apply(this, arguments);
	    }
	    /**
	     * Create a new widget given a document model and a context.
	     */
	    ImageWidgetFactory.prototype.createNew = function (model, context, kernel) {
	        return new ImageWidget(model, context);
	    };
	    return ImageWidgetFactory;
	}(default_1.ABCWidgetFactory));
	exports.ImageWidgetFactory = ImageWidgetFactory;


/***/ },
/* 279 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_disposable_1 = __webpack_require__(8);
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_signaling_1 = __webpack_require__(22);
	var phosphor_widget_1 = __webpack_require__(20);
	var dialog_1 = __webpack_require__(115);
	var context_1 = __webpack_require__(280);
	/**
	 * The class name added to a document container widgets.
	 */
	var DOCUMENT_CLASS = 'jp-DocumentWidget';
	/**
	 * The document manager.
	 *
	 * #### Notes
	 * The document manager is used to register model and widget creators,
	 * and the file browser uses the document manager to create widgets. The
	 * document manager maintains a context for each path and model type that is
	 * open, and a list of widgets for each context. The document manager is in
	 * control of the proper closing and disposal of the widgets and contexts.
	 */
	var DocumentManager = (function () {
	    /**
	     * Construct a new document manager.
	     */
	    function DocumentManager(registry, contentsManager, sessionManager, kernelspecs, opener) {
	        var _this = this;
	        this._widgets = Object.create(null);
	        this._contentsManager = null;
	        this._sessionManager = null;
	        this._contextManager = null;
	        this._specs = null;
	        this._registry = null;
	        this._registry = registry;
	        this._contentsManager = contentsManager;
	        this._sessionManager = sessionManager;
	        this._specs = kernelspecs;
	        this._contextManager = new context_1.ContextManager(contentsManager, sessionManager, kernelspecs, function (id, widget) {
	            var parent = _this._createWidget('', id);
	            parent.setContent(widget);
	            opener.open(parent);
	            return new phosphor_disposable_1.DisposableDelegate(function () {
	                parent.close();
	            });
	        });
	    }
	    Object.defineProperty(DocumentManager.prototype, "kernelspecs", {
	        /**
	         * Get the kernel spec ids for the manager.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._specs;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentManager.prototype, "registry", {
	        /**
	         * Get the registry used by the manager.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._registry;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentManager.prototype, "isDisposed", {
	        /**
	         * Get whether the document manager has been disposed.
	         */
	        get: function () {
	            return this._contentsManager === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the document manager.
	     */
	    DocumentManager.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        for (var id in this._widgets) {
	            for (var _i = 0, _a = this._widgets[id]; _i < _a.length; _i++) {
	                var widget = _a[_i];
	                widget.dispose();
	            }
	        }
	        this._widgets = null;
	        this._contentsManager = null;
	        this._sessionManager = null;
	        this._contextManager.dispose();
	        this._contextManager = null;
	    };
	    /**
	     * Open a file and return the widget used to display the contents.
	     *
	     * @param path - The file path to open.
	     *
	     * @param widgetName - The name of the widget factory to use.
	     *
	     * @param kernel - An optional kernel name/id to override the default.
	     */
	    DocumentManager.prototype.open = function (path, widgetName, kernel) {
	        var _this = this;
	        if (widgetName === void 0) { widgetName = 'default'; }
	        var registry = this._registry;
	        if (widgetName === 'default') {
	            var parts = path.split('.');
	            var ext = void 0;
	            if (parts.length === 1 || (parts[0] === '' && parts.length === 2)) {
	                ext = '';
	            }
	            else {
	                ext = '.' + parts.pop().toLowerCase();
	            }
	            widgetName = registry.listWidgetFactories(ext)[0];
	        }
	        var mFactory = registry.getModelFactory(widgetName);
	        if (!mFactory) {
	            return;
	        }
	        var widget;
	        // Use an existing context if available.
	        var id = this._contextManager.findContext(path, mFactory.name);
	        if (id) {
	            widget = this._createWidget(widgetName, id);
	            this._populateWidget(widget, kernel);
	            return widget;
	        }
	        var lang = mFactory.preferredLanguage(path);
	        var model = mFactory.createNew(lang);
	        id = this._contextManager.createNew(path, model, mFactory);
	        widget = this._createWidget(widgetName, id);
	        // Load the contents from disk.
	        this._contextManager.revert(id).then(function () {
	            _this._populateWidget(widget, kernel);
	        });
	        return widget;
	    };
	    /**
	     * Create a new file of the given name.
	     *
	     * @param path - The file path to use.
	     *
	     * @param widgetName - The name of the widget factory to use.
	     *
	     * @param kernel - An optional kernel name/id to override the default.
	     */
	    DocumentManager.prototype.createNew = function (path, widgetName, kernel) {
	        var _this = this;
	        if (widgetName === void 0) { widgetName = 'default'; }
	        var registry = this._registry;
	        if (widgetName === 'default') {
	            var parts = path.split('.');
	            var ext = void 0;
	            if (parts.length === 1 || (parts[0] === '' && parts.length === 2)) {
	                ext = '';
	            }
	            else {
	                ext = '.' + parts.pop().toLowerCase();
	            }
	            widgetName = registry.listWidgetFactories(ext)[0];
	        }
	        var mFactory = registry.getModelFactory(widgetName);
	        if (!mFactory) {
	            return;
	        }
	        var lang = mFactory.preferredLanguage(path);
	        var model = mFactory.createNew(lang);
	        var id = this._contextManager.createNew(path, model, mFactory);
	        var widget = this._createWidget(widgetName, id);
	        // Save the contents to disk to get a valid contentsModel for the
	        // context.
	        this._contextManager.save(id).then(function () {
	            _this._populateWidget(widget, kernel);
	        });
	        return widget;
	    };
	    /**
	     * List the running notebook sessions.
	     */
	    DocumentManager.prototype.listSessions = function () {
	        return this._sessionManager.listRunning();
	    };
	    /**
	     * Handle the renaming of an open document.
	     *
	     * @param oldPath - The previous path.
	     *
	     * @param newPath - The new path.
	     */
	    DocumentManager.prototype.handleRename = function (oldPath, newPath) {
	        this._contextManager.rename(oldPath, newPath);
	    };
	    /**
	     * Handle a file deletion.
	     */
	    DocumentManager.prototype.handleDelete = function (path) {
	        // TODO: Leave all of the widgets open and flag them as orphaned?
	    };
	    /**
	     * See if a widget already exists for the given path and widget name.
	     *
	     * #### Notes
	     * This can be used to use an existing widget instead of opening
	     * a new widget.
	     */
	    DocumentManager.prototype.findWidget = function (path, widgetName) {
	        if (widgetName === void 0) { widgetName = 'default'; }
	        var ids = this._contextManager.getIdsForPath(path);
	        if (widgetName === 'default') {
	            widgetName = this._registry.defaultWidgetFactory;
	        }
	        for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) {
	            var id = ids_1[_i];
	            for (var _a = 0, _b = this._widgets[id]; _a < _b.length; _a++) {
	                var widget = _b[_a];
	                if (widget.name === widgetName) {
	                    return widget;
	                }
	            }
	        }
	    };
	    /**
	     * Clone a widget.
	     *
	     * #### Notes
	     * This will create a new widget with the same model and context
	     * as this widget.
	     */
	    DocumentManager.prototype.clone = function (widget) {
	        var parent = this._createWidget(widget.name, widget.context.id);
	        this._populateWidget(parent);
	        return parent;
	    };
	    /**
	     * Close the widgets associated with a given path.
	     */
	    DocumentManager.prototype.closeFile = function (path) {
	        var ids = this._contextManager.getIdsForPath(path);
	        for (var _i = 0, ids_2 = ids; _i < ids_2.length; _i++) {
	            var id = ids_2[_i];
	            var widgets = this._widgets[id] || [];
	            for (var _a = 0, widgets_1 = widgets; _a < widgets_1.length; _a++) {
	                var w = widgets_1[_a];
	                w.close();
	            }
	        }
	    };
	    /**
	     * Close all of the open documents.
	     */
	    DocumentManager.prototype.closeAll = function () {
	        for (var id in this._widgets) {
	            for (var _i = 0, _a = this._widgets[id]; _i < _a.length; _i++) {
	                var w = _a[_i];
	                w.close();
	            }
	        }
	    };
	    /**
	     * Create a container widget and handle its lifecycle.
	     */
	    DocumentManager.prototype._createWidget = function (name, id) {
	        var factory = this._registry.getWidgetFactory(name);
	        var widget = new DocumentWidget(name, id, this._contextManager, factory, this._widgets);
	        if (!(id in this._widgets)) {
	            this._widgets[id] = [];
	        }
	        this._widgets[id].push(widget);
	        return widget;
	    };
	    /**
	     * Create a content widget and add it to the container widget.
	     */
	    DocumentManager.prototype._populateWidget = function (parent, kernel) {
	        var factory = this._registry.getWidgetFactory(parent.name);
	        var id = parent.context.id;
	        var model = this._contextManager.getModel(id);
	        model.initialize();
	        var context = this._contextManager.getContext(id);
	        var child = factory.createNew(model, context, kernel);
	        parent.setContent(child);
	        // Handle widget extensions.
	        var disposables = new phosphor_disposable_1.DisposableSet();
	        for (var _i = 0, _a = this._registry.getWidgetExtensions(parent.name); _i < _a.length; _i++) {
	            var extender = _a[_i];
	            disposables.add(extender.createNew(child, model, context));
	        }
	        parent.disposed.connect(function () {
	            disposables.dispose();
	        });
	    };
	    return DocumentManager;
	}());
	exports.DocumentManager = DocumentManager;
	/**
	 * A container widget for documents.
	 */
	var DocumentWidget = (function (_super) {
	    __extends(DocumentWidget, _super);
	    /**
	     * Construct a new document widget.
	     */
	    function DocumentWidget(name, id, manager, factory, widgets) {
	        _super.call(this);
	        this._manager = null;
	        this._factory = null;
	        this._id = '';
	        this._name = '';
	        this._widgets = null;
	        this.addClass(DOCUMENT_CLASS);
	        this.layout = new phosphor_panel_1.PanelLayout();
	        this._name = name;
	        this._id = id;
	        this._manager = manager;
	        this._widgets = widgets;
	        this._factory = factory;
	        this.title.closable = true;
	    }
	    Object.defineProperty(DocumentWidget.prototype, "populated", {
	        /**
	         * A signal emitted when the document widget is populated.
	         */
	        get: function () {
	            return Private.populatedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentWidget.prototype, "name", {
	        /**
	         * Get the name of the widget.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._name;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentWidget.prototype, "context", {
	        /**
	         * The context for the widget.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._manager.getContext(this._id);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentWidget.prototype, "content", {
	        /**
	         * The content widget used by the document widget.
	         */
	        get: function () {
	            var layout = this.layout;
	            return layout.childAt(0);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    DocumentWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        // Remove the widget from the widget registry.
	        var id = this._id;
	        var index = this._widgets[id].indexOf(this);
	        this._widgets[id].splice(index, 1);
	        // Dispose of the context if this is the last widget using it.
	        if (!this._widgets[id].length) {
	            this._manager.removeContext(id);
	        }
	        this._manager = null;
	        this._factory = null;
	        this._widgets = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Set the child the widget.
	     *
	     * #### Notes
	     * This function is not intended to be called by user code.
	     */
	    DocumentWidget.prototype.setContent = function (child) {
	        var _this = this;
	        var layout = this.layout;
	        if (layout.childAt(0)) {
	            throw new Error('Content already set');
	        }
	        this.title.text = child.title.text;
	        this.title.icon = child.title.icon;
	        this.title.className = child.title.className;
	        // Mirror this title based on the child.
	        child.title.changed.connect(function () {
	            _this.title.text = child.title.text;
	            _this.title.icon = child.title.icon;
	            _this.title.className = child.title.className;
	        });
	        // Add the child widget to the layout.
	        this.layout.addChild(child);
	        this.populated.emit(child);
	    };
	    /**
	     * Handle `'close-request'` messages.
	     */
	    DocumentWidget.prototype.onCloseRequest = function (msg) {
	        var _this = this;
	        var model = this._manager.getModel(this._id);
	        var layout = this.layout;
	        var child = layout.childAt(0);
	        // Handle dirty state.
	        this._maybeClose(model.dirty).then(function (result) {
	            if (result) {
	                // Let the widget factory handle closing.
	                return _this._factory.beforeClose(model, _this.context, child);
	            }
	            return result;
	        }).then(function (result) {
	            if (result) {
	                // Perform close tasks.
	                return _this._actuallyClose();
	            }
	            return result;
	        }).then(function (result) {
	            if (result) {
	                // Dispose of document widgets when they are closed.
	                _this.dispose();
	            }
	        }).catch(function () {
	            _this.dispose();
	        });
	    };
	    /**
	     * Ask the user whether to close an unsaved file.
	     */
	    DocumentWidget.prototype._maybeClose = function (dirty) {
	        // Bail if the model is not dirty or other widgets are using the model.
	        var widgets = this._widgets[this._id];
	        if (!dirty || widgets.length > 1) {
	            return Promise.resolve(true);
	        }
	        return dialog_1.showDialog({
	            title: 'Close without saving?',
	            body: "File \"" + this.title.text + "\" has unsaved changes, close without saving?",
	            host: this.node
	        }).then(function (value) {
	            if (value && value.text === 'OK') {
	                return true;
	            }
	            return false;
	        });
	    };
	    /**
	     * Perform closing tasks for the widget.
	     */
	    DocumentWidget.prototype._actuallyClose = function () {
	        var _this = this;
	        // Check for a dangling kernel.
	        var widgets = this._widgets[this._id];
	        var kernelId = this.context.kernel ? this.context.kernel.id : '';
	        if (!kernelId || widgets.length > 1) {
	            return Promise.resolve(true);
	        }
	        for (var id in this._widgets) {
	            for (var _i = 0, _a = this._widgets[id]; _i < _a.length; _i++) {
	                var widget = _a[_i];
	                var kId = widget.context.kernel || widget.context.kernel.id;
	                if (widget !== this && kId === kernelId) {
	                    return Promise.resolve(true);
	                }
	            }
	        }
	        return dialog_1.showDialog({
	            title: 'Shut down kernel?',
	            body: "Shut down " + this.context.kernel.name + "?",
	            host: this.node
	        }).then(function (value) {
	            if (value && value.text === 'OK') {
	                return _this.context.kernel.shutdown();
	            }
	        }).then(function () {
	            return true;
	        });
	    };
	    return DocumentWidget;
	}(phosphor_widget_1.Widget));
	exports.DocumentWidget = DocumentWidget;
	/**
	 * A private namespace for DocumentManager data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when the document widget is populated.
	     */
	    Private.populatedSignal = new phosphor_signaling_1.Signal();
	})(Private || (Private = {}));


/***/ },
/* 280 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var utils = __webpack_require__(106);
	var phosphor_signaling_1 = __webpack_require__(22);
	/**
	 * An implementation of a document context.
	 */
	var Context = (function () {
	    /**
	     * Construct a new document context.
	     */
	    function Context(manager) {
	        this._id = '';
	        this._manager = null;
	        this._manager = manager;
	        this._id = utils.uuid();
	    }
	    Object.defineProperty(Context.prototype, "kernelChanged", {
	        /**
	         * A signal emitted when the kernel changes.
	         */
	        get: function () {
	            return Private.kernelChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "pathChanged", {
	        /**
	         * A signal emitted when the path changes.
	         */
	        get: function () {
	            return Private.pathChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "dirtyCleared", {
	        /**
	         * A signal emitted when the model is saved or reverted.
	         */
	        get: function () {
	            return Private.dirtyClearedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "id", {
	        /**
	         * The unique id of the context.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._id;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "model", {
	        /**
	         * Get the model associated with the document.
	         *
	         * #### Notes
	         * This is a read-only property
	         */
	        get: function () {
	            return this._manager.getModel(this._id);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "kernel", {
	        /**
	         * The current kernel associated with the document.
	         *
	         * #### Notes
	         * This is a read-only propery.
	         */
	        get: function () {
	            return this._manager.getKernel(this._id);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "path", {
	        /**
	         * The current path associated with the document.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._manager.getPath(this._id);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "contentsModel", {
	        /**
	         * The current contents model associated with the document
	         *
	         * #### Notes
	         * This is a read-only property.  The model will have an
	         * empty `contents` field.
	         */
	        get: function () {
	            return this._manager.getContentsModel(this._id);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "kernelspecs", {
	        /**
	         * Get the kernel spec information.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._manager.getKernelspecs();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "isDisposed", {
	        /**
	         * Get whether the context has been disposed.
	         */
	        get: function () {
	            return this._manager === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the context.
	     */
	    Context.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._manager = null;
	        this._id = '';
	    };
	    /**
	     * Change the current kernel associated with the document.
	     */
	    Context.prototype.changeKernel = function (options) {
	        return this._manager.changeKernel(this._id, options);
	    };
	    /**
	     * Save the document contents to disk.
	     */
	    Context.prototype.save = function () {
	        return this._manager.save(this._id);
	    };
	    /**
	     * Save the document to a different path.
	     */
	    Context.prototype.saveAs = function (path) {
	        return this._manager.saveAs(this._id, path);
	    };
	    /**
	     * Revert the document contents to disk contents.
	     */
	    Context.prototype.revert = function () {
	        return this._manager.revert(this._id);
	    };
	    /**
	     * Get the list of running sessions.
	     */
	    Context.prototype.listSessions = function () {
	        return this._manager.listSessions();
	    };
	    /**
	     * Add a sibling widget to the document manager.
	     *
	     * @param widget - The widget to add to the document manager.
	     *
	     * @returns A disposable used to remove the sibling if desired.
	     *
	     * #### Notes
	     * It is assumed that the widget has the same model and context
	     * as the original widget.
	     */
	    Context.prototype.addSibling = function (widget) {
	        return this._manager.addSibling(this._id, widget);
	    };
	    return Context;
	}());
	/**
	 * An object which manages the active contexts.
	 */
	var ContextManager = (function () {
	    /**
	     * Construct a new context manager.
	     */
	    function ContextManager(contentsManager, sessionManager, kernelspecs, opener) {
	        this._contentsManager = null;
	        this._sessionManager = null;
	        this._kernelspecids = null;
	        this._contexts = Object.create(null);
	        this._opener = null;
	        this._contentsManager = contentsManager;
	        this._sessionManager = sessionManager;
	        this._opener = opener;
	        this._kernelspecids = kernelspecs;
	    }
	    Object.defineProperty(ContextManager.prototype, "isDisposed", {
	        /**
	         * Get whether the context manager has been disposed.
	         */
	        get: function () {
	            return this._contentsManager === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the document manager.
	     */
	    ContextManager.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._contentsManager = null;
	        this._sessionManager = null;
	        this._kernelspecids = null;
	        for (var id in this._contexts) {
	            var contextEx = this._contexts[id];
	            contextEx.context.dispose();
	            contextEx.model.dispose();
	            var session = contextEx.session;
	            if (session) {
	                session.dispose();
	            }
	        }
	        this._contexts = null;
	        this._opener = null;
	    };
	    /**
	     * Create a new context.
	     */
	    ContextManager.prototype.createNew = function (path, model, factory) {
	        var context = new Context(this);
	        var id = context.id;
	        this._contexts[id] = {
	            context: context,
	            path: path,
	            model: model,
	            modelName: factory.name,
	            opts: factory.contentsOptions,
	            contentsModel: null,
	            session: null
	        };
	        return id;
	    };
	    /**
	     * Get a context for a given path and model name.
	     */
	    ContextManager.prototype.findContext = function (path, modelName) {
	        for (var id in this._contexts) {
	            var contextEx = this._contexts[id];
	            if (contextEx.path === path && contextEx.modelName === modelName) {
	                return id;
	            }
	        }
	    };
	    /**
	     * Find a context by path.
	     */
	    ContextManager.prototype.getIdsForPath = function (path) {
	        var ids = [];
	        for (var id in this._contexts) {
	            if (this._contexts[id].path === path) {
	                ids.push(id);
	            }
	        }
	        return ids;
	    };
	    /**
	     * Get a context by id.
	     */
	    ContextManager.prototype.getContext = function (id) {
	        return this._contexts[id].context;
	    };
	    /**
	     * Get the model associated with a context.
	     */
	    ContextManager.prototype.getModel = function (id) {
	        return this._contexts[id].model;
	    };
	    /**
	     * Remove a context.
	     */
	    ContextManager.prototype.removeContext = function (id) {
	        var contextEx = this._contexts[id];
	        contextEx.model.dispose();
	        contextEx.context.dispose();
	        delete this._contexts[id];
	    };
	    /**
	     * Get the current kernel associated with a document.
	     */
	    ContextManager.prototype.getKernel = function (id) {
	        var session = this._contexts[id].session;
	        return session ? session.kernel : null;
	    };
	    /**
	     * Get the current path associated with a document.
	     */
	    ContextManager.prototype.getPath = function (id) {
	        return this._contexts[id].path;
	    };
	    /**
	     * Get the current contents model associated with a document.
	     */
	    ContextManager.prototype.getContentsModel = function (id) {
	        return this._contexts[id].contentsModel;
	    };
	    /**
	     * Change the current kernel associated with the document.
	     *
	     * @param options - If given, change the kernel (starting a session
	     * if necessary). If falsey, shut down any existing session and return
	     * a void promise.
	     */
	    ContextManager.prototype.changeKernel = function (id, options) {
	        var contextEx = this._contexts[id];
	        var session = contextEx.session;
	        if (options) {
	            if (session) {
	                return session.changeKernel(options);
	            }
	            else {
	                var path = contextEx.path;
	                var sOptions = {
	                    notebookPath: path,
	                    kernelName: options.name,
	                    kernelId: options.id
	                };
	                return this._startSession(id, sOptions);
	            }
	        }
	        else {
	            if (session) {
	                return session.shutdown().then(function () {
	                    session.dispose();
	                    contextEx.session = null;
	                    return void 0;
	                });
	            }
	            else {
	                return Promise.resolve(void 0);
	            }
	        }
	    };
	    /**
	     * Update the path of an open document.
	     *
	     * @param id - The id of the context.
	     *
	     * @param newPath - The new path.
	     */
	    ContextManager.prototype.rename = function (oldPath, newPath) {
	        // Update all of the paths, but only update one session
	        // so there is only one REST API call.
	        var ids = this.getIdsForPath(oldPath);
	        var sessionUpdated = false;
	        for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) {
	            var id = ids_1[_i];
	            var contextEx = this._contexts[id];
	            contextEx.path = newPath;
	            contextEx.context.pathChanged.emit(newPath);
	            if (!sessionUpdated) {
	                var session = contextEx.session;
	                if (session) {
	                    session.renameNotebook(newPath);
	                    sessionUpdated = true;
	                }
	            }
	        }
	    };
	    /**
	     * Get the current kernelspec information.
	     */
	    ContextManager.prototype.getKernelspecs = function () {
	        return this._kernelspecids;
	    };
	    /**
	     * Save the document contents to disk.
	     */
	    ContextManager.prototype.save = function (id) {
	        var _this = this;
	        var contextEx = this._contexts[id];
	        var opts = utils.copy(contextEx.opts);
	        var path = contextEx.path;
	        var model = contextEx.model;
	        if (model.readOnly) {
	            return Promise.reject(new Error('Read only'));
	        }
	        if (opts.type === 'notebook' || opts.format === 'json') {
	            opts.content = model.toJSON();
	        }
	        else {
	            opts.content = model.toString();
	        }
	        return this._contentsManager.save(path, opts).then(function (contents) {
	            contextEx.contentsModel = _this._copyContentsModel(contents);
	            model.dirty = false;
	        });
	    };
	    /**
	     * Save a document to a new file name.
	     *
	     * This results in a new session.
	     */
	    ContextManager.prototype.saveAs = function (id, newPath) {
	        var _this = this;
	        var contextEx = this._contexts[id];
	        contextEx.path = newPath;
	        contextEx.context.pathChanged.emit(newPath);
	        if (contextEx.session) {
	            var options = {
	                notebook: { path: newPath },
	                kernel: { id: contextEx.session.id }
	            };
	            return this._startSession(id, options).then(function () {
	                return _this.save(id);
	            });
	        }
	        return this.save(id);
	    };
	    /**
	     * Revert the contents of a path.
	     */
	    ContextManager.prototype.revert = function (id) {
	        var _this = this;
	        var contextEx = this._contexts[id];
	        var opts = contextEx.opts;
	        var path = contextEx.path;
	        var model = contextEx.model;
	        return this._contentsManager.get(path, opts).then(function (contents) {
	            if (contents.format === 'json') {
	                model.fromJSON(contents.content);
	            }
	            else {
	                model.fromString(contents.content);
	            }
	            contextEx.contentsModel = _this._copyContentsModel(contents);
	            model.dirty = false;
	        });
	    };
	    /**
	     * Get the list of running sessions.
	     */
	    ContextManager.prototype.listSessions = function () {
	        return this._sessionManager.listRunning();
	    };
	    /**
	     * Add a sibling widget to the document manager.
	     */
	    ContextManager.prototype.addSibling = function (id, widget) {
	        var opener = this._opener;
	        return opener(id, widget);
	    };
	    /**
	     * Start a session and set up its signals.
	     */
	    ContextManager.prototype._startSession = function (id, options) {
	        var contextEx = this._contexts[id];
	        var context = contextEx.context;
	        return this._sessionManager.startNew(options).then(function (session) {
	            if (contextEx.session) {
	                contextEx.session.dispose();
	            }
	            contextEx.session = session;
	            context.kernelChanged.emit(session.kernel);
	            session.notebookPathChanged.connect(function (s, path) {
	                if (path !== contextEx.path) {
	                    contextEx.path = path;
	                    context.pathChanged.emit(path);
	                }
	            });
	            session.kernelChanged.connect(function (s, kernel) {
	                context.kernelChanged.emit(kernel);
	            });
	            return session.kernel;
	        });
	    };
	    /**
	     * Copy the contents of a contents model, without the content.
	     */
	    ContextManager.prototype._copyContentsModel = function (model) {
	        return {
	            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
	        };
	    };
	    return ContextManager;
	}());
	exports.ContextManager = ContextManager;
	/**
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when the kernel changes.
	     */
	    Private.kernelChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when the path changes.
	     */
	    Private.pathChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when the model is saved or reverted.
	     */
	    Private.dirtyClearedSignal = new phosphor_signaling_1.Signal();
	})(Private || (Private = {}));


/***/ },
/* 281 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var utils = __webpack_require__(106);
	var phosphor_disposable_1 = __webpack_require__(8);
	/**
	 * The document registery.
	 *
	 * #### Notes
	 * The document registry is used to register model and widget creators.
	 */
	var DocumentRegistry = (function () {
	    function DocumentRegistry() {
	        this._modelFactories = Object.create(null);
	        this._widgetFactories = Object.create(null);
	        this._defaultWidgetFactory = '';
	        this._defaultWidgetFactories = Object.create(null);
	        this._fileTypes = [];
	        this._creators = [];
	        this._extenders = Object.create(null);
	    }
	    Object.defineProperty(DocumentRegistry.prototype, "defaultWidgetFactory", {
	        /**
	         * The name of the default widget factory.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._defaultWidgetFactory;
	        },
	        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.isDisposed) {
	            return;
	        }
	        for (var modelName in this._modelFactories) {
	            this._modelFactories[modelName].dispose();
	        }
	        this._modelFactories = null;
	        for (var widgetName in this._widgetFactories) {
	            this._widgetFactories[widgetName].factory.dispose();
	        }
	        this._widgetFactories = null;
	    };
	    /**
	     * Register a widget factory with the document registry.
	     *
	     * @param factory - The factory instance.
	     *
	     * @param options - The options used to register the factory.
	     *
	     * @returns A disposable used to unregister the factory.
	     *
	     * #### Notes
	     * If a factory with the given `displayName` is already registered,
	     * an error will be thrown.
	     * If `'.*'` is given as a default extension, the factory will be registered
	     * as the global default.
	     * If a factory is already registered as a default for a given extension or
	     * as the global default, this factory will override the existing default.
	     */
	    DocumentRegistry.prototype.registerWidgetFactory = function (factory, options) {
	        var _this = this;
	        var name = options.displayName;
	        var exOpt = utils.copy(options);
	        exOpt.factory = factory;
	        if (this._widgetFactories[name]) {
	            throw new Error("Duplicate registered factory " + name);
	        }
	        this._widgetFactories[name] = exOpt;
	        if (options.defaultFor) {
	            for (var _i = 0, _a = options.defaultFor; _i < _a.length; _i++) {
	                var option = _a[_i];
	                if (option === '.*') {
	                    this._defaultWidgetFactory = name;
	                }
	                else if (options.fileExtensions.indexOf(option) !== -1) {
	                    this._defaultWidgetFactories[option] = name;
	                }
	            }
	        }
	        return new phosphor_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 opt = _a[_i];
	                var n = _this._defaultWidgetFactories[opt];
	                if (n === name) {
	                    delete _this._defaultWidgetFactories[opt];
	                }
	            }
	        });
	    };
	    /**
	     * Register a model factory.
	     *
	     * @param factory - The factory instance.
	     *
	     * @returns A disposable used to unregister the factory.
	     *
	     * #### Notes
	     * If a factory with the given `name` is already registered, an error
	     * will be thrown.
	     */
	    DocumentRegistry.prototype.registerModelFactory = function (factory) {
	        var _this = this;
	        var name = factory.name;
	        if (this._modelFactories[name]) {
	            throw new Error("Duplicate registered factory " + name);
	        }
	        this._modelFactories[name] = factory;
	        return new phosphor_disposable_1.DisposableDelegate(function () {
	            delete _this._modelFactories[name];
	        });
	    };
	    /**
	     * Register a widget extension.
	     *
	     * @param extension - A widget extension.
	     *
	     * @returns A disposable that can be used to unregister the extension.
	     */
	    DocumentRegistry.prototype.registerExtension = function (widgetName, extension) {
	        var _this = this;
	        if (!(widgetName in this._extenders)) {
	            this._extenders[widgetName] = [];
	        }
	        this._extenders[widgetName].push(extension);
	        return new phosphor_disposable_1.DisposableDelegate(function () {
	            var index = _this._extenders[widgetName].indexOf(extension);
	            _this._extenders[widgetName].splice(index, 1);
	        });
	    };
	    /**
	     * Register a file type with the document registry.
	     *
	     * #### Notes
	     * These are used to populate the "Create New" dialog.
	     */
	    DocumentRegistry.prototype.registerFileType = function (fileType) {
	        var _this = this;
	        this._fileTypes.push(fileType);
	        this._fileTypes.sort(function (a, b) { return a.name.localeCompare(b.name); });
	        return new phosphor_disposable_1.DisposableDelegate(function () {
	            var index = _this._fileTypes.indexOf(fileType);
	            _this._fileTypes.splice(index, 1);
	        });
	    };
	    /**
	     * Register a Create New handler.
	     *
	     * @params creator - The file creator object.
	     *
	     * @params after - The optional item name to insert after.
	     *
	     * #### Notes
	     * If `after` is not given or not already registered, it will be moved
	     * to the end.
	     */
	    DocumentRegistry.prototype.registerCreator = function (creator, after) {
	        var _this = this;
	        var added = false;
	        if (after) {
	            for (var _i = 0, _a = this._creators; _i < _a.length; _i++) {
	                var existing = _a[_i];
	                if (existing.name === after) {
	                    var index = this._creators.indexOf(existing);
	                    this._creators.splice(index, 0, creator);
	                    added = true;
	                }
	            }
	        }
	        if (!added) {
	            this._creators.push(creator);
	        }
	        return new phosphor_disposable_1.DisposableDelegate(function () {
	            var index = _this._creators.indexOf(creator);
	            _this._creators.splice(index, 1);
	        });
	    };
	    /**
	     * Get the list of registered widget factory display names.
	     *
	     * @param path - An optional file path to filter the results.
	     *
	     * #### Notes
	     * The first item in the list is considered the default.
	     */
	    DocumentRegistry.prototype.listWidgetFactories = function (ext) {
	        ext = ext || '';
	        var factories = [];
	        var options;
	        var name = '';
	        // If an extension was given, filter by extension.
	        // Make sure the modelFactory is registered.
	        if (ext.length > 1) {
	            if (ext in this._defaultWidgetFactories) {
	                name = this._defaultWidgetFactories[ext];
	                options = this._widgetFactories[name];
	                if (options.modelName in this._modelFactories) {
	                    factories.push(name);
	                }
	            }
	        }
	        // Add the rest of the valid widgetFactories that can open the path.
	        for (name in this._widgetFactories) {
	            if (factories.indexOf(name) !== -1) {
	                continue;
	            }
	            options = this._widgetFactories[name];
	            if (!(options.modelName in this._modelFactories)) {
	                continue;
	            }
	            var exts = options.fileExtensions;
	            if ((exts.indexOf(ext) !== -1) || (exts.indexOf('.*') !== -1)) {
	                factories.push(name);
	            }
	        }
	        // Add the default widget if it was not already added.
	        name = this._defaultWidgetFactory;
	        if (name && factories.indexOf(name) === -1) {
	            options = this._widgetFactories[name];
	            if (options.modelName in this._modelFactories) {
	                factories.push(name);
	            }
	        }
	        return factories;
	    };
	    /**
	     * Get a list of file types that have been registered.
	     */
	    DocumentRegistry.prototype.listFileTypes = function () {
	        return this._fileTypes.slice();
	    };
	    /**
	     * Get the ordered list of file creator names.
	     */
	    DocumentRegistry.prototype.listCreators = function () {
	        return this._creators.slice();
	    };
	    /**
	     * Get the kernel preference.
	     */
	    DocumentRegistry.prototype.getKernelPreference = function (ext, widgetName) {
	        var widgetFactoryEx = this._getWidgetFactoryEx(widgetName);
	        var modelFactory = this.getModelFactory(widgetName);
	        var language = modelFactory.preferredLanguage(ext);
	        return {
	            language: language,
	            preferKernel: widgetFactoryEx.preferKernel,
	            canStartKernel: widgetFactoryEx.canStartKernel
	        };
	    };
	    /**
	     * Get the model factory registered for a given widget factory.
	     *
	     */
	    DocumentRegistry.prototype.getModelFactory = function (widgetName) {
	        var wFactoryEx = this._getWidgetFactoryEx(widgetName);
	        if (!wFactoryEx) {
	            return;
	        }
	        return this._modelFactories[wFactoryEx.modelName];
	    };
	    /**
	     * Get a widget factory by name.
	     */
	    DocumentRegistry.prototype.getWidgetFactory = function (widgetName) {
	        return this._getWidgetFactoryEx(widgetName).factory;
	    };
	    /**
	     * Get the registered extensions for a given widget.
	     */
	    DocumentRegistry.prototype.getWidgetExtensions = function (widgetName) {
	        if (!(widgetName in this._extenders)) {
	            return [];
	        }
	        return this._extenders[widgetName].slice();
	    };
	    /**
	     * Get the appropriate widget factory by name.
	     */
	    DocumentRegistry.prototype._getWidgetFactoryEx = function (widgetName) {
	        var options;
	        if (widgetName === 'default') {
	            options = this._widgetFactories[this._defaultWidgetFactory];
	        }
	        else {
	            options = this._widgetFactories[widgetName];
	        }
	        return options;
	    };
	    return DocumentRegistry;
	}());
	exports.DocumentRegistry = DocumentRegistry;


/***/ },
/* 282 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var jupyter_js_utils_1 = __webpack_require__(106);
	var jupyter_js_services_1 = __webpack_require__(104);
	/**
	 * An implementation of a services provider.
	 */
	var JupyterServices = (function () {
	    /**
	     * Construct a new services provider.
	     */
	    function JupyterServices(baseUrl, ajaxSettings, specs) {
	        this._kernelManager = null;
	        this._sessionManager = null;
	        this._contentsManager = null;
	        this._kernelspecs = null;
	        var options = { baseUrl: baseUrl, ajaxSettings: ajaxSettings };
	        this._kernelspecs = specs;
	        this._kernelManager = new jupyter_js_services_1.KernelManager(options);
	        this._sessionManager = new jupyter_js_services_1.NotebookSessionManager(options);
	        this._contentsManager = new jupyter_js_services_1.ContentsManager(baseUrl, ajaxSettings);
	    }
	    Object.defineProperty(JupyterServices.prototype, "kernelspecs", {
	        /**
	         * Get kernel specs.
	         */
	        get: function () {
	            return this._kernelspecs;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(JupyterServices.prototype, "kernelManager", {
	        /**
	         * Get kernel manager instance.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._kernelManager;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(JupyterServices.prototype, "notebookSessionManager", {
	        /**
	         * Get the session manager instance.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._sessionManager;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(JupyterServices.prototype, "contentsManager", {
	        /**
	         * Get the contents manager instance.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._contentsManager;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return JupyterServices;
	}());
	exports.JupyterServices = JupyterServices;
	/**
	 * The default services provider.
	 */
	exports.servicesProvider = {
	    id: 'jupyter.services.services',
	    provides: JupyterServices,
	    resolve: function () {
	        var baseUrl = jupyter_js_utils_1.getBaseUrl();
	        var ajaxSettings = jupyter_js_utils_1.getConfigOption('ajaxSettings');
	        var options = { baseUrl: baseUrl, ajaxSettings: ajaxSettings };
	        return jupyter_js_services_1.getKernelSpecs(options).then(function (specs) {
	            return new JupyterServices(baseUrl, ajaxSettings, specs);
	        });
	    }
	};


/***/ },
/* 283 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var docmanager_1 = __webpack_require__(274);
	/**
	 * The editor handler extension.
	 */
	exports.editorHandlerExtension = {
	    id: 'jupyter.extensions.editorHandler',
	    requires: [docmanager_1.DocumentRegistry],
	    activate: function (app, registry) {
	        registry.registerWidgetFactory(new docmanager_1.EditorWidgetFactory(), {
	            fileExtensions: ['.*'],
	            displayName: 'Editor',
	            modelName: 'text',
	            defaultFor: ['.*'],
	            preferKernel: false,
	            canStartKernel: false
	        });
	    }
	};


/***/ },
/* 284 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var browser_1 = __webpack_require__(285);
	var model_1 = __webpack_require__(399);
	var docmanager_1 = __webpack_require__(274);
	var phosphor_menus_1 = __webpack_require__(287);
	var phosphor_tabs_1 = __webpack_require__(40);
	var plugin_1 = __webpack_require__(282);
	/**
	 * The default file browser extension.
	 */
	exports.fileBrowserExtension = {
	    id: 'jupyter.extensions.fileBrowser',
	    requires: [plugin_1.JupyterServices, docmanager_1.DocumentRegistry],
	    activate: activateFileBrowser
	};
	/**
	 * Activate the file browser.
	 */
	function activateFileBrowser(app, provider, registry) {
	    var contents = provider.contentsManager;
	    var sessions = provider.notebookSessionManager;
	    var widgets = [];
	    var activeWidget;
	    var id = 0;
	    var opener = {
	        open: function (widget) {
	            if (!widget.id) {
	                widget.id = "document-manager-" + ++id;
	            }
	            if (!widget.isAttached) {
	                app.shell.addToMainArea(widget);
	            }
	            // TODO: Move this logic to the shell.
	            var stack = widget.parent;
	            if (!stack) {
	                return;
	            }
	            var tabs = stack.parent;
	            if (tabs instanceof phosphor_tabs_1.TabPanel) {
	                tabs.currentWidget = widget;
	            }
	            activeWidget = widget;
	            widget.disposed.connect(function (w) {
	                var index = widgets.indexOf(w);
	                widgets.splice(index, 1);
	            });
	        }
	    };
	    // TODO: Move focus tracking to the shell.
	    document.addEventListener('focus', function (event) {
	        for (var i = 0; i < widgets.length; i++) {
	            var widget_1 = widgets[i];
	            if (widget_1.node.contains(event.target)) {
	                activeWidget = widget_1;
	                break;
	            }
	        }
	    });
	    var docManager = new docmanager_1.DocumentManager(registry, contents, sessions, provider.kernelspecs, opener);
	    var model = new model_1.FileBrowserModel(contents, sessions, provider.kernelspecs);
	    var widget = new browser_1.FileBrowserWidget(model, docManager, opener);
	    var menu = createMenu(widget);
	    // Add a context menu to the dir listing.
	    var node = widget.node.getElementsByClassName('jp-DirListing-content')[0];
	    node.addEventListener('contextmenu', function (event) {
	        event.preventDefault();
	        var x = event.clientX;
	        var y = event.clientY;
	        menu.popup(x, y);
	    });
	    // Add the command for a new items.
	    var newTextFileId = 'file-operations:new-text-file';
	    app.commands.add([
	        {
	            id: newTextFileId,
	            handler: function () { return widget.createNew('file'); }
	        }
	    ]);
	    var newNotebookId = 'file-operations:new-notebook';
	    app.commands.add([
	        {
	            id: newNotebookId,
	            handler: function () { return widget.createNew('notebook'); }
	        }]);
	    // Add the command for saving a document.
	    var saveDocumentId = 'file-operations:save';
	    app.commands.add([
	        {
	            id: saveDocumentId,
	            handler: function () {
	                if (!activeWidget) {
	                    return;
	                }
	                activeWidget.context.save();
	            }
	        }
	    ]);
	    app.palette.add([
	        {
	            command: saveDocumentId,
	            category: 'File Operations',
	            text: 'Save Document',
	            caption: 'Save the current document'
	        }
	    ]);
	    // Add the command for reverting a document.
	    var revertDocumentId = 'file-operations:revert';
	    app.commands.add([
	        {
	            id: revertDocumentId,
	            handler: function () {
	                if (!activeWidget) {
	                    return;
	                }
	                activeWidget.context.revert();
	            }
	        }
	    ]);
	    app.palette.add([
	        {
	            command: revertDocumentId,
	            category: 'File Operations',
	            text: 'Revert Document',
	            caption: 'Revert the current document'
	        }
	    ]);
	    // Add the command for closing a document.
	    var closeDocumentId = 'file-operations:close';
	    app.commands.add([
	        {
	            id: closeDocumentId,
	            handler: function () {
	                if (activeWidget) {
	                    activeWidget.close();
	                }
	            }
	        }
	    ]);
	    app.palette.add([
	        {
	            command: closeDocumentId,
	            category: 'File Operations',
	            text: 'Close Document',
	            caption: 'Close the current document'
	        }
	    ]);
	    // Add the command for closing all documents.
	    var closeAllId = 'file-operations:close-all';
	    app.commands.add([
	        {
	            id: closeAllId,
	            handler: function () {
	                docManager.closeAll();
	            }
	        }
	    ]);
	    app.palette.add([
	        {
	            command: closeAllId,
	            category: 'File Operations',
	            text: 'Close All',
	            caption: 'Close all open documents'
	        }
	    ]);
	    app.palette.add([
	        {
	            command: newTextFileId,
	            category: 'File Operations',
	            text: 'New Text File',
	            caption: 'Create a new text file'
	        },
	        {
	            command: newNotebookId,
	            category: 'File Operations',
	            text: 'New Notebook',
	            caption: 'Create a new notebook'
	        }
	    ]);
	    app.commands.add([
	        {
	            id: 'file-browser:activate',
	            handler: showBrowser
	        },
	        {
	            id: 'file-browser:hide',
	            handler: hideBrowser
	        },
	        {
	            id: 'file-browser:toggle',
	            handler: toggleBrowser
	        }
	    ]);
	    widget.title.text = 'Files';
	    widget.id = 'file-browser';
	    app.shell.addToLeftArea(widget, { rank: 40 });
	    showBrowser();
	    return Promise.resolve(void 0);
	    function showBrowser() {
	        app.shell.activateLeft(widget.id);
	    }
	    function hideBrowser() {
	        if (!widget.isHidden) {
	            app.shell.collapseLeft();
	        }
	    }
	    function toggleBrowser() {
	        if (widget.isHidden) {
	            showBrowser();
	        }
	        else {
	            hideBrowser();
	        }
	    }
	}
	/**
	 * Create a context menu for the file browser listing.
	 */
	function createMenu(fbWidget) {
	    return new phosphor_menus_1.Menu([
	        new phosphor_menus_1.MenuItem({
	            text: '&Open',
	            icon: 'fa fa-folder-open-o',
	            shortcut: 'Ctrl+O',
	            handler: function () { fbWidget.open(); }
	        }),
	        new phosphor_menus_1.MenuItem({
	            text: '&Rename',
	            icon: 'fa fa-edit',
	            shortcut: 'Ctrl+R',
	            handler: function () { fbWidget.rename(); }
	        }),
	        new phosphor_menus_1.MenuItem({
	            text: '&Delete',
	            icon: 'fa fa-remove',
	            shortcut: 'Ctrl+D',
	            handler: function () { fbWidget.delete(); }
	        }),
	        new phosphor_menus_1.MenuItem({
	            text: 'Duplicate',
	            icon: 'fa fa-copy',
	            handler: function () { fbWidget.duplicate(); }
	        }),
	        new phosphor_menus_1.MenuItem({
	            text: 'Cut',
	            icon: 'fa fa-cut',
	            shortcut: 'Ctrl+X',
	            handler: function () { fbWidget.cut(); }
	        }),
	        new phosphor_menus_1.MenuItem({
	            text: '&Copy',
	            icon: 'fa fa-copy',
	            shortcut: 'Ctrl+C',
	            handler: function () { fbWidget.copy(); }
	        }),
	        new phosphor_menus_1.MenuItem({
	            text: '&Paste',
	            icon: 'fa fa-paste',
	            shortcut: 'Ctrl+V',
	            handler: function () { fbWidget.paste(); }
	        }),
	        new phosphor_menus_1.MenuItem({
	            text: 'Download',
	            icon: 'fa fa-download',
	            handler: function () { fbWidget.download(); }
	        }),
	        new phosphor_menus_1.MenuItem({
	            text: 'Shutdown Kernel',
	            icon: 'fa fa-stop-circle-o',
	            handler: function () { fbWidget.shutdownKernels(); }
	        })
	    ]);
	}


/***/ },
/* 285 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_widget_1 = __webpack_require__(20);
	var buttons_1 = __webpack_require__(286);
	var crumbs_1 = __webpack_require__(295);
	var listing_1 = __webpack_require__(296);
	var utils_1 = __webpack_require__(294);
	/**
	 * The class name added to the filebrowser crumbs node.
	 */
	var CRUMBS_CLASS = 'jp-FileBrowser-crumbs';
	/**
	 * The class name added to the filebrowser buttons node.
	 */
	var BUTTON_CLASS = 'jp-FileBrowser-buttons';
	/**
	 * The class name added to the filebrowser listing node.
	 */
	var LISTING_CLASS = 'jp-FileBrowser-listing';
	/**
	 * The duration of auto-refresh in ms.
	 */
	var REFRESH_DURATION = 30000;
	/**
	 * A widget which hosts a file browser.
	 *
	 * The widget uses the Jupyter Contents API to retreive contents,
	 * and presents itself as a flat list of files and directories with
	 * breadcrumbs.
	 */
	var FileBrowserWidget = (function (_super) {
	    __extends(FileBrowserWidget, _super);
	    /**
	     * Construct a new file browser.
	     *
	     * @param model - The file browser view model.
	     */
	    function FileBrowserWidget(model, manager, opener) {
	        _super.call(this);
	        this._model = null;
	        this._crumbs = null;
	        this._buttons = null;
	        this._listing = null;
	        this._timeoutId = -1;
	        this._manager = null;
	        this._opener = null;
	        this.addClass(utils_1.FILE_BROWSER_CLASS);
	        this._model = model;
	        this._model.refreshed.connect(this._handleRefresh, this);
	        this._crumbs = new crumbs_1.BreadCrumbs(model);
	        this._buttons = new buttons_1.FileButtons(model, manager, opener);
	        this._listing = new listing_1.DirListing(model, manager, opener);
	        this._manager = manager;
	        this._opener = opener;
	        model.fileChanged.connect(function (fbModel, args) {
	            if (args.newValue) {
	                manager.handleRename(args.oldValue, args.newValue);
	            }
	            else {
	                manager.handleDelete(args.oldValue);
	            }
	        });
	        this._crumbs.addClass(CRUMBS_CLASS);
	        this._buttons.addClass(BUTTON_CLASS);
	        this._listing.addClass(LISTING_CLASS);
	        var layout = new phosphor_panel_1.PanelLayout();
	        layout.addChild(this._crumbs);
	        layout.addChild(this._buttons);
	        layout.addChild(this._listing);
	        this.layout = layout;
	    }
	    Object.defineProperty(FileBrowserWidget.prototype, "model", {
	        /**
	         * Get the model used by the file browser.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._model;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the file browser.
	     */
	    FileBrowserWidget.prototype.dispose = function () {
	        this._model = null;
	        this._crumbs = null;
	        this._buttons = null;
	        this._listing = null;
	        this._manager = null;
	        this._opener = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Change directory.
	     */
	    FileBrowserWidget.prototype.cd = function (path) {
	        return this._model.cd(path);
	    };
	    /**
	     * Open the currently selected item(s).
	     *
	     * Changes to the first directory encountered.
	     */
	    FileBrowserWidget.prototype.open = function () {
	        var _this = this;
	        var foundDir = false;
	        var items = this._model.sortedItems;
	        for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
	            var item = items_1[_i];
	            if (!this._model.isSelected(item.name)) {
	                continue;
	            }
	            if (item.type === 'directory') {
	                if (!foundDir) {
	                    foundDir = true;
	                    this._model.cd(item.name).catch(function (error) {
	                        return utils_1.showErrorMessage(_this, 'Open directory', error);
	                    });
	                }
	            }
	            else {
	                this.openPath(item.path);
	            }
	        }
	    };
	    /**
	     * Open a file by path.
	     */
	    FileBrowserWidget.prototype.openPath = function (path) {
	        var model = this.model;
	        var widget = this._manager.findWidget(path);
	        if (!widget) {
	            widget = this._manager.open(path);
	            widget.populated.connect(function () { return model.refresh(); });
	            widget.context.kernelChanged.connect(function () { return model.refresh(); });
	        }
	        this._opener.open(widget);
	        return widget;
	    };
	    /**
	     * Create a new untitled file in the current directory.
	     */
	    FileBrowserWidget.prototype.createNew = function (type, ext) {
	        var _this = this;
	        var model = this.model;
	        return model.newUntitled(type, ext).then(function (contents) {
	            var widget = _this._manager.createNew(contents.path);
	            widget.populated.connect(function () { return model.refresh(); });
	            widget.context.kernelChanged.connect(function () { return model.refresh(); });
	            _this._opener.open(widget);
	            return widget;
	        });
	    };
	    /**
	     * Rename the first currently selected item.
	     */
	    FileBrowserWidget.prototype.rename = function () {
	        return this._listing.rename();
	    };
	    /**
	     * Cut the selected items.
	     */
	    FileBrowserWidget.prototype.cut = function () {
	        this._listing.cut();
	    };
	    /**
	     * Copy the selected items.
	     */
	    FileBrowserWidget.prototype.copy = function () {
	        this._listing.copy();
	    };
	    /**
	     * Paste the items from the clipboard.
	     */
	    FileBrowserWidget.prototype.paste = function () {
	        return this._listing.paste();
	    };
	    /**
	     * Delete the currently selected item(s).
	     */
	    FileBrowserWidget.prototype.delete = function () {
	        return this._listing.delete();
	    };
	    /**
	     * Duplicate the currently selected item(s).
	     */
	    FileBrowserWidget.prototype.duplicate = function () {
	        return this._listing.duplicate();
	    };
	    /**
	     * Download the currently selected item(s).
	     */
	    FileBrowserWidget.prototype.download = function () {
	        return this._listing.download().then(function () { return void 0; });
	    };
	    /**
	     * Shut down kernels on the applicable currently selected items.
	     */
	    FileBrowserWidget.prototype.shutdownKernels = function () {
	        return this._listing.shutdownKernels();
	    };
	    /**
	     * Refresh the current directory.
	     */
	    FileBrowserWidget.prototype.refresh = function () {
	        var _this = this;
	        return this._model.refresh().catch(function (error) {
	            utils_1.showErrorMessage(_this, 'Server Connection Error', error);
	        });
	    };
	    /**
	     * Select next item.
	     */
	    FileBrowserWidget.prototype.selectNext = function () {
	        this._listing.selectNext();
	    };
	    /**
	     * Select previous item.
	     */
	    FileBrowserWidget.prototype.selectPrevious = function () {
	        this._listing.selectPrevious();
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    FileBrowserWidget.prototype.onAfterAttach = function (msg) {
	        _super.prototype.onAfterAttach.call(this, msg);
	        this.refresh();
	    };
	    /**
	     * A message handler invoked on an `'after-show'` message.
	     */
	    FileBrowserWidget.prototype.onAfterShow = function (msg) {
	        _super.prototype.onAfterShow.call(this, msg);
	        this.refresh();
	    };
	    /**
	     * Handle a model refresh.
	     */
	    FileBrowserWidget.prototype._handleRefresh = function () {
	        var _this = this;
	        clearTimeout(this._timeoutId);
	        this._timeoutId = setTimeout(function () { return _this.refresh(); }, REFRESH_DURATION);
	    };
	    return FileBrowserWidget;
	}(phosphor_widget_1.Widget));
	exports.FileBrowserWidget = FileBrowserWidget;


/***/ },
/* 286 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_menus_1 = __webpack_require__(287);
	var phosphor_widget_1 = __webpack_require__(20);
	var dialog_1 = __webpack_require__(115);
	var utils = __webpack_require__(294);
	/**
	 * The class name added to a file buttons widget.
	 */
	var FILE_BUTTONS_CLASS = 'jp-FileButtons';
	/**
	 * The class name added to a button node.
	 */
	var BUTTON_CLASS = 'jp-FileButtons-button';
	/**
	 * The class name added to a button content node.
	 */
	var CONTENT_CLASS = 'jp-FileButtons-buttonContent';
	/**
	 * The class name added to a button icon node.
	 */
	var ICON_CLASS = 'jp-FileButtons-buttonIcon';
	/**
	 * The class name added to the create button.
	 */
	var CREATE_CLASS = 'jp-id-create';
	/**
	 * The class name added to the upload button.
	 */
	var UPLOAD_CLASS = 'jp-id-upload';
	/**
	 * The class name added to the refresh button.
	 */
	var REFRESH_CLASS = 'jp-id-refresh';
	/**
	 * The class name added to an active create button.
	 */
	var ACTIVE_CLASS = 'jp-mod-active';
	/**
	 * The class name added to a dropdown icon.
	 */
	var DROPDOWN_CLASS = 'jp-FileButtons-dropdownIcon';
	/**
	 * A widget which hosts the file browser buttons.
	 */
	var FileButtons = (function (_super) {
	    __extends(FileButtons, _super);
	    /**
	     * Construct a new file browser buttons widget.
	     *
	     * @param model - The file browser view model.
	     */
	    function FileButtons(model, manager, opener) {
	        var _this = this;
	        _super.call(this);
	        /**
	         * The 'mousedown' handler for the create button.
	         */
	        this._onCreateButtonPressed = function (event) {
	            // Do nothing if nothing if it's not a left press.
	            if (event.button !== 0) {
	                return;
	            }
	            // Do nothing if the create button is already active.
	            var button = _this._buttons.create;
	            if (button.classList.contains(ACTIVE_CLASS)) {
	                return;
	            }
	            // Create a new dropdown menu and snap the button geometry.
	            var dropdown = Private.createDropdownMenu(_this);
	            var rect = button.getBoundingClientRect();
	            // Mark the button as active.
	            button.classList.add(ACTIVE_CLASS);
	            // Setup the `closed` signal handler. The menu is disposed on an
	            // animation frame to allow a mouse press event which closed the
	            // menu to run its course. This keeps the button from re-opening.
	            dropdown.closed.connect(function () {
	                requestAnimationFrame(function () { dropdown.dispose(); });
	            });
	            // Setup the `disposed` signal handler. This restores the button
	            // to the non-active state and allows a new menu to be opened.
	            dropdown.disposed.connect(function () {
	                button.classList.remove(ACTIVE_CLASS);
	            });
	            // Popup the menu aligned with the bottom of the create button.
	            dropdown.popup(rect.left, rect.bottom, false, true);
	        };
	        /**
	         * The 'click' handler for the upload button.
	         */
	        this._onUploadButtonClicked = function (event) {
	            if (event.button !== 0) {
	                return;
	            }
	            _this._input.click();
	        };
	        /**
	         * The 'click' handler for the refresh button.
	         */
	        this._onRefreshButtonClicked = function (event) {
	            if (event.button !== 0) {
	                return;
	            }
	            _this._model.refresh().catch(function (error) {
	                utils.showErrorMessage(_this, 'Server Connection Error', error);
	            });
	        };
	        /**
	         * The 'change' handler for the input field.
	         */
	        this._onInputChanged = function () {
	            var files = Array.prototype.slice.call(_this._input.files);
	            Private.uploadFiles(_this, files);
	        };
	        this._buttons = Private.createButtons();
	        this._input = Private.createUploadInput();
	        this._manager = null;
	        this._opener = null;
	        this.addClass(FILE_BUTTONS_CLASS);
	        this._model = model;
	        this._buttons.create.onmousedown = this._onCreateButtonPressed;
	        this._buttons.upload.onclick = this._onUploadButtonClicked;
	        this._buttons.refresh.onclick = this._onRefreshButtonClicked;
	        this._input.onchange = this._onInputChanged;
	        var node = this.node;
	        node.appendChild(this._buttons.create);
	        node.appendChild(this._buttons.upload);
	        node.appendChild(this._buttons.refresh);
	        this._manager = manager;
	        this._opener = opener;
	    }
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    FileButtons.prototype.dispose = function () {
	        this._model = null;
	        this._buttons = null;
	        this._input = null;
	        this._manager = null;
	        this._opener = null;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(FileButtons.prototype, "model", {
	        /**
	         * Get the model used by the widget.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._model;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FileButtons.prototype, "manager", {
	        /**
	         * Get the document manager used by the widget.
	         */
	        get: function () {
	            return this._manager;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Open a file by path.
	     */
	    FileButtons.prototype.open = function (path, widgetName, kernel) {
	        var _this = this;
	        if (widgetName === void 0) { widgetName = 'default'; }
	        var widget = this._manager.open(path, widgetName, kernel);
	        var opener = this._opener;
	        opener.open(widget);
	        widget.populated.connect(function () { return _this.model.refresh(); });
	        widget.context.kernelChanged.connect(function () { return _this.model.refresh(); });
	    };
	    /**
	     * Create a new file by path.
	     */
	    FileButtons.prototype.createNew = function (path, widgetName, kernel) {
	        var _this = this;
	        if (widgetName === void 0) { widgetName = 'default'; }
	        var widget = this._manager.createNew(path, widgetName, kernel);
	        var opener = this._opener;
	        opener.open(widget);
	        widget.populated.connect(function () { return _this.model.refresh(); });
	        widget.context.kernelChanged.connect(function () { return _this.model.refresh(); });
	    };
	    return FileButtons;
	}(phosphor_widget_1.Widget));
	exports.FileButtons = FileButtons;
	/**
	 * The namespace for the `FileButtons` private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create the button group for a file buttons widget.
	     */
	    function createButtons() {
	        var create = document.createElement('button');
	        var upload = document.createElement('button');
	        var refresh = document.createElement('button');
	        var createContent = document.createElement('span');
	        var uploadContent = document.createElement('span');
	        var refreshContent = document.createElement('span');
	        var createIcon = document.createElement('span');
	        var uploadIcon = document.createElement('span');
	        var refreshIcon = document.createElement('span');
	        var dropdownIcon = document.createElement('span');
	        create.type = 'button';
	        upload.type = 'button';
	        refresh.type = 'button';
	        create.title = 'Create New...';
	        upload.title = 'Upload File(s)';
	        refresh.title = 'Refresh File List';
	        create.className = BUTTON_CLASS + " " + CREATE_CLASS;
	        upload.className = BUTTON_CLASS + " " + UPLOAD_CLASS;
	        refresh.className = BUTTON_CLASS + " " + REFRESH_CLASS;
	        createContent.className = CONTENT_CLASS;
	        uploadContent.className = CONTENT_CLASS;
	        refreshContent.className = CONTENT_CLASS;
	        // TODO make these icons configurable.
	        createIcon.className = ICON_CLASS + ' fa fa-plus';
	        uploadIcon.className = ICON_CLASS + ' fa fa-upload';
	        refreshIcon.className = ICON_CLASS + ' fa fa-refresh';
	        dropdownIcon.className = DROPDOWN_CLASS + ' fa fa-caret-down';
	        createContent.appendChild(createIcon);
	        createContent.appendChild(dropdownIcon);
	        uploadContent.appendChild(uploadIcon);
	        refreshContent.appendChild(refreshIcon);
	        create.appendChild(createContent);
	        upload.appendChild(uploadContent);
	        refresh.appendChild(refreshContent);
	        return { create: create, upload: upload, refresh: refresh };
	    }
	    Private.createButtons = createButtons;
	    /**
	     * Create the upload input node for a file buttons widget.
	     */
	    function createUploadInput() {
	        var input = document.createElement('input');
	        input.type = 'file';
	        input.multiple = true;
	        return input;
	    }
	    Private.createUploadInput = createUploadInput;
	    /**
	     * Create a new source file.
	     */
	    function createNewFile(widget) {
	        widget.model.newUntitled('file').then(function (contents) {
	            return widget.open(contents.path);
	        }).catch(function (error) {
	            utils.showErrorMessage(widget, 'New File Error', error);
	        });
	    }
	    Private.createNewFile = createNewFile;
	    /**
	     * Create a new folder.
	     */
	    function createNewFolder(widget) {
	        widget.model.newUntitled('directory').then(function (contents) {
	            widget.model.refresh();
	        }).catch(function (error) {
	            utils.showErrorMessage(widget, 'New Folder Error', error);
	        });
	    }
	    Private.createNewFolder = createNewFolder;
	    /**
	     * Create a new item using a file creator.
	     */
	    function createNewItem(widget, creator) {
	        var fileType = creator.type || 'file';
	        var widgetName = creator.widgetName || 'default';
	        var kernel;
	        if (creator.kernelName) {
	            kernel = { name: creator.kernelName };
	        }
	        widget.model.newUntitled(fileType, creator.extension).then(function (contents) {
	            widget.createNew(contents.path, widgetName, kernel);
	        });
	    }
	    /**
	     * Create a new dropdown menu for the create new button.
	     */
	    function createDropdownMenu(widget) {
	        var items = [
	            new phosphor_menus_1.MenuItem({
	                text: 'Text File',
	                handler: function () { createNewFile(widget); }
	            }),
	            new phosphor_menus_1.MenuItem({
	                text: 'Folder',
	                handler: function () { createNewFolder(widget); }
	            })
	        ];
	        var creators = widget.manager.registry.listCreators();
	        if (creators) {
	            items.push(new phosphor_menus_1.MenuItem({ type: phosphor_menus_1.MenuItem.Separator }));
	        }
	        var _loop_1 = function(creator) {
	            var item = new phosphor_menus_1.MenuItem({
	                text: creator.name,
	                handler: function () { createNewItem(widget, creator); }
	            });
	            items.push(item);
	        };
	        for (var _i = 0, creators_1 = creators; _i < creators_1.length; _i++) {
	            var creator = creators_1[_i];
	            _loop_1(creator);
	        }
	        return new phosphor_menus_1.Menu(items);
	    }
	    Private.createDropdownMenu = createDropdownMenu;
	    /**
	     * Upload an array of files to the server.
	     */
	    function uploadFiles(widget, files) {
	        var pending = files.map(function (file) { return uploadFile(widget, file); });
	        Promise.all(pending).then(function () {
	            widget.model.refresh();
	        }).catch(function (error) {
	            utils.showErrorMessage(widget, 'Upload Error', error);
	        });
	    }
	    Private.uploadFiles = uploadFiles;
	    /**
	     * Upload a file to the server.
	     */
	    function uploadFile(widget, file) {
	        return widget.model.upload(file).catch(function (error) {
	            var exists = error.message.indexOf('already exists') !== -1;
	            if (exists) {
	                return uploadFileOverride(widget, file);
	            }
	            throw error;
	        });
	    }
	    /**
	     * Upload a file to the server checking for override.
	     */
	    function uploadFileOverride(widget, file) {
	        var options = {
	            title: 'Overwrite File?',
	            host: widget.parent.node,
	            body: "\"" + file.name + "\" already exists, overwrite?"
	        };
	        return dialog_1.showDialog(options).then(function (button) {
	            if (button.text !== 'Ok') {
	                return;
	            }
	            return widget.model.upload(file, true);
	        });
	    }
	})(Private || (Private = {}));


/***/ },
/* 287 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	__export(__webpack_require__(288));
	__export(__webpack_require__(289));
	__export(__webpack_require__(291));
	__export(__webpack_require__(290));
	__webpack_require__(292);


/***/ },
/* 288 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var arrays = __webpack_require__(3);
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * An abstract base class for implementing menu widgets.
	 *
	 * #### Notes
	 * This class must be subclassed to create a useful menu.
	 */
	var AbstractMenu = (function (_super) {
	    __extends(AbstractMenu, _super);
	    function AbstractMenu() {
	        _super.apply(this, arguments);
	        this._activeIndex = -1;
	        this._items = Object.freeze([]);
	    }
	    Object.defineProperty(AbstractMenu.prototype, "items", {
	        /**
	         * Get the array of menu items for the menu.
	         *
	         * #### Notes
	         * The items array is frozen and cannot be modified in-place.
	         */
	        get: function () {
	            return this._items;
	        },
	        /**
	         * Set the array of menu items for the menu.
	         *
	         * #### Notes
	         * This creates a shallow copy of the assigned menu items.
	         */
	        set: function (value) {
	            if (this._items === value) {
	                return;
	            }
	            this._activeIndex = -1;
	            var oldItems = this._items;
	            this._items = Object.freeze(value.slice());
	            this.onItemsChanged(oldItems, this._items);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(AbstractMenu.prototype, "activeIndex", {
	        /**
	         * Get the index of the currently active menu item.
	         *
	         * #### Notes
	         * This will be `-1` if there is no active item.
	         */
	        get: function () {
	            return this._activeIndex;
	        },
	        /**
	         * Set the index of the currently active menu item.
	         *
	         * #### Notes
	         * If the index is out of range, or points to a menu item which is
	         * not selectable, the index will be set to `-1`.
	         *
	         * Setting the active index has O(1) complexity.
	         */
	        set: function (value) {
	            var newIndex = value | 0;
	            var item = this._items[newIndex];
	            if (!item || !this.isSelectable(item)) {
	                newIndex = -1;
	            }
	            var oldIndex = this._activeIndex;
	            if (oldIndex === newIndex) {
	                return;
	            }
	            this._activeIndex = newIndex;
	            this.onActiveIndexChanged(oldIndex, newIndex);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(AbstractMenu.prototype, "activeItem", {
	        /**
	         * Get the currently active menu item.
	         *
	         * #### Notes
	         * This will be `null` if there is no active item.
	         */
	        get: function () {
	            return this._items[this._activeIndex] || null;
	        },
	        /**
	         * Set the currently active menu item.
	         *
	         * #### Notes
	         * If the item is not contained in the menu, or is not a selectable
	         * item, the active item will be set to `null`.
	         *
	         * Setting the active item has O(n) complexity.
	         */
	        set: function (value) {
	            this.activeIndex = this._items.indexOf(value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Activate the next selectable menu item.
	     *
	     * #### Notes
	     * The search starts with the currently active item, and progresses
	     * forward until the next selectable item is found. The search will
	     * wrap around at the end of the menu.
	     */
	    AbstractMenu.prototype.activateNextItem = function () {
	        var _this = this;
	        var k = this.activeIndex + 1;
	        var i = k >= this.items.length ? 0 : k;
	        var pred = function (item) { return _this.isSelectable(item); };
	        this.activeIndex = arrays.findIndex(this.items, pred, i, true);
	    };
	    /**
	     * Activate the previous selectable menu item.
	     *
	     * #### Notes
	     * The search starts with the currently active item, and progresses
	     * backward until the next selectable item is found. The search will
	     * wrap around at the front of the menu.
	     */
	    AbstractMenu.prototype.activatePreviousItem = function () {
	        var _this = this;
	        var k = this.activeIndex;
	        var i = k <= 0 ? this.items.length - 1 : k - 1;
	        var pred = function (item) { return _this.isSelectable(item); };
	        this.activeIndex = arrays.rfindIndex(this.items, pred, i, true);
	    };
	    /**
	     * Activate the next selectable menu item with the given mnemonic.
	     *
	     * #### Notes
	     * The search starts with the currently active item, and progresses
	     * forward until the next selectable item with the given mnemonic is
	     * found. The search will wrap around at the end of the menu, and the
	     * mnemonic matching is case-insensitive.
	     */
	    AbstractMenu.prototype.activateMnemonicItem = function (char) {
	        var _this = this;
	        var c = char.toUpperCase();
	        var k = this.activeIndex + 1;
	        var i = k >= this.items.length ? 0 : k;
	        this.activeIndex = arrays.findIndex(this.items, function (item) {
	            if (!_this.isSelectable(item)) {
	                return false;
	            }
	            var match = item.text.match(/&\w/);
	            if (!match) {
	                return false;
	            }
	            return match[0][1].toUpperCase() === c;
	        }, i, true);
	    };
	    return AbstractMenu;
	})(phosphor_widget_1.Widget);
	exports.AbstractMenu = AbstractMenu;


/***/ },
/* 289 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var arrays = __webpack_require__(3);
	var phosphor_domutil_1 = __webpack_require__(7);
	var phosphor_messaging_1 = __webpack_require__(13);
	var phosphor_signaling_1 = __webpack_require__(22);
	var phosphor_widget_1 = __webpack_require__(20);
	var base_1 = __webpack_require__(288);
	var menuitem_1 = __webpack_require__(290);
	/**
	 * The class name added to Menu instances.
	 */
	var MENU_CLASS = 'p-Menu';
	/**
	 * The class name added to a menu content node.
	 */
	var CONTENT_CLASS = 'p-Menu-content';
	/**
	 * The class name added to a menu item node.
	 */
	var ITEM_CLASS = 'p-Menu-item';
	/**
	 * The class name added to a menu item icon cell.
	 */
	var ICON_CLASS = 'p-Menu-itemIcon';
	/**
	 * The class name added to a menu item text cell.
	 */
	var TEXT_CLASS = 'p-Menu-itemText';
	/**
	 * The class name added to a menu item shortcut cell.
	 */
	var SHORTCUT_CLASS = 'p-Menu-itemShortcut';
	/**
	 * The class name added to a menu item submenu icon cell.
	 */
	var SUBMENU_CLASS = 'p-Menu-itemSubmenuIcon';
	/**
	 * The class name added to a check type menu item.
	 */
	var CHECK_TYPE_CLASS = 'p-type-check';
	/**
	 * The class name added to a separator type menu item.
	 */
	var SEPARATOR_TYPE_CLASS = 'p-type-separator';
	/**
	 * The class name added to a submenu type menu item.
	 */
	var SUBMENU_TYPE_CLASS = 'p-type-submenu';
	/**
	 * The class name added to active menu items.
	 */
	var ACTIVE_CLASS = 'p-mod-active';
	/**
	 * The class name added to a disabled menu item.
	 */
	var DISABLED_CLASS = 'p-mod-disabled';
	/**
	 * The class name added to a checked menu item.
	 */
	var CHECKED_CLASS = 'p-mod-checked';
	/**
	 * The class name added to a hidden menu item.
	 */
	var HIDDEN_CLASS = 'p-mod-hidden';
	/**
	 * The ms delay for opening a submenu.
	 */
	var OPEN_DELAY = 300;
	/**
	 * The ms delay for closing a submenu.
	 */
	var CLOSE_DELAY = 300;
	/**
	 * The horizontal px overlap for open submenus.
	 */
	var SUBMENU_OVERLAP = 3;
	/**
	 * A widget which displays menu items as a popup menu.
	 */
	var Menu = (function (_super) {
	    __extends(Menu, _super);
	    /**
	     * Construct a new menu.
	     *
	     * @param items - Optional menu items to initialize the menu.
	     *
	     * #### Notes
	     * Subclasses should not pass menu items to `super`. The subclass
	     * should set its own items after it has been fully initialized.
	     */
	    function Menu(items) {
	        _super.call(this);
	        this._openTimerId = 0;
	        this._closeTimerId = 0;
	        this._parentMenu = null;
	        this._childMenu = null;
	        this._childItem = null;
	        this._nodes = [];
	        this.addClass(MENU_CLASS);
	        if (items)
	            this.items = items;
	    }
	    /**
	     * Create the DOM node for a menu.
	     */
	    Menu.createNode = function () {
	        var node = document.createElement('div');
	        var content = document.createElement('ul');
	        content.className = CONTENT_CLASS;
	        node.appendChild(content);
	        return node;
	    };
	    /**
	     * Create a new item node for a menu.
	     *
	     * @returns A new DOM node to use as an item in a menu.
	     *
	     * #### Notes
	     * This method may be reimplemented to create custom items.
	     */
	    Menu.createItemNode = function () {
	        var node = document.createElement('li');
	        var icon = document.createElement('span');
	        var text = document.createElement('span');
	        var shortcut = document.createElement('span');
	        var submenu = document.createElement('span');
	        node.className = ITEM_CLASS;
	        text.className = TEXT_CLASS;
	        shortcut.className = SHORTCUT_CLASS;
	        submenu.className = SUBMENU_CLASS;
	        node.appendChild(icon);
	        node.appendChild(text);
	        node.appendChild(shortcut);
	        node.appendChild(submenu);
	        return node;
	    };
	    /**
	     * Update an item node to reflect the current state of a menu item.
	     *
	     * @param node - A node created by a call to [[createItemNode]].
	     *
	     * @param item - The menu item to use for the item state.
	     *
	     * #### Notes
	     * This is called automatically when the item should be updated.
	     *
	     * If the [[createItemNode]] method is reimplemented, this method
	     * should also be reimplemented so that the item state is properly
	     * updated.
	     */
	    Menu.updateItemNode = function (node, item) {
	        var sep = item.type === menuitem_1.MenuItem.Separator;
	        var sub = item.type === menuitem_1.MenuItem.Submenu;
	        var icon = node.firstChild;
	        var text = icon.nextSibling;
	        var shortcut = text.nextSibling;
	        node.className = MenuPrivate.createItemClass(item);
	        icon.className = ICON_CLASS + (item.icon ? ' ' + item.icon : '');
	        text.textContent = sep ? '' : item.text.replace(/&/g, '');
	        shortcut.textContent = (sep || sub) ? '' : item.shortcut;
	    };
	    /**
	     * Dispose of the resources held by the menu.
	     */
	    Menu.prototype.dispose = function () {
	        this.close();
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(Menu.prototype, "closed", {
	        /**
	         * A signal emitted when the menu item is closed.
	         */
	        get: function () {
	            return MenuPrivate.closedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "parentMenu", {
	        /**
	         * Get the parent menu of the menu.
	         *
	         * #### Notes
	         * This will be `null` if the menu is not an open submenu.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._parentMenu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "childMenu", {
	        /**
	         * Get the child menu of the menu.
	         *
	         * #### Notes
	         * This will be `null` if the menu does not have an open submenu.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._childMenu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "rootMenu", {
	        /**
	         * Find the root menu of this menu hierarchy.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            var menu = this;
	            while (menu._parentMenu) {
	                menu = menu._parentMenu;
	            }
	            return menu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "leafMenu", {
	        /**
	         * Find the leaf menu of this menu hierarchy.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            var menu = this;
	            while (menu._childMenu) {
	                menu = menu._childMenu;
	            }
	            return menu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "contentNode", {
	        /**
	         * Get the menu content node.
	         *
	         * #### Notes
	         * This is the node which holds the menu item nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this.node.getElementsByClassName(CONTENT_CLASS)[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Open the submenu of the active item, if possible.
	     *
	     * #### Notes
	     * This is a no-op if the menu is not visible, if there is no active
	     * item, or if the active item is disabled or has a null submenu.
	     */
	    Menu.prototype.openActiveItem = function () {
	        if (!this.isVisible) {
	            return;
	        }
	        var index = this.activeIndex;
	        if (index === -1) {
	            return;
	        }
	        var item = this.items[index];
	        if (item.disabled || !item.submenu) {
	            return;
	        }
	        this._openChildMenu(item, this._nodes[index], false);
	        this._childMenu.activateNextItem();
	    };
	    /**
	     * Trigger the handler of the active item, if possible.
	     *
	     * #### Notes
	     * This is a no-op if the menu is not visible, if there is no
	     * active item, or if the active item is disabled.
	     */
	    Menu.prototype.triggerActiveItem = function () {
	        if (!this.isVisible) {
	            return;
	        }
	        var index = this.activeIndex;
	        if (index === -1) {
	            return;
	        }
	        var item = this.items[index];
	        if (item.disabled) {
	            return;
	        }
	        if (item.submenu) {
	            this._openChildMenu(item, this._nodes[index], false);
	            this._childMenu.activateNextItem();
	            return;
	        }
	        var handler = item.handler;
	        if (!handler) {
	            return;
	        }
	        this.rootMenu.close();
	        handler(item);
	    };
	    /**
	     * Popup the menu at the specified location.
	     *
	     * 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. The last two optional parameters
	     * control whether the provided coordinate value must be obeyed.
	     *
	     * When the menu is opened as a popup menu, it will handle all key
	     * events related to menu navigation as well as closing the menu
	     * when the mouse is pressed outside of the menu hierarchy. To
	     * prevent these actions, use the [[open]] method instead.
	     *
	     * @param x - The client X coordinate of the popup location.
	     *
	     * @param y - The client Y coordinate of the popup location.
	     *
	     * @param forceX - Whether the X coordinate must be obeyed.
	     *
	     * @param forceY - Whether the Y coordinate must be obeyed.
	     *
	     * #### Notes
	     * This is a no-op if the menu is already attached to the DOM.
	     *
	     * **See also:** [[open]]
	     */
	    Menu.prototype.popup = function (x, y, forceX, forceY) {
	        if (forceX === void 0) { forceX = false; }
	        if (forceY === void 0) { forceY = false; }
	        if (!this.isAttached) {
	            document.addEventListener('keydown', this, true);
	            document.addEventListener('keypress', this, true);
	            document.addEventListener('mousedown', this, true);
	            MenuPrivate.openRootMenu(this, x, y, forceX, forceY);
	        }
	    };
	    /**
	     * Open the menu at the specified location.
	     *
	     * 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. The last two optional parameters
	     * control whether the provided coordinate value must be obeyed.
	     *
	     * When the menu is opened with this method, it will not handle key
	     * events for navigation, nor will it close itself when the mouse is
	     * pressed outside the menu hierarchy. This is useful when using the
	     * menu from a menubar, where the menubar should handle these tasks.
	     * Use the [[popup]] method for the alternative behavior.
	     *
	     * @param x - The client X coordinate of the popup location.
	     *
	     * @param y - The client Y coordinate of the popup location.
	     *
	     * @param forceX - Whether the X coordinate must be obeyed.
	     *
	     * @param forceY - Whether the Y coordinate must be obeyed.
	     *
	     * #### Notes
	     * This is a no-op if the menu is already attached to the DOM.
	     *
	     * **See also:** [[popup]]
	     */
	    Menu.prototype.open = function (x, y, forceX, forceY) {
	        if (forceX === void 0) { forceX = false; }
	        if (forceY === void 0) { forceY = false; }
	        if (!this.isAttached) {
	            MenuPrivate.openRootMenu(this, x, y, forceX, forceY);
	        }
	    };
	    /**
	     * 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 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseleave':
	                this._evtMouseLeave(event);
	                break;
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'keypress':
	                this._evtKeyPress(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A method invoked to test whether an item is selectable.
	     *
	     * @param item - The menu item of interest.
	     *
	     * @returns `true` if the item is selectable, `false` otherwise.
	     */
	    Menu.prototype.isSelectable = function (item) {
	        if (item.disabled || item.type === menuitem_1.MenuItem.Separator) {
	            return false;
	        }
	        if (item.type === menuitem_1.MenuItem.Submenu) {
	            return !!item.submenu;
	        }
	        return !!item.handler;
	    };
	    /**
	     * A method invoked when the menu items change.
	     *
	     * @param oldItems - The old menu items.
	     *
	     * @param newItems - The new menu items.
	     */
	    Menu.prototype.onItemsChanged = function (oldItems, newItems) {
	        // Reset the menu before changing the items.
	        this.close();
	        // Fetch common variables.
	        var nodes = this._nodes;
	        var content = this.contentNode;
	        var constructor = this.constructor;
	        // Remove any excess item nodes.
	        while (nodes.length > newItems.length) {
	            var node = nodes.pop();
	            content.removeChild(node);
	        }
	        // Add any missing item nodes.
	        while (nodes.length < newItems.length) {
	            var node = constructor.createItemNode();
	            content.appendChild(node);
	            nodes.push(node);
	        }
	        // An update is performed just before opening the menu, which
	        // removes the need to connect the menu item `changed` signal.
	    };
	    /**
	     * A method invoked when the active index changes.
	     *
	     * @param oldIndex - The old active index.
	     *
	     * @param newIndex - The new active index.
	     */
	    Menu.prototype.onActiveIndexChanged = function (oldIndex, newIndex) {
	        var oldNode = this._nodes[oldIndex];
	        var newNode = this._nodes[newIndex];
	        if (oldNode)
	            oldNode.classList.remove(ACTIVE_CLASS);
	        if (newNode)
	            newNode.classList.add(ACTIVE_CLASS);
	    };
	    /**
	     * A message handler invoked on a `'close-request'` message.
	     */
	    Menu.prototype.onCloseRequest = function (msg) {
	        // Reset the menu state.
	        this._cancelPendingOpen();
	        this._cancelPendingClose();
	        this.activeIndex = -1;
	        // Close any open child menu.
	        var childMenu = this._childMenu;
	        if (childMenu) {
	            this._childMenu = null;
	            this._childItem = null;
	            childMenu._parentMenu = null;
	            childMenu.close();
	        }
	        // Remove this menu from any parent.
	        var parentMenu = this._parentMenu;
	        if (parentMenu) {
	            this._parentMenu = null;
	            parentMenu._cancelPendingOpen();
	            parentMenu._cancelPendingClose();
	            parentMenu._childMenu = null;
	            parentMenu._childItem = null;
	        }
	        // Ensure this menu is detached.
	        if (this.parent) {
	            this.parent = null;
	            this.closed.emit(void 0);
	        }
	        else if (this.isAttached) {
	            this.detach();
	            this.closed.emit(void 0);
	        }
	    };
	    /**
	     * A handler invoked on an `'update-request'` message.
	     */
	    Menu.prototype.onUpdateRequest = function (msg) {
	        // Fetch common variables.
	        var items = this.items;
	        var nodes = this._nodes;
	        var constructor = this.constructor;
	        // Update the state of the item nodes.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            constructor.updateItemNode(nodes[i], items[i]);
	        }
	        // Restore the active node class.
	        var active = nodes[this.activeIndex];
	        if (active)
	            active.classList.add(ACTIVE_CLASS);
	        // Hide the redundant and useless menu item nodes.
	        MenuPrivate.hideUselessItems(nodes, items);
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    Menu.prototype.onAfterAttach = function (msg) {
	        this.node.addEventListener('mouseup', this);
	        this.node.addEventListener('mousemove', this);
	        this.node.addEventListener('mouseleave', this);
	        this.node.addEventListener('contextmenu', this);
	    };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     */
	    Menu.prototype.onBeforeDetach = function (msg) {
	        this.node.removeEventListener('mouseup', this);
	        this.node.removeEventListener('mousemove', this);
	        this.node.removeEventListener('mouseleave', this);
	        this.node.removeEventListener('contextmenu', this);
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('keypress', this, true);
	        document.removeEventListener('mousedown', this, true);
	    };
	    /**
	     * Handle the `'mousemove'` event for the menu.
	     */
	    Menu.prototype._evtMouseMove = function (event) {
	        var x = event.clientX;
	        var y = event.clientY;
	        var i = arrays.findIndex(this._nodes, function (node) { return phosphor_domutil_1.hitTest(node, x, y); });
	        if (i === this.activeIndex) {
	            return;
	        }
	        this.activeIndex = i;
	        this._syncAncestors();
	        this._closeChildMenu();
	        this._cancelPendingOpen();
	        var item = this.activeItem;
	        if (item && item.submenu) {
	            if (item === this._childItem) {
	                this._cancelPendingClose();
	            }
	            else {
	                this._openChildMenu(item, this._nodes[i], true);
	            }
	        }
	    };
	    /**
	     * Handle the `'mouseleave'` event for the menu.
	     */
	    Menu.prototype._evtMouseLeave = function (event) {
	        this._cancelPendingOpen();
	        var x = event.clientX;
	        var y = event.clientY;
	        var child = this._childMenu;
	        if (!child || !phosphor_domutil_1.hitTest(child.node, x, y)) {
	            this.activeIndex = -1;
	            this._closeChildMenu();
	        }
	    };
	    /**
	     * Handle the `'mousedown'` event for the menu.
	     *
	     * This event listener is attached to the document for a popup menu.
	     *
	     * This allows the event to propagate so the element under the mouse
	     * can be focused without requiring a second click.
	     */
	    Menu.prototype._evtMouseDown = function (event) {
	        var menu = this;
	        var hit = false;
	        var x = event.clientX;
	        var y = event.clientY;
	        while (!hit && menu) {
	            hit = phosphor_domutil_1.hitTest(menu.node, x, y);
	            menu = menu._childMenu;
	        }
	        if (!hit)
	            this.close();
	    };
	    /**
	     * Handle the `'mouseup'` event for the menu.
	     */
	    Menu.prototype._evtMouseUp = function (event) {
	        if (event.button !== 0) {
	            return;
	        }
	        event.preventDefault();
	        event.stopPropagation();
	        var node = this._nodes[this.activeIndex];
	        if (node && node.contains(event.target)) {
	            this.triggerActiveItem();
	        }
	    };
	    /**
	     * Handle the `'keydown'` event for the menu.
	     *
	     * This event listener is attached to the document for a popup menu.
	     */
	    Menu.prototype._evtKeyDown = function (event) {
	        event.stopPropagation();
	        var leaf = this.leafMenu;
	        switch (event.keyCode) {
	            case 13:
	                event.preventDefault();
	                leaf.triggerActiveItem();
	                break;
	            case 27:
	                event.preventDefault();
	                leaf.close();
	                break;
	            case 37:
	                event.preventDefault();
	                if (leaf !== this)
	                    leaf.close();
	                break;
	            case 38:
	                event.preventDefault();
	                leaf.activatePreviousItem();
	                break;
	            case 39:
	                event.preventDefault();
	                leaf.openActiveItem();
	                break;
	            case 40:
	                event.preventDefault();
	                leaf.activateNextItem();
	                break;
	        }
	    };
	    /**
	     * Handle the `'keypress'` event for the menu.
	     *
	     * This event listener is attached to the document for a popup menu.
	     */
	    Menu.prototype._evtKeyPress = function (event) {
	        event.preventDefault();
	        event.stopPropagation();
	        var key = String.fromCharCode(event.charCode);
	        this.leafMenu.activateMnemonicItem(key);
	    };
	    /**
	     * Synchronize the active item hierarchy starting with the parent.
	     *
	     * This ensures that the proper child items are activated for the
	     * ancestor menu hierarchy and that any pending open or close tasks
	     * are canceled.
	     */
	    Menu.prototype._syncAncestors = function () {
	        var menu = this._parentMenu;
	        while (menu) {
	            menu._syncChildItem();
	            menu = menu._parentMenu;
	        }
	    };
	    /**
	     * Synchronize the active index with the current child item.
	     */
	    Menu.prototype._syncChildItem = function () {
	        this._cancelPendingOpen();
	        this._cancelPendingClose();
	        this.activeIndex = this.items.indexOf(this._childItem);
	    };
	    /**
	     * Open the menu item's submenu using the node for location.
	     *
	     * If the given item is already open, this is a no-op.
	     *
	     * Any pending open operation will be canceled before opening the
	     * menu or queuing the delayed task to open the menu.
	     */
	    Menu.prototype._openChildMenu = function (item, node, delayed) {
	        var _this = this;
	        if (item === this._childItem) {
	            return;
	        }
	        this._cancelPendingOpen();
	        if (delayed) {
	            this._openTimerId = setTimeout(function () {
	                var menu = item.submenu;
	                _this._openTimerId = 0;
	                _this._childItem = item;
	                _this._childMenu = menu;
	                menu._parentMenu = _this;
	                MenuPrivate.openSubmenu(menu, node);
	            }, OPEN_DELAY);
	        }
	        else {
	            var menu = item.submenu;
	            this._childItem = item;
	            this._childMenu = menu;
	            menu._parentMenu = this;
	            MenuPrivate.openSubmenu(menu, node);
	        }
	    };
	    /**
	     * Close the currently open child menu using a delayed task.
	     *
	     * If a task is pending or if there is no child menu, this is a no-op.
	     */
	    Menu.prototype._closeChildMenu = function () {
	        var _this = this;
	        if (this._closeTimerId || !this._childMenu) {
	            return;
	        }
	        this._closeTimerId = setTimeout(function () {
	            _this._closeTimerId = 0;
	            var childMenu = _this._childMenu;
	            if (childMenu) {
	                _this._childMenu = null;
	                _this._childItem = null;
	                childMenu._parentMenu = null;
	                childMenu.close();
	            }
	        }, CLOSE_DELAY);
	    };
	    /**
	     * Cancel any pending child menu open task.
	     */
	    Menu.prototype._cancelPendingOpen = function () {
	        if (this._openTimerId) {
	            clearTimeout(this._openTimerId);
	            this._openTimerId = 0;
	        }
	    };
	    /**
	     * Cancel any pending child menu close task.
	     */
	    Menu.prototype._cancelPendingClose = function () {
	        if (this._closeTimerId) {
	            clearTimeout(this._closeTimerId);
	            this._closeTimerId = 0;
	        }
	    };
	    return Menu;
	})(base_1.AbstractMenu);
	exports.Menu = Menu;
	/**
	 * The namespace for the menu private data.
	 */
	var MenuPrivate;
	(function (MenuPrivate) {
	    /**
	     * A signal emitted when the menu is closed.
	     */
	    MenuPrivate.closedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * Create the class name for a menu item.
	     */
	    function createItemClass(item) {
	        var name = ITEM_CLASS;
	        if (item.className) {
	            name += ' ' + item.className;
	        }
	        if (item.type === menuitem_1.MenuItem.Separator) {
	            return name + ' ' + SEPARATOR_TYPE_CLASS;
	        }
	        if (item.type === menuitem_1.MenuItem.Submenu) {
	            name += ' ' + SUBMENU_TYPE_CLASS;
	            if (item.disabled || !item.submenu) {
	                name += ' ' + DISABLED_CLASS;
	            }
	            return name;
	        }
	        if (item.type === menuitem_1.MenuItem.Check) {
	            name += ' ' + CHECK_TYPE_CLASS;
	            if (item.checked) {
	                name += ' ' + CHECKED_CLASS;
	            }
	        }
	        if (item.disabled || !item.handler) {
	            name += ' ' + DISABLED_CLASS;
	        }
	        return name;
	    }
	    MenuPrivate.createItemClass = createItemClass;
	    /**
	     * Hide the irrelevant item nodes for a menu bar.
	     */
	    function hideUselessItems(nodes, items) {
	        // Hide the leading separators.
	        var k1;
	        for (k1 = 0; k1 < items.length; ++k1) {
	            if (items[k1].type !== menuitem_1.MenuItem.Separator) {
	                break;
	            }
	            nodes[k1].classList.add(HIDDEN_CLASS);
	        }
	        // Hide the trailing separators.
	        var k2;
	        for (k2 = items.length - 1; k2 >= 0; --k2) {
	            if (items[k2].type !== menuitem_1.MenuItem.Separator) {
	                break;
	            }
	            nodes[k2].classList.add(HIDDEN_CLASS);
	        }
	        // Hide the remaining consecutive separators.
	        var hide = false;
	        while (++k1 < k2) {
	            if (items[k1].type !== menuitem_1.MenuItem.Separator) {
	                hide = false;
	            }
	            else if (hide) {
	                nodes[k1].classList.add(HIDDEN_CLASS);
	            }
	            else {
	                hide = true;
	            }
	        }
	    }
	    MenuPrivate.hideUselessItems = hideUselessItems;
	    /**
	     * Open the menu as a root menu at the target location.
	     */
	    function openRootMenu(menu, x, y, forceX, forceY) {
	        phosphor_messaging_1.sendMessage(menu, phosphor_widget_1.Widget.MsgUpdateRequest);
	        var rect = clientViewportRect();
	        var size = mountAndMeasure(menu, rect.height - (forceY ? y : 0));
	        if (!forceX && (x + size.width > rect.x + rect.width)) {
	            x = rect.x + rect.width - size.width;
	        }
	        if (!forceY && (y + size.height > rect.y + rect.height)) {
	            if (y > rect.y + rect.height) {
	                y = rect.y + rect.height - size.height;
	            }
	            else {
	                y = y - size.height;
	            }
	        }
	        showMenu(menu, x, y);
	    }
	    MenuPrivate.openRootMenu = openRootMenu;
	    /**
	     * Open a the menu as a submenu using the item node for positioning.
	     */
	    function openSubmenu(menu, item) {
	        phosphor_messaging_1.sendMessage(menu, phosphor_widget_1.Widget.MsgUpdateRequest);
	        var rect = clientViewportRect();
	        var size = mountAndMeasure(menu, rect.height);
	        var box = phosphor_domutil_1.boxSizing(menu.node);
	        var itemRect = item.getBoundingClientRect();
	        var x = itemRect.right - SUBMENU_OVERLAP;
	        var y = itemRect.top - box.borderTop - box.paddingTop;
	        if (x + size.width > rect.x + rect.width) {
	            x = itemRect.left + SUBMENU_OVERLAP - size.width;
	        }
	        if (y + size.height > rect.y + rect.height) {
	            y = itemRect.bottom + box.borderBottom + box.paddingBottom - size.height;
	        }
	        showMenu(menu, x, y);
	    }
	    MenuPrivate.openSubmenu = openSubmenu;
	    /**
	     * Get the currently visible viewport rect in page coordinates.
	     */
	    function clientViewportRect() {
	        var elem = document.documentElement;
	        var x = window.pageXOffset;
	        var y = window.pageYOffset;
	        var width = elem.clientWidth;
	        var height = elem.clientHeight;
	        return { x: x, y: y, width: width, height: height };
	    }
	    /**
	     * Mount the menu as hidden and compute its optimal size.
	     *
	     * If the vertical scrollbar becomes visible, the menu will be expanded
	     * by the scrollbar width to prevent clipping the contents of the menu.
	     */
	    function mountAndMeasure(menu, maxHeight) {
	        var node = menu.node;
	        var style = node.style;
	        style.top = '';
	        style.left = '';
	        style.width = '';
	        style.height = '';
	        style.visibility = 'hidden';
	        style.maxHeight = maxHeight + "px";
	        menu.attach(document.body);
	        if (node.scrollHeight > maxHeight) {
	            style.width = (2 * node.offsetWidth - node.clientWidth) + "px";
	        }
	        var rect = node.getBoundingClientRect();
	        return { width: rect.width, height: rect.height };
	    }
	    /**
	     * Show the menu at the specified position.
	     */
	    function showMenu(menu, x, y) {
	        var style = menu.node.style;
	        style.top = Math.max(0, y) + "px";
	        style.left = Math.max(0, x) + "px";
	        style.visibility = '';
	    }
	})(MenuPrivate || (MenuPrivate = {}));


/***/ },
/* 290 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var phosphor_properties_1 = __webpack_require__(17);
	var phosphor_signaling_1 = __webpack_require__(22);
	/**
	 * An enum of the supported menu item types.
	 */
	(function (MenuItemType) {
	    /**
	     * A normal non-checkable menu item.
	     */
	    MenuItemType[MenuItemType["Normal"] = 0] = "Normal";
	    /**
	     * A checkable menu item.
	     */
	    MenuItemType[MenuItemType["Check"] = 1] = "Check";
	    /**
	     * A separator menu item.
	     */
	    MenuItemType[MenuItemType["Separator"] = 2] = "Separator";
	    /**
	     * A submenu menu item.
	     */
	    MenuItemType[MenuItemType["Submenu"] = 3] = "Submenu";
	})(exports.MenuItemType || (exports.MenuItemType = {}));
	var MenuItemType = exports.MenuItemType;
	/**
	 * An item which can be added to a menu widget.
	 */
	var MenuItem = (function () {
	    /**
	     * Construct a new menu item.
	     *
	     * @param options - The initialization options for the menu item.
	     */
	    function MenuItem(options) {
	        if (options)
	            MenuItemPrivate.initFrom(this, options);
	    }
	    Object.defineProperty(MenuItem.prototype, "changed", {
	        /**
	         * A signal emitted when the menu item state changes.
	         */
	        get: function () {
	            return MenuItemPrivate.changedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuItem.prototype, "type", {
	        /**
	         * Get the type of the menu item.
	         *
	         * #### Notes
	         * The default value is `MenuItemType.Normal`.
	         */
	        get: function () {
	            return MenuItemPrivate.typeProperty.get(this);
	        },
	        /**
	         * Set the type of the menu item.
	         *
	         * #### Notes
	         * Items with submenus are forced to `MenuItemType.Submenu`.
	         */
	        set: function (value) {
	            MenuItemPrivate.typeProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuItem.prototype, "text", {
	        /**
	         * Get the text for the menu item.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         *
	         * An ampersand (`&`) before a character denotes the item mnemonic.
	         */
	        get: function () {
	            return MenuItemPrivate.textProperty.get(this);
	        },
	        /**
	         * Set the text for the menu item.
	         *
	         * #### Notes
	         * An ampersand (`&`) before a character denotes the item mnemonic.
	         */
	        set: function (value) {
	            MenuItemPrivate.textProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuItem.prototype, "icon", {
	        /**
	         * Get the icon class for the menu item.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         *
	         * This is the class name(s) added to a menu item icon node.
	         */
	        get: function () {
	            return MenuItemPrivate.iconProperty.get(this);
	        },
	        /**
	         * Set the icon class for the menu item.
	         *
	         * #### Notes
	         * Multiple class names can be separated with whitespace.
	         */
	        set: function (value) {
	            MenuItemPrivate.iconProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuItem.prototype, "shortcut", {
	        /**
	         * Get the shortcut key for the menu item.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         *
	         * The shortcut string is for decoration only.
	         */
	        get: function () {
	            return MenuItemPrivate.shortcutProperty.get(this);
	        },
	        /**
	         * Set the shortcut key for the menu item.
	         *
	         * #### Notes
	         * The shortcut string is for decoration only.
	         */
	        set: function (value) {
	            MenuItemPrivate.shortcutProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuItem.prototype, "checked", {
	        /**
	         * Get the checked state for the menu item.
	         *
	         * #### Notes
	         * The default value is `false`.
	         */
	        get: function () {
	            return MenuItemPrivate.checkedProperty.get(this);
	        },
	        /**
	         * Set the checked state for the menu item.
	         *
	         * #### Notes
	         * Only a `Check` type menu item can be checked.
	         */
	        set: function (value) {
	            MenuItemPrivate.checkedProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuItem.prototype, "disabled", {
	        /**
	         * Get the disabled state for the menu item.
	         *
	         * #### Notes
	         * The default value is `false`.
	         */
	        get: function () {
	            return MenuItemPrivate.disabledProperty.get(this);
	        },
	        /**
	         * Set the disabled state for the menu item.
	         *
	         * #### Notes
	         * The handler of a disabled menu item will not be invoked.
	         */
	        set: function (value) {
	            MenuItemPrivate.disabledProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuItem.prototype, "className", {
	        /**
	         * Get the extra class name for the menu item.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         *
	         * This is the class name(s) added to a menu item node.
	         */
	        get: function () {
	            return MenuItemPrivate.classNameProperty.get(this);
	        },
	        /**
	         * Set the extra class name for the menu item.
	         *
	         * #### Notes
	         * Multiple class names can be separated with whitespace.
	         */
	        set: function (value) {
	            MenuItemPrivate.classNameProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuItem.prototype, "handler", {
	        /**
	         * Get the handler function for the menu item.
	         *
	         * #### Notes
	         * The default value is `null`.
	         *
	         * The handler will be invoked when the menu item is clicked.
	         */
	        get: function () {
	            return MenuItemPrivate.handlerProperty.get(this);
	        },
	        /**
	         * Set the handler function for the menu item.
	         *
	         * #### Notes
	         * The handler will be invoked when the menu item is clicked.
	         */
	        set: function (value) {
	            MenuItemPrivate.handlerProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuItem.prototype, "submenu", {
	        /**
	         * Get the submenu for the menu item.
	         *
	         * #### Notes
	         * The default value is null.
	         *
	         * An item with a submenu will have type `MenuItemType.Submenu`.
	         */
	        get: function () {
	            return MenuItemPrivate.submenuProperty.get(this);
	        },
	        /**
	         * Set the submenu for the menu item.
	         *
	         * #### Notes
	         * The `type` will be automatically set to `MenuItemType.Submenu`.
	         */
	        set: function (value) {
	            MenuItemPrivate.submenuProperty.set(this, value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return MenuItem;
	})();
	exports.MenuItem = MenuItem;
	/**
	 * The namespace for the `MenuItem` class statics.
	 */
	var MenuItem;
	(function (MenuItem) {
	    /**
	     * A convenience alias of the `Normal` [[MenuItemType]].
	     */
	    MenuItem.Normal = MenuItemType.Normal;
	    /**
	     * A convenience alias of the `Check` [[MenuItemType]].
	     */
	    MenuItem.Check = MenuItemType.Check;
	    /**
	     * A convenience alias of the `Separator` [[MenuItemType]].
	     */
	    MenuItem.Separator = MenuItemType.Separator;
	    /**
	     * A convenience alias of the `Submenu` [[MenuItemType]].
	     */
	    MenuItem.Submenu = MenuItemType.Submenu;
	})(MenuItem = exports.MenuItem || (exports.MenuItem = {}));
	/**
	 * The namespace for the menu item private data.
	 */
	var MenuItemPrivate;
	(function (MenuItemPrivate) {
	    /**
	     * A signal emitted when the menu item state changes.
	     */
	    MenuItemPrivate.changedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * The property descriptor for the menu item type.
	     */
	    MenuItemPrivate.typeProperty = new phosphor_properties_1.Property({
	        name: 'type',
	        value: MenuItemType.Normal,
	        coerce: function (owner, value) { return owner.submenu ? MenuItemType.Submenu : value; },
	        changed: function (owner) { MenuItemPrivate.checkedProperty.coerce(owner); },
	        notify: MenuItemPrivate.changedSignal,
	    });
	    /**
	     * The property descriptor for the menu item text.
	     */
	    MenuItemPrivate.textProperty = new phosphor_properties_1.Property({
	        name: 'text',
	        value: '',
	        notify: MenuItemPrivate.changedSignal,
	    });
	    /**
	     * The property descriptor for the menu item icon class.
	     */
	    MenuItemPrivate.iconProperty = new phosphor_properties_1.Property({
	        name: 'icon',
	        value: '',
	        notify: MenuItemPrivate.changedSignal,
	    });
	    /**
	     * The property descriptor for the menu item shortcut.
	     */
	    MenuItemPrivate.shortcutProperty = new phosphor_properties_1.Property({
	        name: 'shortcut',
	        value: '',
	        notify: MenuItemPrivate.changedSignal,
	    });
	    /**
	     * The property descriptor for the menu item checked state.
	     */
	    MenuItemPrivate.checkedProperty = new phosphor_properties_1.Property({
	        name: 'checked',
	        value: false,
	        coerce: function (owner, value) { return owner.type === MenuItemType.Check ? value : false; },
	        notify: MenuItemPrivate.changedSignal,
	    });
	    /**
	     * The property descriptor for the menu item disabled state.
	     */
	    MenuItemPrivate.disabledProperty = new phosphor_properties_1.Property({
	        name: 'disabled',
	        value: false,
	        notify: MenuItemPrivate.changedSignal,
	    });
	    /**
	     * The property descriptor for the menu item class name.
	     */
	    MenuItemPrivate.classNameProperty = new phosphor_properties_1.Property({
	        name: 'className',
	        value: '',
	        notify: MenuItemPrivate.changedSignal,
	    });
	    /**
	     * The property descriptor for the menu item handler.
	     */
	    MenuItemPrivate.handlerProperty = new phosphor_properties_1.Property({
	        name: 'handler',
	        value: null,
	        coerce: function (owner, value) { return value || null; },
	        notify: MenuItemPrivate.changedSignal,
	    });
	    /**
	     * The property descriptor for the menu item submenu.
	     */
	    MenuItemPrivate.submenuProperty = new phosphor_properties_1.Property({
	        name: 'submenu',
	        value: null,
	        coerce: function (owner, value) { return value || null; },
	        changed: function (owner) { MenuItemPrivate.typeProperty.coerce(owner); },
	        notify: MenuItemPrivate.changedSignal,
	    });
	    /**
	     * Initialize a menu item from an options object.
	     */
	    function initFrom(item, options) {
	        if (options.type !== void 0) {
	            item.type = options.type;
	        }
	        if (options.text !== void 0) {
	            item.text = options.text;
	        }
	        if (options.icon !== void 0) {
	            item.icon = options.icon;
	        }
	        if (options.shortcut !== void 0) {
	            item.shortcut = options.shortcut;
	        }
	        if (options.checked !== void 0) {
	            item.checked = options.checked;
	        }
	        if (options.disabled !== void 0) {
	            item.disabled = options.disabled;
	        }
	        if (options.className !== void 0) {
	            item.className = options.className;
	        }
	        if (options.handler !== void 0) {
	            item.handler = options.handler;
	        }
	        if (options.submenu !== void 0) {
	            item.submenu = options.submenu;
	        }
	    }
	    MenuItemPrivate.initFrom = initFrom;
	})(MenuItemPrivate || (MenuItemPrivate = {}));


/***/ },
/* 291 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2015, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var arrays = __webpack_require__(3);
	var phosphor_domutil_1 = __webpack_require__(7);
	var base_1 = __webpack_require__(288);
	var menuitem_1 = __webpack_require__(290);
	/**
	 * The class name added to a menu bar widget.
	 */
	var MENU_BAR_CLASS = 'p-MenuBar';
	/**
	 * The class name added to a menu bar content node.
	 */
	var CONTENT_CLASS = 'p-MenuBar-content';
	/**
	 * The class name added to an open menu bar menu.
	 */
	var MENU_CLASS = 'p-MenuBar-menu';
	/**
	 * The class name added to a menu bar item node.
	 */
	var ITEM_CLASS = 'p-MenuBar-item';
	/**
	 * The class name added to a menu bar item icon cell.
	 */
	var ICON_CLASS = 'p-MenuBar-itemIcon';
	/**
	 * The class name added to a menu bar item text cell.
	 */
	var TEXT_CLASS = 'p-MenuBar-itemText';
	/**
	 * The class name added to a separator menu bar item.
	 */
	var SEPARATOR_TYPE_CLASS = 'p-type-separator';
	/**
	 * The class name added to an active menu bar and item.
	 */
	var ACTIVE_CLASS = 'p-mod-active';
	/**
	 * The class name added to a disabled menu bar item.
	 */
	var DISABLED_CLASS = 'p-mod-disabled';
	/**
	 * The class name added to a hidden menu bar item.
	 */
	var HIDDEN_CLASS = 'p-mod-hidden';
	/**
	 * A widget which displays menu items as a menu bar.
	 */
	var MenuBar = (function (_super) {
	    __extends(MenuBar, _super);
	    /**
	     * Construct a new menu bar.
	     *
	     * @param items - The menu items to initialize the menu bar.
	     *
	     * #### Notes
	     * Subclasses should not pass menu items to `super`. The subclass
	     * should set its own items after it has been fully initialized.
	     */
	    function MenuBar(items) {
	        _super.call(this);
	        this._active = false;
	        this._childMenu = null;
	        this._nodes = [];
	        this.addClass(MENU_BAR_CLASS);
	        if (items)
	            this.items = items;
	    }
	    /**
	     * Create the DOM node for a menu bar.
	     */
	    MenuBar.createNode = function () {
	        var node = document.createElement('div');
	        var content = document.createElement('ul');
	        content.className = CONTENT_CLASS;
	        node.appendChild(content);
	        return node;
	    };
	    /**
	     * Create a new item node for a menu bar.
	     *
	     * @returns A new DOM node to use as an item in a menu bar.
	     *
	     * #### Notes
	     * This method may be reimplemented to create custom items.
	     */
	    MenuBar.createItemNode = function () {
	        var node = document.createElement('li');
	        var icon = document.createElement('span');
	        var text = document.createElement('span');
	        node.className = ITEM_CLASS;
	        icon.className = ICON_CLASS;
	        text.className = TEXT_CLASS;
	        node.appendChild(icon);
	        node.appendChild(text);
	        return node;
	    };
	    /**
	     * Update an item node to reflect the current state of a menu item.
	     *
	     * @param node - A node created by a call to [[createItemNode]].
	     *
	     * @param item - The menu item to use for the item state.
	     *
	     * #### Notes
	     * This is called automatically when the item should be updated.
	     *
	     * If the [[createItemNode]] method is reimplemented, this method
	     * should also be reimplemented so that the item state is properly
	     * updated.
	     */
	    MenuBar.updateItemNode = function (node, item) {
	        var sep = item.type === menuitem_1.MenuItem.Separator;
	        var icon = node.firstChild;
	        var text = node.lastChild;
	        node.className = MenuBarPrivate.createItemClass(item);
	        icon.className = ICON_CLASS + (item.icon ? ' ' + item.icon : '');
	        text.textContent = sep ? '' : item.text.replace(/&/g, '');
	    };
	    /**
	     * Dispose of the resources held by the menu bar.
	     */
	    MenuBar.prototype.dispose = function () {
	        this._reset();
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(MenuBar.prototype, "childMenu", {
	        /**
	         * Get the child menu of the menu bar.
	         *
	         * #### Notes
	         * This will be `null` if the menu bar does not have an open menu.
	         *
	         * This is a read-only property.
	         */
	        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 item nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return this.node.getElementsByClassName(CONTENT_CLASS)[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Open the submenu of the active item, if possible.
	     *
	     * #### Notes
	     * This is a no-op if the menu bar is not visible, if there is no
	     * active item, or if the active item is disabled or has no submenu.
	     */
	    MenuBar.prototype.openActiveItem = function () {
	        if (!this.isVisible) {
	            return;
	        }
	        var index = this.activeIndex;
	        if (index === -1) {
	            return;
	        }
	        var item = this.items[index];
	        if (item.disabled || !item.submenu) {
	            return;
	        }
	        this._activate();
	        this._closeChildMenu();
	        this._openChildMenu(item.submenu, this._nodes[index]);
	    };
	    /**
	     * 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 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseleave':
	                this._evtMouseLeave(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'keypress':
	                this._evtKeyPress(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A method invoked to test whether an item is selectable.
	     *
	     * @param item - The menu item of interest.
	     *
	     * @returns `true` if the item is selectable, `false` otherwise.
	     */
	    MenuBar.prototype.isSelectable = function (item) {
	        return !item.disabled && !!item.submenu;
	    };
	    /**
	     * A method invoked when the menu items change.
	     *
	     * @param oldItems - The old menu items.
	     *
	     * @param newItems - The new menu items.
	     */
	    MenuBar.prototype.onItemsChanged = function (oldItems, newItems) {
	        // Reset the menu bar before updating the items.
	        this._reset();
	        // Disconnect the old item signals.
	        for (var _i = 0; _i < oldItems.length; _i++) {
	            var item = oldItems[_i];
	            if (newItems.indexOf(item) === -1) {
	                item.changed.disconnect(this._onItemChanged, this);
	            }
	        }
	        // Connect the new item signals.
	        for (var _a = 0; _a < newItems.length; _a++) {
	            var item = newItems[_a];
	            if (oldItems.indexOf(item) === -1) {
	                item.changed.connect(this._onItemChanged, this);
	            }
	        }
	        // Fetch common variables.
	        var nodes = this._nodes;
	        var content = this.contentNode;
	        var constructor = this.constructor;
	        // Remove any excess item nodes.
	        while (nodes.length > newItems.length) {
	            var node = nodes.pop();
	            content.removeChild(node);
	        }
	        // Add any missing item nodes.
	        while (nodes.length < newItems.length) {
	            var node = constructor.createItemNode();
	            content.appendChild(node);
	            nodes.push(node);
	        }
	        // Schedule an update of the item nodes.
	        this.update();
	    };
	    /**
	     * A method invoked when the active index changes.
	     *
	     * @param oldIndex - The old active index.
	     *
	     * @param newIndex - The new active index.
	     */
	    MenuBar.prototype.onActiveIndexChanged = function (oldIndex, newIndex) {
	        var oldNode = this._nodes[oldIndex];
	        var newNode = this._nodes[newIndex];
	        if (oldNode)
	            oldNode.classList.remove(ACTIVE_CLASS);
	        if (newNode)
	            newNode.classList.add(ACTIVE_CLASS);
	    };
	    /**
	     * A handler invoked on an `'update-request'` message.
	     */
	    MenuBar.prototype.onUpdateRequest = function (msg) {
	        // Fetch common variables.
	        var items = this.items;
	        var nodes = this._nodes;
	        var constructor = this.constructor;
	        // Update the state of the item nodes.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            constructor.updateItemNode(nodes[i], items[i]);
	        }
	        // Restore the active node class.
	        var active = nodes[this.activeIndex];
	        if (active)
	            active.classList.add(ACTIVE_CLASS);
	        // Hide the redundant and useless menu item nodes.
	        MenuBarPrivate.hideUselessItems(nodes, items);
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    MenuBar.prototype.onAfterAttach = function (msg) {
	        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 a `'before-detach'` message.
	     */
	    MenuBar.prototype.onBeforeDetach = function (msg) {
	        this.node.removeEventListener('mousedown', this);
	        this.node.removeEventListener('mousemove', this);
	        this.node.removeEventListener('mouseleave', this);
	        this.node.removeEventListener('contextmenu', this);
	        this._reset();
	    };
	    /**
	     * Handle the `'mousedown'` event for the menu bar.
	     */
	    MenuBar.prototype._evtMouseDown = function (event) {
	        // If the bar is active and the mouse press is on an open menu,
	        // let that menu handle the press. The bar will reset when the
	        // menu emits its `closed` signal.
	        var x = event.clientX;
	        var y = event.clientY;
	        if (this._active && MenuBarPrivate.hitTestMenus(this._childMenu, x, y)) {
	            return;
	        }
	        // Stop the propagation if the click was on the menu bar. This
	        // prevents duplicate notification when the document mousedown
	        // listener is also installed.
	        if (phosphor_domutil_1.hitTest(this.node, x, y)) {
	            event.preventDefault();
	            event.stopPropagation();
	        }
	        // Check if the mouse was pressed on one of the menu items.
	        var i = arrays.findIndex(this._nodes, function (node) { return phosphor_domutil_1.hitTest(node, x, y); });
	        // If the press was not on an item, reset the menu bar.
	        if (i === -1) {
	            this._deactivate();
	            this._closeChildMenu();
	            this.activeIndex = -1;
	            return;
	        }
	        // If the press was not the left mouse button, do nothing further.
	        if (event.button !== 0) {
	            return;
	        }
	        // If the bar is active, deactivate it and close the child menu.
	        if (this._active) {
	            this._deactivate();
	            this._closeChildMenu();
	            this.activeIndex = i;
	            return;
	        }
	        // Otherwise, activate the bar and open the item if possible.
	        this._activate();
	        this.activeIndex = i;
	        this.openActiveItem();
	    };
	    /**
	     * 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 x = event.clientX;
	        var y = event.clientY;
	        var i = arrays.findIndex(this._nodes, function (node) { return phosphor_domutil_1.hitTest(node, x, y); });
	        // Bail early if the active index will not change.
	        if (i === this.activeIndex) {
	            return;
	        }
	        // Bail early if the bar is active and the mouse is not over an
	        // item. This allows the leading and trailing menus to be kept
	        // open when the mouse is over the empty part of the menu bar.
	        if (i === -1 && this._active) {
	            return;
	        }
	        // Update the active index to the hovered item.
	        this.activeIndex = i;
	        // If the bar is not active, there's nothing more to do.
	        if (!this._active) {
	            return;
	        }
	        // Otherwise, close the current child menu and open the new one.
	        this._closeChildMenu();
	        this.openActiveItem();
	    };
	    /**
	     * Handle the `'mouseleave'` event for the menu bar.
	     */
	    MenuBar.prototype._evtMouseLeave = function (event) {
	        if (!this._active)
	            this.activeIndex = -1;
	    };
	    /**
	     * Handle the `'keydown'` event for the menu bar.
	     */
	    MenuBar.prototype._evtKeyDown = function (event) {
	        event.stopPropagation();
	        var menu = this._childMenu;
	        var leaf = menu && menu.leafMenu;
	        switch (event.keyCode) {
	            case 13:
	                event.preventDefault();
	                if (leaf)
	                    leaf.triggerActiveItem();
	                break;
	            case 27:
	                event.preventDefault();
	                if (leaf)
	                    leaf.close();
	                break;
	            case 37:
	                event.preventDefault();
	                if (leaf && leaf !== menu) {
	                    leaf.close();
	                }
	                else {
	                    this._closeChildMenu();
	                    this.activatePreviousItem();
	                    this.openActiveItem();
	                }
	                break;
	            case 38:
	                event.preventDefault();
	                if (leaf)
	                    leaf.activatePreviousItem();
	                break;
	            case 39:
	                event.preventDefault();
	                if (leaf && leaf.activeItem && leaf.activeItem.submenu) {
	                    leaf.openActiveItem();
	                }
	                else {
	                    this._closeChildMenu();
	                    this.activateNextItem();
	                    this.openActiveItem();
	                }
	                break;
	            case 40:
	                event.preventDefault();
	                if (leaf)
	                    leaf.activateNextItem();
	                break;
	        }
	    };
	    /**
	     * Handle the `'keypress'` event for the menu bar.
	     */
	    MenuBar.prototype._evtKeyPress = function (event) {
	        event.preventDefault();
	        event.stopPropagation();
	        var menu = this._childMenu;
	        var leaf = menu && menu.leafMenu;
	        var key = String.fromCharCode(event.charCode);
	        (leaf || this).activateMnemonicItem(key);
	    };
	    /**
	     * Activate the menu bar and install the document listeners.
	     */
	    MenuBar.prototype._activate = function () {
	        if (this._active) {
	            return;
	        }
	        this._active = true;
	        this.addClass(ACTIVE_CLASS);
	        document.addEventListener('mousedown', this, true);
	        document.addEventListener('keydown', this, true);
	        document.addEventListener('keypress', this, true);
	    };
	    /**
	     * Deactivate the menu bar and remove the document listeners.
	     */
	    MenuBar.prototype._deactivate = function () {
	        if (!this._active) {
	            return;
	        }
	        this._active = false;
	        this.removeClass(ACTIVE_CLASS);
	        document.removeEventListener('mousedown', this, true);
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('keypress', this, true);
	    };
	    /**
	     * Open the child menu using the given item node for location.
	     */
	    MenuBar.prototype._openChildMenu = function (menu, node) {
	        var rect = node.getBoundingClientRect();
	        this._childMenu = menu;
	        menu.addClass(MENU_CLASS);
	        menu.open(rect.left, rect.bottom, false, true);
	        menu.closed.connect(this._onMenuClosed, this);
	    };
	    /**
	     * Close the current child menu, if one exists.
	     */
	    MenuBar.prototype._closeChildMenu = function () {
	        var menu = this._childMenu;
	        if (!menu) {
	            return;
	        }
	        this._childMenu = null;
	        menu.closed.disconnect(this._onMenuClosed, this);
	        menu.removeClass(MENU_CLASS);
	        menu.close();
	    };
	    /**
	     * Reset the menu bar to its default state.
	     */
	    MenuBar.prototype._reset = function () {
	        this._deactivate();
	        this._closeChildMenu();
	        this.activeIndex = -1;
	    };
	    /**
	     * Handle the `changed` signal from a menu item.
	     */
	    MenuBar.prototype._onItemChanged = function () {
	        this._reset();
	        this.update();
	    };
	    /**
	     * Handle the `closed` signal from the child menu.
	     */
	    MenuBar.prototype._onMenuClosed = function (sender) {
	        sender.closed.disconnect(this._onMenuClosed, this);
	        sender.removeClass(MENU_CLASS);
	        this._deactivate();
	        this._childMenu = null;
	        this.activeIndex = -1;
	    };
	    return MenuBar;
	})(base_1.AbstractMenu);
	exports.MenuBar = MenuBar;
	/**
	 * The namespace for the menu bar private data.
	 */
	var MenuBarPrivate;
	(function (MenuBarPrivate) {
	    /**
	     * Create the class name for a menu bar item.
	     */
	    function createItemClass(item) {
	        var name = ITEM_CLASS;
	        if (item.className) {
	            name += ' ' + item.className;
	        }
	        if (item.type === menuitem_1.MenuItem.Separator) {
	            return name + ' ' + SEPARATOR_TYPE_CLASS;
	        }
	        if (item.disabled || (item.type === menuitem_1.MenuItem.Submenu && !item.submenu)) {
	            return name + ' ' + DISABLED_CLASS;
	        }
	        return name;
	    }
	    MenuBarPrivate.createItemClass = createItemClass;
	    /**
	     * Hit test the chain of menus for the given client position.
	     */
	    function hitTestMenus(menu, x, y) {
	        while (menu) {
	            if (phosphor_domutil_1.hitTest(menu.node, x, y)) {
	                return true;
	            }
	            menu = menu.childMenu;
	        }
	        return false;
	    }
	    MenuBarPrivate.hitTestMenus = hitTestMenus;
	    /**
	     * Hide the irrelevant item nodes for a menu bar.
	     */
	    function hideUselessItems(nodes, items) {
	        // Hide the leading non-submenu items.
	        var k1;
	        for (k1 = 0; k1 < items.length; ++k1) {
	            if (items[k1].type === menuitem_1.MenuItem.Submenu) {
	                break;
	            }
	            nodes[k1].classList.add(HIDDEN_CLASS);
	        }
	        // Hide the trailing separator items.
	        var k2;
	        for (k2 = items.length - 1; k2 >= 0; --k2) {
	            if (items[k2].type === menuitem_1.MenuItem.Submenu) {
	                break;
	            }
	            nodes[k2].classList.add(HIDDEN_CLASS);
	        }
	        // Hide the consecutive separators and other non-submenu items.
	        var hide = false;
	        while (++k1 < k2) {
	            if (items[k1].type === menuitem_1.MenuItem.Submenu) {
	                hide = false;
	            }
	            else if (items[k1].type !== menuitem_1.MenuItem.Separator) {
	                nodes[k1].classList.add(HIDDEN_CLASS);
	            }
	            else if (hide) {
	                nodes[k1].classList.add(HIDDEN_CLASS);
	            }
	            else {
	                hide = true;
	            }
	        }
	    }
	    MenuBarPrivate.hideUselessItems = hideUselessItems;
	})(MenuBarPrivate || (MenuBarPrivate = {}));


/***/ },
/* 292 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(293);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../css-loader/index.js!./index.css", function() {
				var newContent = require("!!./../../css-loader/index.js!./index.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 293 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*-----------------------------------------------------------------------------\r\n| Copyright (c) 2014-2015, PhosphorJS Contributors\r\n|\r\n| Distributed under the terms of the BSD 3-Clause License.\r\n|\r\n| The full license is in the file LICENSE, distributed with this software.\r\n|----------------------------------------------------------------------------*/\r\n.p-MenuBar-content {\r\n  margin: 0;\r\n  padding: 0;\r\n  display: flex;\r\n  flex-direction: row;\r\n  list-style-type: none;\r\n}\r\n\r\n\r\n.p-MenuBar-item {\r\n  box-sizing: border-box;\r\n}\r\n\r\n\r\n.p-MenuBar-item.p-mod-hidden {\r\n  display: none;\r\n}\r\n\r\n\r\n.p-Menu {\r\n  position: absolute;\r\n  white-space: nowrap;\r\n  overflow-x: hidden;\r\n  overflow-y: auto;\r\n}\r\n\r\n\r\n.p-Menu-content {\r\n  margin: 0;\r\n  padding: 0;\r\n  display: table;\r\n  list-style-type: none;\r\n}\r\n\r\n\r\n.p-Menu-item {\r\n  display: table-row;\r\n}\r\n\r\n\r\n.p-Menu-item.p-mod-hidden {\r\n  display: none;\r\n}\r\n\r\n\r\n.p-Menu-itemIcon,\r\n.p-Menu-itemSubmenuIcon {\r\n  display: table-cell;\r\n  text-align: center;\r\n}\r\n\r\n\r\n.p-Menu-itemText {\r\n  display: table-cell;\r\n  text-align: left;\r\n}\r\n\r\n\r\n.p-Menu-itemShortcut {\r\n  display: table-cell;\r\n  text-align: right;\r\n}\r\n", ""]);
	
	// exports


/***/ },
/* 294 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var phosphor_domutil_1 = __webpack_require__(7);
	var dialog_1 = __webpack_require__(115);
	/**
	 * The class name added to FileBrowser instances.
	 */
	exports.FILE_BROWSER_CLASS = 'jp-FileBrowser';
	/**
	 * The class name added to drop targets.
	 */
	exports.DROP_TARGET_CLASS = 'jp-mod-dropTarget';
	/**
	 * The class name added to selected rows.
	 */
	exports.SELECTED_CLASS = 'jp-mod-selected';
	/**
	 * The mime type for a contents drag object.
	 */
	exports.CONTENTS_MIME = 'application/x-jupyter-icontents';
	/**
	 * An error message dialog to show in the filebrowser widget.
	 */
	function showErrorMessage(host, title, error) {
	    console.error(error);
	    if (!host.isAttached) {
	        return;
	    }
	    // Find the file browser node.
	    var node = host.node;
	    while (!node.classList.contains(exports.FILE_BROWSER_CLASS)) {
	        node = node.parentElement;
	    }
	    var options = {
	        title: title,
	        host: node,
	        body: error.message || "File " + title,
	        buttons: [dialog_1.okButton],
	        okText: 'DISMISS'
	    };
	    return dialog_1.showDialog(options).then(function () { });
	}
	exports.showErrorMessage = showErrorMessage;
	/**
	 * Get the index of the node at a client position, or `-1`.
	 */
	function hitTestNodes(nodes, x, y) {
	    for (var i = 0, n = nodes.length; i < n; ++i) {
	        if (phosphor_domutil_1.hitTest(nodes[i], x, y))
	            return i;
	    }
	    return -1;
	}
	exports.hitTestNodes = hitTestNodes;
	/**
	 * Find the first element matching a class name.
	 */
	function findElement(parent, className) {
	    var elements = parent.getElementsByClassName(className);
	    if (elements.length)
	        return elements[0];
	}
	exports.findElement = findElement;


/***/ },
/* 295 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_dragdrop_1 = __webpack_require__(31);
	var phosphor_widget_1 = __webpack_require__(20);
	var dialog_1 = __webpack_require__(115);
	var utils = __webpack_require__(294);
	/**
	 * The class name added to the breadcrumb node.
	 */
	var BREADCRUMB_CLASS = 'jp-BreadCrumbs';
	/**
	 * The class name added to the breadcrumb node.
	 */
	var BREADCRUMB_ITEM_CLASS = 'jp-BreadCrumbs-item';
	/**
	 * Bread crumb paths.
	 */
	var BREAD_CRUMB_PATHS = ['/', '../../', '../', ''];
	/**
	 * A class which hosts folder breadcrumbs.
	 */
	var BreadCrumbs = (function (_super) {
	    __extends(BreadCrumbs, _super);
	    /**
	     * Construct a new file browser crumb widget.
	     *
	     * @param model - The file browser view model.
	     */
	    function BreadCrumbs(model) {
	        _super.call(this);
	        this._model = null;
	        this._crumbs = [];
	        this._crumbSeps = [];
	        this._model = model;
	        this.addClass(BREADCRUMB_CLASS);
	        this._crumbs = Private.createCrumbs();
	        this._crumbSeps = Private.createCrumbSeparators();
	        this.node.appendChild(this._crumbs[Private.Crumb.Home]);
	        this._model.refreshed.connect(this.update, this);
	    }
	    /**
	     * Handle the DOM events for the bread crumbs.
	     *
	     * @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.
	     */
	    BreadCrumbs.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'click':
	                this._evtClick(event);
	                break;
	            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;
	        }
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    BreadCrumbs.prototype.onAfterAttach = function (msg) {
	        _super.prototype.onAfterAttach.call(this, msg);
	        var node = this.node;
	        node.addEventListener('click', this);
	        node.addEventListener('p-dragenter', this);
	        node.addEventListener('p-dragleave', this);
	        node.addEventListener('p-dragover', this);
	        node.addEventListener('p-drop', this);
	    };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     */
	    BreadCrumbs.prototype.onBeforeDetach = function (msg) {
	        _super.prototype.onBeforeDetach.call(this, msg);
	        var node = this.node;
	        node.removeEventListener('click', this);
	        node.removeEventListener('p-dragenter', this);
	        node.removeEventListener('p-dragleave', this);
	        node.removeEventListener('p-dragover', this);
	        node.removeEventListener('p-drop', this);
	    };
	    /**
	     * A handler invoked on an `'update-request'` message.
	     */
	    BreadCrumbs.prototype.onUpdateRequest = function (msg) {
	        // Update the breadcrumb list.
	        Private.updateCrumbs(this._crumbs, this._crumbSeps, this._model.path);
	    };
	    /**
	     * Handle the `'click'` event for the widget.
	     */
	    BreadCrumbs.prototype._evtClick = function (event) {
	        var _this = this;
	        // Do nothing if it's not a left mouse press.
	        if (event.button !== 0) {
	            return;
	        }
	        // Find a valid click target.
	        var node = event.target;
	        while (node && node !== this.node) {
	            if (node.classList.contains(BREADCRUMB_ITEM_CLASS)) {
	                var index = this._crumbs.indexOf(node);
	                this._model.cd(BREAD_CRUMB_PATHS[index]).catch(function (error) {
	                    return utils.showErrorMessage(_this, 'Open Error', error);
	                });
	                // Stop the event propagation.
	                event.preventDefault();
	                event.stopPropagation();
	                return;
	            }
	            node = node.parentElement;
	        }
	    };
	    /**
	     * Handle the `'p-dragenter'` event for the widget.
	     */
	    BreadCrumbs.prototype._evtDragEnter = function (event) {
	        if (event.mimeData.hasData(utils.CONTENTS_MIME)) {
	            var index = utils.hitTestNodes(this._crumbs, event.clientX, event.clientY);
	            if (index !== -1) {
	                if (index !== Private.Crumb.Current) {
	                    this._crumbs[index].classList.add(utils.DROP_TARGET_CLASS);
	                    event.preventDefault();
	                    event.stopPropagation();
	                }
	            }
	        }
	    };
	    /**
	     * Handle the `'p-dragleave'` event for the widget.
	     */
	    BreadCrumbs.prototype._evtDragLeave = function (event) {
	        event.preventDefault();
	        event.stopPropagation();
	        var dropTarget = utils.findElement(this.node, utils.DROP_TARGET_CLASS);
	        if (dropTarget)
	            dropTarget.classList.remove(utils.DROP_TARGET_CLASS);
	    };
	    /**
	     * Handle the `'p-dragover'` event for the widget.
	     */
	    BreadCrumbs.prototype._evtDragOver = function (event) {
	        event.preventDefault();
	        event.stopPropagation();
	        event.dropAction = event.proposedAction;
	        var dropTarget = utils.findElement(this.node, utils.DROP_TARGET_CLASS);
	        if (dropTarget)
	            dropTarget.classList.remove(utils.DROP_TARGET_CLASS);
	        var index = utils.hitTestNodes(this._crumbs, event.clientX, event.clientY);
	        if (index !== -1)
	            this._crumbs[index].classList.add(utils.DROP_TARGET_CLASS);
	    };
	    /**
	     * Handle the `'p-drop'` event for the widget.
	     */
	    BreadCrumbs.prototype._evtDrop = function (event) {
	        var _this = this;
	        event.preventDefault();
	        event.stopPropagation();
	        if (event.proposedAction === phosphor_dragdrop_1.DropAction.None) {
	            event.dropAction = phosphor_dragdrop_1.DropAction.None;
	            return;
	        }
	        if (!event.mimeData.hasData(utils.CONTENTS_MIME)) {
	            return;
	        }
	        event.dropAction = event.proposedAction;
	        var target = event.target;
	        while (target && target.parentElement) {
	            if (target.classList.contains(utils.DROP_TARGET_CLASS)) {
	                target.classList.remove(utils.DROP_TARGET_CLASS);
	                break;
	            }
	            target = target.parentElement;
	        }
	        // Get the path based on the target node.
	        var index = this._crumbs.indexOf(target);
	        if (index === -1) {
	            return;
	        }
	        var path = BREAD_CRUMB_PATHS[index];
	        // Move all of the items.
	        var promises = [];
	        var names = event.mimeData.getData(utils.CONTENTS_MIME);
	        var _loop_1 = function(name_1) {
	            var newPath = path + name_1;
	            promises.push(this_1._model.rename(name_1, newPath).catch(function (error) {
	                if (error.xhr) {
	                    error.message = error.xhr.status + ": error.statusText";
	                }
	                if (error.message.indexOf('409') !== -1) {
	                    var options = {
	                        title: 'Overwrite file?',
	                        host: _this.parent.node,
	                        body: "\"" + newPath + "\" already exists, overwrite?",
	                        okText: 'OVERWRITE'
	                    };
	                    return dialog_1.showDialog(options).then(function (button) {
	                        if (button.text === 'OVERWRITE') {
	                            return _this._model.delete(newPath).then(function () {
	                                return _this._model.rename(name_1, newPath).then(function () {
	                                    return _this._model.refresh();
	                                });
	                            });
	                        }
	                    });
	                }
	            }));
	        };
	        var this_1 = this;
	        for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
	            var name_1 = names_1[_i];
	            _loop_1(name_1);
	        }
	        Promise.all(promises).then(function () { return _this._model.refresh(); }, function (err) { return utils.showErrorMessage(_this, 'Move Error', err); });
	    };
	    return BreadCrumbs;
	}(phosphor_widget_1.Widget));
	exports.BreadCrumbs = BreadCrumbs;
	/**
	 * The namespace for the crumbs private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Breadcrumb item list enum.
	     */
	    (function (Crumb) {
	        Crumb[Crumb["Home"] = 0] = "Home";
	        Crumb[Crumb["Ellipsis"] = 1] = "Ellipsis";
	        Crumb[Crumb["Parent"] = 2] = "Parent";
	        Crumb[Crumb["Current"] = 3] = "Current";
	    })(Private.Crumb || (Private.Crumb = {}));
	    var Crumb = Private.Crumb;
	    /**
	     * Populate the breadcrumb node.
	     */
	    function updateCrumbs(breadcrumbs, separators, path) {
	        var node = breadcrumbs[0].parentNode;
	        // Remove all but the home node.
	        while (node.firstChild.nextSibling) {
	            node.removeChild(node.firstChild.nextSibling);
	        }
	        var parts = path.split('/');
	        if (parts.length > 2) {
	            node.appendChild(separators[0]);
	            node.appendChild(breadcrumbs[Crumb.Ellipsis]);
	            var grandParent = parts.slice(0, parts.length - 2).join('/');
	            breadcrumbs[Crumb.Ellipsis].title = grandParent;
	        }
	        if (path) {
	            if (parts.length >= 2) {
	                node.appendChild(separators[1]);
	                breadcrumbs[Crumb.Parent].textContent = parts[parts.length - 2];
	                node.appendChild(breadcrumbs[Crumb.Parent]);
	                var parent_1 = parts.slice(0, parts.length - 1).join('/');
	                breadcrumbs[Crumb.Parent].title = parent_1;
	            }
	            node.appendChild(separators[2]);
	            breadcrumbs[Crumb.Current].textContent = parts[parts.length - 1];
	            node.appendChild(breadcrumbs[Crumb.Current]);
	            breadcrumbs[Crumb.Current].title = path;
	        }
	    }
	    Private.updateCrumbs = updateCrumbs;
	    /**
	     * Create the breadcrumb nodes.
	     */
	    function createCrumbs() {
	        var home = document.createElement('i');
	        home.className = 'fa fa-home ' + BREADCRUMB_ITEM_CLASS;
	        var ellipsis = document.createElement('i');
	        ellipsis.className = 'fa fa-ellipsis-h ' + BREADCRUMB_ITEM_CLASS;
	        var parent = document.createElement('span');
	        parent.className = BREADCRUMB_ITEM_CLASS;
	        var current = document.createElement('span');
	        current.className = BREADCRUMB_ITEM_CLASS;
	        return [home, ellipsis, parent, current];
	    }
	    Private.createCrumbs = createCrumbs;
	    /**
	     * Create the breadcrumb separator nodes.
	     */
	    function createCrumbSeparators() {
	        var items = [];
	        for (var i = 0; i < 3; i++) {
	            var item = document.createElement('i');
	            item.className = 'fa fa-angle-right';
	            items.push(item);
	        }
	        return items;
	    }
	    Private.createCrumbSeparators = createCrumbSeparators;
	})(Private || (Private = {}));


/***/ },
/* 296 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var moment = __webpack_require__(297);
	var arrays = __webpack_require__(3);
	var phosphor_dragdrop_1 = __webpack_require__(31);
	var phosphor_widget_1 = __webpack_require__(20);
	var dialog_1 = __webpack_require__(115);
	var utils = __webpack_require__(294);
	var utils_1 = __webpack_require__(294);
	/**
	 * The class name added to DirListing widget.
	 */
	var DIR_LISTING_CLASS = 'jp-DirListing';
	/**
	 * The class name added to a dir listing header node.
	 */
	var HEADER_CLASS = 'jp-DirListing-header';
	/**
	 * The class name added to a dir listing list header cell.
	 */
	var HEADER_ITEM_CLASS = 'jp-DirListing-headerItem';
	/**
	 * The class name added to a header cell text node.
	 */
	var HEADER_ITEM_TEXT_CLASS = 'jp-DirListing-headerItemText';
	/**
	 * The class name added to a header cell icon node.
	 */
	var HEADER_ITEM_ICON_CLASS = 'jp-DirListing-headerItemIcon';
	/**
	 * The class name added to the dir listing content node.
	 */
	var CONTENT_CLASS = 'jp-DirListing-content';
	/**
	 * The class name added to dir listing content item.
	 */
	var ITEM_CLASS = 'jp-DirListing-item';
	/**
	 * The class name added to the listing item text cell.
	 */
	var ITEM_TEXT_CLASS = 'jp-DirListing-itemText';
	/**
	 * The class name added to the listing item icon cell.
	 */
	var ITEM_ICON_CLASS = 'jp-DirListing-itemIcon';
	/**
	 * The class name added to the listing item modified cell.
	 */
	var ITEM_MODIFIED_CLASS = 'jp-DirListing-itemModified';
	/**
	 * The class name added to the dir listing editor node.
	 */
	var EDITOR_CLASS = 'jp-DirListing-editor';
	/**
	 * The class name added to the name column header cell.
	 */
	var NAME_ID_CLASS = 'jp-id-name';
	/**
	 * The class name added to the modified column header cell.
	 */
	var MODIFIED_ID_CLASS = 'jp-id-modified';
	/**
	 * The class name added to a file type content item.
	 */
	var FILE_TYPE_CLASS = 'jp-type-file';
	/**
	 * The class name added to a folder type content item.
	 */
	var FOLDER_TYPE_CLASS = 'jp-type-folder';
	/**
	 * The class name added to a notebook type content item.
	 */
	var NOTEBOOK_TYPE_CLASS = 'jp-type-notebook';
	/**
	 * The class name added to the widget when there are items on the clipboard.
	 */
	var CLIPBOARD_CLASS = 'jp-mod-clipboard';
	/**
	 * The class name added to cut rows.
	 */
	var CUT_CLASS = 'jp-mod-cut';
	/**
	 * The class name added when there are more than one selected rows.
	 */
	var MULTI_SELECTED_CLASS = 'jp-mod-multiSelected';
	/**
	 * The class name added to indicate running notebook.
	 */
	var RUNNING_CLASS = 'jp-mod-running';
	/**
	 * The class name added for a decending sort.
	 */
	var DESCENDING_CLASS = 'jp-mod-descending';
	/**
	 * The minimum duration for a rename select in ms.
	 */
	var RENAME_DURATION = 500;
	/**
	 * 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/x-phosphor-widget-factory';
	/**
	 * A widget which hosts a file list area.
	 */
	var DirListing = (function (_super) {
	    __extends(DirListing, _super);
	    /**
	     * Construct a new file browser directory listing widget.
	     *
	     * @param model - The file browser view model.
	     */
	    function DirListing(model, manager, opener) {
	        _super.call(this);
	        this._model = null;
	        this._editNode = null;
	        this._items = [];
	        this._drag = null;
	        this._dragData = null;
	        this._selectTimer = -1;
	        this._noSelectTimer = -1;
	        this._isCut = false;
	        this._prevPath = '';
	        this._clipboard = [];
	        this._softSelection = '';
	        this._manager = null;
	        this._opener = null;
	        this.addClass(DIR_LISTING_CLASS);
	        this._model = model;
	        this._model.refreshed.connect(this._onModelRefreshed, this);
	        this._model.selectionChanged.connect(this._onSelectionChanged, this);
	        this._editNode = document.createElement('input');
	        this._editNode.className = EDITOR_CLASS;
	        this._manager = manager;
	        this._opener = opener;
	    }
	    /**
	     * Create the DOM node for a dir listing.
	     */
	    DirListing.createNode = function () {
	        var node = document.createElement('div');
	        var content = document.createElement('ul');
	        var header = this.createHeaderNode();
	        content.className = CONTENT_CLASS;
	        node.appendChild(header);
	        node.appendChild(content);
	        node.tabIndex = 1;
	        return node;
	    };
	    /**
	     * Create the header node for a dir listing.
	     *
	     * @returns A new DOM node to use as the dir listing header.
	     *
	     * #### Notes
	     * This method may be reimplemented to create custom headers.
	     */
	    DirListing.createHeaderNode = function () {
	        var node = document.createElement('div');
	        var name = createItemNode('Name');
	        var modified = createItemNode('Last Modified');
	        node.className = HEADER_CLASS;
	        name.classList.add(NAME_ID_CLASS);
	        name.classList.add(utils_1.SELECTED_CLASS);
	        modified.classList.add(MODIFIED_ID_CLASS);
	        node.appendChild(name);
	        node.appendChild(modified);
	        return node;
	        function createItemNode(label) {
	            var node = document.createElement('div');
	            var text = document.createElement('span');
	            var icon = document.createElement('span');
	            node.className = HEADER_ITEM_CLASS;
	            text.className = HEADER_ITEM_TEXT_CLASS;
	            icon.className = HEADER_ITEM_ICON_CLASS;
	            text.textContent = label;
	            node.appendChild(text);
	            node.appendChild(icon);
	            return node;
	        }
	    };
	    /**
	     * Create a new item node for a dir listing.
	     *
	     * @returns A new DOM node to use as a content item.
	     *
	     * #### Notes
	     * This method may be reimplemented to create custom items.
	     */
	    DirListing.createItemNode = function () {
	        var node = document.createElement('li');
	        var icon = document.createElement('span');
	        var text = document.createElement('span');
	        var modified = document.createElement('span');
	        node.className = ITEM_CLASS;
	        icon.className = ITEM_ICON_CLASS;
	        text.className = ITEM_TEXT_CLASS;
	        modified.className = ITEM_MODIFIED_CLASS;
	        node.appendChild(icon);
	        node.appendChild(text);
	        node.appendChild(modified);
	        return node;
	    };
	    /**
	     * Update an item node to reflect the current state of a model.
	     *
	     * @param node - A node created by a call to [[createItemNode]].
	     *
	     * @param model - The model object to use for the item state.
	     *
	     * #### Notes
	     * This is called automatically when the item should be updated.
	     *
	     * If the [[createItemNode]] method is reimplemented, this method
	     * should also be reimplemented so that the item state is properly
	     * updated.
	     */
	    DirListing.updateItemNode = function (node, model) {
	        var icon = node.firstChild;
	        var text = icon.nextSibling;
	        var modified = text.nextSibling;
	        var type;
	        switch (model.type) {
	            case 'directory':
	                type = FOLDER_TYPE_CLASS;
	                break;
	            case 'notebook':
	                type = NOTEBOOK_TYPE_CLASS;
	                break;
	            default:
	                type = FILE_TYPE_CLASS;
	                break;
	        }
	        var modText = '';
	        var modTitle = '';
	        if (model.last_modified) {
	            var time = moment(model.last_modified).fromNow();
	            modText = time === 'a few seconds ago' ? 'seconds ago' : time;
	            modTitle = moment(model.last_modified).format('YYYY-MM-DD HH:mm');
	        }
	        node.className = ITEM_CLASS + " " + type;
	        text.textContent = model.name;
	        modified.textContent = modText;
	        modified.title = modTitle;
	    };
	    /**
	     * Dispose of the resources held by the directory listing.
	     */
	    DirListing.prototype.dispose = function () {
	        this._model = null;
	        this._items = null;
	        this._editNode = null;
	        this._drag = null;
	        this._dragData = null;
	        this._manager = null;
	        this._opener = null;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(DirListing.prototype, "model", {
	        /**
	         * Get the model used by the listing.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._model;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DirListing.prototype, "headerNode", {
	        /**
	         * Get the dir listing header node.
	         *
	         * #### Notes
	         * This is the node which holds the header cells.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return utils.findElement(this.node, HEADER_CLASS);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DirListing.prototype, "contentNode", {
	        /**
	         * Get the dir listing content node.
	         *
	         * #### Notes
	         * This is the node which holds the item nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return utils.findElement(this.node, CONTENT_CLASS);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Rename the first currently selected item.
	     */
	    DirListing.prototype.rename = function () {
	        return this._doRename();
	    };
	    /**
	     * Cut the selected items.
	     */
	    DirListing.prototype.cut = function () {
	        this._isCut = true;
	        this._copy();
	    };
	    /**
	     * Copy the selected items.
	     */
	    DirListing.prototype.copy = function () {
	        this._copy();
	    };
	    /**
	     * Paste the items from the clipboard.
	     */
	    DirListing.prototype.paste = function () {
	        var _this = this;
	        if (!this._clipboard.length) {
	            return;
	        }
	        var promises = [];
	        for (var _i = 0, _a = this._clipboard; _i < _a.length; _i++) {
	            var path = _a[_i];
	            if (this._isCut) {
	                var parts = path.split('/');
	                var name_1 = parts[parts.length - 1];
	                promises.push(this._model.rename(path, name_1));
	            }
	            else {
	                promises.push(this._model.copy(path, '.'));
	            }
	        }
	        // Remove any cut modifiers.
	        for (var _b = 0, _c = this._items; _b < _c.length; _b++) {
	            var item = _c[_b];
	            item.classList.remove(CUT_CLASS);
	        }
	        this._clipboard = [];
	        this._isCut = false;
	        this.removeClass(CLIPBOARD_CLASS);
	        return Promise.all(promises).then(function () { return _this._model.refresh(); }, function (error) { return utils.showErrorMessage(_this, 'Paste Error', error); });
	    };
	    /**
	     * Delete the currently selected item(s).
	     */
	    DirListing.prototype.delete = function () {
	        var _this = this;
	        var names = [];
	        if (this._softSelection) {
	            names.push(this._softSelection);
	        }
	        else {
	            var items = this._model.sortedItems;
	            for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
	                var item = items_1[_i];
	                if (this._model.isSelected(item.name)) {
	                    names.push(item.name);
	                }
	            }
	        }
	        var message = "Permanantly delete these " + names.length + " files?";
	        if (names.length === 1) {
	            message = "Permanently delete file \"" + names[0] + "\"?";
	        }
	        if (names.length) {
	            return dialog_1.showDialog({
	                title: 'Delete file?',
	                body: message,
	                host: this.node.parentElement,
	                okText: 'DELETE'
	            }).then(function (result) {
	                if (result.text === 'DELETE') {
	                    return _this._delete(names);
	                }
	            });
	        }
	        return Promise.resolve(void 0);
	    };
	    /**
	     * Duplicate the currently selected item(s).
	     */
	    DirListing.prototype.duplicate = function () {
	        var _this = this;
	        var promises = [];
	        for (var _i = 0, _a = this._getSelectedItems(); _i < _a.length; _i++) {
	            var item = _a[_i];
	            if (item.type !== 'directory') {
	                promises.push(this._model.copy(item.path, this._model.path));
	            }
	        }
	        return Promise.all(promises).then(function () { return _this._model.refresh(); }, function (error) { return utils.showErrorMessage(_this, 'Duplicate file', error); });
	    };
	    /**
	     * Download the currently selected item(s).
	     */
	    DirListing.prototype.download = function () {
	        var _this = this;
	        for (var _i = 0, _a = this._getSelectedItems(); _i < _a.length; _i++) {
	            var item = _a[_i];
	            if (item.type !== 'directory') {
	                return this._model.download(item.path).catch(function (error) {
	                    return utils.showErrorMessage(_this, 'Download file', error);
	                });
	            }
	        }
	    };
	    /**
	     * Shut down kernels on the applicable currently selected items.
	     */
	    DirListing.prototype.shutdownKernels = function () {
	        var _this = this;
	        var promises = [];
	        var items = this._model.sortedItems;
	        var paths = items.map(function (item) { return item.path; });
	        for (var _i = 0, _a = this._model.sessionIds; _i < _a.length; _i++) {
	            var sessionId = _a[_i];
	            var index = paths.indexOf(sessionId.notebook.path);
	            if (!this._softSelection && this._model.isSelected(items[index].name)) {
	                promises.push(this._model.shutdown(sessionId));
	            }
	            else if (this._softSelection === items[index].name) {
	                promises.push(this._model.shutdown(sessionId));
	            }
	        }
	        return Promise.all(promises).then(function () { return _this._model.refresh(); }, function (error) { return utils.showErrorMessage(_this, 'Shutdown kernel', error); });
	    };
	    /**
	     * Select next item.
	     *
	     * @param keepExisting - Whether to keep the current selection and add to it.
	     */
	    DirListing.prototype.selectNext = function (keepExisting) {
	        if (keepExisting === void 0) { keepExisting = false; }
	        var index = -1;
	        var selected = this._model.getSelected();
	        var items = this._model.sortedItems;
	        if (selected.length === 1 || keepExisting) {
	            // Select the next item.
	            var name_2 = selected[selected.length - 1];
	            index = arrays.findIndex(items, function (value, index) { return value.name === name_2; });
	            index += 1;
	            if (index === this._items.length)
	                index = 0;
	        }
	        else if (selected.length === 0) {
	            // Select the first item.
	            index = 0;
	        }
	        else {
	            // Select the last selected item.
	            var name_3 = selected[selected.length - 1];
	            index = arrays.findIndex(items, function (value, index) { return value.name === name_3; });
	        }
	        if (index !== -1)
	            this._selectItem(index, keepExisting);
	    };
	    /**
	     * Select previous item.
	     *
	     * @param keepExisting - Whether to keep the current selection and add to it.
	     */
	    DirListing.prototype.selectPrevious = function (keepExisting) {
	        if (keepExisting === void 0) { keepExisting = false; }
	        var index = -1;
	        var selected = this._model.getSelected();
	        var items = this._model.sortedItems;
	        if (selected.length === 1 || keepExisting) {
	            // Select the previous item.
	            var name_4 = selected[0];
	            index = arrays.findIndex(items, function (value, index) { return value.name === name_4; });
	            index -= 1;
	            if (index === -1)
	                index = this._items.length - 1;
	        }
	        else if (selected.length === 0) {
	            // Select the last item.
	            index = this._items.length - 1;
	        }
	        else {
	            // Select the first selected item.
	            var name_5 = selected[0];
	            index = arrays.findIndex(items, function (value, index) { return value.name === name_5; });
	        }
	        if (index !== -1)
	            this._selectItem(index, keepExisting);
	    };
	    /**
	     * 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.
	     */
	    DirListing.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;
	            case 'keydown':
	                this._evtKeydown(event);
	                break;
	            case 'click':
	                this._evtClick(event);
	                break;
	            case 'dblclick':
	                this._evtDblClick(event);
	                break;
	            case 'scroll':
	                this._evtScroll(event);
	                break;
	            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;
	        }
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    DirListing.prototype.onAfterAttach = function (msg) {
	        _super.prototype.onAfterAttach.call(this, msg);
	        var node = this.node;
	        var content = utils.findElement(node, CONTENT_CLASS);
	        node.addEventListener('mousedown', this);
	        node.addEventListener('keydown', this);
	        node.addEventListener('click', this);
	        node.addEventListener('dblclick', this);
	        content.addEventListener('scroll', this);
	        content.addEventListener('p-dragenter', this);
	        content.addEventListener('p-dragleave', this);
	        content.addEventListener('p-dragover', this);
	        content.addEventListener('p-drop', this);
	    };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     */
	    DirListing.prototype.onBeforeDetach = function (msg) {
	        _super.prototype.onBeforeDetach.call(this, msg);
	        var node = this.node;
	        var content = utils.findElement(node, CONTENT_CLASS);
	        node.removeEventListener('mousedown', this);
	        node.removeEventListener('keydown', this);
	        node.removeEventListener('click', this);
	        node.removeEventListener('dblclick', this);
	        content.removeEventListener('scroll', this);
	        content.removeEventListener('p-dragenter', this);
	        content.removeEventListener('p-dragleave', this);
	        content.removeEventListener('p-dragover', this);
	        content.removeEventListener('p-drop', this);
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('mouseup', this, true);
	    };
	    /**
	     * A handler invoked on an `'update-request'` message.
	     */
	    DirListing.prototype.onUpdateRequest = function (msg) {
	        // Fetch common variables.
	        var items = this._model.sortedItems;
	        var nodes = this._items;
	        var content = utils.findElement(this.node, CONTENT_CLASS);
	        var subtype = this.constructor;
	        this.removeClass(MULTI_SELECTED_CLASS);
	        this.removeClass(utils_1.SELECTED_CLASS);
	        // Remove any excess item nodes.
	        while (nodes.length > items.length) {
	            var node = nodes.pop();
	            content.removeChild(node);
	        }
	        // Add any missing item nodes.
	        while (nodes.length < items.length) {
	            var node = subtype.createItemNode();
	            nodes.push(node);
	            content.appendChild(node);
	        }
	        // Update the node states to match the model contents.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            subtype.updateItemNode(nodes[i], items[i]);
	            if (this._model.isSelected(items[i].name)) {
	                nodes[i].classList.add(utils_1.SELECTED_CLASS);
	                if (this._isCut && this._model.path === this._prevPath) {
	                    nodes[i].classList.add(CUT_CLASS);
	                }
	            }
	        }
	        // Handle the selectors on the widget node.
	        var selectedNames = this._model.getSelected();
	        if (selectedNames.length > 1) {
	            this.addClass(MULTI_SELECTED_CLASS);
	        }
	        if (selectedNames.length) {
	            this.addClass(utils_1.SELECTED_CLASS);
	        }
	        // Handle notebook session statuses.
	        var paths = items.map(function (item) { return item.path; });
	        var specs = this._model.kernelspecs;
	        for (var _i = 0, _a = this._model.sessionIds; _i < _a.length; _i++) {
	            var sessionId = _a[_i];
	            var index = paths.indexOf(sessionId.notebook.path);
	            var node = this._items[index];
	            node.classList.add(RUNNING_CLASS);
	            node.title = specs.kernelspecs[sessionId.kernel.name].spec.display_name;
	        }
	        this._prevPath = this._model.path;
	    };
	    /**
	     * Handle the `'click'` event for the widget.
	     */
	    DirListing.prototype._evtClick = function (event) {
	        this._softSelection = '';
	        var target = event.target;
	        var header = this.headerNode;
	        if (header.contains(target)) {
	            var children = header.getElementsByClassName(HEADER_ITEM_CLASS);
	            var name_6 = children[0];
	            var modified = children[1];
	            if (name_6.contains(target)) {
	                if (this._model.sortKey === 'name') {
	                    var flag = !this._model.sortAscending;
	                    this._model.sortAscending = flag;
	                    if (flag)
	                        name_6.classList.remove(DESCENDING_CLASS);
	                    else
	                        name_6.classList.add(DESCENDING_CLASS);
	                }
	                else {
	                    this._model.sortKey = 'name';
	                    this._model.sortAscending = true;
	                    name_6.classList.remove(DESCENDING_CLASS);
	                }
	                name_6.classList.add(utils_1.SELECTED_CLASS);
	                modified.classList.remove(utils_1.SELECTED_CLASS);
	                modified.classList.remove(DESCENDING_CLASS);
	            }
	            else if (modified.contains(target)) {
	                if (this._model.sortKey === 'last_modified') {
	                    var flag = !this._model.sortAscending;
	                    this._model.sortAscending = flag;
	                    if (flag)
	                        modified.classList.remove(DESCENDING_CLASS);
	                    else
	                        modified.classList.add(DESCENDING_CLASS);
	                }
	                else {
	                    this._model.sortKey = 'last_modified';
	                    this._model.sortAscending = true;
	                    modified.classList.remove(DESCENDING_CLASS);
	                }
	                modified.classList.add(utils_1.SELECTED_CLASS);
	                name_6.classList.remove(utils_1.SELECTED_CLASS);
	                name_6.classList.remove(DESCENDING_CLASS);
	            }
	            this.update();
	            return;
	        }
	        // Bail if editing.
	        if (this._editNode.contains(target)) {
	            return;
	        }
	        var content = this.contentNode;
	        if (content.contains(target)) {
	            this._handleFileSelect(event);
	        }
	    };
	    /**
	     * Handle the `'scroll'` event for the widget.
	     */
	    DirListing.prototype._evtScroll = function (event) {
	        this.headerNode.scrollLeft = this.contentNode.scrollLeft;
	    };
	    /**
	     * Handle the `'mousedown'` event for the widget.
	     */
	    DirListing.prototype._evtMousedown = function (event) {
	        // Bail if clicking within the edit node
	        if (event.target === this._editNode) {
	            return;
	        }
	        // Blur the edit node if necessary.
	        if (this._editNode.parentNode) {
	            if (this._editNode !== event.target) {
	                this._editNode.focus();
	                this._editNode.blur();
	                clearTimeout(this._selectTimer);
	            }
	            else {
	                return;
	            }
	        }
	        var index = utils.hitTestNodes(this._items, event.clientX, event.clientY);
	        if (index === -1) {
	            return;
	        }
	        this._softSelection = '';
	        var items = this._model.sortedItems;
	        var selected = this._model.getSelected();
	        if (selected.indexOf(items[index].name) === -1) {
	            this._softSelection = items[index].name;
	        }
	        // Left mouse press for drag start.
	        if (event.button === 0) {
	            this._dragData = { pressX: event.clientX, pressY: event.clientY,
	                index: index };
	            document.addEventListener('mouseup', this, true);
	            document.addEventListener('mousemove', this, true);
	        }
	        if (event.button !== 0) {
	            clearTimeout(this._selectTimer);
	        }
	    };
	    /**
	     * Handle the `'mouseup'` event for the widget.
	     */
	    DirListing.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.
	     */
	    DirListing.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(data.index, event.clientX, event.clientY);
	    };
	    /**
	     * Handle the `'keydown'` event for the widget.
	     */
	    DirListing.prototype._evtKeydown = function (event) {
	        switch (event.keyCode) {
	            case 38:
	                this.selectPrevious(event.shiftKey);
	                event.stopPropagation();
	                event.preventDefault();
	                break;
	            case 40:
	                this.selectNext(event.shiftKey);
	                event.stopPropagation();
	                event.preventDefault();
	                break;
	        }
	    };
	    /**
	     * Handle the `'dblclick'` event for the widget.
	     */
	    DirListing.prototype._evtDblClick = function (event) {
	        var _this = this;
	        // Do nothing if it's not a left mouse press.
	        if (event.button !== 0) {
	            return;
	        }
	        // Do nothing if any modifier keys are pressed.
	        if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey) {
	            return;
	        }
	        // Stop the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        clearTimeout(this._selectTimer);
	        this._noSelectTimer = setTimeout(function () {
	            _this._noSelectTimer = -1;
	        }, RENAME_DURATION);
	        this._editNode.blur();
	        // Find a valid double click target.
	        var target = event.target;
	        var i = arrays.findIndex(this._items, function (node) { return node.contains(target); });
	        if (i === -1) {
	            return;
	        }
	        var item = this._model.sortedItems[i];
	        if (item.type === 'directory') {
	            this._model.cd(item.name).catch(function (error) {
	                return utils_1.showErrorMessage(_this, 'Open directory', error);
	            });
	        }
	        else {
	            var path = item.path;
	            var widget = this._manager.findWidget(path);
	            if (!widget) {
	                widget = this._manager.open(item.path);
	                widget.populated.connect(function () { return _this.model.refresh(); });
	                widget.context.kernelChanged.connect(function () { return _this.model.refresh(); });
	            }
	            this._opener.open(widget);
	        }
	    };
	    /**
	     * Handle the `'p-dragenter'` event for the widget.
	     */
	    DirListing.prototype._evtDragEnter = function (event) {
	        if (event.mimeData.hasData(utils.CONTENTS_MIME)) {
	            var index = utils.hitTestNodes(this._items, event.clientX, event.clientY);
	            if (index === -1) {
	                return;
	            }
	            var item = this._model.sortedItems[index];
	            var target = this._items[index];
	            if (!target.classList.contains(FOLDER_TYPE_CLASS)) {
	                return;
	            }
	            if (!this._softSelection && this._model.isSelected(item.name)) {
	                return;
	            }
	            target.classList.add(utils.DROP_TARGET_CLASS);
	            event.preventDefault();
	            event.stopPropagation();
	        }
	    };
	    /**
	     * Handle the `'p-dragleave'` event for the widget.
	     */
	    DirListing.prototype._evtDragLeave = function (event) {
	        event.preventDefault();
	        event.stopPropagation();
	        var dropTarget = utils.findElement(this.node, utils.DROP_TARGET_CLASS);
	        if (dropTarget)
	            dropTarget.classList.remove(utils.DROP_TARGET_CLASS);
	    };
	    /**
	     * Handle the `'p-dragover'` event for the widget.
	     */
	    DirListing.prototype._evtDragOver = function (event) {
	        event.preventDefault();
	        event.stopPropagation();
	        event.dropAction = event.proposedAction;
	        var dropTarget = utils.findElement(this.node, utils.DROP_TARGET_CLASS);
	        if (dropTarget)
	            dropTarget.classList.remove(utils.DROP_TARGET_CLASS);
	        var index = utils.hitTestNodes(this._items, event.clientX, event.clientY);
	        this._items[index].classList.add(utils.DROP_TARGET_CLASS);
	    };
	    /**
	     * Handle the `'p-drop'` event for the widget.
	     */
	    DirListing.prototype._evtDrop = function (event) {
	        var _this = this;
	        event.preventDefault();
	        event.stopPropagation();
	        clearTimeout(this._selectTimer);
	        if (event.proposedAction === phosphor_dragdrop_1.DropAction.None) {
	            event.dropAction = phosphor_dragdrop_1.DropAction.None;
	            return;
	        }
	        if (!event.mimeData.hasData(utils.CONTENTS_MIME)) {
	            return;
	        }
	        event.dropAction = event.proposedAction;
	        var target = event.target;
	        while (target && target.parentElement) {
	            if (target.classList.contains(utils.DROP_TARGET_CLASS)) {
	                target.classList.remove(utils.DROP_TARGET_CLASS);
	                break;
	            }
	            target = target.parentElement;
	        }
	        // Get the path based on the target node.
	        var index = this._items.indexOf(target);
	        var items = this._model.sortedItems;
	        var path = items[index].name + '/';
	        // Move all of the items.
	        var promises = [];
	        var names = event.mimeData.getData(utils.CONTENTS_MIME);
	        var _loop_1 = function(name_7) {
	            var newPath = path + name_7;
	            promises.push(this_1._model.rename(name_7, newPath).catch(function (error) {
	                if (error.xhr) {
	                    error.message = error.xhr.statusText + " " + error.xhr.status;
	                }
	                if (error.message.indexOf('409') !== -1) {
	                    var options = {
	                        title: 'Overwrite file?',
	                        host: _this.parent.node,
	                        body: "\"" + newPath + "\" already exists, overwrite?",
	                        okText: 'OVERWRITE'
	                    };
	                    return dialog_1.showDialog(options).then(function (button) {
	                        if (button.text === 'OVERWRITE') {
	                            return _this._model.delete(newPath).then(function () {
	                                return _this._model.rename(name_7, newPath);
	                            });
	                        }
	                    });
	                }
	            }));
	        };
	        var this_1 = this;
	        for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
	            var name_7 = names_1[_i];
	            _loop_1(name_7);
	        }
	        Promise.all(promises).then(function () { return _this._model.refresh(); }, function (error) { return utils.showErrorMessage(_this, 'Move Error', error); });
	    };
	    /**
	     * Start a drag event.
	     */
	    DirListing.prototype._startDrag = function (index, clientX, clientY) {
	        var _this = this;
	        var selectedNames = this._model.getSelected();
	        var source = this._items[index];
	        var items = this._model.sortedItems;
	        var item = null;
	        // If the source node is not selected, use just that node.
	        if (!source.classList.contains(utils_1.SELECTED_CLASS)) {
	            item = items[index];
	            selectedNames = [item.name];
	        }
	        else if (selectedNames.length === 1) {
	            var name_8 = selectedNames[0];
	            item = arrays.find(items, function (value, index) { return value.name === name_8; });
	        }
	        // Create the drag image.
	        var dragImage = source.cloneNode(true);
	        dragImage.removeChild(dragImage.lastChild);
	        if (selectedNames.length > 1) {
	            var text = utils.findElement(dragImage, ITEM_TEXT_CLASS);
	            text.textContent = '(' + selectedNames.length + ')';
	        }
	        // Set up the drag event.
	        this._drag = new phosphor_dragdrop_1.Drag({
	            dragImage: dragImage,
	            mimeData: new phosphor_dragdrop_1.MimeData(),
	            supportedActions: phosphor_dragdrop_1.DropActions.Move,
	            proposedAction: phosphor_dragdrop_1.DropAction.Move
	        });
	        this._drag.mimeData.setData(utils.CONTENTS_MIME, selectedNames);
	        if (item && item.type !== 'directory') {
	            this._drag.mimeData.setData(FACTORY_MIME, function () {
	                var path = item.path;
	                var widget = _this._manager.findWidget(path);
	                if (!widget) {
	                    widget = _this._manager.open(item.path);
	                    widget.populated.connect(function () { return _this.model.refresh(); });
	                    widget.context.kernelChanged.connect(function () { return _this.model.refresh(); });
	                }
	            });
	        }
	        // Start the drag and remove the mousemove listener.
	        this._drag.start(clientX, clientY).then(function (action) {
	            _this._drag = null;
	            clearTimeout(_this._selectTimer);
	        });
	        document.removeEventListener('mousemove', this, true);
	    };
	    /**
	     * Handle selection on a file node.
	     */
	    DirListing.prototype._handleFileSelect = function (event) {
	        var _this = this;
	        // Fetch common variables.
	        var items = this._model.sortedItems;
	        var index = utils.hitTestNodes(this._items, event.clientX, event.clientY);
	        clearTimeout(this._selectTimer);
	        if (index == -1)
	            return;
	        var name = items[index].name;
	        var selected = this._model.getSelected();
	        // Handle toggling.
	        if (event.metaKey || event.ctrlKey) {
	            if (this._model.isSelected(name)) {
	                this._model.deselect(name);
	            }
	            else {
	                this._model.select(name);
	            }
	        }
	        else if (event.shiftKey) {
	            this._handleMultiSelect(selected, index);
	        }
	        else {
	            // Handle a rename.
	            if (selected.length === 1 && selected[0] === name) {
	                this._selectTimer = setTimeout(function () {
	                    if (_this._noSelectTimer === -1) {
	                        _this._doRename();
	                    }
	                }, RENAME_DURATION);
	            }
	            this._model.clearSelected();
	            this._model.select(name);
	        }
	        this._isCut = false;
	        this.update();
	    };
	    /**
	     * Handle a multiple select on a file item node.
	     */
	    DirListing.prototype._handleMultiSelect = function (selected, index) {
	        // Find the "nearest selected".
	        var items = this._model.sortedItems;
	        var nearestIndex = -1;
	        for (var i = 0; i < this._items.length; i++) {
	            if (i === index) {
	                continue;
	            }
	            var name_9 = items[i].name;
	            if (selected.indexOf(name_9) !== -1) {
	                if (nearestIndex === -1) {
	                    nearestIndex = i;
	                }
	                else {
	                    if (Math.abs(index - i) < Math.abs(nearestIndex - i)) {
	                        nearestIndex = i;
	                    }
	                }
	            }
	        }
	        // Default to the first element (and fill down).
	        if (nearestIndex === -1) {
	            nearestIndex = 0;
	        }
	        // Select the rows between the current and the nearest selected.
	        for (var i = 0; i < this._items.length; i++) {
	            if (nearestIndex >= i && index <= i ||
	                nearestIndex <= i && index >= i) {
	                this._model.select(items[i].name);
	            }
	        }
	    };
	    /**
	     * Get the currently selected items.
	     */
	    DirListing.prototype._getSelectedItems = function () {
	        var _this = this;
	        var items = this._model.sortedItems;
	        if (!this._softSelection) {
	            return items.filter(function (item) { return _this._model.isSelected(item.name); });
	        }
	        return items.filter(function (item) { return item.name === _this._softSelection; });
	    };
	    /**
	     * Copy the selected items, and optionally cut as well.
	     */
	    DirListing.prototype._copy = function () {
	        this._clipboard = [];
	        for (var _i = 0, _a = this._getSelectedItems(); _i < _a.length; _i++) {
	            var item = _a[_i];
	            if (item.type !== 'directory') {
	                // Store the absolute path of the item.
	                this._clipboard.push('/' + item.path);
	            }
	        }
	        this.update();
	    };
	    /**
	     * Delete the files with the given names.
	     */
	    DirListing.prototype._delete = function (names) {
	        var _this = this;
	        var promises = [];
	        for (var _i = 0, names_2 = names; _i < names_2.length; _i++) {
	            var name_10 = names_2[_i];
	            promises.push(this._model.delete(name_10));
	        }
	        return Promise.all(promises).then(function () { return _this._model.refresh(); }, function (error) { return utils.showErrorMessage(_this, 'Delete file', error); });
	    };
	    /**
	     * Allow the user to rename item on a given row.
	     */
	    DirListing.prototype._doRename = function () {
	        var _this = this;
	        var items = this._model.sortedItems;
	        var name = this._softSelection || this._model.getSelected()[0];
	        var index = arrays.findIndex(items, function (value, index) { return value.name === name; });
	        var row = this._items[index];
	        var text = utils.findElement(row, ITEM_TEXT_CLASS);
	        var original = text.textContent;
	        return Private.doRename(row, text, this._editNode).then(function (changed) {
	            if (!changed) {
	                return original;
	            }
	            var newPath = text.textContent;
	            return _this._model.rename(original, newPath).catch(function (error) {
	                if (error.xhr) {
	                    error.message = error.xhr.status + ": error.statusText";
	                }
	                if (error.message.indexOf('409') !== -1 ||
	                    error.message.indexOf('already exists') !== -1) {
	                    var options = {
	                        title: 'Overwrite file?',
	                        host: _this.parent.node,
	                        body: "\"" + newPath + "\" already exists, overwrite?",
	                        okText: 'OVERWRITE'
	                    };
	                    return dialog_1.showDialog(options).then(function (button) {
	                        if (button.text === 'OVERWRITE') {
	                            return _this._model.delete(newPath).then(function () {
	                                return _this._model.rename(original, newPath).then(function () {
	                                    _this._model.refresh();
	                                });
	                            });
	                        }
	                        else {
	                            text.textContent = original;
	                        }
	                    });
	                }
	            }).catch(function (error) {
	                utils.showErrorMessage(_this, 'Rename Error', error);
	                return original;
	            }).then(function () {
	                _this._model.refresh();
	                return text.textContent;
	            });
	        });
	    };
	    /**
	     * Select a given item.
	     */
	    DirListing.prototype._selectItem = function (index, keepExisting) {
	        // Selected the given row(s)
	        var items = this._model.sortedItems;
	        if (!keepExisting) {
	            this._model.clearSelected();
	        }
	        var name = items[index].name;
	        this._model.select(name);
	        Private.scrollIfNeeded(this.contentNode, this._items[index]);
	        this._isCut = false;
	    };
	    /**
	     * Handle the `refreshed` signal from the model.
	     */
	    DirListing.prototype._onModelRefreshed = function () {
	        this.update();
	    };
	    /**
	     * Handle the `selectionChanged` signal from the model.
	     */
	    DirListing.prototype._onSelectionChanged = function () {
	        this.update();
	    };
	    return DirListing;
	}(phosphor_widget_1.Widget));
	exports.DirListing = DirListing;
	/**
	 * The namespace for the listing private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Handle editing text on a node.
	     *
	     * @returns Boolean indicating whether the name changed.
	     */
	    function doRename(parent, text, edit) {
	        var changed = true;
	        parent.replaceChild(edit, text);
	        edit.value = text.textContent;
	        edit.focus();
	        var index = edit.value.lastIndexOf('.');
	        if (index === -1) {
	            edit.setSelectionRange(0, edit.value.length);
	        }
	        else {
	            edit.setSelectionRange(0, index);
	        }
	        return new Promise(function (resolve, reject) {
	            edit.onblur = function () {
	                parent.replaceChild(text, edit);
	                if (text.textContent === edit.value) {
	                    changed = false;
	                }
	                if (changed)
	                    text.textContent = edit.value;
	                resolve(changed);
	            };
	            edit.onkeydown = function (event) {
	                switch (event.keyCode) {
	                    case 13:
	                        event.stopPropagation();
	                        event.preventDefault();
	                        edit.blur();
	                        break;
	                    case 27:
	                        event.stopPropagation();
	                        event.preventDefault();
	                        changed = false;
	                        edit.blur();
	                        break;
	                }
	            };
	        });
	    }
	    Private.doRename = doRename;
	    /**
	     * Scroll an element into view if needed.
	     *
	     * @param area - The scroll area element.
	     *
	     * @param elem - The element of interest.
	     */
	    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;
	        }
	    }
	    Private.scrollIfNeeded = scrollIfNeeded;
	})(Private || (Private = {}));


/***/ },
/* 297 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(module) {//! moment.js
	//! version : 2.13.0
	//! 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 utils_hooks__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 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 create_utc__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
	        };
	    }
	
	    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;
	        };
	    }
	
	    function valid__isValid(m) {
	        if (m._isValid == null) {
	            var flags = getParsingFlags(m);
	            var parsedParts = some.call(flags.parsedDateParts, function (i) {
	                return i != null;
	            });
	            m._isValid = !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) {
	                m._isValid = m._isValid &&
	                    flags.charsLeftOver === 0 &&
	                    flags.unusedTokens.length === 0 &&
	                    flags.bigHour === undefined;
	            }
	        }
	        return m._isValid;
	    }
	
	    function valid__createInvalid (flags) {
	        var m = create_utc__createUTC(NaN);
	        if (flags != null) {
	            extend(getParsingFlags(m), flags);
	        }
	        else {
	            getParsingFlags(m).userInvalidated = true;
	        }
	
	        return m;
	    }
	
	    function isUndefined(input) {
	        return input === void 0;
	    }
	
	    // Plugins that add properties should also add the key here (null value),
	    // so we can properly clone ourselves.
	    var momentProperties = utils_hooks__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 in momentProperties) {
	                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);
	        // Prevent infinite loop in case updateOffset creates new moment
	        // objects.
	        if (updateInProgress === false) {
	            updateInProgress = true;
	            utils_hooks__hooks.updateOffset(this);
	            updateInProgress = false;
	        }
	    }
	
	    function isMoment (obj) {
	        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
	    }
	
	    function absFloor (number) {
	        if (number < 0) {
	            return Math.ceil(number);
	        } 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 (utils_hooks__hooks.suppressDeprecationWarnings === false &&
	                (typeof console !==  'undefined') && console.warn) {
	            console.warn('Deprecation warning: ' + msg);
	        }
	    }
	
	    function deprecate(msg, fn) {
	        var firstTime = true;
	
	        return extend(function () {
	            if (utils_hooks__hooks.deprecationHandler != null) {
	                utils_hooks__hooks.deprecationHandler(null, msg);
	            }
	            if (firstTime) {
	                warn(msg + '\nArguments: ' + Array.prototype.slice.call(arguments).join(', ') + '\n' + (new Error()).stack);
	                firstTime = false;
	            }
	            return fn.apply(this, arguments);
	        }, fn);
	    }
	
	    var deprecations = {};
	
	    function deprecateSimple(name, msg) {
	        if (utils_hooks__hooks.deprecationHandler != null) {
	            utils_hooks__hooks.deprecationHandler(name, msg);
	        }
	        if (!deprecations[name]) {
	            warn(msg);
	            deprecations[name] = true;
	        }
	    }
	
	    utils_hooks__hooks.suppressDeprecationWarnings = false;
	    utils_hooks__hooks.deprecationHandler = null;
	
	    function isFunction(input) {
	        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
	    }
	
	    function isObject(input) {
	        return Object.prototype.toString.call(input) === '[object Object]';
	    }
	
	    function locale_set__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 _ordinalParseLenient.
	        this._ordinalParseLenient = new RegExp(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];
	                }
	            }
	        }
	        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;
	        };
	    }
	
	    // internal storage for locale config files
	    var locales = {};
	    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;
	                __webpack_require__(298)("./" + name);
	                // because defineLocale currently also sets the global locale, we
	                // want to undo that for lazy loaded locales
	                locale_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 locale_locales__getSetGlobalLocale (key, values) {
	        var data;
	        if (key) {
	            if (isUndefined(values)) {
	                data = locale_locales__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) {
	            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');
	                config = mergeConfigs(locales[name]._config, config);
	            } else if (config.parentLocale != null) {
	                if (locales[config.parentLocale] != null) {
	                    config = mergeConfigs(locales[config.parentLocale]._config, config);
	                } else {
	                    // treat as if there is no base config
	                    deprecateSimple('parentLocaleUndefined',
	                            'specified parentLocale is not defined yet');
	                }
	            }
	            locales[name] = new Locale(config);
	
	            // backwards compat for now: also set the locale
	            locale_locales__getSetGlobalLocale(name);
	
	            return locales[name];
	        } else {
	            // useful for testing
	            delete locales[name];
	            return null;
	        }
	    }
	
	    function updateLocale(name, config) {
	        if (config != null) {
	            var locale;
	            if (locales[name] != null) {
	                config = mergeConfigs(locales[name]._config, config);
	            }
	            locale = new Locale(config);
	            locale.parentLocale = locales[name];
	            locales[name] = locale;
	
	            // backwards compat for now: also set the locale
	            locale_locales__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 locale_locales__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 locale_locales__listLocales() {
	        return keys(locales);
	    }
	
	    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;
	    }
	
	    function makeGetSet (unit, keepTime) {
	        return function (value) {
	            if (value != null) {
	                get_set__set(this, unit, value);
	                utils_hooks__hooks.updateOffset(this, keepTime);
	                return this;
	            } else {
	                return get_set__get(this, unit);
	            }
	        };
	    }
	
	    function get_set__get (mom, unit) {
	        return mom.isValid() ?
	            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
	    }
	
	    function get_set__set (mom, unit, value) {
	        if (mom.isValid()) {
	            mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
	        }
	    }
	
	    // MOMENTS
	
	    function getSet (units, value) {
	        var unit;
	        if (typeof units === 'object') {
	            for (unit in units) {
	                this.set(unit, units[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 += array[i] instanceof Function ? 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 (typeof callback === 'number') {
	            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;
	        };
	    }
	
	    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');
	
	    // 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) {
	        return isArray(this._months) ? this._months[m.month()] :
	            this._months[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) {
	        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
	            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
	    }
	
	    function units_month__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 = create_utc__createUTC([2000, i]);
	                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
	                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
	            }
	        }
	
	        if (strict) {
	            if (format === 'MMM') {
	                ii = indexOf.call(this._shortMonthsParse, llc);
	                return ii !== -1 ? ii : null;
	            } else {
	                ii = indexOf.call(this._longMonthsParse, llc);
	                return ii !== -1 ? ii : null;
	            }
	        } else {
	            if (format === 'MMM') {
	                ii = indexOf.call(this._shortMonthsParse, llc);
	                if (ii !== -1) {
	                    return ii;
	                }
	                ii = indexOf.call(this._longMonthsParse, llc);
	                return ii !== -1 ? ii : null;
	            } else {
	                ii = indexOf.call(this._longMonthsParse, llc);
	                if (ii !== -1) {
	                    return ii;
	                }
	                ii = indexOf.call(this._shortMonthsParse, llc);
	                return ii !== -1 ? ii : null;
	            }
	        }
	    }
	
	    function localeMonthsParse (monthName, format, strict) {
	        var i, mom, regex;
	
	        if (this._monthsParseExact) {
	            return units_month__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 = create_utc__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 (typeof value !== 'number') {
	                    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);
	            utils_hooks__hooks.updateOffset(this, true);
	            return this;
	        } else {
	            return get_set__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 {
	            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 {
	            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 = create_utc__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]);
	            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');
	    }
	
	    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;
	        }
	    }
	
	    // 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;
	            utils_hooks__hooks.createFromInputFallback(config);
	        }
	    }
	
	    utils_hooks__hooks.createFromInputFallback = deprecate(
	        'moment construction falls back to js Date. This is ' +
	        'discouraged and will be removed in upcoming major ' +
	        'release. Please refer to ' +
	        'https://github.com/moment/moment/issues/1407 for more info.',
	        function (config) {
	            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
	        }
	    );
	
	    function createDate (y, m, d, h, M, s, ms) {
	        //can't just apply() to create a date:
	        //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
	        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;
	    }
	
	    // 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');
	
	    // 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 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);
	    });
	    addParseToken('YY', function (input, array) {
	        array[YEAR] = utils_hooks__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
	
	    utils_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());
	    }
	
	    // 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;
	    }
	
	    //http://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;
	    }
	
	    // 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(utils_hooks__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) {
	            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
	
	            if (config._dayOfYear > daysInYear(yearToUse)) {
	                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(local__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;
	
	            weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);
	            week = defaults(w.w, 1);
	
	            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
	    utils_hooks__hooks.ISO_8601 = 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 === utils_hooks__hooks.ISO_8601) {
	            configFromISO(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 (getParsingFlags(config).bigHour === true &&
	                config._a[HOUR] <= 12 &&
	                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 (!valid__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 || locale_locales__getLocale(config._l);
	
	        if (input === null || (format === undefined && input === '')) {
	            return valid__createInvalid({nullInput: true});
	        }
	
	        if (typeof input === 'string') {
	            config._i = input = config._locale.preparse(input);
	        }
	
	        if (isMoment(input)) {
	            return new Moment(checkOverflow(input));
	        } else if (isArray(format)) {
	            configFromStringAndArray(config);
	        } else if (format) {
	            configFromStringAndFormat(config);
	        } else if (isDate(input)) {
	            config._d = input;
	        } else {
	            configFromInput(config);
	        }
	
	        if (!valid__isValid(config)) {
	            config._d = null;
	        }
	
	        return config;
	    }
	
	    function configFromInput(config) {
	        var input = config._i;
	        if (input === undefined) {
	            config._d = new Date(utils_hooks__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 (typeof(input) === 'object') {
	            configFromObject(config);
	        } else if (typeof(input) === 'number') {
	            // from milliseconds
	            config._d = new Date(input);
	        } else {
	            utils_hooks__hooks.createFromInputFallback(config);
	        }
	    }
	
	    function createLocalOrUTC (input, format, locale, strict, isUTC) {
	        var c = {};
	
	        if (typeof(locale) === 'boolean') {
	            strict = locale;
	            locale = 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 local__createLocal (input, format, locale, strict) {
	        return createLocalOrUTC(input, format, locale, strict, false);
	    }
	
	    var prototypeMin = deprecate(
	         'moment().min is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
	         function () {
	             var other = local__createLocal.apply(null, arguments);
	             if (this.isValid() && other.isValid()) {
	                 return other < this ? this : other;
	             } else {
	                 return valid__createInvalid();
	             }
	         }
	     );
	
	    var prototypeMax = deprecate(
	        'moment().max is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
	        function () {
	            var other = local__createLocal.apply(null, arguments);
	            if (this.isValid() && other.isValid()) {
	                return other > this ? this : other;
	            } else {
	                return valid__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 local__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());
	    };
	
	    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;
	
	        // 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 = locale_locales__getLocale();
	
	        this._bubble();
	    }
	
	    function isDuration (obj) {
	        return obj instanceof Duration;
	    }
	
	    // 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) || []);
	        var chunk   = matches[matches.length - 1] || [];
	        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
	        var minutes = +(parts[1] * 60) + toInt(parts[2]);
	
	        return 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() : local__createLocal(input).valueOf()) - res.valueOf();
	            // Use low-level api, because this fn is low-level api.
	            res._d.setTime(res._d.valueOf() + diff);
	            utils_hooks__hooks.updateOffset(res, false);
	            return res;
	        } else {
	            return local__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.
	    utils_hooks__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) {
	        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);
	            } else if (Math.abs(input) < 16) {
	                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) {
	                    add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false);
	                } else if (!this._changeInProgress) {
	                    this._changeInProgress = true;
	                    utils_hooks__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) {
	            this.utcOffset(this._tzm);
	        } else if (typeof this._i === 'string') {
	            this.utcOffset(offsetFromString(matchOffset, this._i));
	        }
	        return this;
	    }
	
	    function hasAlignedHourOffset (input) {
	        if (!this.isValid()) {
	            return false;
	        }
	        input = input ? local__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 ? create_utc__createUTC(c._a) : local__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{3})?\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 create__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 (typeof input === 'number') {
	            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(match[MILLISECOND]) * sign
	            };
	        } 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(local__createLocal(duration.from), local__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;
	    }
	
	    create__createDuration.fn = Duration.prototype;
	
	    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;
	    }
	
	    function absRound (number) {
	        if (number < 0) {
	            return Math.round(-1 * number) * -1;
	        } else {
	            return Math.round(number);
	        }
	    }
	
	    // 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).');
	                tmp = val; val = period; period = tmp;
	            }
	
	            val = typeof val === 'string' ? +val : val;
	            dur = create__createDuration(val, period);
	            add_subtract__addSubtract(this, dur, direction);
	            return this;
	        };
	    }
	
	    function add_subtract__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) {
	            get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);
	        }
	        if (months) {
	            setMonth(mom, get_set__get(mom, 'Month') + months * isAdding);
	        }
	        if (updateOffset) {
	            utils_hooks__hooks.updateOffset(mom, days || months);
	        }
	    }
	
	    var add_subtract__add      = createAdder(1, 'add');
	    var add_subtract__subtract = createAdder(-1, 'subtract');
	
	    function moment_calendar__calendar (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 || local__createLocal(),
	            sod = cloneWithOffset(now, this).startOf('day'),
	            diff = this.diff(sod, 'days', true),
	            format = diff < -6 ? 'sameElse' :
	                diff < -1 ? 'lastWeek' :
	                diff < 0 ? 'lastDay' :
	                diff < 1 ? 'sameDay' :
	                diff < 2 ? 'nextDay' :
	                diff < 7 ? 'nextWeek' : 'sameElse';
	
	        var output = formats && (isFunction(formats[format]) ? formats[format]() : formats[format]);
	
	        return this.format(output || this.localeData().calendar(format, this, local__createLocal(now)));
	    }
	
	    function clone () {
	        return new Moment(this);
	    }
	
	    function isAfter (input, units) {
	        var localInput = isMoment(input) ? input : local__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 : local__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 : local__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;
	    }
	
	    utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
	    utils_hooks__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 moment_format__toISOString () {
	        var m = this.clone().utc();
	        if (0 < m.year() && m.year() <= 9999) {
	            if (isFunction(Date.prototype.toISOString)) {
	                // native implementation is ~50x faster, use it when we can
	                return this.toDate().toISOString();
	            } else {
	                return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
	            }
	        } else {
	            return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
	        }
	    }
	
	    function format (inputString) {
	        if (!inputString) {
	            inputString = this.isUtc() ? utils_hooks__hooks.defaultFormatUtc : utils_hooks__hooks.defaultFormat;
	        }
	        var output = formatMoment(this, inputString);
	        return this.localeData().postformat(output);
	    }
	
	    function from (time, withoutSuffix) {
	        if (this.isValid() &&
	                ((isMoment(time) && time.isValid()) ||
	                 local__createLocal(time).isValid())) {
	            return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
	        } else {
	            return this.localeData().invalidDate();
	        }
	    }
	
	    function fromNow (withoutSuffix) {
	        return this.from(local__createLocal(), withoutSuffix);
	    }
	
	    function to (time, withoutSuffix) {
	        if (this.isValid() &&
	                ((isMoment(time) && time.isValid()) ||
	                 local__createLocal(time).isValid())) {
	            return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
	        } else {
	            return this.localeData().invalidDate();
	        }
	    }
	
	    function toNow (withoutSuffix) {
	        return this.to(local__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 = locale_locales__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 to_type__valueOf () {
	        return this._d.valueOf() - ((this._offset || 0) * 60000);
	    }
	
	    function unix () {
	        return Math.floor(this.valueOf() / 1000);
	    }
	
	    function toDate () {
	        return this._offset ? new Date(this.valueOf()) : this._d;
	    }
	
	    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 moment_valid__isValid () {
	        return valid__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');
	
	    // 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] = utils_hooks__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');
	
	    // 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('w', ['ww', 2], 'wo', 'week');
	    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
	
	    // ALIASES
	
	    addUnitAlias('week', 'w');
	    addUnitAlias('isoWeek', 'W');
	
	    // 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', ['DD', 2], 'Do', 'date');
	
	    // ALIASES
	
	    addUnitAlias('date', 'D');
	
	    // PARSING
	
	    addRegexToken('D',  match1to2);
	    addRegexToken('DD', match1to2, match2);
	    addRegexToken('Do', function (isStrict, locale) {
	        return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;
	    });
	
	    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('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');
	
	    // 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;
	    }
	
	    // LOCALES
	
	    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
	    function localeWeekdays (m, format) {
	        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 this._weekdaysShort[m.day()];
	    }
	
	    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
	    function localeWeekdaysMin (m) {
	        return this._weekdaysMin[m.day()];
	    }
	
	    function day_of_week__handleStrictParse(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 = create_utc__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.call(this._weekdaysParse, llc);
	                return ii !== -1 ? ii : null;
	            } else if (format === 'ddd') {
	                ii = indexOf.call(this._shortWeekdaysParse, llc);
	                return ii !== -1 ? ii : null;
	            } else {
	                ii = indexOf.call(this._minWeekdaysParse, llc);
	                return ii !== -1 ? ii : null;
	            }
	        } else {
	            if (format === 'dddd') {
	                ii = indexOf.call(this._weekdaysParse, llc);
	                if (ii !== -1) {
	                    return ii;
	                }
	                ii = indexOf.call(this._shortWeekdaysParse, llc);
	                if (ii !== -1) {
	                    return ii;
	                }
	                ii = indexOf.call(this._minWeekdaysParse, llc);
	                return ii !== -1 ? ii : null;
	            } else if (format === 'ddd') {
	                ii = indexOf.call(this._shortWeekdaysParse, llc);
	                if (ii !== -1) {
	                    return ii;
	                }
	                ii = indexOf.call(this._weekdaysParse, llc);
	                if (ii !== -1) {
	                    return ii;
	                }
	                ii = indexOf.call(this._minWeekdaysParse, llc);
	                return ii !== -1 ? ii : null;
	            } else {
	                ii = indexOf.call(this._minWeekdaysParse, llc);
	                if (ii !== -1) {
	                    return ii;
	                }
	                ii = indexOf.call(this._weekdaysParse, llc);
	                if (ii !== -1) {
	                    return ii;
	                }
	                ii = indexOf.call(this._shortWeekdaysParse, llc);
	                return ii !== -1 ? ii : null;
	            }
	        }
	    }
	
	    function localeWeekdaysParse (weekdayName, format, strict) {
	        var i, mom, regex;
	
	        if (this._weekdaysParseExact) {
	            return day_of_week__handleStrictParse.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 = create_utc__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.
	        return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 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 {
	            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 {
	            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 {
	            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 = create_utc__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
	
	    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
	
	    // ALIASES
	
	    addUnitAlias('dayOfYear', 'DDD');
	
	    // 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
	
	    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');
	
	    // PARSING
	
	    function matchMeridiem (isStrict, locale) {
	        return locale._meridiemParse;
	    }
	
	    addRegexToken('a',  matchMeridiem);
	    addRegexToken('A',  matchMeridiem);
	    addRegexToken('H',  match1to2);
	    addRegexToken('h',  match1to2);
	    addRegexToken('HH', match1to2, match2);
	    addRegexToken('hh', match1to2, match2);
	
	    addRegexToken('hmm', match3to4);
	    addRegexToken('hmmss', match5to6);
	    addRegexToken('Hmm', match3to4);
	    addRegexToken('Hmmss', match5to6);
	
	    addParseToken(['H', 'HH'], HOUR);
	    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);
	
	    // FORMATTING
	
	    addFormatToken('m', ['mm', 2], 0, 'minute');
	
	    // ALIASES
	
	    addUnitAlias('minute', 'm');
	
	    // 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');
	
	    // 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');
	
	    // 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 momentPrototype__proto = Moment.prototype;
	
	    momentPrototype__proto.add               = add_subtract__add;
	    momentPrototype__proto.calendar          = moment_calendar__calendar;
	    momentPrototype__proto.clone             = clone;
	    momentPrototype__proto.diff              = diff;
	    momentPrototype__proto.endOf             = endOf;
	    momentPrototype__proto.format            = format;
	    momentPrototype__proto.from              = from;
	    momentPrototype__proto.fromNow           = fromNow;
	    momentPrototype__proto.to                = to;
	    momentPrototype__proto.toNow             = toNow;
	    momentPrototype__proto.get               = getSet;
	    momentPrototype__proto.invalidAt         = invalidAt;
	    momentPrototype__proto.isAfter           = isAfter;
	    momentPrototype__proto.isBefore          = isBefore;
	    momentPrototype__proto.isBetween         = isBetween;
	    momentPrototype__proto.isSame            = isSame;
	    momentPrototype__proto.isSameOrAfter     = isSameOrAfter;
	    momentPrototype__proto.isSameOrBefore    = isSameOrBefore;
	    momentPrototype__proto.isValid           = moment_valid__isValid;
	    momentPrototype__proto.lang              = lang;
	    momentPrototype__proto.locale            = locale;
	    momentPrototype__proto.localeData        = localeData;
	    momentPrototype__proto.max               = prototypeMax;
	    momentPrototype__proto.min               = prototypeMin;
	    momentPrototype__proto.parsingFlags      = parsingFlags;
	    momentPrototype__proto.set               = getSet;
	    momentPrototype__proto.startOf           = startOf;
	    momentPrototype__proto.subtract          = add_subtract__subtract;
	    momentPrototype__proto.toArray           = toArray;
	    momentPrototype__proto.toObject          = toObject;
	    momentPrototype__proto.toDate            = toDate;
	    momentPrototype__proto.toISOString       = moment_format__toISOString;
	    momentPrototype__proto.toJSON            = toJSON;
	    momentPrototype__proto.toString          = toString;
	    momentPrototype__proto.unix              = unix;
	    momentPrototype__proto.valueOf           = to_type__valueOf;
	    momentPrototype__proto.creationData      = creationData;
	
	    // Year
	    momentPrototype__proto.year       = getSetYear;
	    momentPrototype__proto.isLeapYear = getIsLeapYear;
	
	    // Week Year
	    momentPrototype__proto.weekYear    = getSetWeekYear;
	    momentPrototype__proto.isoWeekYear = getSetISOWeekYear;
	
	    // Quarter
	    momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;
	
	    // Month
	    momentPrototype__proto.month       = getSetMonth;
	    momentPrototype__proto.daysInMonth = getDaysInMonth;
	
	    // Week
	    momentPrototype__proto.week           = momentPrototype__proto.weeks        = getSetWeek;
	    momentPrototype__proto.isoWeek        = momentPrototype__proto.isoWeeks     = getSetISOWeek;
	    momentPrototype__proto.weeksInYear    = getWeeksInYear;
	    momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;
	
	    // Day
	    momentPrototype__proto.date       = getSetDayOfMonth;
	    momentPrototype__proto.day        = momentPrototype__proto.days             = getSetDayOfWeek;
	    momentPrototype__proto.weekday    = getSetLocaleDayOfWeek;
	    momentPrototype__proto.isoWeekday = getSetISODayOfWeek;
	    momentPrototype__proto.dayOfYear  = getSetDayOfYear;
	
	    // Hour
	    momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;
	
	    // Minute
	    momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;
	
	    // Second
	    momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;
	
	    // Millisecond
	    momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;
	
	    // Offset
	    momentPrototype__proto.utcOffset            = getSetOffset;
	    momentPrototype__proto.utc                  = setOffsetToUTC;
	    momentPrototype__proto.local                = setOffsetToLocal;
	    momentPrototype__proto.parseZone            = setOffsetToParsedOffset;
	    momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset;
	    momentPrototype__proto.isDST                = isDaylightSavingTime;
	    momentPrototype__proto.isDSTShifted         = isDaylightSavingTimeShifted;
	    momentPrototype__proto.isLocal              = isLocal;
	    momentPrototype__proto.isUtcOffset          = isUtcOffset;
	    momentPrototype__proto.isUtc                = isUtc;
	    momentPrototype__proto.isUTC                = isUtc;
	
	    // Timezone
	    momentPrototype__proto.zoneAbbr = getZoneAbbr;
	    momentPrototype__proto.zoneName = getZoneName;
	
	    // Deprecations
	    momentPrototype__proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
	    momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
	    momentPrototype__proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
	    momentPrototype__proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779', getSetZone);
	
	    var momentPrototype = momentPrototype__proto;
	
	    function moment__createUnix (input) {
	        return local__createLocal(input * 1000);
	    }
	
	    function moment__createInZone () {
	        return local__createLocal.apply(null, arguments).parseZone();
	    }
	
	    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 locale_calendar__calendar (key, mom, now) {
	        var output = this._calendar[key];
	        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 defaultOrdinalParse = /\d{1,2}/;
	
	    function ordinal (number) {
	        return this._ordinal.replace('%d', number);
	    }
	
	    function preParsePostFormat (string) {
	        return string;
	    }
	
	    var defaultRelativeTime = {
	        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'
	    };
	
	    function relative__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 prototype__proto = Locale.prototype;
	
	    prototype__proto._calendar       = defaultCalendar;
	    prototype__proto.calendar        = locale_calendar__calendar;
	    prototype__proto._longDateFormat = defaultLongDateFormat;
	    prototype__proto.longDateFormat  = longDateFormat;
	    prototype__proto._invalidDate    = defaultInvalidDate;
	    prototype__proto.invalidDate     = invalidDate;
	    prototype__proto._ordinal        = defaultOrdinal;
	    prototype__proto.ordinal         = ordinal;
	    prototype__proto._ordinalParse   = defaultOrdinalParse;
	    prototype__proto.preparse        = preParsePostFormat;
	    prototype__proto.postformat      = preParsePostFormat;
	    prototype__proto._relativeTime   = defaultRelativeTime;
	    prototype__proto.relativeTime    = relative__relativeTime;
	    prototype__proto.pastFuture      = pastFuture;
	    prototype__proto.set             = locale_set__set;
	
	    // Month
	    prototype__proto.months            =        localeMonths;
	    prototype__proto._months           = defaultLocaleMonths;
	    prototype__proto.monthsShort       =        localeMonthsShort;
	    prototype__proto._monthsShort      = defaultLocaleMonthsShort;
	    prototype__proto.monthsParse       =        localeMonthsParse;
	    prototype__proto._monthsRegex      = defaultMonthsRegex;
	    prototype__proto.monthsRegex       = monthsRegex;
	    prototype__proto._monthsShortRegex = defaultMonthsShortRegex;
	    prototype__proto.monthsShortRegex  = monthsShortRegex;
	
	    // Week
	    prototype__proto.week = localeWeek;
	    prototype__proto._week = defaultLocaleWeek;
	    prototype__proto.firstDayOfYear = localeFirstDayOfYear;
	    prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;
	
	    // Day of Week
	    prototype__proto.weekdays       =        localeWeekdays;
	    prototype__proto._weekdays      = defaultLocaleWeekdays;
	    prototype__proto.weekdaysMin    =        localeWeekdaysMin;
	    prototype__proto._weekdaysMin   = defaultLocaleWeekdaysMin;
	    prototype__proto.weekdaysShort  =        localeWeekdaysShort;
	    prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort;
	    prototype__proto.weekdaysParse  =        localeWeekdaysParse;
	
	    prototype__proto._weekdaysRegex      = defaultWeekdaysRegex;
	    prototype__proto.weekdaysRegex       =        weekdaysRegex;
	    prototype__proto._weekdaysShortRegex = defaultWeekdaysShortRegex;
	    prototype__proto.weekdaysShortRegex  =        weekdaysShortRegex;
	    prototype__proto._weekdaysMinRegex   = defaultWeekdaysMinRegex;
	    prototype__proto.weekdaysMinRegex    =        weekdaysMinRegex;
	
	    // Hours
	    prototype__proto.isPM = localeIsPM;
	    prototype__proto._meridiemParse = defaultLocaleMeridiemParse;
	    prototype__proto.meridiem = localeMeridiem;
	
	    function lists__get (format, index, field, setter) {
	        var locale = locale_locales__getLocale();
	        var utc = create_utc__createUTC().set(setter, index);
	        return locale[field](utc, format);
	    }
	
	    function listMonthsImpl (format, index, field) {
	        if (typeof format === 'number') {
	            index = format;
	            format = undefined;
	        }
	
	        format = format || '';
	
	        if (index != null) {
	            return lists__get(format, index, field, 'month');
	        }
	
	        var i;
	        var out = [];
	        for (i = 0; i < 12; i++) {
	            out[i] = lists__get(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 (typeof format === 'number') {
	                index = format;
	                format = undefined;
	            }
	
	            format = format || '';
	        } else {
	            format = localeSorted;
	            index = format;
	            localeSorted = false;
	
	            if (typeof format === 'number') {
	                index = format;
	                format = undefined;
	            }
	
	            format = format || '';
	        }
	
	        var locale = locale_locales__getLocale(),
	            shift = localeSorted ? locale._week.dow : 0;
	
	        if (index != null) {
	            return lists__get(format, (index + shift) % 7, field, 'day');
	        }
	
	        var i;
	        var out = [];
	        for (i = 0; i < 7; i++) {
	            out[i] = lists__get(format, (i + shift) % 7, field, 'day');
	        }
	        return out;
	    }
	
	    function lists__listMonths (format, index) {
	        return listMonthsImpl(format, index, 'months');
	    }
	
	    function lists__listMonthsShort (format, index) {
	        return listMonthsImpl(format, index, 'monthsShort');
	    }
	
	    function lists__listWeekdays (localeSorted, format, index) {
	        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
	    }
	
	    function lists__listWeekdaysShort (localeSorted, format, index) {
	        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
	    }
	
	    function lists__listWeekdaysMin (localeSorted, format, index) {
	        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
	    }
	
	    locale_locales__getSetGlobalLocale('en', {
	        ordinalParse: /\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
	    utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);
	    utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);
	
	    var mathAbs = Math.abs;
	
	    function duration_abs__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 duration_add_subtract__addSubtract (duration, input, value, direction) {
	        var other = create__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 duration_add_subtract__add (input, value) {
	        return duration_add_subtract__addSubtract(this, input, value, 1);
	    }
	
	    // supports only 2.0-style subtract(1, 's') or subtract(duration)
	    function duration_add_subtract__subtract (input, value) {
	        return duration_add_subtract__addSubtract(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) {
	        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 duration_as__valueOf () {
	        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 duration_get__get (units) {
	        units = normalizeUnits(units);
	        return this[units + 's']();
	    }
	
	    function makeGetter(name) {
	        return function () {
	            return this._data[name];
	        };
	    }
	
	    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 = {
	        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 duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) {
	        var duration = create__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.s && ['s', 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 a threshold for relative time strings
	    function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) {
	        if (thresholds[threshold] === undefined) {
	            return false;
	        }
	        if (limit === undefined) {
	            return thresholds[threshold];
	        }
	        thresholds[threshold] = limit;
	        return true;
	    }
	
	    function humanize (withSuffix) {
	        var locale = this.localeData();
	        var output = duration_humanize__relativeTime(this, !withSuffix, locale);
	
	        if (withSuffix) {
	            output = locale.pastFuture(+this, output);
	        }
	
	        return locale.postformat(output);
	    }
	
	    var iso_string__abs = Math.abs;
	
	    function iso_string__toISOString() {
	        // 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)
	        var seconds = iso_string__abs(this._milliseconds) / 1000;
	        var days         = iso_string__abs(this._days);
	        var months       = iso_string__abs(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 duration_prototype__proto = Duration.prototype;
	
	    duration_prototype__proto.abs            = duration_abs__abs;
	    duration_prototype__proto.add            = duration_add_subtract__add;
	    duration_prototype__proto.subtract       = duration_add_subtract__subtract;
	    duration_prototype__proto.as             = as;
	    duration_prototype__proto.asMilliseconds = asMilliseconds;
	    duration_prototype__proto.asSeconds      = asSeconds;
	    duration_prototype__proto.asMinutes      = asMinutes;
	    duration_prototype__proto.asHours        = asHours;
	    duration_prototype__proto.asDays         = asDays;
	    duration_prototype__proto.asWeeks        = asWeeks;
	    duration_prototype__proto.asMonths       = asMonths;
	    duration_prototype__proto.asYears        = asYears;
	    duration_prototype__proto.valueOf        = duration_as__valueOf;
	    duration_prototype__proto._bubble        = bubble;
	    duration_prototype__proto.get            = duration_get__get;
	    duration_prototype__proto.milliseconds   = milliseconds;
	    duration_prototype__proto.seconds        = seconds;
	    duration_prototype__proto.minutes        = minutes;
	    duration_prototype__proto.hours          = hours;
	    duration_prototype__proto.days           = days;
	    duration_prototype__proto.weeks          = weeks;
	    duration_prototype__proto.months         = months;
	    duration_prototype__proto.years          = years;
	    duration_prototype__proto.humanize       = humanize;
	    duration_prototype__proto.toISOString    = iso_string__toISOString;
	    duration_prototype__proto.toString       = iso_string__toISOString;
	    duration_prototype__proto.toJSON         = iso_string__toISOString;
	    duration_prototype__proto.locale         = locale;
	    duration_prototype__proto.localeData     = localeData;
	
	    // Deprecations
	    duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);
	    duration_prototype__proto.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
	
	
	    utils_hooks__hooks.version = '2.13.0';
	
	    setHookCallback(local__createLocal);
	
	    utils_hooks__hooks.fn                    = momentPrototype;
	    utils_hooks__hooks.min                   = min;
	    utils_hooks__hooks.max                   = max;
	    utils_hooks__hooks.now                   = now;
	    utils_hooks__hooks.utc                   = create_utc__createUTC;
	    utils_hooks__hooks.unix                  = moment__createUnix;
	    utils_hooks__hooks.months                = lists__listMonths;
	    utils_hooks__hooks.isDate                = isDate;
	    utils_hooks__hooks.locale                = locale_locales__getSetGlobalLocale;
	    utils_hooks__hooks.invalid               = valid__createInvalid;
	    utils_hooks__hooks.duration              = create__createDuration;
	    utils_hooks__hooks.isMoment              = isMoment;
	    utils_hooks__hooks.weekdays              = lists__listWeekdays;
	    utils_hooks__hooks.parseZone             = moment__createInZone;
	    utils_hooks__hooks.localeData            = locale_locales__getLocale;
	    utils_hooks__hooks.isDuration            = isDuration;
	    utils_hooks__hooks.monthsShort           = lists__listMonthsShort;
	    utils_hooks__hooks.weekdaysMin           = lists__listWeekdaysMin;
	    utils_hooks__hooks.defineLocale          = defineLocale;
	    utils_hooks__hooks.updateLocale          = updateLocale;
	    utils_hooks__hooks.locales               = locale_locales__listLocales;
	    utils_hooks__hooks.weekdaysShort         = lists__listWeekdaysShort;
	    utils_hooks__hooks.normalizeUnits        = normalizeUnits;
	    utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;
	    utils_hooks__hooks.prototype             = momentPrototype;
	
	    var _moment = utils_hooks__hooks;
	
	    return _moment;
	
	}));
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(67)(module)))

/***/ },
/* 298 */
/***/ function(module, exports, __webpack_require__) {

	var map = {
		"./af": 299,
		"./af.js": 299,
		"./ar": 300,
		"./ar-ma": 301,
		"./ar-ma.js": 301,
		"./ar-sa": 302,
		"./ar-sa.js": 302,
		"./ar-tn": 303,
		"./ar-tn.js": 303,
		"./ar.js": 300,
		"./az": 304,
		"./az.js": 304,
		"./be": 305,
		"./be.js": 305,
		"./bg": 306,
		"./bg.js": 306,
		"./bn": 307,
		"./bn.js": 307,
		"./bo": 308,
		"./bo.js": 308,
		"./br": 309,
		"./br.js": 309,
		"./bs": 310,
		"./bs.js": 310,
		"./ca": 311,
		"./ca.js": 311,
		"./cs": 312,
		"./cs.js": 312,
		"./cv": 313,
		"./cv.js": 313,
		"./cy": 314,
		"./cy.js": 314,
		"./da": 315,
		"./da.js": 315,
		"./de": 316,
		"./de-at": 317,
		"./de-at.js": 317,
		"./de.js": 316,
		"./dv": 318,
		"./dv.js": 318,
		"./el": 319,
		"./el.js": 319,
		"./en-au": 320,
		"./en-au.js": 320,
		"./en-ca": 321,
		"./en-ca.js": 321,
		"./en-gb": 322,
		"./en-gb.js": 322,
		"./en-ie": 323,
		"./en-ie.js": 323,
		"./en-nz": 324,
		"./en-nz.js": 324,
		"./eo": 325,
		"./eo.js": 325,
		"./es": 326,
		"./es.js": 326,
		"./et": 327,
		"./et.js": 327,
		"./eu": 328,
		"./eu.js": 328,
		"./fa": 329,
		"./fa.js": 329,
		"./fi": 330,
		"./fi.js": 330,
		"./fo": 331,
		"./fo.js": 331,
		"./fr": 332,
		"./fr-ca": 333,
		"./fr-ca.js": 333,
		"./fr-ch": 334,
		"./fr-ch.js": 334,
		"./fr.js": 332,
		"./fy": 335,
		"./fy.js": 335,
		"./gd": 336,
		"./gd.js": 336,
		"./gl": 337,
		"./gl.js": 337,
		"./he": 338,
		"./he.js": 338,
		"./hi": 339,
		"./hi.js": 339,
		"./hr": 340,
		"./hr.js": 340,
		"./hu": 341,
		"./hu.js": 341,
		"./hy-am": 342,
		"./hy-am.js": 342,
		"./id": 343,
		"./id.js": 343,
		"./is": 344,
		"./is.js": 344,
		"./it": 345,
		"./it.js": 345,
		"./ja": 346,
		"./ja.js": 346,
		"./jv": 347,
		"./jv.js": 347,
		"./ka": 348,
		"./ka.js": 348,
		"./kk": 349,
		"./kk.js": 349,
		"./km": 350,
		"./km.js": 350,
		"./ko": 351,
		"./ko.js": 351,
		"./ky": 352,
		"./ky.js": 352,
		"./lb": 353,
		"./lb.js": 353,
		"./lo": 354,
		"./lo.js": 354,
		"./lt": 355,
		"./lt.js": 355,
		"./lv": 356,
		"./lv.js": 356,
		"./me": 357,
		"./me.js": 357,
		"./mk": 358,
		"./mk.js": 358,
		"./ml": 359,
		"./ml.js": 359,
		"./mr": 360,
		"./mr.js": 360,
		"./ms": 361,
		"./ms-my": 362,
		"./ms-my.js": 362,
		"./ms.js": 361,
		"./my": 363,
		"./my.js": 363,
		"./nb": 364,
		"./nb.js": 364,
		"./ne": 365,
		"./ne.js": 365,
		"./nl": 366,
		"./nl.js": 366,
		"./nn": 367,
		"./nn.js": 367,
		"./pa-in": 368,
		"./pa-in.js": 368,
		"./pl": 369,
		"./pl.js": 369,
		"./pt": 370,
		"./pt-br": 371,
		"./pt-br.js": 371,
		"./pt.js": 370,
		"./ro": 372,
		"./ro.js": 372,
		"./ru": 373,
		"./ru.js": 373,
		"./se": 374,
		"./se.js": 374,
		"./si": 375,
		"./si.js": 375,
		"./sk": 376,
		"./sk.js": 376,
		"./sl": 377,
		"./sl.js": 377,
		"./sq": 378,
		"./sq.js": 378,
		"./sr": 379,
		"./sr-cyrl": 380,
		"./sr-cyrl.js": 380,
		"./sr.js": 379,
		"./ss": 381,
		"./ss.js": 381,
		"./sv": 382,
		"./sv.js": 382,
		"./sw": 383,
		"./sw.js": 383,
		"./ta": 384,
		"./ta.js": 384,
		"./te": 385,
		"./te.js": 385,
		"./th": 386,
		"./th.js": 386,
		"./tl-ph": 387,
		"./tl-ph.js": 387,
		"./tlh": 388,
		"./tlh.js": 388,
		"./tr": 389,
		"./tr.js": 389,
		"./tzl": 390,
		"./tzl.js": 390,
		"./tzm": 391,
		"./tzm-latn": 392,
		"./tzm-latn.js": 392,
		"./tzm.js": 391,
		"./uk": 393,
		"./uk.js": 393,
		"./uz": 394,
		"./uz.js": 394,
		"./vi": 395,
		"./vi.js": 395,
		"./x-pseudo": 396,
		"./x-pseudo.js": 396,
		"./zh-cn": 397,
		"./zh-cn.js": 397,
		"./zh-tw": 398,
		"./zh-tw.js": 398
	};
	function webpackContext(req) {
		return __webpack_require__(webpackContextResolve(req));
	};
	function webpackContextResolve(req) {
		return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }());
	};
	webpackContext.keys = function webpackContextKeys() {
		return Object.keys(map);
	};
	webpackContext.resolve = webpackContextResolve;
	module.exports = webpackContext;
	webpackContext.id = 298;


/***/ },
/* 299 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : afrikaans (af)
	//! author : Werner Mollentze : https://github.com/wernerm
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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_Mar_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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 300 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! Locale: Arabic (ar)
	//! Author: Abdel Said: https://github.com/abdelsaid
	//! Changes in months, weekdays: Ahmed Elkhatib
	//! Native plural forms: forabi https://github.com/forabi
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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': '٠'
	    }, numberMap = {
	        '١': '1',
	        '٢': '2',
	        '٣': '3',
	        '٤': '4',
	        '٥': '5',
	        '٦': '6',
	        '٧': '7',
	        '٨': '8',
	        '٩': '9',
	        '٠': '0'
	    }, 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;
	    }, 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 عام']
	    }, 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);
	        };
	    }, 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;
	
	}));

/***/ },
/* 301 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Moroccan Arabic (ar-ma)
	//! author : ElFadili Yassine : https://github.com/ElFadiliY
	//! author : Abdel Said : https://github.com/abdelsaid
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var ar_ma = 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 ar_ma;
	
	}));

/***/ },
/* 302 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Arabic Saudi Arabia (ar-sa)
	//! author : Suhail Alkowaileet : https://github.com/xsoh
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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': '٠'
	    }, numberMap = {
	        '١': '1',
	        '٢': '2',
	        '٣': '3',
	        '٤': '4',
	        '٥': '5',
	        '٦': '6',
	        '٧': '7',
	        '٨': '8',
	        '٩': '9',
	        '٠': '0'
	    };
	
	    var ar_sa = 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 : 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_sa;
	
	}));

/***/ },
/* 303 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale  : Tunisian Arabic (ar-tn)
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var ar_tn = 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 ar_tn;
	
	}));

/***/ },
/* 304 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : azerbaijani (az)
	//! author : topchiyev : https://github.com/topchiyev
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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';
	            }
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 305 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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 'вечара';
	            }
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 306 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : bulgarian (bg)
	//! author : Krasen Borisov : https://github.com/kraz
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 години'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 307 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Bengali (bn)
	//! author : Kaushik Gandhi : https://github.com/kaushikgandhi
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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': '০'
	    },
	    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;
	
	}));

/***/ },
/* 308 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : tibetan (bo)
	//! author : Thupten N. Chakrishar : https://github.com/vajradog
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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': '༠'
	    },
	    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;
	
	}));

/***/ },
/* 309 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : breton (br)
	//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 310 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 311 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : catalan (ca)
	//! author : Juan G. Hurtado : https://github.com/juanghurtado
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var ca = moment.defineLocale('ca', {
	        months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),
	        monthsShort : 'gen._febr._mar._abr._mai._jun._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 : 'D MMMM YYYY',
	            LLL : 'D MMMM YYYY H:mm',
	            LLLL : 'dddd D MMMM 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 : 'en %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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 312 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : czech (cs)
	//! author : petrbela : https://github.com/petrbela
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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('_'),
	        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'
	        },
	        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
	        },
	        ordinalParse : /\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;
	
	}));

/***/ },
/* 313 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : chuvash (cv)
	//! author : Anatoly Mironov : https://github.com/mirontoli
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 ҫул'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 314 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Welsh (cy)
	//! author : Robert Allen
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 315 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : danish (da)
	//! author : Ulrik Nielsen : https://github.com/mrbase
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 HH:mm'
	        },
	        calendar : {
	            sameDay : '[I dag kl.] LT',
	            nextDay : '[I morgen kl.] LT',
	            nextWeek : 'dddd [kl.] LT',
	            lastDay : '[I går kl.] LT',
	            lastWeek : '[sidste] dddd [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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 316 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 317 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : austrian german (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(__webpack_require__(297)) :
	   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_at = 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
	        },
	        ordinalParse: /\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_at;
	
	}));

/***/ },
/* 318 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : dhivehi (dv)
	//! author : Jawish Hameed : https://github.com/jawish
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var months = [
	        'ޖެނުއަރީ',
	        'ފެބްރުއަރީ',
	        'މާރިޗު',
	        'އޭޕްރީލު',
	        'މޭ',
	        'ޖޫން',
	        'ޖުލައި',
	        'އޯގަސްޓު',
	        'ސެޕްޓެމްބަރު',
	        'އޮކްޓޯބަރު',
	        'ނޮވެމްބަރު',
	        'ޑިސެމްބަރު'
	    ], 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;
	
	}));

/***/ },
/* 319 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : modern greek (el)
	//! author : Aggelos Karalias : https://github.com/mehiel
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 (/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 χρόνια'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 320 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : australian english (en-au)
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var en_au = 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'
	        },
	        ordinalParse: /\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 en_au;
	
	}));

/***/ },
/* 321 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : canadian english (en-ca)
	//! author : Jonathan Abourbih : https://github.com/jonbca
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var en_ca = 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'
	        },
	        ordinalParse: /\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 en_ca;
	
	}));

/***/ },
/* 322 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : great britain english (en-gb)
	//! author : Chris Gedrim : https://github.com/chrisgedrim
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var en_gb = 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'
	        },
	        ordinalParse: /\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 en_gb;
	
	}));

/***/ },
/* 323 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Irish english (en-ie)
	//! author : Chris Cartlidge : https://github.com/chriscartlidge
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var en_ie = 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'
	        },
	        ordinalParse: /\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 en_ie;
	
	}));

/***/ },
/* 324 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : New Zealand english (en-nz)
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var en_nz = 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'
	        },
	        ordinalParse: /\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 en_nz;
	
	}));

/***/ },
/* 325 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : esperanto (eo)
	//! author : Colin Dean : https://github.com/colindean
	//! komento: Mi estas malcerta se mi korekte traktis akuzativojn en tiu traduko.
	//!          Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni!
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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[-an de] MMMM, YYYY',
	            LLL : 'D[-an de] MMMM, YYYY HH:mm',
	            LLLL : 'dddd, [la] D[-an 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 : 'je %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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 326 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : spanish (es)
	//! author : Julio Napurí : https://github.com/julionc
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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('_'),
	        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 (/-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'
	        },
	        ordinalParse : /\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;
	
	}));

/***/ },
/* 327 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 328 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : euskara (eu)
	//! author : Eneko Illarramendi : https://github.com/eillarra
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 329 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Persian (fa)
	//! author : Ebrahim Byagowi : https://github.com/ebraminio
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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': '۰'
	    }, 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, '،');
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 330 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : finnish (fi)
	//! author : Tarmo Aidantausta : https://github.com/bleadof
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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(' '),
	        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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 331 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : faroese (fo)
	//! author : Ragnar Johannesen : https://github.com/ragnar123
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 332 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : french (fr)
	//! author : John Fischer : https://github.com/jfroffice
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\d{1,2}(er|)/,
	        ordinal : function (number) {
	            return number + (number === 1 ? 'er' : '');
	        },
	        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;
	
	}));

/***/ },
/* 333 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : canadian french (fr-ca)
	//! author : Jonathan Abourbih : https://github.com/jonbca
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var fr_ca = 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'
	        },
	        ordinalParse: /\d{1,2}(er|e)/,
	        ordinal : function (number) {
	            return number + (number === 1 ? 'er' : 'e');
	        }
	    });
	
	    return fr_ca;
	
	}));

/***/ },
/* 334 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : swiss french (fr)
	//! author : Gaspard Bucher : https://github.com/gaspard
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var fr_ch = 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'
	        },
	        ordinalParse: /\d{1,2}(er|e)/,
	        ordinal : function (number) {
	            return number + (number === 1 ? 'er' : '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_ch;
	
	}));

/***/ },
/* 335 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : frisian (fy)
	//! author : Robin van der Vliet : https://github.com/robin0van0der0v
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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('_'),
	        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 (/-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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 336 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : great britain scottish gealic (gd)
	//! author : Jon Ashdown : https://github.com/jonashdown
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse : /\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;
	
	}));

/***/ },
/* 337 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : galician (gl)
	//! author : Juan G. Hurtado : https://github.com/juanghurtado
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 MMMM YYYY',
	            LLL : 'D MMMM YYYY H:mm',
	            LLLL : 'dddd D MMMM 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 === 'uns segundos') {
	                    return 'nuns segundos';
	                }
	                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'
	        },
	        ordinalParse : /\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 gl;
	
	}));

/***/ },
/* 338 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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;
	
	}));

/***/ },
/* 339 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : hindi (hi)
	//! author : Mayank Singhal : https://github.com/mayanksinghal
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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': '०'
	    },
	    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;
	
	}));

/***/ },
/* 340 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : hrvatski (hr)
	//! author : Bojan Marković : https://github.com/bmarkovic
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 341 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : hungarian (hu)
	//! author : Adam Brunner : https://github.com/adambrunner
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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
	        },
	        ordinalParse: /\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 hu;
	
	}));

/***/ },
/* 342 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Armenian (hy-am)
	//! author : Armendarabyan : https://github.com/armendarabyan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var hy_am = 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 'երեկոյան';
	            }
	        },
	        ordinalParse: /\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 hy_am;
	
	}));

/***/ },
/* 343 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Bahasa Indonesia (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(__webpack_require__(297)) :
	   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;
	
	}));

/***/ },
/* 344 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : icelandic (is)
	//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 345 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse : /\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;
	
	}));

/***/ },
/* 346 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : japanese (ja)
	//! author : LI Long : https://github.com/baryon
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 : 'Ah時m分',
	            LTS : 'Ah時m分s秒',
	            L : 'YYYY/MM/DD',
	            LL : 'YYYY年M月D日',
	            LLL : 'YYYY年M月D日Ah時m分',
	            LLLL : 'YYYY年M月D日Ah時m分 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'
	        },
	        ordinalParse : /\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;
	
	}));

/***/ },
/* 347 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Boso Jowo (jv)
	//! author : Rony Lantip : https://github.com/lantip
	//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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;
	
	}));

/***/ },
/* 348 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Georgian (ka)
	//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 წელი'
	        },
	        ordinalParse: /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;
	
	}));

/***/ },
/* 349 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : kazakh (kk)
	//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 жыл'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 350 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : khmer (km)
	//! author : Kruy Vanna : https://github.com/kruyvanna
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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;
	
	}));

/***/ },
/* 351 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : korean (ko)
	//!
	//! authors
	//!
	//! - Kyungwook, Park : https://github.com/kyungw00k
	//! - Jeeeyul Lee <jeeeyul@gmail.com>
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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시 m분',
	            LTS : 'A h시 m분 s초',
	            L : 'YYYY.MM.DD',
	            LL : 'YYYY년 MMMM D일',
	            LLL : 'YYYY년 MMMM D일 A h시 m분',
	            LLLL : 'YYYY년 MMMM D일 dddd A h시 m분'
	        },
	        calendar : {
	            sameDay : '오늘 LT',
	            nextDay : '내일 LT',
	            nextWeek : 'dddd LT',
	            lastDay : '어제 LT',
	            lastWeek : '지난주 dddd LT',
	            sameElse : 'L'
	        },
	        relativeTime : {
	            future : '%s 후',
	            past : '%s 전',
	            s : '몇 초',
	            ss : '%d초',
	            m : '일분',
	            mm : '%d분',
	            h : '한 시간',
	            hh : '%d시간',
	            d : '하루',
	            dd : '%d일',
	            M : '한 달',
	            MM : '%d달',
	            y : '일 년',
	            yy : '%d년'
	        },
	        ordinalParse : /\d{1,2}일/,
	        ordinal : '%d일',
	        meridiemParse : /오전|오후/,
	        isPM : function (token) {
	            return token === '오후';
	        },
	        meridiem : function (hour, minute, isUpper) {
	            return hour < 12 ? '오전' : '오후';
	        }
	    });
	
	    return ko;
	
	}));

/***/ },
/* 352 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : kyrgyz (ky)
	//! author : Chyngyz Arystan uulu : https://github.com/chyngyz
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 жыл'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 353 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Luxembourgish (lb)
	//! author : mweimerskirch : https://github.com/mweimerskirch, David Raison : https://github.com/kwisatz
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 354 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : lao (lo)
	//! author : Ryan Hart : https://github.com/ryanhart2
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 ປີ'
	        },
	        ordinalParse: /(ທີ່)\d{1,2}/,
	        ordinal : function (number) {
	            return 'ທີ່' + number;
	        }
	    });
	
	    return lo;
	
	}));

/***/ },
/* 355 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Lithuanian (lt)
	//! author : Mindaugas Mozūras : https://github.com/mmozuras
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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('_')
	        },
	        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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 356 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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 !== 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 !== 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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 357 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Montenegrin (me)
	//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 358 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : macedonian (mk)
	//! author : Borislav Mickov : https://github.com/B0k0
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 години'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 359 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : malayalam (ml)
	//! author : Floyd Pink : https://github.com/floydpink
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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;
	
	}));

/***/ },
/* 360 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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': '०'
	    },
	    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;
	
	}));

/***/ },
/* 361 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Bahasa Malaysia (ms-MY)
	//! author : Weldan Jamili : https://github.com/weldan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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;
	
	}));

/***/ },
/* 362 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Bahasa Malaysia (ms-MY)
	//! author : Weldan Jamili : https://github.com/weldan
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var ms_my = 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 ms_my;
	
	}));

/***/ },
/* 363 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Burmese (my)
	//! author : Squar team, mysquar.com
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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': '၀'
	    }, 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;
	
	}));

/***/ },
/* 364 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 365 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : nepali/nepalese
	//! author : suvash : https://github.com/suvash
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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': '०'
	    },
	    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;
	
	}));

/***/ },
/* 366 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : dutch (nl)
	//! author : Joris Röling : https://github.com/jjupiter
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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('_'),
	        monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');
	
	    var nl = moment.defineLocale('nl', {
	        months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),
	        monthsShort : function (m, format) {
	            if (/-MMM-/.test(format)) {
	                return monthsShortWithoutDots[m.month()];
	            } else {
	                return monthsShortWithDots[m.month()];
	            }
	        },
	        monthsParseExact : true,
	        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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 367 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : norwegian nynorsk (nn)
	//! author : https://github.com/mechuwind
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 368 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : punjabi india (pa-in)
	//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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': '੦'
	    },
	    numberMap = {
	        '੧': '1',
	        '੨': '2',
	        '੩': '3',
	        '੪': '4',
	        '੫': '5',
	        '੬': '6',
	        '੭': '7',
	        '੮': '8',
	        '੯': '9',
	        '੦': '0'
	    };
	
	    var pa_in = 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 pa_in;
	
	}));

/***/ },
/* 369 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : polish (pl)
	//! author : Rafal Hirsz : https://github.com/evoL
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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('_'),
	        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 (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 : 'nie_pon_wt_śr_czw_pt_sb'.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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 370 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : portuguese (pt)
	//! author : Jefferson : https://github.com/jalex79
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 371 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : brazilian portuguese (pt-br)
	//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var pt_br = 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 : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.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'
	        },
	        ordinalParse: /\d{1,2}º/,
	        ordinal : '%dº'
	    });
	
	    return pt_br;
	
	}));

/***/ },
/* 372 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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;
	
	}));

/***/ },
/* 373 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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,
	        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 'вечера';
	            }
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 374 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Northern Sami (se)
	//! authors : Bård Rolstad Henriksen : https://github.com/karamell
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 375 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Sinhalese (si)
	//! author : Sampath Sitinamaluwa : https://github.com/sampathsris
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 376 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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('_'),
	        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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 377 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : slovenian (sl)
	//! author : Robert Sedovšek : https://github.com/sedovsek
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 378 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Albanian (sq)
	//! author : Flakërim Ismani : https://github.com/flakerimi
	//! author: Menelion Elensúle: https://github.com/Oire (tests)
	//! author : Oerd Cukalla : https://github.com/oerd (fixes)
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 379 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Serbian-latin (sr)
	//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 380 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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 sr_cyrl = 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
	        },
	        ordinalParse: /\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_cyrl;
	
	}));

/***/ },
/* 381 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : siSwati (ss)
	//! author : Nicolai Davies<mail@nicolai.io> : https://github.com/nicolaidavies
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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;
	            }
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 382 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : swedish (sv)
	//! author : Jens Alm : https://github.com/ulmus
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 383 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : swahili (sw)
	//! author : Fahad Kassim : https://github.com/fadsel
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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;
	
	}));

/***/ },
/* 384 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : tamil (ta)
	//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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': '௦'
	    }, 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 ஆண்டுகள்'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 385 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : telugu (te)
	//! author : Krishna Chaitanya Thota : https://github.com/kcthota
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 సంవత్సరాలు'
	        },
	        ordinalParse : /\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;
	
	}));

/***/ },
/* 386 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : thai (th)
	//! author : Kridsada Thanabulpong : https://github.com/sirn
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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 นาฬิกา m นาที',
	            LTS : 'H นาฬิกา m นาที s วินาที',
	            L : 'YYYY/MM/DD',
	            LL : 'D MMMM YYYY',
	            LLL : 'D MMMM YYYY เวลา H นาฬิกา m นาที',
	            LLLL : 'วันddddที่ D MMMM YYYY เวลา H นาฬิกา m นาที'
	        },
	        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;
	
	}));

/***/ },
/* 387 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Tagalog/Filipino (tl-ph)
	//! author : Dan Hagman
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var tl_ph = 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: '[Ngayon sa] LT',
	            nextDay: '[Bukas sa] LT',
	            nextWeek: 'dddd [sa] LT',
	            lastDay: '[Kahapon sa] LT',
	            lastWeek: 'dddd [huling linggo] LT',
	            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'
	        },
	        ordinalParse: /\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 tl_ph;
	
	}));

/***/ },
/* 388 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Klingon (tlh)
	//! author : Dominika Kruk : https://github.com/amaranthrose
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 389 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 390 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : talossan (tzl)
	//! author : Robin van der Vliet : https://github.com/robin0van0der0v with the help of Iustì Canun
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 391 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Morocco Central Atlas Tamaziɣt (tzm)
	//! author : Abdel Said : https://github.com/abdelsaid
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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;
	
	}));

/***/ },
/* 392 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn)
	//! author : Abdel Said : https://github.com/abdelsaid
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var tzm_latn = 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 tzm_latn;
	
	}));

/***/ },
/* 393 */
/***/ function(module, exports, __webpack_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(__webpack_require__(297)) :
	   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('_')
	        },
	        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 'вечора';
	            }
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 394 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : uzbek (uz)
	//! author : Sardor Muminov : https://github.com/muminoff
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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;
	
	}));

/***/ },
/* 395 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : vietnamese (vi)
	//! author : Bang Nguyen : https://github.com/bangnk
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   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'
	        },
	        ordinalParse: /\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;
	
	}));

/***/ },
/* 396 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : pseudo (x-pseudo)
	//! author : Andrew Hood : https://github.com/andrewhood125
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var x_pseudo = 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'
	        },
	        ordinalParse: /\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 x_pseudo;
	
	}));

/***/ },
/* 397 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : chinese (zh-cn)
	//! author : suupic : https://github.com/suupic
	//! author : Zeno Zeng : https://github.com/zenozeng
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var zh_cn = 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 : 'Ah点mm分',
	            LTS : 'Ah点m分s秒',
	            L : 'YYYY-MM-DD',
	            LL : 'YYYY年MMMD日',
	            LLL : 'YYYY年MMMD日Ah点mm分',
	            LLLL : 'YYYY年MMMD日ddddAh点mm分',
	            l : 'YYYY-MM-DD',
	            ll : 'YYYY年MMMD日',
	            lll : 'YYYY年MMMD日Ah点mm分',
	            llll : 'YYYY年MMMD日ddddAh点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 : function () {
	                return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT';
	            },
	            nextDay : function () {
	                return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT';
	            },
	            lastDay : function () {
	                return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT';
	            },
	            nextWeek : function () {
	                var startOfWeek, prefix;
	                startOfWeek = moment().startOf('week');
	                prefix = this.diff(startOfWeek, 'days') >= 7 ? '[下]' : '[本]';
	                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
	            },
	            lastWeek : function () {
	                var startOfWeek, prefix;
	                startOfWeek = moment().startOf('week');
	                prefix = this.unix() < startOfWeek.unix()  ? '[上]' : '[本]';
	                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
	            },
	            sameElse : 'LL'
	        },
	        ordinalParse: /\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 zh_cn;
	
	}));

/***/ },
/* 398 */
/***/ function(module, exports, __webpack_require__) {

	//! moment.js locale configuration
	//! locale : traditional chinese (zh-tw)
	//! author : Ben : https://github.com/ben-lin
	
	;(function (global, factory) {
	    true ? factory(__webpack_require__(297)) :
	   typeof define === 'function' && define.amd ? define(['moment'], factory) :
	   factory(global.moment)
	}(this, function (moment) { 'use strict';
	
	
	    var zh_tw = 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 : 'Ah點mm分',
	            LTS : 'Ah點m分s秒',
	            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日Ah點mm分',
	            llll : 'YYYY年MMMD日ddddAh點mm分'
	        },
	        meridiemParse: /早上|上午|中午|下午|晚上/,
	        meridiemHour : function (hour, meridiem) {
	            if (hour === 12) {
	                hour = 0;
	            }
	            if (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 < 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'
	        },
	        ordinalParse: /\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 zh_tw;
	
	}));

/***/ },
/* 399 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var phosphor_signaling_1 = __webpack_require__(22);
	/**
	 * An implementation of a file browser view model.
	 *
	 * #### Notes
	 * All paths parameters without a leading `'/'` are interpreted as relative to
	 * the current directory.  Supports `'../'` syntax.
	 */
	var FileBrowserModel = (function () {
	    /**
	     * Construct a new file browser view model.
	     */
	    function FileBrowserModel(contentsManager, sessionManager, specs) {
	        this._maxUploadSizeMb = 15;
	        this._contentsManager = null;
	        this._sessionIds = [];
	        this._sessionManager = null;
	        this._selection = Object.create(null);
	        this._sortKey = 'name';
	        this._ascending = true;
	        this._unsortedNames = [];
	        this._specs = null;
	        this._contentsManager = contentsManager;
	        this._sessionManager = sessionManager;
	        this._specs = specs;
	        this._model = { path: '', name: '/', type: 'directory', content: [] };
	        this.cd();
	    }
	    Object.defineProperty(FileBrowserModel.prototype, "refreshed", {
	        /**
	         * Get the refreshed signal.
	         */
	        get: function () {
	            return Private.refreshedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FileBrowserModel.prototype, "fileChanged", {
	        /**
	         * Get the file path changed signal.
	         */
	        get: function () {
	            return Private.fileChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FileBrowserModel.prototype, "path", {
	        /**
	         * Get the current path.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._model.path;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FileBrowserModel.prototype, "selectionChanged", {
	        /**
	         * Get the selection changed signal.
	         */
	        get: function () {
	            return Private.selectionChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FileBrowserModel.prototype, "isDisposed", {
	        /**
	         * Get whether the view model is disposed.
	         */
	        get: function () {
	            return this._model === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FileBrowserModel.prototype, "sessionIds", {
	        /**
	         * Get the session ids for active notebooks.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._sessionIds.slice();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FileBrowserModel.prototype, "kernelspecs", {
	        /**
	         * Get the kernel specs.
	         */
	        get: function () {
	            return this._specs;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FileBrowserModel.prototype, "sortAscending", {
	        /**
	         * Get whether the items are sorted in ascending order.
	         */
	        get: function () {
	            return this._ascending;
	        },
	        /**
	         * Set whether the items are sorted in ascending order.
	         */
	        set: function (value) {
	            this._ascending = value;
	            this._sort();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FileBrowserModel.prototype, "sortKey", {
	        /**
	         * Get which key the items are sorted on.
	         */
	        get: function () {
	            return this._sortKey;
	        },
	        /**
	         * Set which key the items are sorted on.
	         */
	        set: function (value) {
	            this._sortKey = value;
	            this._sort();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FileBrowserModel.prototype, "sortedItems", {
	        /**
	         * Get the sorted list of items.
	         *
	         * #### Notes
	         * This is a read-only property and should be treated as immutable.
	         */
	        get: function () {
	            return this._model.content;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Select an item by name.
	     *
	     * #### Notes
	     * This is a no-op if the name is not valid or already selected.
	     */
	    FileBrowserModel.prototype.select = function (name) {
	        if (!this._selection[name]) {
	            this._selection[name] = true;
	            this.selectionChanged.emit(void 0);
	        }
	    };
	    /**
	     * De-select an item by name.
	     *
	     * #### Notes
	     * This is a no-op if the name is not valid or not selected.
	     */
	    FileBrowserModel.prototype.deselect = function (name) {
	        if (this._selection[name]) {
	            delete this._selection[name];
	            this.selectionChanged.emit(void 0);
	        }
	    };
	    /**
	     * Check whether an item is selected.
	     *
	     * #### Notes
	     * Returns `true` for a valid name that is selected, `false` otherwise.
	     */
	    FileBrowserModel.prototype.isSelected = function (name) {
	        return !!this._selection[name];
	    };
	    /**
	     * Get the list of selected names.
	     */
	    FileBrowserModel.prototype.getSelected = function () {
	        return Object.keys(this._selection);
	    };
	    /**
	     * Clear the selected items.
	     */
	    FileBrowserModel.prototype.clearSelected = function () {
	        this._selection = Object.create(null);
	        this.selectionChanged.emit(void 0);
	    };
	    /**
	     * Dispose of the resources held by the view model.
	     */
	    FileBrowserModel.prototype.dispose = function () {
	        this._model = null;
	        this._contentsManager = null;
	        this._selection = null;
	        phosphor_signaling_1.clearSignalData(this);
	    };
	    /**
	     * Change directory.
	     *
	     * @param path - The path to the file or directory.
	     *
	     * @returns A promise with the contents of the directory.
	     */
	    FileBrowserModel.prototype.cd = function (path) {
	        var _this = this;
	        if (path === void 0) { path = ''; }
	        if (path !== '') {
	            path = Private.normalizePath(this._model.path, path);
	        }
	        var previous = this._selection;
	        if (path !== this.path) {
	            previous = Object.create(null);
	        }
	        var selection = Object.create(null);
	        return this._contentsManager.get(path, {}).then(function (contents) {
	            _this._model = contents;
	            var content = contents.content;
	            var names = content.map(function (value, index) { return value.name; });
	            for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
	                var name_1 = names_1[_i];
	                if (previous[name_1]) {
	                    selection[name_1] = true;
	                }
	            }
	            _this._unsortedNames = content.map(function (value, index) { return value.name; });
	            if (_this._sortKey !== 'name' || !_this._ascending) {
	                _this._sort();
	            }
	            return _this._findSessions();
	        }).then(function () {
	            _this.selectionChanged.emit(void 0);
	            _this.refreshed.emit(void 0);
	        });
	    };
	    /**
	     * Refresh the current directory.
	     */
	    FileBrowserModel.prototype.refresh = function () {
	        return this.cd('.').catch(function (error) {
	            console.error(error);
	            var msg = 'Unable to refresh the directory listing due to ';
	            msg += 'lost server connection.';
	            error.message = msg;
	            throw error;
	        });
	    };
	    /**
	     * Copy a file.
	     *
	     * @param fromFile - The path of the original file.
	     *
	     * @param toDir - The path to the target directory.
	     *
	     * @returns A promise which resolves to the contents of the file.
	     */
	    FileBrowserModel.prototype.copy = function (fromFile, toDir) {
	        var _this = this;
	        var normalizePath = Private.normalizePath;
	        fromFile = normalizePath(this._model.path, fromFile);
	        toDir = normalizePath(this._model.path, toDir);
	        return this._contentsManager.copy(fromFile, toDir).then(function (contents) {
	            _this.fileChanged.emit({
	                name: 'file',
	                oldValue: void 0,
	                newValue: contents.path
	            });
	            return contents;
	        });
	    };
	    /**
	     * Delete a file.
	     *
	     * @param: path - The path to the file to be deleted.
	     *
	     * @returns A promise which resolves when the file is deleted.
	     */
	    FileBrowserModel.prototype.delete = function (path) {
	        var _this = this;
	        var normalizePath = Private.normalizePath;
	        path = normalizePath(this._model.path, path);
	        return this._contentsManager.delete(path).then(function () {
	            _this.fileChanged.emit({
	                name: 'file',
	                oldValue: path,
	                newValue: void 0
	            });
	        });
	    };
	    /**
	     * Download a file.
	     *
	     * @param - path - The path of the file to be downloaded.
	     *
	     * @returns - A promise which resolves to the file contents.
	     */
	    FileBrowserModel.prototype.download = function (path) {
	        var normalizePath = Private.normalizePath;
	        path = normalizePath(this._model.path, path);
	        return this._contentsManager.get(path, {}).then(function (contents) {
	            var element = document.createElement('a');
	            element.setAttribute('href', 'data:text/text;charset=utf-8,' + encodeURI(contents.content));
	            element.setAttribute('download', contents.name);
	            element.click();
	            return contents;
	        });
	    };
	    /**
	     * Create a new untitled file or directory in the current directory.
	     *
	     * @param type - The type of file object to create. One of
	     *  `['file', 'notebook', 'directory']`.
	     *
	     * @param ext - Optional extension for `'file'` types (defaults to `'.txt'`).
	     *
	     * @returns A promise containing the new file contents model.
	     */
	    FileBrowserModel.prototype.newUntitled = function (type, ext) {
	        var _this = this;
	        if (type === 'file') {
	            ext = ext || '.txt';
	        }
	        else {
	            ext = '';
	        }
	        return this._contentsManager.newUntitled(this._model.path, { type: type, ext: ext }).then(function (contents) {
	            _this.fileChanged.emit({
	                name: 'file',
	                oldValue: void 0,
	                newValue: contents.path
	            });
	            return contents;
	        });
	    };
	    /**
	     * Rename a file or directory.
	     *
	     * @param path - The path to the original file.
	     *
	     * @param newPath - The path to the new file.
	     *
	     * @returns A promise containing the new file contents model.
	     */
	    FileBrowserModel.prototype.rename = function (path, newPath) {
	        var _this = this;
	        // Handle relative paths.
	        var normalizePath = Private.normalizePath;
	        path = normalizePath(this._model.path, path);
	        newPath = normalizePath(this._model.path, newPath);
	        return this._contentsManager.rename(path, newPath).then(function (contents) {
	            _this.fileChanged.emit({
	                name: 'file',
	                oldValue: path,
	                newValue: newPath
	            });
	            return contents;
	        });
	    };
	    /**
	     * Upload a `File` object.
	     *
	     * @param file - The `File` object to upload.
	     *
	     * @param overwrite - Whether to overwrite an existing file.
	     *
	     * @returns A promise containing the new file contents model.
	     *
	     * #### Notes
	     * This will fail to upload files that are too big to be sent in one
	     * request to the server.
	     */
	    FileBrowserModel.prototype.upload = function (file, overwrite) {
	        var _this = this;
	        // Skip large files with a warning.
	        if (file.size > this._maxUploadSizeMb * 1024 * 1024) {
	            var msg = "Cannot upload file (>" + this._maxUploadSizeMb + " MB) ";
	            msg += "\"" + file.name + "\"";
	            console.warn(msg);
	            return Promise.reject(new Error(msg));
	        }
	        if (overwrite) {
	            return this._upload(file);
	        }
	        return this._contentsManager.get(file.name, {}).then(function () {
	            return Private.typedThrow("\"" + file.name + "\" already exists");
	        }, function () {
	            return _this._upload(file);
	        });
	    };
	    /**
	     * Shut down a notebook session by session id.
	     */
	    FileBrowserModel.prototype.shutdown = function (sessionId) {
	        return this._sessionManager.connectTo(sessionId.id).then(function (session) {
	            return session.shutdown();
	        });
	    };
	    /**
	     * Start a new session on a notebook.
	     */
	    FileBrowserModel.prototype.startSession = function (path, kernel) {
	        return this._sessionManager.startNew({
	            notebookPath: path,
	            kernelName: kernel
	        });
	    };
	    /**
	     * Sort the model items.
	     */
	    FileBrowserModel.prototype._sort = function () {
	        var _this = this;
	        if (!this._unsortedNames) {
	            return;
	        }
	        var items = this._model.content.slice();
	        if (this._sortKey === 'name') {
	            items.sort(function (a, b) {
	                var indexA = _this._unsortedNames.indexOf(a.name);
	                var indexB = _this._unsortedNames.indexOf(b.name);
	                return indexA - indexB;
	            });
	        }
	        else if (this._sortKey === 'last_modified') {
	            items.sort(function (a, b) {
	                var valA = new Date(a.last_modified).getTime();
	                var valB = new Date(b.last_modified).getTime();
	                return valB - valA;
	            });
	        }
	        // Reverse the order if descending.
	        if (!this._ascending) {
	            items.reverse();
	        }
	        this._model.content = items;
	    };
	    /**
	     * Perform the actual upload.
	     */
	    FileBrowserModel.prototype._upload = function (file) {
	        var _this = this;
	        // Gather the file model parameters.
	        var path = this._model.path;
	        path = path ? path + '/' + file.name : file.name;
	        var name = file.name;
	        var isNotebook = file.name.indexOf('.ipynb') !== -1;
	        var type = isNotebook ? 'notebook' : 'file';
	        var format = isNotebook ? 'json' : 'base64';
	        // Get the file content.
	        var reader = new FileReader();
	        if (isNotebook) {
	            reader.readAsText(file);
	        }
	        else {
	            reader.readAsArrayBuffer(file);
	        }
	        return new Promise(function (resolve, reject) {
	            reader.onload = function (event) {
	                var model = {
	                    type: type,
	                    format: format,
	                    name: name,
	                    content: Private.getContent(reader)
	                };
	                _this._contentsManager.save(path, model).then(function (contents) {
	                    _this.fileChanged.emit({
	                        name: 'file',
	                        oldValue: void 0,
	                        newValue: contents.path
	                    });
	                    resolve(contents);
	                });
	            };
	            reader.onerror = function (event) {
	                reject(Error(("Failed to upload \"" + file.name + "\":") + event));
	            };
	        });
	    };
	    /**
	     * Get the notebook sessions for the current directory.
	     */
	    FileBrowserModel.prototype._findSessions = function () {
	        var _this = this;
	        this._sessionIds = [];
	        var notebooks = this._model.content.filter(function (content) { return content.type === 'notebook'; });
	        if (!notebooks.length) {
	            return Promise.resolve(void 0);
	        }
	        return this._sessionManager.listRunning().then(function (sessionIds) {
	            if (!sessionIds.length) {
	                return;
	            }
	            var paths = notebooks.map(function (notebook) {
	                return notebook.path;
	            });
	            for (var _i = 0, sessionIds_1 = sessionIds; _i < sessionIds_1.length; _i++) {
	                var sessionId = sessionIds_1[_i];
	                var index = paths.indexOf(sessionId.notebook.path);
	                if (index !== -1) {
	                    _this._sessionIds.push(sessionId);
	                }
	            }
	        });
	    };
	    return FileBrowserModel;
	}());
	exports.FileBrowserModel = FileBrowserModel;
	/**
	 * The namespace for the file browser model private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when a model refresh occurs.
	     */
	    Private.refreshedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when the a file changes path.
	     */
	    Private.fileChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when the selection changes.
	     */
	    Private.selectionChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * Parse the content of a `FileReader`.
	     *
	     * If the result is an `ArrayBuffer`, return a Base64-encoded string.
	     * Otherwise, return the JSON parsed result.
	     */
	    function getContent(reader) {
	        if (reader.result instanceof ArrayBuffer) {
	            // Base64-encode binary file data.
	            var bytes = '';
	            var buf = new Uint8Array(reader.result);
	            var nbytes = buf.byteLength;
	            for (var i = 0; i < nbytes; i++) {
	                bytes += String.fromCharCode(buf[i]);
	            }
	            return btoa(bytes);
	        }
	        else {
	            return JSON.parse(reader.result);
	        }
	    }
	    Private.getContent = getContent;
	    /**
	     * Normalize a path based on a root directory, accounting for relative paths.
	     */
	    function normalizePath(root, path) {
	        // Current directory
	        if (path === '.') {
	            return root;
	        }
	        // Root path.
	        if (path.indexOf('/') === 0) {
	            path = path.slice(1, path.length);
	            root = '';
	        }
	        else if (path.indexOf('./') === 0) {
	            path = path.slice(2, path.length);
	        }
	        else if (path.indexOf('../../') === 0) {
	            var parts = root.split('/');
	            root = parts.splice(0, parts.length - 2).join('/');
	            path = path.slice(6, path.length);
	        }
	        else if (path.indexOf('../') === 0) {
	            var parts = root.split('/');
	            root = parts.splice(0, parts.length - 1).join('/');
	            path = path.slice(3, path.length);
	        }
	        else {
	        }
	        if (path[path.length - 1] === '/') {
	            path = path.slice(0, path.length - 1);
	        }
	        // Combine the root and the path if necessary.
	        if (root && path) {
	            path = root + '/' + path;
	        }
	        else if (root) {
	            path = root;
	        }
	        return path;
	    }
	    Private.normalizePath = normalizePath;
	    /**
	     * Work around TS 1.8 type inferencing in promises which only throw.
	     */
	    function typedThrow(msg) {
	        throw new Error(msg);
	    }
	    Private.typedThrow = typedThrow;
	})(Private || (Private = {}));


/***/ },
/* 400 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var iframe_1 = __webpack_require__(401);
	/**
	 * The class name added to the help widget.
	 */
	var HELP_CLASS = 'jp-Help';
	/**
	 * A list of commands to add to the help widget.
	 */
	var COMMANDS = [
	    {
	        text: 'Scipy Lecture Notes',
	        id: 'help-doc:scipy-lecture-notes',
	        url: 'http://www.scipy-lectures.org/'
	    },
	    {
	        text: 'Numpy Reference',
	        id: 'help-doc:numpy-reference',
	        url: 'http://docs.scipy.org/doc/numpy/reference/'
	    },
	    {
	        text: 'Scipy Reference',
	        id: 'help-doc:scipy-reference',
	        url: 'http://docs.scipy.org/doc/scipy/reference/'
	    },
	    {
	        text: 'Notebook Tutorial',
	        id: 'help-doc:notebook-tutorial',
	        url: 'http://nbviewer.jupyter.org/github/jupyter/notebook/' +
	            'blob/master/docs/source/examples/Notebook/Notebook Basics.ipynb'
	    }
	];
	/**
	 * The help handler extension.
	 */
	exports.helpHandlerExtension = {
	    id: 'jupyter.extensions.helpHandler',
	    activate: activateHelpHandler
	};
	/**
	 * Activate the help handler extension.
	 *
	 * @param app - The phosphide application object.
	 *
	 * returns A promise that resolves when the extension is activated.
	 */
	function activateHelpHandler(app) {
	    var widget = new iframe_1.IFrame();
	    widget.addClass(HELP_CLASS);
	    widget.title.text = 'Help';
	    widget.id = 'help-doc';
	    var helpCommandItems = COMMANDS.map(function (command) {
	        return {
	            id: command.id,
	            handler: function () {
	                attachHelp();
	                showHelp();
	                widget.loadURL(command.url);
	            }
	        };
	    });
	    app.commands.add(helpCommandItems);
	    app.commands.add([
	        {
	            id: 'help-doc:activate',
	            handler: showHelp
	        },
	        {
	            id: 'help-doc:hide',
	            handler: hideHelp
	        },
	        {
	            id: 'help-doc:toggle',
	            handler: toggleHelp
	        }
	    ]);
	    var helpPaletteItems = COMMANDS.map(function (command) {
	        return {
	            command: command.id,
	            text: command.text,
	            caption: "Open " + command.text,
	            category: 'Help'
	        };
	    });
	    app.palette.add(helpPaletteItems);
	    return Promise.resolve(void 0);
	    function attachHelp() {
	        if (!widget.isAttached)
	            app.shell.addToRightArea(widget);
	    }
	    function showHelp() {
	        app.shell.activateRight(widget.id);
	    }
	    function hideHelp() {
	        if (!widget.isHidden)
	            app.shell.collapseRight();
	    }
	    function toggleHelp() {
	        if (widget.isHidden) {
	            showHelp();
	        }
	        else {
	            hideHelp();
	        }
	    }
	}


/***/ },
/* 401 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * The class name added to an IFrame widget.
	 */
	var IFRAME_CLASS = 'jp-IFrame';
	/**
	 * A phosphor widget which wraps an IFrame.
	 */
	var IFrame = (function (_super) {
	    __extends(IFrame, _super);
	    /**
	     * Create a new iframe widget.
	     */
	    function IFrame() {
	        _super.call(this);
	        this.addClass(IFRAME_CLASS);
	    }
	    /**
	     * Create the main content node of an iframe widget.
	     */
	    IFrame.createNode = function () {
	        var node = document.createElement('div');
	        var iframe = document.createElement('iframe');
	        iframe.style.height = '100%';
	        iframe.style.width = '100%';
	        node.appendChild(iframe);
	        return node;
	    };
	    /**
	     * Load a URL into the iframe.
	     *
	     * @param url - The URL to load into the iframe widget.
	     */
	    IFrame.prototype.loadURL = function (url) {
	        this.node.querySelector('iframe').setAttribute('src', url);
	    };
	    return IFrame;
	}(phosphor_widget_1.Widget));
	exports.IFrame = IFrame;


/***/ },
/* 402 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var docmanager_1 = __webpack_require__(274);
	/**
	 * The list of file extensions for images.
	 */
	var EXTENSIONS = ['.png', '.gif', '.jpeg', '.jpg', '.svg', '.bmp', '.ico',
	    '.xbm', '.tiff', '.tif'];
	/**
	 * The image file handler extension.
	 */
	exports.imageHandlerExtension = {
	    id: 'jupyter.extensions.imageHandler',
	    requires: [docmanager_1.DocumentRegistry],
	    activate: function (app, registry) {
	        registry.registerWidgetFactory(new docmanager_1.ImageWidgetFactory(), {
	            fileExtensions: EXTENSIONS,
	            displayName: 'Image',
	            modelName: 'base64',
	            defaultFor: EXTENSIONS,
	            preferKernel: false,
	            canStartKernel: false
	        });
	    }
	};


/***/ },
/* 403 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * The landing page extension.
	 */
	exports.landingExtension = {
	    id: 'jupyter.extensions.landing',
	    activate: activateLanding
	};
	function activateLanding(app) {
	    var widget = new phosphor_widget_1.Widget();
	    widget.id = 'landing-jupyterlab';
	    widget.title.text = 'JupyterLab';
	    widget.title.closable = true;
	    widget.addClass('jp-Landing');
	    var dialog = document.createElement('div');
	    dialog.className = 'jp-Landing-dialog';
	    widget.node.appendChild(dialog);
	    var title = document.createElement('span');
	    title.textContent = 'Welcome to';
	    title.className = 'jp-Landing-title';
	    dialog.appendChild(title);
	    var logo = document.createElement('span');
	    logo.className = 'jp-Landing-logo';
	    dialog.appendChild(logo);
	    var header = document.createElement('span');
	    header.textContent = 'Start a new activity:';
	    header.className = 'jp-Landing-header';
	    dialog.appendChild(header);
	    var body = document.createElement('div');
	    body.className = 'jp-Landing-body';
	    dialog.appendChild(body);
	    for (var _i = 0, _a = ['Notebook', 'Terminal', 'Text Editor']; _i < _a.length; _i++) {
	        var name_1 = _a[_i];
	        var column = document.createElement('div');
	        body.appendChild(column);
	        column.className = 'jp-Landing-column';
	        var img_1 = document.createElement('span');
	        var imgName = name_1.replace(' ', '');
	        img_1.className = "jp-Landing-image" + imgName + " jp-Landing-image";
	        column.appendChild(img_1);
	        var text = document.createElement('span');
	        text.textContent = name_1;
	        text.className = 'jp-Landing-text';
	        column.appendChild(text);
	    }
	    var img = body.getElementsByClassName('jp-Landing-imageNotebook')[0];
	    img.addEventListener('click', function () {
	        app.commands.execute('file-operations:new-notebook');
	    });
	    img = body.getElementsByClassName('jp-Landing-imageTextEditor')[0];
	    img.addEventListener('click', function () {
	        app.commands.execute('file-operations:new-text-file');
	    });
	    img = body.getElementsByClassName('jp-Landing-imageTerminal')[0];
	    img.addEventListener('click', function () {
	        app.commands.execute('terminal:create-new');
	    });
	    app.commands.add([{
	            id: 'jupyterlab-launcher:show',
	            handler: function () {
	                if (!widget.isAttached) {
	                    app.shell.addToMainArea(widget);
	                }
	                app.shell.activateMain(widget.id);
	            }
	        }]);
	    app.palette.add([{
	            command: 'jupyterlab-launcher:show',
	            text: 'JupyterLab Launcher',
	            category: 'Help'
	        }]);
	    app.shell.addToMainArea(widget);
	}


/***/ },
/* 404 */
/***/ function(module, exports) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	/**
	 * The main extension.
	 */
	exports.mainExtension = {
	    id: 'jupyter.extensions.main',
	    activate: function (app) {
	        window.onbeforeunload = function (event) {
	            var msg = 'Are you sure you want to exit JupyterLab?';
	            msg += '\nAny unsaved changes will be lost.';
	            return msg;
	        };
	    }
	};


/***/ },
/* 405 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var index_1 = __webpack_require__(406);
	var docmanager_1 = __webpack_require__(274);
	var rendermime_1 = __webpack_require__(273);
	var phosphor_dragdrop_1 = __webpack_require__(31);
	var phosphor_signaling_1 = __webpack_require__(22);
	var plugin_1 = __webpack_require__(282);
	/**
	 * The map of command ids used by the notebook.
	 */
	var cmdIds = {
	    interrupt: 'notebook:interrupt-kernel',
	    restart: 'notebook:restart-kernel',
	    restartClear: 'notebook:restart-clear',
	    restartRunAll: 'notebook:restart-runAll',
	    switchKernel: 'notebook:switch-kernel',
	    clearAllOutputs: 'notebook:clear-outputs',
	    run: 'notebook-cells:run',
	    runAndAdvance: 'notebook-cells:runAndAdvance',
	    runAndInsert: 'notebook-cells:runAndInsert',
	    runAll: 'notebook:run-all',
	    toCode: 'notebook-cells:to-code',
	    toMarkdown: 'notebook-cells:to-markdown',
	    toRaw: 'notebook-cells:to-raw',
	    cut: 'notebook-cells:cut',
	    copy: 'notebook-cells:copy',
	    paste: 'notebook-cells:paste',
	    clearOutputs: 'notebook-cells:clear-output',
	    deleteCell: 'notebook-cells:delete',
	    insertAbove: 'notebook-cells:insert-above',
	    insertBelow: 'notebook-cells:insert-below',
	    selectAbove: 'notebook-cells:select-above',
	    selectBelow: 'notebook-cells:select-below',
	    extendAbove: 'notebook-cells:extend-above',
	    extendBelow: 'notebook-cells:extend-below',
	    editMode: 'notebook:editMode',
	    merge: 'notebook-cells:merge',
	    split: 'notebook-cells:split',
	    commandMode: 'notebook:commandMode',
	    newNotebook: 'notebook:create-new',
	    toggleLines: 'notebook-cells:toggle-lineNumbers',
	    toggleAllLines: 'notebook-cells:toggle-allLineNumbers',
	    undo: 'notebook-cells:undo',
	    redo: 'notebook-cells:redo'
	};
	/**
	 * The notebook file handler provider.
	 */
	exports.notebookHandlerExtension = {
	    id: 'jupyter.extensions.notebookHandler',
	    requires: [docmanager_1.DocumentRegistry, plugin_1.JupyterServices, rendermime_1.RenderMime, phosphor_dragdrop_1.MimeData],
	    activate: activateNotebookHandler
	};
	/**
	 * An interface exposing the current active notebook.
	 */
	var ActiveNotebook = (function () {
	    /**
	     * Construct a new active notebook tracker.
	     */
	    function ActiveNotebook() {
	        var _this = this;
	        this._activeWidget = null;
	        this._widgets = [];
	        // Temporary notebook focus follower.
	        document.body.addEventListener('focus', function (event) {
	            for (var _i = 0, _a = _this._widgets; _i < _a.length; _i++) {
	                var widget = _a[_i];
	                var target = event.target;
	                if (widget.isAttached && widget.isVisible) {
	                    if (widget.node.contains(target)) {
	                        _this.activeNotebook = widget;
	                        return;
	                    }
	                }
	            }
	        }, true);
	    }
	    Object.defineProperty(ActiveNotebook.prototype, "activeNotebookChanged", {
	        /**
	         * A signal emitted when the active notebook changes.
	         */
	        get: function () {
	            return Private.activeNotebookChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ActiveNotebook.prototype, "activeNotebook", {
	        /**
	         * The current active notebook.
	         */
	        get: function () {
	            return this._activeWidget;
	        },
	        set: function (widget) {
	            var _this = this;
	            if (this._activeWidget === widget) {
	                return;
	            }
	            if (this._widgets.indexOf(widget) !== -1) {
	                this._activeWidget = widget;
	                this.activeNotebookChanged.emit(widget);
	                return;
	            }
	            if (widget === null) {
	                return;
	            }
	            this._widgets.push(widget);
	            widget.disposed.connect(function () {
	                var index = _this._widgets.indexOf(widget);
	                _this._widgets.splice(index, 1);
	                if (_this._activeWidget === widget) {
	                    _this.activeNotebook = null;
	                }
	            });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ActiveNotebook;
	}());
	exports.ActiveNotebook = ActiveNotebook;
	/**
	 * A service tracking the active notebook widget.
	 */
	exports.activeNotebookProvider = {
	    id: 'jupyter.services.activeNotebook',
	    provides: ActiveNotebook,
	    resolve: function () {
	        return Private.notebookTracker;
	    }
	};
	/**
	 * A version of the notebook widget factory that uses the notebook tracker.
	 */
	var TrackingNotebookWidgetFactory = (function (_super) {
	    __extends(TrackingNotebookWidgetFactory, _super);
	    function TrackingNotebookWidgetFactory() {
	        _super.apply(this, arguments);
	    }
	    /**
	     * Create a new widget.
	     */
	    TrackingNotebookWidgetFactory.prototype.createNew = function (model, context, kernel) {
	        var widget = _super.prototype.createNew.call(this, model, context, kernel);
	        Private.notebookTracker.activeNotebook = widget;
	        return widget;
	    };
	    return TrackingNotebookWidgetFactory;
	}(index_1.NotebookWidgetFactory));
	/**
	 * Activate the notebook handler extension.
	 */
	function activateNotebookHandler(app, registry, services, rendermime, clipboard) {
	    var widgetFactory = new TrackingNotebookWidgetFactory(rendermime, clipboard);
	    registry.registerModelFactory(new index_1.NotebookModelFactory());
	    registry.registerWidgetFactory(widgetFactory, {
	        fileExtensions: ['.ipynb'],
	        displayName: 'Notebook',
	        modelName: 'notebook',
	        defaultFor: ['.ipynb'],
	        preferKernel: true,
	        canStartKernel: true
	    });
	    // Add the ability to launch notebooks for each kernel type.
	    var displayNameMap = Object.create(null);
	    var specs = services.kernelspecs;
	    for (var kernelName in specs.kernelspecs) {
	        var displayName = specs.kernelspecs[kernelName].spec.display_name;
	        displayNameMap[displayName] = kernelName;
	    }
	    var displayNames = Object.keys(displayNameMap).sort(function (a, b) {
	        return a.localeCompare(b);
	    });
	    for (var _i = 0, displayNames_1 = displayNames; _i < displayNames_1.length; _i++) {
	        var displayName = displayNames_1[_i];
	        registry.registerCreator({
	            name: displayName + " Notebook",
	            extension: '.ipynb',
	            type: 'notebook',
	            kernelName: displayNameMap[displayName]
	        });
	    }
	    var tracker = Private.notebookTracker;
	    app.commands.add([
	        {
	            id: cmdIds['runAndAdvance'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.runAndAdvance(nbWidget.content, nbWidget.context.kernel);
	                }
	            }
	        },
	        {
	            id: cmdIds['run'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.run(nbWidget.content, nbWidget.context.kernel);
	                }
	            }
	        },
	        {
	            id: cmdIds['runAndInsert'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.runAndInsert(nbWidget.content, nbWidget.context.kernel);
	                }
	            }
	        },
	        {
	            id: cmdIds['runAll'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.runAll(nbWidget.content, nbWidget.context.kernel);
	                }
	            }
	        },
	        {
	            id: cmdIds['restart'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    nbWidget.restart();
	                }
	            }
	        },
	        {
	            id: cmdIds['restartClear'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget_1 = tracker.activeNotebook;
	                    nbWidget_1.restart().then(function (result) {
	                        if (result) {
	                            index_1.NotebookActions.clearAllOutputs(nbWidget_1.content);
	                        }
	                    });
	                }
	            }
	        },
	        {
	            id: cmdIds['restartRunAll'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget_2 = tracker.activeNotebook;
	                    nbWidget_2.restart().then(function (result) {
	                        index_1.NotebookActions.runAll(nbWidget_2.content, nbWidget_2.context.kernel);
	                    });
	                }
	            }
	        },
	        {
	            id: cmdIds['clearAllOutputs'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.clearAllOutputs(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['clearOutputs'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.clearOutputs(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['interrupt'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var kernel = tracker.activeNotebook.context.kernel;
	                    if (kernel) {
	                        kernel.interrupt();
	                    }
	                }
	            }
	        },
	        {
	            id: cmdIds['toCode'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.changeCellType(nbWidget.content, 'code');
	                }
	            }
	        },
	        {
	            id: cmdIds['toMarkdown'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.changeCellType(nbWidget.content, 'markdown');
	                }
	            }
	        },
	        {
	            id: cmdIds['toRaw'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.changeCellType(nbWidget.content, 'raw');
	                }
	            }
	        },
	        {
	            id: cmdIds['cut'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.cut(nbWidget.content, nbWidget.clipboard);
	                }
	            }
	        },
	        {
	            id: cmdIds['copy'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.copy(nbWidget.content, nbWidget.clipboard);
	                }
	            }
	        },
	        {
	            id: cmdIds['paste'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.paste(nbWidget.content, nbWidget.clipboard);
	                }
	            }
	        },
	        {
	            id: cmdIds['deleteCell'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.deleteCells(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['split'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.splitCell(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['merge'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.mergeCells(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['insertAbove'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.insertAbove(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['insertBelow'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.insertBelow(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['selectAbove'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.selectAbove(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['selectBelow'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.selectBelow(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['extendAbove'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.extendSelectionAbove(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['extendBelow'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.extendSelectionBelow(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['toggleLines'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.toggleLineNumbers(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['toggleAllLines'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    var nbWidget = tracker.activeNotebook;
	                    index_1.NotebookActions.toggleAllLineNumbers(nbWidget.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['commandMode'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    tracker.activeNotebook.content.mode = 'command';
	                }
	            }
	        },
	        {
	            id: cmdIds['editMode'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    tracker.activeNotebook.content.mode = 'edit';
	                }
	            }
	        },
	        {
	            id: cmdIds['undo'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    index_1.NotebookActions.undo(tracker.activeNotebook.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['redo'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    index_1.NotebookActions.redo(tracker.activeNotebook.content);
	                }
	            }
	        },
	        {
	            id: cmdIds['switchKernel'],
	            handler: function () {
	                if (tracker.activeNotebook) {
	                    docmanager_1.selectKernelForContext(tracker.activeNotebook.context, tracker.activeNotebook.node);
	                }
	            }
	        }
	    ]);
	    app.palette.add([
	        {
	            command: cmdIds['run'],
	            category: 'Notebook Cell Operations',
	            text: 'Run Cell(s)'
	        },
	        {
	            command: cmdIds['runAndAdvance'],
	            category: 'Notebook Cell Operations',
	            text: 'Run Cell(s) and Advance'
	        },
	        {
	            command: cmdIds['runAndInsert'],
	            category: 'Notebook Cell Operations',
	            text: 'Run Cell(s) and Insert'
	        },
	        {
	            command: cmdIds['interrupt'],
	            category: 'Notebook Operations',
	            text: 'Interrupt Kernel'
	        },
	        {
	            command: cmdIds['restart'],
	            category: 'Notebook Operations',
	            text: 'Restart Kernel'
	        },
	        {
	            command: cmdIds['restartClear'],
	            category: 'Notebook Operations',
	            text: 'Restart Kernel & Clear Outputs'
	        },
	        {
	            command: cmdIds['restartRunAll'],
	            category: 'Notebook Operations',
	            text: 'Restart Kernel & Run All'
	        },
	        {
	            command: cmdIds['runAll'],
	            category: 'Notebook Operations',
	            text: 'Run All Cells'
	        },
	        {
	            command: cmdIds['clearAllOutputs'],
	            category: 'Notebook Operations',
	            text: 'Clear All Outputs'
	        },
	        {
	            command: cmdIds['clearOutputs'],
	            category: 'Notebook Cell Operations',
	            text: 'Clear Output(s)'
	        },
	        {
	            command: cmdIds['toCode'],
	            category: 'Notebook Cell Operations',
	            text: 'Convert to Code'
	        },
	        {
	            command: cmdIds['toMarkdown'],
	            category: 'Notebook Cell Operations',
	            text: 'Convert to Markdown'
	        },
	        {
	            command: cmdIds['toRaw'],
	            category: 'Notebook Cell Operations',
	            text: 'Convert to Raw'
	        },
	        {
	            command: cmdIds['cut'],
	            category: 'Notebook Cell Operations',
	            text: 'Cut Cell(s)'
	        },
	        {
	            command: cmdIds['copy'],
	            category: 'Notebook Cell Operations',
	            text: 'Copy Cell(s)'
	        },
	        {
	            command: cmdIds['paste'],
	            category: 'Notebook Cell Operations',
	            text: 'Paste Cell(s)'
	        },
	        {
	            command: cmdIds['deleteCell'],
	            category: 'Notebook Cell Operations',
	            text: 'Delete Cell(s)'
	        },
	        {
	            command: cmdIds['split'],
	            category: 'Notebook Cell Operations',
	            text: 'Split Cell'
	        },
	        {
	            command: cmdIds['merge'],
	            category: 'Notebook Cell Operations',
	            text: 'Merge Selected Cell(s)'
	        },
	        {
	            command: cmdIds['insertAbove'],
	            category: 'Notebook Cell Operations',
	            text: 'Insert Cell Above'
	        },
	        {
	            command: cmdIds['insertBelow'],
	            category: 'Notebook Cell Operations',
	            text: 'Insert Cell Below'
	        },
	        {
	            command: cmdIds['selectAbove'],
	            category: 'Notebook Cell Operations',
	            text: 'Select Cell Above'
	        },
	        {
	            command: cmdIds['selectBelow'],
	            category: 'Notebook Cell Operations',
	            text: 'Select Cell Below'
	        },
	        {
	            command: cmdIds['extendAbove'],
	            category: 'Notebook Cell Operations',
	            text: 'Extend Selection Above'
	        },
	        {
	            command: cmdIds['extendBelow'],
	            category: 'Notebook Cell Operations',
	            text: 'Extend Selection Below'
	        },
	        {
	            command: cmdIds['toggleLines'],
	            category: 'Notebook Cell Operations',
	            text: 'Toggle Line Numbers'
	        },
	        {
	            command: cmdIds['toggleAllLines'],
	            category: 'Notebook Operations',
	            text: 'Toggle All Line Numbers'
	        },
	        {
	            command: cmdIds['editMode'],
	            category: 'Notebook Operations',
	            text: 'To Edit Mode'
	        },
	        {
	            command: cmdIds['commandMode'],
	            category: 'Notebook Operations',
	            text: 'To Command Mode'
	        },
	        {
	            command: cmdIds['switchKernel'],
	            category: 'Notebook Operations',
	            text: 'Switch Kernel'
	        },
	        {
	            command: cmdIds['undo'],
	            category: 'Notebook Cell Operations',
	            text: 'Undo Cell Operation'
	        },
	        {
	            command: cmdIds['redo'],
	            category: 'Notebook Cell Operations',
	            text: 'Redo Cell Operation'
	        }
	    ]);
	    return Promise.resolve(void 0);
	}
	/**
	 * A namespace for notebook plugin private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when the active notebook changes.
	     */
	    Private.activeNotebookChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A singleton notebook tracker instance.
	     */
	    Private.notebookTracker = new ActiveNotebook();
	})(Private || (Private = {}));


/***/ },
/* 406 */
/***/ function(module, exports, __webpack_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];
	}
	__export(__webpack_require__(102));
	__export(__webpack_require__(407));


/***/ },
/* 407 */
/***/ function(module, exports, __webpack_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];
	}
	__export(__webpack_require__(408));
	__export(__webpack_require__(409));
	__export(__webpack_require__(411));
	__export(__webpack_require__(413));
	__export(__webpack_require__(123));
	__export(__webpack_require__(414));
	__export(__webpack_require__(410));
	__export(__webpack_require__(416));
	__export(__webpack_require__(415));
	__export(__webpack_require__(417));


/***/ },
/* 408 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var cells_1 = __webpack_require__(116);
	/**
	 * The mimetype used for Jupyter cell data.
	 */
	var JUPYTER_CELL_MIME = 'application/vnd.jupyter.cells';
	/**
	 * A namespace for handling actions on a notebook.
	 */
	var NotebookActions;
	(function (NotebookActions) {
	    /**
	     * Split the active cell into two cells.
	     */
	    function splitCell(widget) {
	        Private.deselectCells(widget);
	        var nbModel = widget.model;
	        var index = widget.activeCellIndex;
	        var child = widget.childAt(index);
	        var position = child.editor.getCursorPosition();
	        var orig = child.model.source;
	        // Create new models to preserve history.
	        var clone0 = Private.cloneCell(nbModel, child.model);
	        var clone1 = Private.cloneCell(nbModel, child.model);
	        if (clone0.type === 'code') {
	            clone0.outputs.clear();
	        }
	        clone0.source = orig.slice(0, position);
	        clone1.source = orig.slice(position).replace(/^\s+/g, '');
	        // Make the changes while preserving history.
	        nbModel.cells.replace(index, 1, [clone0, clone1]);
	        widget.activeCellIndex++;
	    }
	    NotebookActions.splitCell = splitCell;
	    /**
	     * Merge selected cells.
	     */
	    function mergeCells(widget) {
	        var toMerge = [];
	        var toDelete = [];
	        var model = widget.model;
	        var cells = model.cells;
	        var index = widget.activeCellIndex;
	        var primary = widget.childAt(widget.activeCellIndex);
	        var child;
	        if (!primary) {
	            return;
	        }
	        // Get the other cells to merge.
	        for (var i = 0; i < widget.childCount(); i++) {
	            if (i === index) {
	                continue;
	            }
	            child = widget.childAt(i);
	            if (widget.isSelected(child)) {
	                toMerge.push(child.model.source);
	                toDelete.push(child.model);
	            }
	        }
	        // Make sure there are cells to merge and select cells.
	        if (!toMerge.length) {
	            // Choose the cell after the active cell.
	            child = widget.childAt(cells.length - 1);
	            if (!child) {
	                return;
	            }
	            toMerge.push(child.model.source);
	            toDelete.push(child.model);
	        }
	        Private.deselectCells(widget);
	        // Create a new cell for the source to preserve history.
	        var newModel = Private.cloneCell(model, primary.model);
	        newModel.source += toMerge.join('\n\n');
	        if (newModel instanceof cells_1.CodeCellModel) {
	            newModel.outputs.clear();
	        }
	        // Make the changes while preserving history.
	        model.cells.beginCompoundOperation();
	        cells.set(index, newModel);
	        for (var _i = 0, toDelete_1 = toDelete; _i < toDelete_1.length; _i++) {
	            var cell = toDelete_1[_i];
	            cells.remove(cell);
	        }
	        model.cells.endCompoundOperation();
	        // If the original cell is a markdown cell, make sure it is unrendered.
	        if (primary instanceof cells_1.MarkdownCellWidget) {
	            var current = widget.childAt(index);
	            current.rendered = false;
	        }
	    }
	    NotebookActions.mergeCells = mergeCells;
	    /**
	     * Delete the selected cells.
	     */
	    function deleteCells(widget) {
	        var model = widget.model;
	        var cells = model.cells;
	        // Delete the cells as one undo event.
	        model.cells.beginCompoundOperation();
	        for (var i = 0; i < widget.childCount(); i++) {
	            var child = widget.childAt(i);
	            if (widget.isSelected(child)) {
	                var cell = cells.get(i);
	                cells.remove(cell);
	            }
	        }
	        if (!model.cells.length) {
	            var cell = model.createCodeCell();
	            model.cells.add(cell);
	        }
	        model.cells.endCompoundOperation();
	        Private.deselectCells(widget);
	    }
	    NotebookActions.deleteCells = deleteCells;
	    /**
	     * Insert a new code cell above the current cell.
	     */
	    function insertAbove(widget) {
	        var cell = widget.model.createCodeCell();
	        widget.model.cells.insert(widget.activeCellIndex, cell);
	        Private.deselectCells(widget);
	    }
	    NotebookActions.insertAbove = insertAbove;
	    /**
	     * Insert a node code cell below the current cell.
	     */
	    function insertBelow(widget) {
	        var cell = widget.model.createCodeCell();
	        widget.model.cells.insert(widget.activeCellIndex + 1, cell);
	        Private.deselectCells(widget);
	    }
	    NotebookActions.insertBelow = insertBelow;
	    /**
	     * Change the selected cell type(s).
	     */
	    function changeCellType(widget, value) {
	        var model = widget.model;
	        model.cells.beginCompoundOperation();
	        for (var i = 0; i < widget.childCount(); i++) {
	            var child = widget.childAt(i);
	            if (!widget.isSelected(child)) {
	                continue;
	            }
	            if (child.model.type === value) {
	                continue;
	            }
	            var newCell = void 0;
	            switch (value) {
	                case 'code':
	                    newCell = model.createCodeCell(child.model.toJSON());
	                    break;
	                case 'markdown':
	                    newCell = model.createMarkdownCell(child.model.toJSON());
	                    break;
	                default:
	                    newCell = model.createRawCell(child.model.toJSON());
	            }
	            model.cells.replace(i, 1, [newCell]);
	            if (value === 'markdown') {
	                // Fetch the new widget and unrender it.
	                child = widget.childAt(i);
	                child.rendered = false;
	            }
	        }
	        model.cells.endCompoundOperation();
	        Private.deselectCells(widget);
	    }
	    NotebookActions.changeCellType = changeCellType;
	    /**
	     * Run the selected cell(s).
	     */
	    function run(widget, kernel) {
	        var selected = [];
	        for (var i = 0; i < widget.childCount(); i++) {
	            var child = widget.childAt(i);
	            if (widget.isSelected(child)) {
	                selected.push(child);
	            }
	        }
	        for (var _i = 0, selected_1 = selected; _i < selected_1.length; _i++) {
	            var child = selected_1[_i];
	            Private.runCell(child, kernel);
	        }
	        if (widget.mode === 'command') {
	            widget.node.focus();
	        }
	        else {
	            var active = widget.childAt(widget.activeCellIndex);
	            active.focus();
	        }
	    }
	    NotebookActions.run = run;
	    /**
	     * Run the selected cell(s) and advance to the next cell.
	     *
	     * #### Notes
	     * If the last cell is run, a new code cell will be created in
	     * edit mode and selected.
	     */
	    function runAndAdvance(widget, kernel) {
	        run(widget, kernel);
	        var model = widget.model;
	        if (widget.activeCellIndex === widget.childCount() - 1) {
	            var cell = model.createCodeCell();
	            model.cells.add(cell);
	            widget.mode = 'edit';
	        }
	        else {
	            widget.mode = 'command';
	        }
	        widget.activeCellIndex++;
	        Private.deselectCells(widget);
	    }
	    NotebookActions.runAndAdvance = runAndAdvance;
	    /**
	     * Run the selected cell(s) and insert a new code cell below in edit mode.
	     */
	    function runAndInsert(widget, kernel) {
	        run(widget, kernel);
	        var model = widget.model;
	        var cell = model.createCodeCell();
	        model.cells.insert(widget.activeCellIndex + 1, cell);
	        widget.activeCellIndex++;
	        widget.mode = 'edit';
	        Private.deselectCells(widget);
	    }
	    NotebookActions.runAndInsert = runAndInsert;
	    /**
	     * Run all of the cells in the notebook.
	     */
	    function runAll(widget, kernel) {
	        for (var i = 0; i < widget.childCount(); i++) {
	            Private.runCell(widget.childAt(i), kernel);
	        }
	        widget.mode = 'command';
	        widget.activeCellIndex = widget.childCount() - 1;
	    }
	    NotebookActions.runAll = runAll;
	    /**
	     * Select the cell below the active cell.
	     */
	    function selectBelow(widget) {
	        if (widget.activeCellIndex === widget.childCount() - 1) {
	            return;
	        }
	        widget.activeCellIndex += 1;
	        widget.mode = 'command';
	        Private.deselectCells(widget);
	    }
	    NotebookActions.selectBelow = selectBelow;
	    /**
	     * Select the above the active cell.
	     */
	    function selectAbove(widget) {
	        if (widget.activeCellIndex === 0) {
	            return;
	        }
	        widget.activeCellIndex -= 1;
	        widget.mode = 'command';
	        Private.deselectCells(widget);
	    }
	    NotebookActions.selectAbove = selectAbove;
	    /**
	     * Extend the selection to the cell above.
	     */
	    function extendSelectionAbove(widget) {
	        // Do not wrap around.
	        if (widget.activeCellIndex === 0) {
	            return;
	        }
	        widget.mode = 'command';
	        var current = widget.childAt(widget.activeCellIndex);
	        var prev = widget.childAt(widget.activeCellIndex - 1);
	        if (widget.isSelected(prev)) {
	            widget.deselect(current);
	            if (widget.activeCellIndex >= 1) {
	                var prevPrev = widget.childAt(widget.activeCellIndex - 1);
	                if (!widget.isSelected(prevPrev)) {
	                    widget.deselect(prev);
	                }
	            }
	            else {
	                widget.deselect(prev);
	            }
	        }
	        else {
	            widget.select(current);
	        }
	        widget.activeCellIndex -= 1;
	    }
	    NotebookActions.extendSelectionAbove = extendSelectionAbove;
	    /**
	     * Extend the selection to the cell below.
	     */
	    function extendSelectionBelow(widget) {
	        // Do not wrap around.
	        if (widget.activeCellIndex === widget.childCount() - 1) {
	            return;
	        }
	        widget.mode = 'command';
	        var current = widget.childAt(widget.activeCellIndex);
	        var next = widget.childAt(widget.activeCellIndex + 1);
	        if (widget.isSelected(next)) {
	            widget.deselect(current);
	            if (widget.activeCellIndex < widget.childCount() - 1) {
	                var nextNext = widget.childAt(widget.activeCellIndex + 1);
	                if (!widget.isSelected(nextNext)) {
	                    widget.deselect(next);
	                }
	            }
	            else {
	                widget.deselect(next);
	            }
	        }
	        else {
	            widget.select(current);
	        }
	        widget.activeCellIndex += 1;
	    }
	    NotebookActions.extendSelectionBelow = extendSelectionBelow;
	    /**
	     * Copy the selected cells to a clipboard.
	     */
	    function copy(widget, clipboard) {
	        clipboard.clear();
	        var data = [];
	        for (var i = 0; i < widget.childCount(); i++) {
	            var child = widget.childAt(i);
	            if (widget.isSelected(child)) {
	                data.push(child.model.toJSON());
	            }
	        }
	        clipboard.setData(JUPYTER_CELL_MIME, data);
	        Private.deselectCells(widget);
	    }
	    NotebookActions.copy = copy;
	    /**
	     * Cut the selected cells to a clipboard.
	     */
	    function cut(widget, clipboard) {
	        clipboard.clear();
	        var data = [];
	        var model = widget.model;
	        var cells = model.cells;
	        // Preserve the history as one undo event.
	        model.cells.beginCompoundOperation();
	        for (var i = 0; i < widget.childCount(); i++) {
	            var child = widget.childAt(i);
	            if (widget.isSelected(child)) {
	                data.push(child.model.toJSON());
	                cells.remove(child.model);
	            }
	        }
	        if (!model.cells.length) {
	            var cell = model.createCodeCell();
	            model.cells.add(cell);
	        }
	        model.cells.endCompoundOperation();
	        clipboard.setData(JUPYTER_CELL_MIME, data);
	        Private.deselectCells(widget);
	    }
	    NotebookActions.cut = cut;
	    /**
	     * Paste cells from a clipboard.
	     */
	    function paste(widget, clipboard) {
	        if (!clipboard.hasData(JUPYTER_CELL_MIME)) {
	            return;
	        }
	        var values = clipboard.getData(JUPYTER_CELL_MIME);
	        var model = widget.model;
	        var cells = [];
	        for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
	            var value = values_1[_i];
	            switch (value.cell_type) {
	                case 'code':
	                    cells.push(model.createCodeCell(value));
	                    break;
	                case 'markdown':
	                    cells.push(model.createMarkdownCell(value));
	                    break;
	                default:
	                    cells.push(model.createRawCell(value));
	                    break;
	            }
	        }
	        var index = widget.activeCellIndex;
	        widget.model.cells.replace(index, 0, cells);
	        Private.deselectCells(widget);
	    }
	    NotebookActions.paste = paste;
	    /**
	     * Undo a cell action.
	     */
	    function undo(widget) {
	        widget.mode = 'command';
	        widget.model.cells.undo();
	    }
	    NotebookActions.undo = undo;
	    /**
	     * Redo a cell action.
	     */
	    function redo(widget) {
	        widget.mode = 'command';
	        widget.model.cells.redo();
	    }
	    NotebookActions.redo = redo;
	    /**
	     * Toggle line numbers on the selected cell(s).
	     */
	    function toggleLineNumbers(widget) {
	        var cell = widget.childAt(widget.activeCellIndex);
	        var editor = cell.editor.editor;
	        var lineNumbers = editor.getOption('lineNumbers');
	        for (var i = 0; i < widget.childCount(); i++) {
	            cell = widget.childAt(i);
	            if (widget.isSelected(cell)) {
	                editor = cell.editor.editor;
	                editor.setOption('lineNumbers', !lineNumbers);
	            }
	        }
	    }
	    NotebookActions.toggleLineNumbers = toggleLineNumbers;
	    /**
	     * Toggle the line number of all cells.
	     */
	    function toggleAllLineNumbers(widget) {
	        var cell = widget.childAt(widget.activeCellIndex);
	        var editor = cell.editor.editor;
	        var lineNumbers = editor.getOption('lineNumbers');
	        for (var i = 0; i < widget.childCount(); i++) {
	            cell = widget.childAt(i);
	            editor = cell.editor.editor;
	            editor.setOption('lineNumbers', !lineNumbers);
	        }
	    }
	    NotebookActions.toggleAllLineNumbers = toggleAllLineNumbers;
	    /**
	     * Clear the outputs of the currently selected cells.
	     */
	    function clearOutputs(widget) {
	        var cells = widget.model.cells;
	        for (var i = 0; i < cells.length; i++) {
	            var cell = cells.get(i);
	            var child = widget.childAt(i);
	            if (widget.isSelected(child) && cell.type === 'code') {
	                cell.outputs.clear();
	                cell.executionCount = null;
	            }
	        }
	    }
	    NotebookActions.clearOutputs = clearOutputs;
	    /**
	     * Clear the code outputs on the widget.
	     */
	    function clearAllOutputs(widget) {
	        var cells = widget.model.cells;
	        for (var i = 0; i < cells.length; i++) {
	            var cell = cells.get(i);
	            if (cell.type === 'code') {
	                cell.outputs.clear();
	                cell.executionCount = null;
	            }
	        }
	    }
	    NotebookActions.clearAllOutputs = clearAllOutputs;
	})(NotebookActions = exports.NotebookActions || (exports.NotebookActions = {}));
	/**
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Deselect all of the cells.
	     */
	    function deselectCells(widget) {
	        for (var i = 0; i < widget.childCount(); i++) {
	            var child = widget.childAt(i);
	            widget.deselect(child);
	        }
	    }
	    Private.deselectCells = deselectCells;
	    /**
	     * Clone a cell model.
	     */
	    function cloneCell(model, cell) {
	        switch (cell.type) {
	            case 'code':
	                return model.createCodeCell(cell.toJSON());
	            case 'markdown':
	                return model.createMarkdownCell(cell.toJSON());
	            default:
	                return model.createRawCell(cell.toJSON());
	        }
	    }
	    Private.cloneCell = cloneCell;
	    /**
	     * Run a cell.
	     */
	    function runCell(widget, kernel) {
	        switch (widget.model.type) {
	            case 'markdown':
	                widget.rendered = true;
	                break;
	            case 'code':
	                if (kernel) {
	                    widget.execute(kernel);
	                }
	                else {
	                    widget.model.executionCount = null;
	                }
	                break;
	            default:
	                break;
	        }
	    }
	    Private.runCell = runCell;
	})(Private || (Private = {}));


/***/ },
/* 409 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var jupyter_js_services_1 = __webpack_require__(104);
	var phosphor_widget_1 = __webpack_require__(20);
	var toolbar_1 = __webpack_require__(410);
	var actions_1 = __webpack_require__(408);
	/**
	 * The class name added to toolbar save button.
	 */
	var TOOLBAR_SAVE = 'jp-NBToolbar-save';
	/**
	 * The class name added to toolbar insert button.
	 */
	var TOOLBAR_INSERT = 'jp-NBToolbar-insert';
	/**
	 * The class name added to toolbar cut button.
	 */
	var TOOLBAR_CUT = 'jp-NBToolbar-cut';
	/**
	 * The class name added to toolbar copy button.
	 */
	var TOOLBAR_COPY = 'jp-NBToolbar-copy';
	/**
	 * The class name added to toolbar paste button.
	 */
	var TOOLBAR_PASTE = 'jp-NBToolbar-paste';
	/**
	 * The class name added to toolbar run button.
	 */
	var TOOLBAR_RUN = 'jp-NBToolbar-run';
	/**
	 * The class name added to toolbar interrupt button.
	 */
	var TOOLBAR_INTERRUPT = 'jp-NBToolbar-interrupt';
	/**
	 * The class name added to toolbar restart button.
	 */
	var TOOLBAR_RESTART = 'jp-NBToolbar-restart';
	/**
	 * The class name added to toolbar cell type dropdown wrapper.
	 */
	var TOOLBAR_CELL_WRAP = 'jp-NBToolbar-cellWrapper';
	/**
	 * The class name added to toolbar cell type dropdown.
	 */
	var TOOLBAR_CELL = 'jp-NBToolbar-cellType';
	/**
	 * The class name added to toolbar kernel name text.
	 */
	var TOOLBAR_KERNEL = 'jp-NBToolbar-kernelName';
	/**
	 * The class name added to toolbar kernel indicator icon.
	 */
	var TOOLBAR_INDICATOR = 'jp-NBToolbar-kernelIndicator';
	/**
	 * The class name added to a busy kernel indicator.
	 */
	var TOOLBAR_BUSY = 'jp-mod-busy';
	/**
	 * A namespace for the default toolbar items.
	 */
	var ToolbarItems;
	(function (ToolbarItems) {
	    /**
	     * Create save button toolbar item.
	     */
	    function createSaveButton(panel) {
	        return new toolbar_1.ToolbarButton(TOOLBAR_SAVE, function () {
	            panel.context.save();
	        }, 'Save the notebook contents');
	    }
	    ToolbarItems.createSaveButton = createSaveButton;
	    /**
	     * Create an insert toolbar item.
	     */
	    function createInsertButton(panel) {
	        return new toolbar_1.ToolbarButton(TOOLBAR_INSERT, function () {
	            actions_1.NotebookActions.insertBelow(panel.content);
	        }, 'Insert a cell below');
	    }
	    ToolbarItems.createInsertButton = createInsertButton;
	    /**
	     * Create a cut toolbar item.
	     */
	    function createCutButton(panel) {
	        return new toolbar_1.ToolbarButton(TOOLBAR_CUT, function () {
	            actions_1.NotebookActions.cut(panel.content, panel.clipboard);
	        }, 'Cut the selected cell(s)');
	    }
	    ToolbarItems.createCutButton = createCutButton;
	    /**
	     * Create a copy toolbar item.
	     */
	    function createCopyButton(panel) {
	        return new toolbar_1.ToolbarButton(TOOLBAR_COPY, function () {
	            actions_1.NotebookActions.copy(panel.content, panel.clipboard);
	        }, 'Copy the selected cell(s)');
	    }
	    ToolbarItems.createCopyButton = createCopyButton;
	    /**
	     * Create a paste toolbar item.
	     */
	    function createPasteButton(panel) {
	        return new toolbar_1.ToolbarButton(TOOLBAR_PASTE, function () {
	            actions_1.NotebookActions.paste(panel.content, panel.clipboard);
	        }, 'Paste cell(s) from the clipboard');
	    }
	    ToolbarItems.createPasteButton = createPasteButton;
	    /**
	     * Create a run toolbar item.
	     */
	    function createRunButton(panel) {
	        return new toolbar_1.ToolbarButton(TOOLBAR_RUN, function () {
	            actions_1.NotebookActions.runAndAdvance(panel.content, panel.context.kernel);
	        }, 'Run the selected cell(s) and advance');
	    }
	    ToolbarItems.createRunButton = createRunButton;
	    /**
	     * Create an interrupt toolbar item.
	     */
	    function createInterruptButton(panel) {
	        return new toolbar_1.ToolbarButton(TOOLBAR_INTERRUPT, function () {
	            if (panel.context.kernel) {
	                panel.context.kernel.interrupt();
	            }
	        }, 'Interrupt the kernel');
	    }
	    ToolbarItems.createInterruptButton = createInterruptButton;
	    /**
	     * Create a restart toolbar item.
	     */
	    function createRestartButton(panel) {
	        return new toolbar_1.ToolbarButton(TOOLBAR_RESTART, function () {
	            panel.restart();
	        }, 'Restart the kernel');
	    }
	    ToolbarItems.createRestartButton = createRestartButton;
	    /**
	     * Create a cell type switcher item.
	     */
	    function createCellTypeItem(panel) {
	        return new CellTypeSwitcher(panel);
	    }
	    ToolbarItems.createCellTypeItem = createCellTypeItem;
	    /**
	     * Create a kernel name indicator item.
	     */
	    function createKernelNameItem(panel) {
	        var widget = new phosphor_widget_1.Widget();
	        widget.addClass(TOOLBAR_KERNEL);
	        widget.node.textContent = 'No Kernel!';
	        if (panel.context.kernel) {
	            panel.context.kernel.getKernelSpec().then(function (spec) {
	                widget.node.textContent = spec.display_name;
	            });
	        }
	        panel.context.kernelChanged.connect(function () {
	            panel.context.kernel.getKernelSpec().then(function (spec) {
	                widget.node.textContent = spec.display_name;
	            });
	        });
	        return widget;
	    }
	    ToolbarItems.createKernelNameItem = createKernelNameItem;
	    /**
	     * Create a kernel status indicator item.
	     */
	    function createKernelStatusItem(panel) {
	        return new KernelIndicator(panel.context);
	    }
	    ToolbarItems.createKernelStatusItem = createKernelStatusItem;
	    /**
	     * Add the default items to a toolbar.
	     */
	    function populateDefaults(panel) {
	        var toolbar = panel.toolbar;
	        toolbar.add('save', createSaveButton(panel));
	        toolbar.add('insert', createInsertButton(panel));
	        toolbar.add('cut', createCutButton(panel));
	        toolbar.add('copy', createCopyButton(panel));
	        toolbar.add('paste', createPasteButton(panel));
	        toolbar.add('run', createRunButton(panel));
	        toolbar.add('interrupt', createInterruptButton(panel));
	        toolbar.add('restart', createRestartButton(panel));
	        toolbar.add('cellType', createCellTypeItem(panel));
	        toolbar.add('kernelName', createKernelNameItem(panel));
	        toolbar.add('kernelStatus', createKernelStatusItem(panel));
	    }
	    ToolbarItems.populateDefaults = populateDefaults;
	})(ToolbarItems = exports.ToolbarItems || (exports.ToolbarItems = {}));
	/**
	 * A toolbar widget that switches cell types.
	 */
	var CellTypeSwitcher = (function (_super) {
	    __extends(CellTypeSwitcher, _super);
	    /**
	     * Construct a new cell type switcher.
	     */
	    function CellTypeSwitcher(panel) {
	        var _this = this;
	        _super.call(this);
	        this._changeGuard = false;
	        this.addClass(TOOLBAR_CELL_WRAP);
	        var select = this.node.firstChild;
	        // Set the initial value.
	        var index = panel.content.activeCellIndex;
	        select.value = panel.model.cells.get(index).type;
	        // Follow the type of the current cell.
	        panel.content.stateChanged.connect(function (sender, args) {
	            if (args.name === 'activeCellIndex') {
	                _this._changeGuard = true;
	                select.value = panel.model.cells.get(args.newValue).type;
	                _this._changeGuard = false;
	            }
	        });
	        // Follow a change in the cells.
	        panel.content.model.cells.changed.connect(function (sender, args) {
	            index = panel.content.activeCellIndex;
	            _this._changeGuard = true;
	            select.value = panel.model.cells.get(index).type;
	            _this._changeGuard = false;
	        });
	        // Change current cell type on a change in the dropdown.
	        select.addEventListener('change', function (event) {
	            if (!_this._changeGuard) {
	                actions_1.NotebookActions.changeCellType(panel.content, select.value);
	            }
	        });
	    }
	    /**
	     * Create the node for the cell type switcher.
	     */
	    CellTypeSwitcher.createNode = function () {
	        var div = document.createElement('div');
	        var select = document.createElement('select');
	        for (var _i = 0, _a = ['Code', 'Markdown', 'Raw']; _i < _a.length; _i++) {
	            var t = _a[_i];
	            var option = document.createElement('option');
	            option.value = t.toLowerCase();
	            option.textContent = t;
	            select.appendChild(option);
	        }
	        select.className = TOOLBAR_CELL;
	        div.appendChild(select);
	        return div;
	    };
	    return CellTypeSwitcher;
	}(phosphor_widget_1.Widget));
	/**
	 * A toolbar item that displays kernel status.
	 */
	var KernelIndicator = (function (_super) {
	    __extends(KernelIndicator, _super);
	    /**
	     * Construct a new kernel status widget.
	     */
	    function KernelIndicator(context) {
	        var _this = this;
	        _super.call(this);
	        this.addClass(TOOLBAR_INDICATOR);
	        if (context.kernel) {
	            this._handleStatus(context.kernel, context.kernel.status);
	            context.kernel.statusChanged.connect(this._handleStatus, this);
	        }
	        else {
	            this.addClass(TOOLBAR_BUSY);
	            this.node.title = 'No Kernel!';
	        }
	        context.kernelChanged.connect(function (c, kernel) {
	            _this._handleStatus(kernel, kernel.status);
	            kernel.statusChanged.connect(_this._handleStatus, _this);
	        });
	    }
	    /**
	     * Handle a status on a kernel.
	     */
	    KernelIndicator.prototype._handleStatus = function (kernel, status) {
	        this.toggleClass(TOOLBAR_BUSY, status !== jupyter_js_services_1.KernelStatus.Idle);
	        switch (status) {
	            case jupyter_js_services_1.KernelStatus.Idle:
	                this.node.title = 'Kernel Idle';
	                break;
	            case jupyter_js_services_1.KernelStatus.Busy:
	                this.node.title = 'Kernel Busy';
	                break;
	            case jupyter_js_services_1.KernelStatus.Dead:
	                this.node.title = 'Kernel Died';
	                break;
	            case jupyter_js_services_1.KernelStatus.Reconnecting:
	                this.node.title = 'Kernel Reconnecting';
	                break;
	            case jupyter_js_services_1.KernelStatus.Restarting:
	                this.node.title = 'Kernel Restarting';
	                break;
	            case jupyter_js_services_1.KernelStatus.Starting:
	                this.node.title = 'Kernel Starting';
	                break;
	            default:
	                this.node.title = 'Kernel Status Unknown';
	                break;
	        }
	    };
	    return KernelIndicator;
	}(phosphor_widget_1.Widget));


/***/ },
/* 410 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_properties_1 = __webpack_require__(17);
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_widget_1 = __webpack_require__(20);
	/**
	 * The class name added to notebook toolbars.
	 */
	var NB_TOOLBAR = 'jp-NBToolbar';
	/**
	 * The class name added to notebook toolbar items.
	 */
	var TOOLBAR_ITEM = 'jp-NBToolbar-item';
	/**
	 * The class name added to notebook toolbar buttons.
	 */
	var TOOLBAR_BUTTON = 'jp-NBToolbar-button';
	/**
	 * The class name added to a pressed button.
	 */
	var TOOLBAR_PRESSED = 'jp-mod-pressed';
	/**
	 * A class which provides a notebook toolbar widget.
	 */
	var NotebookToolbar = (function (_super) {
	    __extends(NotebookToolbar, _super);
	    /**
	     * Construct a new toolbar widget.
	     */
	    function NotebookToolbar() {
	        _super.call(this);
	        this.addClass(NB_TOOLBAR);
	        this.layout = new phosphor_panel_1.PanelLayout();
	    }
	    /**
	     * Add an item to the toolbar.
	     *
	     * @param name - The name of the widget to add to the toolbar.
	     *
	     * @param widget - The widget to add to the toolbar.
	     *
	     * @param after - The optional name of the item to insert after.
	     *
	     * #### Notes
	     * An error is thrown if a widget of the same name is already given.
	     * If `after` is not given, or the named widget is not in the toolbar,
	     * the widget will be added to the end of the toolbar.
	     */
	    NotebookToolbar.prototype.add = function (name, widget, after) {
	        var names = this.list();
	        if (names.indexOf(name) !== -1) {
	            throw new Error("A button named \"" + name + "\" was already added");
	        }
	        widget.addClass(TOOLBAR_ITEM);
	        var layout = this.layout;
	        var index = names.indexOf(after);
	        if (index === -1) {
	            layout.addChild(widget);
	        }
	        else {
	            layout.insertChild(index, widget);
	        }
	        Private.nameProperty.set(widget, name);
	    };
	    /**
	     * List the names of the toolbar items.
	     *
	     * @returns A new array of the current toolbar item names.
	     */
	    NotebookToolbar.prototype.list = function () {
	        var names = [];
	        var layout = this.layout;
	        for (var i = 0; i < layout.childCount(); i++) {
	            var widget = layout.childAt(i);
	            names.push(Private.nameProperty.get(widget));
	        }
	        return names;
	    };
	    return NotebookToolbar;
	}(phosphor_widget_1.Widget));
	exports.NotebookToolbar = NotebookToolbar;
	/**
	 * A widget which acts as a button in a toolbar.
	 */
	var ToolbarButton = (function (_super) {
	    __extends(ToolbarButton, _super);
	    /**
	     * Construct a new toolbar button.
	     */
	    function ToolbarButton(className, onClick, tooltip) {
	        _super.call(this);
	        this._onClick = null;
	        this.addClass(TOOLBAR_BUTTON);
	        this.addClass(className);
	        this._onClick = onClick;
	        if (tooltip) {
	            this.node.title = tooltip;
	        }
	    }
	    /**
	     * Create the node for the toolbar button.
	     */
	    ToolbarButton.createNode = function () {
	        return document.createElement('span');
	    };
	    /**
	     * 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':
	                var cb = this._onClick;
	                cb();
	                break;
	            case 'mousedown':
	                this.addClass(TOOLBAR_PRESSED);
	                break;
	            case 'mouseup':
	            case 'mouseout':
	                this.removeClass(TOOLBAR_PRESSED);
	                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;
	}(phosphor_widget_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 phosphor_properties_1.Property({
	        name: 'name',
	    });
	})(Private || (Private = {}));


/***/ },
/* 411 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var utils = __webpack_require__(106);
	var phosphor_observablelist_1 = __webpack_require__(122);
	var phosphor_signaling_1 = __webpack_require__(22);
	var model_1 = __webpack_require__(117);
	var json_1 = __webpack_require__(118);
	var metadata_1 = __webpack_require__(119);
	var undo_1 = __webpack_require__(412);
	var nbformat_1 = __webpack_require__(123);
	/**
	 * An implementation of a notebook Model.
	 */
	var NotebookModel = (function () {
	    /**
	     * Construct a new notebook model.
	     */
	    function NotebookModel(languagePreference) {
	        var _this = this;
	        this._cells = null;
	        this._metadata = Private.createMetadata();
	        this._dirty = false;
	        this._readOnly = false;
	        this._cursors = Object.create(null);
	        this._nbformat = nbformat_1.nbformat.MAJOR_VERSION;
	        this._nbformatMinor = nbformat_1.nbformat.MINOR_VERSION;
	        this._cells = new undo_1.OberservableUndoableList(function (data) {
	            switch (data.cell_type) {
	                case 'code':
	                    return _this.createCodeCell(data);
	                case 'markdown':
	                    return _this.createMarkdownCell(data);
	                default:
	                    return _this.createRawCell(data);
	            }
	        });
	        this._cells.changed.connect(this.onCellsChanged, this);
	        if (languagePreference) {
	            this._metadata['language_info'] = "{\"name\":\"" + languagePreference + "\"}";
	        }
	    }
	    Object.defineProperty(NotebookModel.prototype, "contentChanged", {
	        /**
	         * A signal emitted when the document content changes.
	         */
	        get: function () {
	            return Private.contentChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookModel.prototype, "stateChanged", {
	        /**
	         * A signal emitted when a model state changes.
	         */
	        get: function () {
	            return Private.stateChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookModel.prototype, "metadataChanged", {
	        /**
	         * A signal emitted when a metadata field changes.
	         */
	        get: function () {
	            return Private.metadataChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookModel.prototype, "cells", {
	        /**
	         * Get the observable list of notebook cells.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._cells;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookModel.prototype, "nbformat", {
	        /**
	         * The major version number of the nbformat.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._nbformat;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookModel.prototype, "nbformatMinor", {
	        /**
	         * The minor version number of the nbformat.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._nbformatMinor;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookModel.prototype, "dirty", {
	        /**
	         * The dirty state of the model.
	         *
	         * #### Notes
	         * This should be cleared when the document is loaded from
	         * or saved to disk.
	         */
	        get: function () {
	            return this._dirty;
	        },
	        set: function (newValue) {
	            if (newValue === this._dirty) {
	                return;
	            }
	            var oldValue = this._dirty;
	            this._dirty = newValue;
	            this.stateChanged.emit({ name: 'dirty', oldValue: oldValue, newValue: newValue });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookModel.prototype, "readOnly", {
	        /**
	         * The read-only state of the model.
	         */
	        get: function () {
	            return this._readOnly;
	        },
	        set: function (newValue) {
	            if (newValue === this._readOnly) {
	                return;
	            }
	            var oldValue = this._readOnly;
	            this._readOnly = newValue;
	            this.stateChanged.emit({ name: 'readOnly', oldValue: oldValue, newValue: newValue });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookModel.prototype, "defaultKernelName", {
	        /**
	         * The default kernel name of the document.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            var spec = this._metadata['kernelspec'];
	            return spec ? spec.name : '';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookModel.prototype, "defaultKernelLanguage", {
	        /**
	         * The default kernel language of the document.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            var info = this._metadata['language_info'];
	            return info ? info.name : '';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookModel.prototype, "isDisposed", {
	        /**
	         * Get whether the model is disposed.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._cells === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the model.
	     */
	    NotebookModel.prototype.dispose = function () {
	        // Do nothing if already disposed.
	        if (this.isDisposed) {
	            return;
	        }
	        var cells = this._cells;
	        cells.dispose();
	        phosphor_signaling_1.clearSignalData(this);
	        for (var i = 0; i < cells.length; i++) {
	            var cell = cells.get(i);
	            cell.dispose();
	        }
	        cells.clear();
	        this._cells = null;
	        for (var key in this._cursors) {
	            this._cursors[key].dispose();
	        }
	        this._cursors = null;
	        this._metadata = null;
	    };
	    /**
	     * Serialize the model to a string.
	     */
	    NotebookModel.prototype.toString = function () {
	        return JSON.stringify(this.toJSON());
	    };
	    /**
	     * Deserialize the model from a string.
	     *
	     * #### Notes
	     * Should emit a [contentChanged] signal.
	     */
	    NotebookModel.prototype.fromString = function (value) {
	        this.fromJSON(JSON.parse(value));
	    };
	    /**
	     * Serialize the model to JSON.
	     */
	    NotebookModel.prototype.toJSON = function () {
	        var cells = [];
	        for (var i = 0; i < this.cells.length; i++) {
	            var cell = this.cells.get(i);
	            cells.push(cell.toJSON());
	        }
	        var metadata = utils.copy(this._metadata);
	        return {
	            metadata: metadata,
	            nbformat_minor: this._nbformatMinor,
	            nbformat: this._nbformat,
	            cells: cells
	        };
	    };
	    /**
	     * Deserialize the model from JSON.
	     *
	     * #### Notes
	     * Should emit a [contentChanged] signal.
	     */
	    NotebookModel.prototype.fromJSON = function (value) {
	        var cells = [];
	        for (var _i = 0, _a = value.cells; _i < _a.length; _i++) {
	            var data = _a[_i];
	            switch (data.cell_type) {
	                case 'code':
	                    cells.push(new model_1.CodeCellModel(data));
	                    break;
	                case 'markdown':
	                    cells.push(new model_1.MarkdownCellModel(data));
	                    break;
	                case 'raw':
	                    cells.push(new model_1.RawCellModel(data));
	                    break;
	                default:
	                    continue;
	            }
	        }
	        this.cells.assign(cells);
	        var oldValue = 0;
	        var newValue = 0;
	        if (value.nbformat !== this._nbformat) {
	            oldValue = this._nbformat;
	            this._nbformat = newValue = value.nbformat;
	            this.stateChanged.emit({ name: 'nbformat', oldValue: oldValue, newValue: newValue });
	        }
	        if (value.nbformat_minor !== this._nbformatMinor) {
	            oldValue = this._nbformat;
	            this._nbformatMinor = newValue = value.nbformat_minor;
	            this.stateChanged.emit({ name: 'nbformatMinor', oldValue: oldValue, newValue: newValue });
	        }
	        // Update the metadata.
	        var metadata = value.metadata;
	        var builtins = ['kernelspec', 'language_info', 'orig_nbformat'];
	        for (var key in this._metadata) {
	            if (builtins.indexOf(key) !== -1) {
	                continue;
	            }
	            if (!(key in metadata)) {
	                this.setCursorData(key, null);
	                delete this._metadata[key];
	                if (this._cursors[key]) {
	                    this._cursors[key].dispose();
	                    delete this._cursors[key];
	                }
	            }
	        }
	        for (var key in metadata) {
	            this.setCursorData(key, metadata[key]);
	        }
	        this.dirty = true;
	    };
	    /**
	     * Initialize the model state.
	     */
	    NotebookModel.prototype.initialize = function () {
	        this._cells.clearUndo();
	        this.dirty = false;
	    };
	    /**
	     * A factory for creating a new code cell.
	     *
	     * @param source - The data to use for the original source data.
	     *
	     * @returns A new code cell. If a source cell is provided, the
	     *   new cell will be intialized with the data from the source.
	     *
	     * #### Notes
	     * If the source argument does not give an input mimetype, the code cell
	     * defaults to the notebook [[defaultMimetype]].
	     */
	    NotebookModel.prototype.createCodeCell = function (source) {
	        return new model_1.CodeCellModel(source);
	    };
	    /**
	     * A factory for creating a new Markdown cell.
	     *
	     * @param source - The data to use for the original source data.
	     *
	     * @returns A new markdown cell. If a source cell is provided, the
	     *   new cell will be intialized with the data from the source.
	     */
	    NotebookModel.prototype.createMarkdownCell = function (source) {
	        return new model_1.MarkdownCellModel(source);
	    };
	    /**
	     * A factory for creating a new raw cell.
	     *
	     * @param source - The data to use for the original source data.
	     *
	     * @returns A new raw cell. If a source cell is provided, the
	     *   new cell will be intialized with the data from the source.
	     */
	    NotebookModel.prototype.createRawCell = function (source) {
	        return new model_1.RawCellModel(source);
	    };
	    /**
	     * Get a metadata cursor for the notebook.
	     *
	     * #### Notes
	     * Metadata associated with the nbformat spec are set directly
	     * on the model.  This method is used to interact with a namespaced
	     * set of metadata on the notebook.
	     */
	    NotebookModel.prototype.getMetadata = function (name) {
	        var _this = this;
	        if (name in this._cursors) {
	            return this._cursors[name];
	        }
	        var cursor = new metadata_1.MetadataCursor(name, function () {
	            return _this._metadata[name];
	        }, function (value) {
	            _this.setCursorData(name, value);
	        });
	        this._cursors[name] = cursor;
	        return cursor;
	    };
	    /**
	     * List the metadata namespace keys for the notebook.
	     */
	    NotebookModel.prototype.listMetadata = function () {
	        return Object.keys(this._metadata);
	    };
	    /**
	     * Handle a change in the cells list.
	     */
	    NotebookModel.prototype.onCellsChanged = function (list, change) {
	        var cell;
	        switch (change.type) {
	            case phosphor_observablelist_1.ListChangeType.Add:
	                cell = change.newValue;
	                cell.contentChanged.connect(this.onCellChanged, this);
	                break;
	            case phosphor_observablelist_1.ListChangeType.Remove:
	                change.oldValue.dispose();
	                break;
	            case phosphor_observablelist_1.ListChangeType.Replace:
	                var newValues = change.newValue;
	                for (var _i = 0, newValues_1 = newValues; _i < newValues_1.length; _i++) {
	                    cell = newValues_1[_i];
	                    cell.contentChanged.connect(this.onCellChanged, this);
	                }
	                var oldValues = change.oldValue;
	                for (var _a = 0, oldValues_1 = oldValues; _a < oldValues_1.length; _a++) {
	                    cell = oldValues_1[_a];
	                    cell.dispose();
	                }
	                break;
	            case phosphor_observablelist_1.ListChangeType.Set:
	                cell = change.newValue;
	                cell.contentChanged.connect(this.onCellChanged, this);
	                if (change.oldValue) {
	                    change.oldValue.dispose();
	                }
	                break;
	            default:
	                return;
	        }
	        this.dirty = true;
	    };
	    /**
	     * Handle a change to a cell state.
	     */
	    NotebookModel.prototype.onCellChanged = function (cell, change) {
	        this.dirty = true;
	        this.contentChanged.emit(void 0);
	    };
	    /**
	     * Set the cursor data for a given field.
	     */
	    NotebookModel.prototype.setCursorData = function (name, newValue) {
	        var oldValue = this._metadata[name];
	        if (json_1.deepEqual(oldValue, newValue)) {
	            return;
	        }
	        this._metadata[name] = newValue;
	        this.dirty = true;
	        this.contentChanged.emit(void 0);
	        this.metadataChanged.emit({ name: name, oldValue: oldValue, newValue: newValue });
	    };
	    return NotebookModel;
	}());
	exports.NotebookModel = NotebookModel;
	/**
	 * A private namespace for notebook model data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A signal emitted when the content of the model changes.
	     */
	    Private.contentChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when a model state changes.
	     */
	    Private.stateChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * A signal emitted when a metadata field changes.
	     */
	    Private.metadataChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * Create the default metadata for the notebook.
	     */
	    function createMetadata() {
	        return {
	            kernelspec: { name: 'unknown', display_name: 'Unknown' },
	            language_info: { name: 'unknown' },
	            orig_nbformat: 1
	        };
	    }
	    Private.createMetadata = createMetadata;
	})(Private || (Private = {}));


/***/ },
/* 412 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_observablelist_1 = __webpack_require__(122);
	/**
	 * An observable list that supports undo/redo.
	 */
	var OberservableUndoableList = (function (_super) {
	    __extends(OberservableUndoableList, _super);
	    /**
	     * Construct a new undoable observable list.
	     */
	    function OberservableUndoableList(factory) {
	        _super.call(this);
	        this._inCompound = false;
	        this._isUndoable = true;
	        this._madeCompoundChange = false;
	        this._index = -1;
	        this._stack = [];
	        this._factory = null;
	        this._factory = factory;
	        this.changed.connect(this._onListChanged, this);
	    }
	    Object.defineProperty(OberservableUndoableList.prototype, "canRedo", {
	        /**
	         * Whether the object can redo changes.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._index < this._stack.length - 1;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(OberservableUndoableList.prototype, "canUndo", {
	        /**
	         * Whether the object can undo changes.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._index >= 0;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(OberservableUndoableList.prototype, "isDisposed", {
	        /**
	         * Get whether the object is disposed.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._stack === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the model.
	     */
	    OberservableUndoableList.prototype.dispose = function () {
	        // Do nothing if already disposed.
	        if (this.isDisposed) {
	            return;
	        }
	        this._factory = null;
	        this._stack = null;
	    };
	    /**
	     * Begin a compound operation.
	     */
	    OberservableUndoableList.prototype.beginCompoundOperation = function (isUndoAble) {
	        this._inCompound = true;
	        this._isUndoable = (isUndoAble !== false);
	        this._madeCompoundChange = false;
	    };
	    /**
	     * End a compound operation.
	     */
	    OberservableUndoableList.prototype.endCompoundOperation = function () {
	        this._inCompound = false;
	        this._isUndoable = true;
	        if (this._madeCompoundChange) {
	            this._index++;
	        }
	    };
	    /**
	     * Undo an operation.
	     */
	    OberservableUndoableList.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.
	     */
	    OberservableUndoableList.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.
	     */
	    OberservableUndoableList.prototype.clearUndo = function () {
	        this._index = -1;
	        this._stack = [];
	    };
	    /**
	     * Handle a change in the list.
	     */
	    OberservableUndoableList.prototype._onListChanged = function (list, change) {
	        if (!this._isUndoable) {
	            return;
	        }
	        // Clear everything after this position.
	        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.
	     */
	    OberservableUndoableList.prototype._undoChange = function (change) {
	        var value;
	        switch (change.type) {
	            case phosphor_observablelist_1.ListChangeType.Add:
	                this.removeAt(change.newIndex);
	                break;
	            case phosphor_observablelist_1.ListChangeType.Set:
	                value = this._createValue(change.oldValue);
	                this.set(change.oldIndex, value);
	                break;
	            case phosphor_observablelist_1.ListChangeType.Remove:
	                value = this._createValue(change.oldValue);
	                this.insert(change.oldIndex, value);
	                break;
	            case phosphor_observablelist_1.ListChangeType.Move:
	                this.move(change.newIndex, change.oldIndex);
	                break;
	            case phosphor_observablelist_1.ListChangeType.Replace:
	                var len = change.newValue.length;
	                var values = this._createValues(change.oldValue);
	                this.replace(change.oldIndex, len, values);
	                break;
	            default:
	                return;
	        }
	    };
	    /**
	     * Redo a change event.
	     */
	    OberservableUndoableList.prototype._redoChange = function (change) {
	        var value;
	        switch (change.type) {
	            case phosphor_observablelist_1.ListChangeType.Add:
	                value = this._createValue(change.newValue);
	                this.insert(change.newIndex, value);
	                break;
	            case phosphor_observablelist_1.ListChangeType.Set:
	                value = this._createValue(change.newValue);
	                this.set(change.newIndex, value);
	                break;
	            case phosphor_observablelist_1.ListChangeType.Remove:
	                this.removeAt(change.oldIndex);
	                break;
	            case phosphor_observablelist_1.ListChangeType.Move:
	                this.move(change.oldIndex, change.newIndex);
	                break;
	            case phosphor_observablelist_1.ListChangeType.Replace:
	                var len = change.oldValue.length;
	                var cells = this._createValues(change.newValue);
	                this.replace(change.oldIndex, len, cells);
	                break;
	            default:
	                return;
	        }
	    };
	    /**
	     * Create a value from JSON.
	     */
	    OberservableUndoableList.prototype._createValue = function (data) {
	        var factory = this._factory;
	        return factory(data);
	    };
	    /**
	     * Create a list of cell models from JSON.
	     */
	    OberservableUndoableList.prototype._createValues = function (bundles) {
	        var values = [];
	        for (var _i = 0, bundles_1 = bundles; _i < bundles_1.length; _i++) {
	            var bundle = bundles_1[_i];
	            values.push(this._createValue(bundle));
	        }
	        return values;
	    };
	    /**
	     * Copy a change as JSON.
	     */
	    OberservableUndoableList.prototype._copyChange = function (change) {
	        if (change.type === phosphor_observablelist_1.ListChangeType.Replace) {
	            return this._copyReplace(change);
	        }
	        var oldValue = null;
	        var newValue = null;
	        switch (change.type) {
	            case phosphor_observablelist_1.ListChangeType.Add:
	            case phosphor_observablelist_1.ListChangeType.Set:
	            case phosphor_observablelist_1.ListChangeType.Remove:
	                if (change.oldValue) {
	                    oldValue = change.oldValue.toJSON();
	                }
	                if (change.newValue) {
	                    newValue = change.newValue.toJSON();
	                }
	                break;
	            case phosphor_observablelist_1.ListChangeType.Move:
	                // Only need the indices.
	                break;
	            default:
	                return;
	        }
	        return {
	            type: change.type,
	            oldIndex: change.oldIndex,
	            newIndex: change.newIndex,
	            oldValue: oldValue,
	            newValue: newValue
	        };
	    };
	    /**
	     * Copy a replace change as JSON.
	     */
	    OberservableUndoableList.prototype._copyReplace = function (change) {
	        var oldValue = [];
	        for (var _i = 0, _a = change.oldValue; _i < _a.length; _i++) {
	            var value = _a[_i];
	            oldValue.push(value.toJSON());
	        }
	        var newValue = [];
	        for (var _b = 0, _c = change.newValue; _b < _c.length; _b++) {
	            var value = _c[_b];
	            newValue.push(value.toJSON());
	        }
	        return {
	            type: phosphor_observablelist_1.ListChangeType.Replace,
	            oldIndex: change.oldIndex,
	            newIndex: change.newIndex,
	            oldValue: oldValue,
	            newValue: newValue
	        };
	    };
	    return OberservableUndoableList;
	}(phosphor_observablelist_1.ObservableList));
	exports.OberservableUndoableList = OberservableUndoableList;


/***/ },
/* 413 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var model_1 = __webpack_require__(411);
	/**
	 * A model factory for notebooks.
	 */
	var NotebookModelFactory = (function () {
	    function NotebookModelFactory() {
	        this._disposed = false;
	    }
	    Object.defineProperty(NotebookModelFactory.prototype, "name", {
	        /**
	         * The name of the model.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return 'notebook';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookModelFactory.prototype, "contentsOptions", {
	        /**
	         * The contents options used to fetch/save files.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return { type: 'notebook' };
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookModelFactory.prototype, "isDisposed", {
	        /**
	         * Get whether the model factory has been disposed.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the model factory.
	     */
	    NotebookModelFactory.prototype.dispose = function () {
	        this._disposed = true;
	    };
	    /**
	     * Create a new model for a given path.
	     *
	     * @param languagePreference - An optional kernel language preference.
	     *
	     * @returns A new document model.
	     */
	    NotebookModelFactory.prototype.createNew = function (languagePreference) {
	        var model = new model_1.NotebookModel(languagePreference);
	        var cell = model.createCodeCell();
	        model.cells.add(cell);
	        return model;
	    };
	    /**
	     * Get the preferred kernel language given a path.
	     */
	    NotebookModelFactory.prototype.preferredLanguage = function (path) {
	        return '';
	    };
	    return NotebookModelFactory;
	}());
	exports.NotebookModelFactory = NotebookModelFactory;


/***/ },
/* 414 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var dialog_1 = __webpack_require__(115);
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_widget_1 = __webpack_require__(20);
	var completion_1 = __webpack_require__(270);
	var toolbar_1 = __webpack_require__(410);
	var widget_1 = __webpack_require__(415);
	/**
	 * The class name added to notebook panels.
	 */
	var NB_PANEL = 'jp-Notebook-panel';
	/**
	 * The class name added to notebook container widgets.
	 */
	var NB_CONTAINER = 'jp-Notebook-container';
	/**
	 * The class name added to a dirty widget.
	 */
	var DIRTY_CLASS = 'jp-mod-dirty';
	/**
	 * A widget that hosts a notebook toolbar and content area.
	 *
	 * #### Notes
	 * The widget keeps the document metadata in sync with the current
	 * kernel on the context.
	 */
	var NotebookPanel = (function (_super) {
	    __extends(NotebookPanel, _super);
	    /**
	     * Construct a new notebook panel.
	     */
	    function NotebookPanel(model, rendermime, context, clipboard) {
	        var _this = this;
	        _super.call(this);
	        this._rendermime = null;
	        this._context = null;
	        this._model = null;
	        this._content = null;
	        this._toolbar = null;
	        this._clipboard = null;
	        this._completion = null;
	        this._pendingComplete = 0;
	        this.addClass(NB_PANEL);
	        this._model = model;
	        this._rendermime = rendermime;
	        this._context = context;
	        this._clipboard = clipboard;
	        context.kernelChanged.connect(function () {
	            _this.handleKernelChange(context.kernel);
	        });
	        if (context.kernel) {
	            this.handleKernelChange(context.kernel);
	        }
	        this.layout = new phosphor_panel_1.PanelLayout();
	        var ctor = this.constructor;
	        this._content = ctor.createContent(model, rendermime);
	        this._toolbar = ctor.createToolbar();
	        var container = new phosphor_panel_1.Panel();
	        container.addClass(NB_CONTAINER);
	        container.addChild(this._content);
	        var layout = this.layout;
	        layout.addChild(this._toolbar);
	        layout.addChild(container);
	        // Instantiate tab completion widget.
	        this._completion = ctor.createCompletion();
	        this._completion.reference = this;
	        this._completion.attach(document.body);
	        this._completion.selected.connect(this.onCompletionSelect, this);
	        // Connect signals.
	        this._content.stateChanged.connect(this.onContentChanged, this);
	        var cell = this._content.childAt(this._content.activeCellIndex);
	        if (cell) {
	            var editor = cell.editor;
	            editor.textChanged.connect(this.onTextChange, this);
	            editor.completionRequested.connect(this.onCompletionRequest, this);
	        }
	        // Handle the document title.
	        this.title.text = context.path.split('/').pop();
	        context.pathChanged.connect(function (c, path) {
	            _this.title.text = path.split('/').pop();
	        });
	        // Handle changes to dirty state.
	        model.stateChanged.connect(function (m, args) {
	            if (args.name === 'dirty') {
	                if (args.newValue) {
	                    _this.title.className += " " + DIRTY_CLASS;
	                }
	                else {
	                    _this.title.className = _this.title.className.replace(DIRTY_CLASS, '');
	                }
	            }
	        });
	    }
	    /**
	     * Create a new content area for the notebook.
	     */
	    NotebookPanel.createContent = function (model, rendermime) {
	        return new widget_1.ActiveNotebook(model, rendermime);
	    };
	    /**
	     * Create a new toolbar for the notebook.
	     */
	    NotebookPanel.createToolbar = function () {
	        return new toolbar_1.NotebookToolbar();
	    };
	    /**
	     * Create a new completion widget.
	     */
	    NotebookPanel.createCompletion = function () {
	        var model = new completion_1.CompletionModel();
	        return new completion_1.CompletionWidget(model);
	    };
	    Object.defineProperty(NotebookPanel.prototype, "toolbar", {
	        /**
	         * Get the toolbar used by the widget.
	         */
	        get: function () {
	            return this._toolbar;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookPanel.prototype, "content", {
	        /**
	         * Get the content area used by the widget.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._content;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookPanel.prototype, "rendermime", {
	        /**
	         * Get the rendermime instance used by the widget.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._rendermime;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookPanel.prototype, "clipboard", {
	        /**
	         * Get the clipboard instance used by the widget.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._clipboard;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookPanel.prototype, "model", {
	        /**
	         * Get the model used by the widget.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._model;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookPanel.prototype, "context", {
	        /**
	         * Get the document context for the widget.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._context;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources used by the widget.
	     */
	    NotebookPanel.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._context = null;
	        this._rendermime = null;
	        this._content = null;
	        this._toolbar = null;
	        this._clipboard = null;
	        this._completion.dispose();
	        this._completion = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Restart the kernel on the panel.
	     */
	    NotebookPanel.prototype.restart = function () {
	        var kernel = this.context.kernel;
	        if (!kernel) {
	            return Promise.resolve(false);
	        }
	        return dialog_1.showDialog({
	            title: 'Restart Kernel?',
	            body: 'Do you want to restart the current kernel? All variables will be lost.',
	            host: this.node
	        }).then(function (result) {
	            if (result.text === 'OK') {
	                return kernel.restart().then(function () { return true; });
	            }
	            else {
	                return false;
	            }
	        });
	    };
	    /**
	     * Handle a change in the kernel by updating the document metadata.
	     */
	    NotebookPanel.prototype.handleKernelChange = function (kernel) {
	        var _this = this;
	        kernel.kernelInfo().then(function (info) {
	            var infoCursor = _this.model.getMetadata('language_info');
	            infoCursor.setValue(info.language_info);
	        });
	        kernel.getKernelSpec().then(function (spec) {
	            var specCursor = _this.model.getMetadata('kernelspec');
	            specCursor.setValue({
	                name: kernel.name,
	                display_name: spec.display_name,
	                language: spec.language
	            });
	        });
	    };
	    /**
	     * Handle a change in the content area.
	     */
	    NotebookPanel.prototype.onContentChanged = function (sender, args) {
	        switch (args.name) {
	            case 'activeCellIndex':
	                var cell = this._content.childAt(args.oldValue);
	                var editor = cell.editor;
	                editor.textChanged.disconnect(this.onTextChange, this);
	                editor.completionRequested.disconnect(this.onCompletionRequest, this);
	                cell = this._content.childAt(args.newValue);
	                editor = cell.editor;
	                editor.textChanged.connect(this.onTextChange, this);
	                editor.completionRequested.connect(this.onCompletionRequest, this);
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle a text changed signal from an editor.
	     */
	    NotebookPanel.prototype.onTextChange = function (editor, change) {
	        var line = change.newValue.split('\n')[change.line];
	        var model = this._completion.model;
	        // If last character entered is not whitespace, update completion.
	        if (line[change.ch - 1] && line[change.ch - 1].match(/\S/)) {
	            // If there is currently a completion
	            if (model.original) {
	                model.current = change;
	            }
	        }
	        else {
	            // If final character is whitespace, reset completion.
	            model.options = null;
	            model.original = null;
	            model.cursor = null;
	            return;
	        }
	    };
	    /**
	     * Handle a completion requested signal from an editor.
	     */
	    NotebookPanel.prototype.onCompletionRequest = function (editor, change) {
	        var _this = this;
	        var kernel = this.context.kernel;
	        if (!kernel) {
	            return;
	        }
	        var contents = {
	            // Only send the current line of code for completion.
	            code: change.currentValue.split('\n')[change.line],
	            cursor_pos: change.ch
	        };
	        var pendingComplete = ++this._pendingComplete;
	        var model = this._completion.model;
	        kernel.complete(contents).then(function (value) {
	            // If model has been disposed, bail.
	            if (model.isDisposed) {
	                return;
	            }
	            // If a newer completion requesy has created a pending request, bail.
	            if (pendingComplete !== _this._pendingComplete) {
	                return;
	            }
	            // Completion request failures or negative results fail silently.
	            if (value.status !== 'ok') {
	                return;
	            }
	            // Update the model.
	            model.options = value.matches;
	            model.cursor = { start: value.cursor_start, end: value.cursor_end };
	        }).then(function () {
	            model.original = change;
	        });
	    };
	    /**
	     * Handle a completion selected signal from the completion widget.
	     */
	    NotebookPanel.prototype.onCompletionSelect = function (widget, value) {
	        var patch = this._completion.model.createPatch(value);
	        var cell = this._content.childAt(this._content.activeCellIndex);
	        var editor = cell.editor.editor;
	        var doc = editor.getDoc();
	        doc.setValue(patch.text);
	        doc.setCursor(doc.posFromIndex(patch.position));
	    };
	    return NotebookPanel;
	}(phosphor_widget_1.Widget));
	exports.NotebookPanel = NotebookPanel;


/***/ },
/* 415 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var phosphor_observablelist_1 = __webpack_require__(122);
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_properties_1 = __webpack_require__(17);
	var phosphor_signaling_1 = __webpack_require__(22);
	var phosphor_widget_1 = __webpack_require__(20);
	var cells_1 = __webpack_require__(116);
	var mimetype_1 = __webpack_require__(267);
	/**
	 * The class name added to notebook widgets.
	 */
	var NB_CLASS = 'jp-Notebook';
	/**
	 * The class name added to notebook widget cells.
	 */
	var NB_CELL_CLASS = 'jp-Notebook-cell';
	/**
	 * The class name added to a notebook in edit mode.
	 */
	var EDIT_CLASS = 'jp-mod-editMode';
	/**
	 * The class name added to a notebook in command mode.
	 */
	var COMMAND_CLASS = 'jp-mod-commandMode';
	/**
	 * The class name added to the active cell.
	 */
	var ACTIVE_CLASS = 'jp-mod-active';
	/**
	 * The class name added to selected cells.
	 */
	var SELECTED_CLASS = 'jp-mod-selected';
	/**
	 * The class name added to an active cell when there are other selected cells.
	 */
	var OTHER_SELECTED_CLASS = 'jp-mod-multiSelected';
	/**
	 * A widget which renders notebooks.
	 */
	var NotebookRenderer = (function (_super) {
	    __extends(NotebookRenderer, _super);
	    /**
	     * Construct a notebook widget.
	     */
	    function NotebookRenderer(model, rendermime) {
	        _super.call(this);
	        this._model = null;
	        this._rendermime = null;
	        this._mimetype = 'text/plain';
	        this._langInfoCursor = null;
	        this.node.tabIndex = -1; // Allow the widget to take focus.
	        this.addClass(NB_CLASS);
	        this._model = model;
	        this._rendermime = rendermime;
	        this._langInfoCursor = model.getMetadata('language_info');
	        this._mimetype = this.getMimetype();
	        this.layout = new phosphor_panel_1.PanelLayout();
	        // Add the current cells.
	        if (model.cells.length === 0) {
	            // Add a new code cell if there are no cells.
	            var cell = model.createCodeCell();
	            model.cells.add(cell);
	        }
	        var layout = this.layout;
	        var constructor = this.constructor;
	        var factory = constructor.createCell;
	        for (var i = 0; i < model.cells.length; i++) {
	            var widget = factory(model.cells.get(i), rendermime);
	            this.initializeCellWidget(widget);
	            layout.addChild(widget);
	        }
	        model.cells.changed.connect(this.onCellsChanged, this);
	        model.metadataChanged.connect(this.onMetadataChanged, this);
	    }
	    /**
	     * Create a new cell widget given a cell model.
	     */
	    NotebookRenderer.createCell = function (cell, rendermime) {
	        switch (cell.type) {
	            case 'code':
	                return new cells_1.CodeCellWidget(cell, rendermime);
	            case 'markdown':
	                return new cells_1.MarkdownCellWidget(cell, rendermime);
	            // If there are any issues, just return a raw
	            // widget so the lists stay in sync.
	            default:
	                return new cells_1.RawCellWidget(cell);
	        }
	    };
	    Object.defineProperty(NotebookRenderer.prototype, "model", {
	        /**
	         * Get the model for the widget.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._model;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(NotebookRenderer.prototype, "rendermime", {
	        /**
	         * Get the rendermime instance used by the widget.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._rendermime;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the child widget at the specified index.
	     */
	    NotebookRenderer.prototype.childAt = function (index) {
	        var layout = this.layout;
	        return layout.childAt(index);
	    };
	    /**
	     * Get the number of child widgets.
	     */
	    NotebookRenderer.prototype.childCount = function () {
	        var layout = this.layout;
	        return layout.childCount();
	    };
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    NotebookRenderer.prototype.dispose = function () {
	        // Do nothing if already disposed.
	        if (this.isDisposed) {
	            return;
	        }
	        this._langInfoCursor = null;
	        this._model.dispose();
	        this._model = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Find the cell index containing the target html element.
	     *
	     * #### Notes
	     * Returns -1 if the cell is not found.
	     */
	    NotebookRenderer.prototype.findCell = function (node) {
	        // Trace up the DOM hierarchy to find the root cell node.
	        // Then find the corresponding child and select it.
	        var layout = this.layout;
	        while (node && node !== this.node) {
	            if (node.classList.contains(NB_CELL_CLASS)) {
	                for (var i = 0; i < layout.childCount(); i++) {
	                    if (layout.childAt(i).node === node) {
	                        return i;
	                    }
	                }
	                break;
	            }
	            node = node.parentElement;
	        }
	        return -1;
	    };
	    /**
	     * Handle changes to the notebook model.
	     */
	    NotebookRenderer.prototype.onMetadataChanged = function (model, args) {
	        switch (args.name) {
	            case 'language_info':
	                this._mimetype = this.getMimetype();
	                this._updateMimetypes();
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle a change cells event.
	     */
	    NotebookRenderer.prototype.onCellsChanged = function (sender, args) {
	        var layout = this.layout;
	        var constructor = this.constructor;
	        var factory = constructor.createCell;
	        var widget;
	        switch (args.type) {
	            case phosphor_observablelist_1.ListChangeType.Add:
	                widget = factory(args.newValue, this._rendermime);
	                this.initializeCellWidget(widget);
	                layout.insertChild(args.newIndex, widget);
	                break;
	            case phosphor_observablelist_1.ListChangeType.Move:
	                layout.insertChild(args.newIndex, layout.childAt(args.oldIndex));
	                break;
	            case phosphor_observablelist_1.ListChangeType.Remove:
	                widget = layout.childAt(args.oldIndex);
	                layout.removeChild(widget);
	                widget.dispose();
	                break;
	            case phosphor_observablelist_1.ListChangeType.Replace:
	                var oldValues = args.oldValue;
	                for (var i = 0; i < oldValues.length; i++) {
	                    widget = layout.childAt(args.oldIndex);
	                    layout.removeChild(widget);
	                    widget.dispose();
	                }
	                var newValues = args.newValue;
	                for (var i = newValues.length; i > 0; i--) {
	                    widget = factory(newValues[i - 1], this._rendermime);
	                    this.initializeCellWidget(widget);
	                    layout.insertChild(args.newIndex, widget);
	                }
	                break;
	            case phosphor_observablelist_1.ListChangeType.Set:
	                widget = layout.childAt(args.newIndex);
	                layout.removeChild(widget);
	                widget.dispose();
	                widget = factory(args.newValue, this._rendermime);
	                layout.insertChild(args.newIndex, widget);
	                this.initializeCellWidget(widget);
	                break;
	            default:
	                return;
	        }
	        this.update();
	    };
	    /**
	     * The mime type for code cells.
	     *
	     * #### Notes
	     * The default implementation uses the language info to set the
	     * mimetype.
	     */
	    NotebookRenderer.prototype.getMimetype = function () {
	        var info = this._langInfoCursor.getValue();
	        return mimetype_1.mimetypeForLanguage(info);
	    };
	    /**
	     * Initialize a cell widget.
	     */
	    NotebookRenderer.prototype.initializeCellWidget = function (widget) {
	        widget.addClass(NB_CELL_CLASS);
	        if (widget.model.type === 'code') {
	            widget.mimetype = this._mimetype;
	        }
	    };
	    /**
	     * Update the mimetype of code widgets.
	     */
	    NotebookRenderer.prototype._updateMimetypes = function () {
	        var layout = this.layout;
	        for (var i = 0; i < layout.childCount(); i++) {
	            var widget = layout.childAt(i);
	            if (widget instanceof cells_1.CodeCellWidget) {
	                widget.mimetype = this._mimetype;
	            }
	        }
	    };
	    return NotebookRenderer;
	}(phosphor_widget_1.Widget));
	exports.NotebookRenderer = NotebookRenderer;
	/**
	 * A notebook widget that supports interactivity.
	 */
	var ActiveNotebook = (function (_super) {
	    __extends(ActiveNotebook, _super);
	    function ActiveNotebook() {
	        _super.apply(this, arguments);
	        this._mode = 'command';
	        this._activeCellIndex = 0;
	    }
	    Object.defineProperty(ActiveNotebook.prototype, "stateChanged", {
	        /**
	         * A signal emitted when the state of the notebook changes.
	         */
	        get: function () {
	            return Private.stateChangedSignal.bind(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ActiveNotebook.prototype, "mode", {
	        /**
	         * The interactivity mode of the notebook.
	         */
	        get: function () {
	            return this._mode;
	        },
	        set: function (newValue) {
	            if (newValue === this._mode) {
	                return;
	            }
	            var oldValue = this._mode;
	            this._mode = newValue;
	            // Edit mode deselects all cells.
	            if (newValue === 'edit') {
	                var layout = this.layout;
	                for (var i = 0; i < layout.childCount(); i++) {
	                    var widget = layout.childAt(i);
	                    this.deselect(widget);
	                }
	            }
	            this.stateChanged.emit({ name: 'mode', oldValue: oldValue, newValue: newValue });
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ActiveNotebook.prototype, "activeCellIndex", {
	        /**
	         * The active cell index of the notebook.
	         */
	        get: function () {
	            return this._activeCellIndex;
	        },
	        set: function (newValue) {
	            newValue = Math.max(newValue, 0);
	            newValue = Math.min(newValue, this.model.cells.length - 1);
	            if (newValue === this._activeCellIndex) {
	                return;
	            }
	            var oldValue = this._activeCellIndex;
	            this._activeCellIndex = newValue;
	            var widget = this.layout.childAt(newValue);
	            if (widget instanceof cells_1.MarkdownCellWidget) {
	                if (this.mode === 'edit') {
	                    widget.rendered = false;
	                }
	            }
	            this.stateChanged.emit({ name: 'activeCellIndex', oldValue: oldValue, newValue: newValue });
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Select a cell widget.
	     */
	    ActiveNotebook.prototype.select = function (widget) {
	        Private.selectedProperty.set(widget, true);
	        this.update();
	    };
	    /**
	     * Deselect a cell widget.
	     *
	     * #### Notes
	     * This has no effect on the "active" cell.
	     */
	    ActiveNotebook.prototype.deselect = function (widget) {
	        Private.selectedProperty.set(widget, false);
	        this.update();
	    };
	    /**
	     * Whether a cell is selected or is the active cell.
	     */
	    ActiveNotebook.prototype.isSelected = function (widget) {
	        var layout = this.layout;
	        if (layout.childAt(this._activeCellIndex) === widget) {
	            return true;
	        }
	        return Private.selectedProperty.get(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.
	     */
	    ActiveNotebook.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'click':
	                this._evtClick(event);
	                break;
	            case 'dblclick':
	                this._evtDblClick(event);
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle `after_attach` messages for the widget.
	     */
	    ActiveNotebook.prototype.onAfterAttach = function (msg) {
	        this.node.addEventListener('click', this);
	        this.node.addEventListener('dblclick', this);
	        this.update();
	    };
	    /**
	     * Handle `before_detach` messages for the widget.
	     */
	    ActiveNotebook.prototype.onBeforeDetach = function (msg) {
	        this.node.removeEventListener('click', this);
	        this.node.removeEventListener('dblclick', this);
	    };
	    /**
	     * Handle `update-request` messages sent to the widget.
	     */
	    ActiveNotebook.prototype.onUpdateRequest = function (msg) {
	        // Set the appropriate classes on the cells.
	        var layout = this.layout;
	        var widget = layout.childAt(this.activeCellIndex);
	        if (this.mode === 'edit') {
	            this.addClass(EDIT_CLASS);
	            this.removeClass(COMMAND_CLASS);
	            if (widget) {
	                widget.focus();
	            }
	            if (widget instanceof cells_1.MarkdownCellWidget) {
	                widget.rendered = false;
	            }
	        }
	        else {
	            this.addClass(COMMAND_CLASS);
	            this.removeClass(EDIT_CLASS);
	            this.node.focus();
	        }
	        if (widget) {
	            widget.addClass(ACTIVE_CLASS);
	            Private.scrollIfNeeded(this.parent.node, widget.node);
	        }
	        var count = 0;
	        for (var i = 0; i < layout.childCount(); i++) {
	            widget = layout.childAt(i);
	            if (i !== this.activeCellIndex) {
	                widget.removeClass(ACTIVE_CLASS);
	            }
	            widget.removeClass(OTHER_SELECTED_CLASS);
	            if (this.isSelected(widget)) {
	                widget.addClass(SELECTED_CLASS);
	                count++;
	            }
	            else {
	                widget.removeClass(SELECTED_CLASS);
	            }
	        }
	        if (count > 1) {
	            widget = layout.childAt(this.activeCellIndex);
	            widget.addClass(OTHER_SELECTED_CLASS);
	        }
	    };
	    /**
	     * Initialize a cell widget.
	     */
	    ActiveNotebook.prototype.initializeCellWidget = function (widget) {
	        _super.prototype.initializeCellWidget.call(this, widget);
	        widget.editor.edgeRequested.connect(this.onEdgeRequest, this);
	    };
	    /**
	     * Handle edge request signals from cells.
	     */
	    ActiveNotebook.prototype.onEdgeRequest = function (widget, location) {
	        if (location === 'top') {
	            this.activeCellIndex--;
	        }
	        else {
	            this.activeCellIndex++;
	        }
	    };
	    /**
	     * Handle `click` events for the widget.
	     */
	    ActiveNotebook.prototype._evtClick = function (event) {
	        var model = this.model;
	        if (model.readOnly) {
	            return;
	        }
	        var i = this.findCell(event.target);
	        if (i === -1) {
	            return;
	        }
	        this.activeCellIndex = i;
	        this.mode = document.activeElement === this.node ? 'command' : 'edit';
	    };
	    /**
	     * Handle `dblclick` events for the widget.
	     */
	    ActiveNotebook.prototype._evtDblClick = function (event) {
	        var model = this.model;
	        if (model.readOnly) {
	            return;
	        }
	        var i = this.findCell(event.target);
	        if (i === -1) {
	            return;
	        }
	        var cell = model.cells.get(i);
	        var widget = this.layout.childAt(i);
	        if (cell.type !== 'markdown' || !widget.rendered) {
	            return;
	        }
	        if (widget.node.contains(event.target)) {
	            this.mode = 'edit';
	        }
	    };
	    return ActiveNotebook;
	}(NotebookRenderer));
	exports.ActiveNotebook = ActiveNotebook;
	/**
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * An attached property for the selected state of a cell.
	     */
	    Private.selectedProperty = new phosphor_properties_1.Property({
	        name: 'selected',
	        value: false
	    });
	    /**
	     * A signal emitted when the state changes on the notebook.
	     */
	    Private.stateChangedSignal = new phosphor_signaling_1.Signal();
	    /**
	     * Scroll an element into view if needed.
	     *
	     * @param area - The scroll area element.
	     *
	     * @param elem - The element of interest.
	     */
	    function scrollIfNeeded(area, elem) {
	        var ar = area.getBoundingClientRect();
	        var er = elem.getBoundingClientRect();
	        if (er.top < ar.top - 10) {
	            area.scrollTop -= ar.top - er.top + 10;
	        }
	        else if (er.bottom > ar.bottom + 10) {
	            area.scrollTop += er.bottom - ar.bottom + 10;
	        }
	    }
	    Private.scrollIfNeeded = scrollIfNeeded;
	})(Private || (Private = {}));


/***/ },
/* 416 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, Jupyter Development Team.
	|
	| Distributed under the terms of the Modified BSD License.
	|----------------------------------------------------------------------------*/
	'use strict';
	var dialog_1 = __webpack_require__(115);
	// The message to display to the user when prompting to trust the notebook.
	var TRUST_MESSAGE = '<p>A trusted Jupyter notebook may execute hidden malicious code when you open it.<br>Selecting trust will re-render this notebook in a trusted state.<br>For more information, see the <a href="http://ipython.org/ipython-doc/2/notebook/security.html">Jupyter security documentation</a>.</p>';
	/**
	 * Trust the notebook after prompting the user.
	 *
	 * @param model - The notebook model.
	 *
	 * @param host - The host node for the confirmation dialog (defaults to body).
	 *
	 * @returns a promise that resolves when the transaction is finished.
	 *
	 * #### Notes
	 * No dialog will be presented if the notebook is already trusted.
	 */
	function trustNotebook(model, host) {
	    // Do nothing if already trusted.
	    var cells = model.cells;
	    var trusted = true;
	    for (var i = 0; i < cells.length; i++) {
	        var cell = cells.get(i);
	        if (!cell.getMetadata('trusted').getValue()) {
	            trusted = false;
	        }
	    }
	    if (trusted) {
	        return Promise.resolve(void 0);
	    }
	    return dialog_1.showDialog({
	        host: host || document.body,
	        body: TRUST_MESSAGE,
	        title: 'Trust this notebook?'
	    }).then(function (result) {
	        if (result.text === 'OK') {
	            for (var i = 0; i < cells.length; i++) {
	                var cell = cells.get(i);
	                cell.getMetadata('trusted').setValue(true);
	            }
	        }
	    });
	}
	exports.trustNotebook = trustNotebook;


/***/ },
/* 417 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var docmanager_1 = __webpack_require__(274);
	var default_toolbar_1 = __webpack_require__(409);
	var panel_1 = __webpack_require__(414);
	/**
	 * A widget factory for notebook panels.
	 */
	var NotebookWidgetFactory = (function () {
	    /**
	     * Construct a new notebook widget factory.
	     */
	    function NotebookWidgetFactory(rendermime, clipboard) {
	        this._rendermime = null;
	        this._clipboard = null;
	        this._rendermime = rendermime.clone();
	        this._clipboard = clipboard;
	    }
	    Object.defineProperty(NotebookWidgetFactory.prototype, "isDisposed", {
	        /**
	         * Get whether the factory has been disposed.
	         */
	        get: function () {
	            return this._rendermime === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources used by the factory.
	     */
	    NotebookWidgetFactory.prototype.dispose = function () {
	        this._rendermime = null;
	        this._clipboard = null;
	    };
	    /**
	     * Create a new widget.
	     */
	    NotebookWidgetFactory.prototype.createNew = function (model, context, kernel) {
	        var rendermime = this._rendermime.clone();
	        if (kernel) {
	            context.changeKernel(kernel);
	        }
	        else {
	            var name_1 = docmanager_1.findKernel(model.defaultKernelName, model.defaultKernelLanguage, context.kernelspecs);
	            context.changeKernel({ name: name_1 });
	        }
	        var panel = new panel_1.NotebookPanel(model, rendermime, context, this._clipboard);
	        default_toolbar_1.ToolbarItems.populateDefaults(panel);
	        return panel;
	    };
	    /**
	     * Take an action on a widget before closing it.
	     *
	     * @returns A promise that resolves to true if the document should close
	     *   and false otherwise.
	     */
	    NotebookWidgetFactory.prototype.beforeClose = function (model, context, widget) {
	        // No special action required.
	        return Promise.resolve(true);
	    };
	    return NotebookWidgetFactory;
	}());
	exports.NotebookWidgetFactory = NotebookWidgetFactory;


/***/ },
/* 418 */
/***/ function(module, exports) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	/**
	 * The list of default application shortcuts.
	 *
	 * #### Notes
	 * When setting shortcut selectors, there are two concepts to consider:
	 * specificity and matchability. These two interact in sometimes
	 * counterintuitive ways. Keyboard events are triggered from an element and
	 * they propagate up the DOM until they reach the `documentElement` (`<body>`).
	 *
	 * When a registered shortcut sequence is fired, the shortcut manager checks
	 * the node that fired the event and each of its ancestors until a node matches
	 * one or more registered selectors. The *first* matching selector in the
	 * chain of ancestors will invoke the shortcut handler and the traversal will
	 * end at that point. If a node matches more than one selector, the handler for
	 * whichever selector is more *specific* fires.
	 * @see https://www.w3.org/TR/css3-selectors/#specificity
	 *
	 * The practical consequence of this is that a very broadly matching selector,
	 * e.g. `'*'` or `'div'` may match and therefore invoke a handler *before* a
	 * more specific selector. The most common pitfall is to use the universal
	 * (`'*'`) selector. For almost any use case where a global keyboard shortcut is
	 * required, using the `'body'` selector is more appropriate.
	 */
	var SHORTCUTS = [
	    {
	        command: 'command-palette:toggle',
	        selector: 'body',
	        sequence: ['Accel Shift P']
	    },
	    {
	        command: 'command-palette:hide',
	        selector: 'body[data-left-area="command-palette"]',
	        sequence: ['Escape']
	    },
	    {
	        command: 'file-browser:toggle',
	        selector: 'body',
	        sequence: ['Accel Shift F']
	    },
	    {
	        command: 'file-browser:hide',
	        selector: 'body[data-left-area="file-browser"]',
	        sequence: ['Escape']
	    },
	    {
	        command: 'file-operations:new-text-file',
	        selector: 'body',
	        sequence: ['Ctrl O']
	    },
	    {
	        command: 'file-operations:new-notebook',
	        selector: 'body',
	        sequence: ['Ctrl Shift N']
	    },
	    {
	        command: 'file-operations:save',
	        selector: '.jp-DocumentWidget',
	        sequence: ['Accel S']
	    },
	    {
	        command: 'file-operations:close',
	        selector: '.jp-DocumentWidget',
	        sequence: ['Ctrl Q']
	    },
	    {
	        command: 'file-operations:close-all',
	        selector: '.jp-DocumentWidget',
	        sequence: ['Ctrl Shift Q']
	    },
	    {
	        command: 'help-doc:toggle',
	        selector: 'body',
	        sequence: ['Accel Shift H']
	    },
	    {
	        command: 'help-doc:hide',
	        selector: 'body[data-right-area="help-doc"]',
	        sequence: ['Escape']
	    },
	    {
	        command: 'notebook-cells:runAndAdvance',
	        selector: '.jp-Notebook',
	        sequence: ['Shift Enter']
	    },
	    {
	        command: 'notebook-cells:runAndInsert',
	        selector: '.jp-Notebook',
	        sequence: ['Alt Enter']
	    },
	    {
	        command: 'notebook-cells:run',
	        selector: '.jp-Notebook',
	        sequence: ['Ctrl Enter']
	    },
	    {
	        command: 'notebook:interrupt-kernel',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['I', 'I']
	    },
	    {
	        command: 'notebook:restart-kernel',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['0', '0']
	    },
	    {
	        command: 'notebook-cells:to-code',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['E']
	    },
	    {
	        command: 'notebook-cells:to-markdown',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['M']
	    },
	    {
	        command: 'notebook-cells:to-raw',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['R']
	    },
	    {
	        command: 'notebook-cells:delete',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['D', 'D'],
	    },
	    {
	        command: 'notebook-cells:split',
	        selector: '.jp-Notebook.jp-mod-editMode',
	        sequence: ['Ctrl Shift -'],
	    },
	    {
	        command: 'notebook-cells:merge',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['Shift M'],
	    },
	    {
	        command: 'notebook-cells:select-above',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['ArrowUp'],
	    },
	    {
	        command: 'notebook-cells:select-below',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['ArrowDown'],
	    },
	    {
	        command: 'notebook-cells:extend-above',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['Shift ArrowUp'],
	    },
	    {
	        command: 'notebook-cells:extend-below',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['Shift ArrowDown'],
	    },
	    {
	        command: 'notebook-cells:undo',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['Z'],
	    },
	    {
	        command: 'notebook-cells:redo',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['Y'],
	    },
	    {
	        command: 'notebook-cells:cut',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['X']
	    },
	    {
	        command: 'notebook-cells:copy',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['C']
	    },
	    {
	        command: 'notebook-cells:paste',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['V']
	    },
	    {
	        command: 'notebook-cells:insert-above',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['A']
	    },
	    {
	        command: 'notebook-cells:insert-below',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['B']
	    },
	    {
	        command: 'notebook-cells:select-previous',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['ArrowUp']
	    },
	    {
	        command: 'notebook-cells:select-next',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['ArrowDown']
	    },
	    {
	        command: 'notebook-cells:toggle-lineNumbers',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['L']
	    },
	    {
	        command: 'notebook-cells:editMode',
	        selector: '.jp-Notebook.jp-mod-commandMode',
	        sequence: ['Enter']
	    },
	    {
	        command: 'notebook-cells:commandMode',
	        selector: '.jp-Notebook.jp-mod-editMode',
	        sequence: ['Escape']
	    },
	    {
	        command: 'console:execute',
	        selector: '.jp-Console .jp-CellEditor',
	        sequence: ['Shift Enter']
	    },
	];
	/**
	 * The default shortcuts extension.
	 */
	exports.shortcutsExtension = {
	    id: 'jupyter.extensions.shortcuts',
	    activate: function (app) {
	        app.shortcuts.add(SHORTCUTS);
	        return Promise.resolve(void 0);
	    }
	};


/***/ },
/* 419 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var index_1 = __webpack_require__(420);
	var phosphor_tabs_1 = __webpack_require__(40);
	/**
	 * The default terminal extension.
	 */
	exports.terminalExtension = {
	    id: 'jupyter.extensions.terminal',
	    activate: activateTerminal
	};
	function activateTerminal(app) {
	    var newTerminalId = 'terminal:create-new';
	    app.commands.add([{
	            id: newTerminalId,
	            handler: function () {
	                var term = new index_1.TerminalWidget();
	                term.color = 'black';
	                term.background = 'white';
	                term.title.closable = true;
	                app.shell.addToMainArea(term);
	                var stack = term.parent;
	                if (!stack) {
	                    return;
	                }
	                var tabs = stack.parent;
	                if (tabs instanceof phosphor_tabs_1.TabPanel) {
	                    tabs.currentWidget = term;
	                }
	            }
	        }]);
	    app.palette.add([
	        {
	            command: newTerminalId,
	            category: 'Terminal',
	            text: 'New Terminal',
	            caption: 'Start a new terminal session'
	        }
	    ]);
	    return Promise.resolve(void 0);
	}


/***/ },
/* 420 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var jupyter_js_utils_1 = __webpack_require__(106);
	var phosphor_domutil_1 = __webpack_require__(7);
	var phosphor_messaging_1 = __webpack_require__(13);
	var phosphor_widget_1 = __webpack_require__(20);
	var Terminal = __webpack_require__(421);
	/**
	 * The class name added to a terminal widget.
	 */
	var TERMINAL_CLASS = 'jp-TerminalWidget';
	/**
	 * The class name added to a terminal body.
	 */
	var TERMINAL_BODY_CLASS = 'jp-TerminalWidget-body';
	/**
	 * The number of rows to use in the dummy terminal.
	 */
	var DUMMY_ROWS = 24;
	/**
	 * The number of cols to use in the dummy terminal.
	 */
	var DUMMY_COLS = 80;
	/**
	 * A widget which manages a terminal session.
	 */
	var TerminalWidget = (function (_super) {
	    __extends(TerminalWidget, _super);
	    /**
	     * Construct a new terminal widget.
	     *
	     * @param options - The terminal configuration options.
	     */
	    function TerminalWidget(options) {
	        var _this = this;
	        _super.call(this);
	        this._term = null;
	        this._ws = null;
	        this._sheet = null;
	        this._dummyTerm = null;
	        this._fontSize = -1;
	        this._dirty = false;
	        this._rowHeight = -1;
	        this._colWidth = -1;
	        this._background = '';
	        this._color = '';
	        this._box = null;
	        options = options || {};
	        this.addClass(TERMINAL_CLASS);
	        var baseUrl = options.baseUrl || jupyter_js_utils_1.getWsUrl();
	        TerminalWidget.nterms += 1;
	        var url = baseUrl + 'terminals/websocket/' + TerminalWidget.nterms;
	        this._ws = new WebSocket(url);
	        this.id = "jp-TerminalWidget-" + TerminalWidget.nterms;
	        // Set the default title.
	        this.title.text = 'Terminal ' + TerminalWidget.nterms;
	        Terminal.brokenBold = true;
	        this._dummyTerm = createDummyTerm();
	        this._ws.onopen = function (event) {
	            _this._createTerm(options);
	        };
	        this._ws.onmessage = function (event) {
	            _this._handleWSMessage(event);
	        };
	        this._sheet = document.createElement('style');
	        this.node.appendChild(this._sheet);
	    }
	    Object.defineProperty(TerminalWidget.prototype, "fontSize", {
	        /**
	         * Get the font size of the terminal in pixels.
	         */
	        get: function () {
	            return this._fontSize;
	        },
	        /**
	         * Set the font size of the terminal in pixels.
	         */
	        set: function (size) {
	            this._fontSize = size;
	            this._term.element.style.fontSize = size + "px";
	            this._snapTermSizing();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TerminalWidget.prototype, "background", {
	        /**
	         * Get the background color of the terminal.
	         */
	        get: function () {
	            return this._background;
	        },
	        /**
	         * Set the background color of the terminal.
	         */
	        set: function (value) {
	            this._background = value;
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TerminalWidget.prototype, "color", {
	        /**
	         * Get the text color of the terminal.
	         */
	        get: function () {
	            return this._color;
	        },
	        /**
	         * Set the text color of the terminal.
	         */
	        set: function (value) {
	            this._color = value;
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TerminalWidget.prototype, "visualBell", {
	        /**
	         * Get whether the bell is shown.
	         */
	        get: function () {
	            return this._term.visualBell;
	        },
	        /**
	         * Set whether the bell is shown.
	         */
	        set: function (value) {
	            this._term.visualBell = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TerminalWidget.prototype, "popOnBell", {
	        /**
	         * Get whether to focus on a bell event.
	         */
	        get: function () {
	            return this._term.popOnBell;
	        },
	        /**
	         * Set whether to focus on a bell event.
	         */
	        set: function (value) {
	            this._term.popOnBell = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TerminalWidget.prototype, "scrollback", {
	        /**
	         * Get the size of the scrollback buffer in the terminal.
	         */
	        get: function () {
	            return this._term.scrollback;
	        },
	        /**
	         * Set the size of the scrollback buffer in the terminal.
	         */
	        set: function (value) {
	            this._term.scrollback = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the terminal widget.
	     */
	    TerminalWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._ws.close();
	        this._term.destroy();
	        this._sheet = null;
	        this._ws = null;
	        this._term = null;
	        this._dummyTerm = null;
	        this._box = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Process a message sent to the widget.
	     *
	     * @param msg - The message sent to the widget.
	     *
	     * #### Notes
	     * Subclasses may reimplement this method as needed.
	     */
	    TerminalWidget.prototype.processMessage = function (msg) {
	        _super.prototype.processMessage.call(this, msg);
	        switch (msg.type) {
	            case 'fit-request':
	                this.onFitRequest(msg);
	                break;
	        }
	    };
	    /**
	     * Set the size of the terminal when attached if dirty.
	     */
	    TerminalWidget.prototype.onAfterAttach = function (msg) {
	        if (this._dirty) {
	            this._snapTermSizing();
	        }
	    };
	    /**
	     * Set the size of the terminal when shown if dirty.
	     */
	    TerminalWidget.prototype.onAfterShow = function (msg) {
	        if (this._dirty) {
	            this._snapTermSizing();
	        }
	        this._term.focus();
	    };
	    /**
	     * Dispose of the terminal when closing.
	     */
	    TerminalWidget.prototype.onCloseRequest = function (msg) {
	        _super.prototype.onCloseRequest.call(this, msg);
	        this.dispose();
	    };
	    /**
	     * On resize, use the computed row and column sizes to resize the terminal.
	     */
	    TerminalWidget.prototype.onResize = function (msg) {
	        this._resizeTerminal(msg.width, msg.height);
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    TerminalWidget.prototype.onUpdateRequest = function (msg) {
	        // Set the fg and bg colors of the terminal and cursor.
	        this.node.style.backgroundColor = this.background;
	        this.node.style.color = this.color;
	        this._term.element.style.backgroundColor = this.background;
	        this._term.element.style.color = this.color;
	        this._sheet.innerHTML = ("#" + this.node.id + " .terminal-cursor {background:\n                             " + this.color + ";color:" + this.background + ";}");
	    };
	    /**
	     * A message handler invoked on an `'fit-request'` message.
	     */
	    TerminalWidget.prototype.onFitRequest = function (msg) {
	        var resize = phosphor_widget_1.ResizeMessage.UnknownSize;
	        phosphor_messaging_1.sendMessage(this, resize);
	    };
	    /**
	     * Create the terminal object.
	     */
	    TerminalWidget.prototype._createTerm = function (options) {
	        var _this = this;
	        this._term = new Terminal(getConfig(options));
	        this._term.open(this.node);
	        this._term.element.classList.add(TERMINAL_BODY_CLASS);
	        this.fontSize = options.fontSize || 11;
	        this.background = options.background || 'white';
	        this.color = options.color || 'black';
	        this._term.on('data', function (data) {
	            _this._ws.send(JSON.stringify(['stdin', data]));
	        });
	        this._term.on('title', function (title) {
	            _this.title.text = title;
	        });
	        this._resizeTerminal(-1, -1);
	    };
	    /**
	     * Handle a message from the terminal websocket.
	     */
	    TerminalWidget.prototype._handleWSMessage = function (event) {
	        var json_msg = JSON.parse(event.data);
	        switch (json_msg[0]) {
	            case 'stdout':
	                this._term.write(json_msg[1]);
	                break;
	            case 'disconnect':
	                this._term.write('\r\n\r\n[Finished... Term Session]\r\n');
	                break;
	        }
	    };
	    /**
	     * Use the dummy terminal to measure the row and column sizes.
	     */
	    TerminalWidget.prototype._snapTermSizing = function () {
	        if (!this.isVisible) {
	            this._dirty = true;
	            return;
	        }
	        var node = this._dummyTerm;
	        this._term.element.appendChild(node);
	        this._rowHeight = node.offsetHeight / DUMMY_ROWS;
	        this._colWidth = node.offsetWidth / DUMMY_COLS;
	        this._term.element.removeChild(node);
	        this._resizeTerminal(-1, -1);
	    };
	    /**
	     * Resize the terminal based on the computed geometry.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    TerminalWidget.prototype._resizeTerminal = function (offsetWidth, offsetHeight) {
	        if (this._rowHeight === -1 || !this.isVisible) {
	            this._dirty = true;
	            return;
	        }
	        if (offsetWidth < 0) {
	            offsetWidth = this.node.offsetWidth;
	        }
	        if (offsetHeight < 0) {
	            offsetHeight = this.node.offsetHeight;
	        }
	        var box = this._box || (this._box = phosphor_domutil_1.boxSizing(this.node));
	        var height = offsetHeight - box.verticalSum;
	        var width = offsetWidth - box.horizontalSum;
	        var rows = Math.floor(height / this._rowHeight) - 1;
	        var cols = Math.floor(width / this._colWidth) - 1;
	        this._term.resize(cols, rows);
	        this._ws.send(JSON.stringify(['set_size', rows, cols,
	            height, width]));
	        this._dirty = false;
	    };
	    /**
	     * The number of terminals started.  Used to ensure unique sessions.
	     */
	    TerminalWidget.nterms = 0;
	    return TerminalWidget;
	}(phosphor_widget_1.Widget));
	exports.TerminalWidget = TerminalWidget;
	/**
	 * Get term.js options from ITerminalOptions.
	 */
	function getConfig(options) {
	    var config = {};
	    if (options.cursorBlink !== void 0) {
	        config.cursorBlink = options.cursorBlink;
	    }
	    else {
	        config.cursorBlink = true;
	    }
	    if (options.visualBell !== void 0) {
	        config.visualBell = options.visualBell;
	    }
	    if (options.popOnBell !== void 0) {
	        config.popOnBell = options.popOnBell;
	    }
	    if (options.scrollback !== void 0) {
	        config.scrollback = options.scrollback;
	    }
	    return config;
	}
	/**
	 * Create a dummy terminal element used to measure text size.
	 */
	function createDummyTerm() {
	    var node = document.createElement('div');
	    var rowspan = document.createElement('span');
	    rowspan.innerHTML = Array(DUMMY_ROWS).join('a<br>');
	    var colspan = document.createElement('span');
	    colspan.textContent = Array(DUMMY_COLS + 1).join('a');
	    node.appendChild(rowspan);
	    node.appendChild(colspan);
	    node.style.visibility = 'hidden';
	    node.style.position = 'absolute';
	    node.style.height = 'auto';
	    node.style.width = 'auto';
	    node.style['white-space'] = 'nowrap';
	    return node;
	}


/***/ },
/* 421 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * xterm.js: xterm, in the browser
	 * Copyright (c) 2014, sourceLair Limited (www.sourcelair.com (MIT License)
	 * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
	 * https://github.com/chjj/term.js
	 *
	 * 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.
	 *
	 * Originally forked from (with the author's permission):
	 *   Fabrice Bellard's javascript vt100 for jslinux:
	 *   http://bellard.org/jslinux/
	 *   Copyright (c) 2011 Fabrice Bellard
	 *   The original design remains. The terminal itself
	 *   has been extended to include xterm CSI codes, among
	 *   other features.
	 */
	
	(function (xterm) {
	    if (true) {
	        /*
	         * npm/nodejs project
	         */
	        module.exports = xterm.call(this);
	    } else if (typeof define == 'function') {
	        /*
	         * Require.js is available
	         */
	        define([], xterm.bind(window));
	    } else {
	        /*
	         * Plain browser environment
	         */
	        this.Xterm = xterm.call(this);
	        this.Terminal = this.Xterm; /* Backwards compatibility with term.js */
	    }
	})(function() {
	    /**
	     * Terminal Emulation References:
	     *   http://vt100.net/
	     *   http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt
	     *   http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
	     *   http://invisible-island.net/vttest/
	     *   http://www.inwap.com/pdp10/ansicode.txt
	     *   http://linux.die.net/man/4/console_codes
	     *   http://linux.die.net/man/7/urxvt
	     */
	
	    'use strict';
	
	    /**
	     * Shared
	     */
	
	    var window = this, document = this.document;
	
	    /**
	     * EventEmitter
	     */
	
	    function EventEmitter() {
	      this._events = this._events || {};
	    }
	
	    EventEmitter.prototype.addListener = function(type, listener) {
	      this._events[type] = this._events[type] || [];
	      this._events[type].push(listener);
	    };
	
	    EventEmitter.prototype.on = EventEmitter.prototype.addListener;
	
	    EventEmitter.prototype.removeListener = function(type, listener) {
	      if (!this._events[type]) return;
	
	      var obj = this._events[type]
	        , i = obj.length;
	
	      while (i--) {
	        if (obj[i] === listener || obj[i].listener === listener) {
	          obj.splice(i, 1);
	          return;
	        }
	      }
	    };
	
	    EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
	
	    EventEmitter.prototype.removeAllListeners = function(type) {
	      if (this._events[type]) delete this._events[type];
	    };
	
	    EventEmitter.prototype.once = function(type, listener) {
	      function on() {
	        var args = Array.prototype.slice.call(arguments);
	        this.removeListener(type, on);
	        return listener.apply(this, args);
	      }
	      on.listener = listener;
	      return this.on(type, on);
	    };
	
	    EventEmitter.prototype.emit = function(type) {
	      if (!this._events[type]) return;
	
	      var args = Array.prototype.slice.call(arguments, 1)
	        , obj = this._events[type]
	        , l = obj.length
	        , i = 0;
	
	      for (; i < l; i++) {
	        obj[i].apply(this, args);
	      }
	    };
	
	    EventEmitter.prototype.listeners = function(type) {
	      return this._events[type] = this._events[type] || [];
	    };
	
	
	    /**
	     * States
	     */
	    var normal = 0, escaped = 1, csi = 2, osc = 3, charset = 4, dcs = 5, ignore = 6;
	
	    /**
	     * Terminal
	     */
	
	    function Terminal(options) {
	      var self = this;
	
	      if (!(this instanceof Terminal)) {
	        return new Terminal(arguments[0], arguments[1], arguments[2]);
	      }
	
	      self.cancel = Terminal.cancel;
	
	      EventEmitter.call(this);
	
	      if (typeof options === 'number') {
	        options = {
	          cols: arguments[0],
	          rows: arguments[1],
	          handler: arguments[2]
	        };
	      }
	
	      options = options || {};
	
	
	      Object.keys(Terminal.defaults).forEach(function(key) {
	        if (options[key] == null) {
	          options[key] = Terminal.options[key];
	
	          if (Terminal[key] !== Terminal.defaults[key]) {
	            options[key] = Terminal[key];
	          }
	        }
	        self[key] = options[key];
	      });
	
	      if (options.colors.length === 8) {
	        options.colors = options.colors.concat(Terminal._colors.slice(8));
	      } else if (options.colors.length === 16) {
	        options.colors = options.colors.concat(Terminal._colors.slice(16));
	      } else if (options.colors.length === 10) {
	        options.colors = options.colors.slice(0, -2).concat(
	          Terminal._colors.slice(8, -2), options.colors.slice(-2));
	      } else if (options.colors.length === 18) {
	        options.colors = options.colors.concat(
	          Terminal._colors.slice(16, -2), options.colors.slice(-2));
	      }
	      this.colors = options.colors;
	
	      this.options = options;
	
	      // this.context = options.context || window;
	      // this.document = options.document || document;
	      this.parent = options.body || options.parent
	        || (document ? document.getElementsByTagName('body')[0] : null);
	
	      this.cols = options.cols || options.geometry[0];
	      this.rows = options.rows || options.geometry[1];
	
	      if (options.handler) {
	        this.on('data', options.handler);
	      }
	
	      this.ybase = 0;
	      this.ydisp = 0;
	      this.x = 0;
	      this.y = 0;
	      this.cursorState = 0;
	      this.cursorHidden = false;
	      this.convertEol;
	      this.state = 0;
	      this.queue = '';
	      this.scrollTop = 0;
	      this.scrollBottom = this.rows - 1;
	
	      // modes
	      this.applicationKeypad = false;
	      this.applicationCursor = false;
	      this.originMode = false;
	      this.insertMode = false;
	      this.wraparoundMode = false;
	      this.normal = null;
	
	      // charset
	      this.charset = null;
	      this.gcharset = null;
	      this.glevel = 0;
	      this.charsets = [null];
	
	      // mouse properties
	      this.decLocator;
	      this.x10Mouse;
	      this.vt200Mouse;
	      this.vt300Mouse;
	      this.normalMouse;
	      this.mouseEvents;
	      this.sendFocus;
	      this.utfMouse;
	      this.sgrMouse;
	      this.urxvtMouse;
	
	      // misc
	      this.element;
	      this.children;
	      this.refreshStart;
	      this.refreshEnd;
	      this.savedX;
	      this.savedY;
	      this.savedCols;
	
	      // stream
	      this.readable = true;
	      this.writable = true;
	
	      this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);
	      this.curAttr = this.defAttr;
	
	      this.params = [];
	      this.currentParam = 0;
	      this.prefix = '';
	      this.postfix = '';
	
	      this.lines = [];
	      var i = this.rows;
	      while (i--) {
	        this.lines.push(this.blankLine());
	      }
	
	      this.tabs;
	      this.setupStops();
	    }
	
	    inherits(Terminal, EventEmitter);
	
	    // back_color_erase feature for xterm.
	    Terminal.prototype.eraseAttr = function() {
	      // if (this.is('screen')) return this.defAttr;
	      return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);
	    };
	
	    /**
	     * Colors
	     */
	
	    // Colors 0-15
	    Terminal.tangoColors = [
	      // dark:
	      '#2e3436',
	      '#cc0000',
	      '#4e9a06',
	      '#c4a000',
	      '#3465a4',
	      '#75507b',
	      '#06989a',
	      '#d3d7cf',
	      // bright:
	      '#555753',
	      '#ef2929',
	      '#8ae234',
	      '#fce94f',
	      '#729fcf',
	      '#ad7fa8',
	      '#34e2e2',
	      '#eeeeec'
	    ];
	
	    // Colors 0-15 + 16-255
	    // Much thanks to TooTallNate for writing this.
	    Terminal.colors = (function() {
	      var colors = Terminal.tangoColors.slice()
	        , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]
	        , i;
	
	      // 16-231
	      i = 0;
	      for (; i < 216; i++) {
	        out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);
	      }
	
	      // 232-255 (grey)
	      i = 0;
	      for (; i < 24; i++) {
	        r = 8 + i * 10;
	        out(r, r, r);
	      }
	
	      function out(r, g, b) {
	        colors.push('#' + hex(r) + hex(g) + hex(b));
	      }
	
	      function hex(c) {
	        c = c.toString(16);
	        return c.length < 2 ? '0' + c : c;
	      }
	
	      return colors;
	    })();
	
	    Terminal._colors = Terminal.colors.slice();
	
	    Terminal.vcolors = (function() {
	      var out = []
	        , colors = Terminal.colors
	        , i = 0
	        , color;
	
	      for (; i < 256; i++) {
	        color = parseInt(colors[i].substring(1), 16);
	        out.push([
	          (color >> 16) & 0xff,
	          (color >> 8) & 0xff,
	          color & 0xff
	        ]);
	      }
	
	      return out;
	    })();
	
	    /**
	     * Options
	     */
	
	    Terminal.defaults = {
	      colors: Terminal.colors,
	      theme: 'default',
	      convertEol: false,
	      termName: 'xterm',
	      geometry: [80, 24],
	      cursorBlink: false,
	      visualBell: false,
	      popOnBell: false,
	      scrollback: 1000,
	      screenKeys: false,
	      debug: false,
	      cancelEvents: false
	      // programFeatures: false,
	      // focusKeys: false,
	    };
	
	    Terminal.options = {};
	
	    Terminal.focus = null;
	
	    each(keys(Terminal.defaults), function(key) {
	      Terminal[key] = Terminal.defaults[key];
	      Terminal.options[key] = Terminal.defaults[key];
	    });
	
	    /**
	     * Focused Terminal
	     */
	    Terminal.prototype.focus = function() {
	      if (document.activeElement === this.textarea) {
	        return;
	      }
	
	      if (this.sendFocus) {
	        this.send('\x1b[I');
	      }
	
	      this.showCursor();
	      this.textarea.focus();
	      Terminal.focus = this;
	    };
	
	    Terminal.prototype.blur = function() {
	      if (Terminal.focus !== this) {
	        return;
	      }
	
	      this.cursorState = 0;
	      this.refresh(this.y, this.y);
	      this.textarea.blur();
	
	      if (this.sendFocus) {
	        this.send('\x1b[O');
	      }
	      Terminal.focus = null;
	    };
	
	    /**
	     * Initialize default behavior
	     */
	
	    Terminal.prototype.initGlobal = function() {
	      Terminal.bindPaste(this);
	      Terminal.bindKeys(this);
	      Terminal.bindCopy(this);
	    };
	
	    /**
	     * Bind to paste event
	     */
	    Terminal.bindPaste = function(term) {
	      on([term.textarea, term.element], 'paste', function(ev) {
	        ev.stopPropagation();
	        if (ev.clipboardData) {
	          var text = ev.clipboardData.getData('text/plain');
	          term.handler(text);
	        }
	        term.textarea.value = '';
	        return term.cancel(ev);
	      });
	    };
	
	
	    /*
	     * Apply key handling to the terminal
	     */
	    Terminal.bindKeys = function(term) {
	      on(term.element, 'keydown', function(ev) {
	        if (document.activeElement != this) {
	          return;
	        }
	        term.keyDown(ev);
	      }, true);
	
	      on(term.element, 'keypress', function(ev) {
	        if (document.activeElement != this) {
	          return;
	        }
	        term.keyPress(ev);
	      }, true);
	
	      on(term.element, 'keyup', term.focus.bind(term));
	
	      on(term.textarea, 'keydown', function(ev) {
	        term.keyDown(ev);
	      }, true);
	
	      on(term.textarea, 'keypress', function(ev) {
	        term.keyPress(ev);
	
	        /*
	        * Truncate the textarea's value, since it is not needed
	        */
	        this.value = '';
	      }, true);
	    };
	
	
	    /*
	     * Bind copy event
	     */
	    Terminal.bindCopy = function(term) {
	      on(term.element, 'copy', function(ev) {
	        return; //temporary
	      });
	    };
	
	
	    /*
	     * Insert the given row to the terminal or produce a new one
	     * if no row argument is passed. Return the inserted row.
	     */
	    Terminal.prototype.insertRow = function (row) {
	      if (typeof row != 'object') {
	        row = document.createElement('div');
	      }
	
	      this.rowContainer.appendChild(row);
	      this.children.push(row);
	
	      return row;
	    }
	
	
	    /*
	     * Open Terminal in the DOM
	     */
	    Terminal.prototype.open = function(parent) {
	      var self=this, i=0, div;
	
	      this.parent = parent || this.parent;
	
	      if (!this.parent) {
	        throw new Error('Terminal requires a parent element.');
	      }
	
	      /*
	      * Grab global elements
	      */
	      this.context = this.parent.ownerDocument.defaultView;
	      this.document = this.parent.ownerDocument;
	      this.body = this.document.getElementsByTagName('body')[0];
	
	      /*
	      * Parse User-Agent
	      */
	      if (this.context.navigator && this.context.navigator.userAgent) {
	        this.isMac = !!~this.context.navigator.userAgent.indexOf('Mac');
	        this.isIpad = !!~this.context.navigator.userAgent.indexOf('iPad');
	        this.isIphone = !!~this.context.navigator.userAgent.indexOf('iPhone');
	        this.isMSIE = !!~this.context.navigator.userAgent.indexOf('MSIE');
	      }
	
	      /*
	      * Create main element container
	      */
	      this.element = this.document.createElement('div');
	      this.element.classList.add('terminal');
	      this.element.classList.add('xterm');
	      this.element.classList.add('xterm-theme-' + this.theme);
	      this.element.setAttribute('tabindex', 0);
	
	      /*
	      * Create the container that will hold the lines of the terminal and then
	      * produce the lines the lines.
	      */
	      this.rowContainer = document.createElement('div');
	      this.rowContainer.classList.add('xterm-rows');
	      this.element.appendChild(this.rowContainer);
	      this.children = [];
	
	      /*
	      * Create the container that will hold helpers like the textarea for
	      * capturing DOM Events. Then produce the helpers.
	      */
	      this.helperContainer = document.createElement('div');
	      this.helperContainer.classList.add('xterm-helpers');
	      this.element.appendChild(this.helperContainer);
	      this.textarea = document.createElement('textarea');
	      this.textarea.classList.add('xterm-helper-textarea');
	      this.textarea.setAttribute('autocorrect', 'off');
	      this.textarea.setAttribute('autocapitalize', 'off');
	      this.textarea.setAttribute('spellcheck', 'false');
	      this.textarea.tabIndex = 0;
	      this.textarea.onfocus = function() {
	        self.emit('focus', {terminal: self});
	      }
	      this.textarea.onblur = function() {
	        self.emit('blur', {terminal: self});
	      }
	      this.helperContainer.appendChild(this.textarea);
	
	      for (; i < this.rows; i++) {
	        this.insertRow();
	      }
	      this.parent.appendChild(this.element);
	
	      // Draw the screen.
	      this.refresh(0, this.rows - 1);
	
	      // Initialize global actions that
	      // need to be taken on the document.
	      this.initGlobal();
	
	      // Ensure there is a Terminal.focus.
	      this.focus();
	
	      // Start blinking the cursor.
	      this.startBlink();
	
	      on(this.element, 'mouseup', function() {
	        var selection = document.getSelection(),
	            collapsed = selection.isCollapsed,
	            isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';
	        if (!isRange) {
	          self.focus();
	        }
	      });
	
	      // Listen for mouse events and translate
	      // them into terminal mouse protocols.
	      this.bindMouse();
	
	      // Figure out whether boldness affects
	      // the character width of monospace fonts.
	      if (Terminal.brokenBold == null) {
	        Terminal.brokenBold = isBoldBroken(this.document);
	      }
	
	      this.emit('open');
	    };
	
	    // XTerm mouse events
	    // http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
	    // To better understand these
	    // the xterm code is very helpful:
	    // Relevant files:
	    //   button.c, charproc.c, misc.c
	    // Relevant functions in xterm/button.c:
	    //   BtnCode, EmitButtonCode, EditorButton, SendMousePosition
	    Terminal.prototype.bindMouse = function() {
	      var el = this.element
	        , self = this
	        , pressed = 32;
	
	      var wheelEvent = 'onmousewheel' in this.context
	        ? 'mousewheel'
	        : 'DOMMouseScroll';
	
	      // mouseup, mousedown, mousewheel
	      // left click: ^[[M 3<^[[M#3<
	      // mousewheel up: ^[[M`3>
	      function sendButton(ev) {
	        var button
	          , pos;
	
	        // get the xterm-style button
	        button = getButton(ev);
	
	        // get mouse coordinates
	        pos = getCoords(ev);
	        if (!pos) return;
	
	        sendEvent(button, pos);
	
	        switch (ev.type) {
	          case 'mousedown':
	            pressed = button;
	            break;
	          case 'mouseup':
	            // keep it at the left
	            // button, just in case.
	            pressed = 32;
	            break;
	          case wheelEvent:
	            // nothing. don't
	            // interfere with
	            // `pressed`.
	            break;
	        }
	      }
	
	      // motion example of a left click:
	      // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<
	      function sendMove(ev) {
	        var button = pressed
	          , pos;
	
	        pos = getCoords(ev);
	        if (!pos) return;
	
	        // buttons marked as motions
	        // are incremented by 32
	        button += 32;
	
	        sendEvent(button, pos);
	      }
	
	      // encode button and
	      // position to characters
	      function encode(data, ch) {
	        if (!self.utfMouse) {
	          if (ch === 255) return data.push(0);
	          if (ch > 127) ch = 127;
	          data.push(ch);
	        } else {
	          if (ch === 2047) return data.push(0);
	          if (ch < 127) {
	            data.push(ch);
	          } else {
	            if (ch > 2047) ch = 2047;
	            data.push(0xC0 | (ch >> 6));
	            data.push(0x80 | (ch & 0x3F));
	          }
	        }
	      }
	
	      // send a mouse event:
	      // regular/utf8: ^[[M Cb Cx Cy
	      // urxvt: ^[[ Cb ; Cx ; Cy M
	      // sgr: ^[[ Cb ; Cx ; Cy M/m
	      // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \r
	      // locator: CSI P e ; P b ; P r ; P c ; P p & w
	      function sendEvent(button, pos) {
	        // self.emit('mouse', {
	        //   x: pos.x - 32,
	        //   y: pos.x - 32,
	        //   button: button
	        // });
	
	        if (self.vt300Mouse) {
	          // NOTE: Unstable.
	          // http://www.vt100.net/docs/vt3xx-gp/chapter15.html
	          button &= 3;
	          pos.x -= 32;
	          pos.y -= 32;
	          var data = '\x1b[24';
	          if (button === 0) data += '1';
	          else if (button === 1) data += '3';
	          else if (button === 2) data += '5';
	          else if (button === 3) return;
	          else data += '0';
	          data += '~[' + pos.x + ',' + pos.y + ']\r';
	          self.send(data);
	          return;
	        }
	
	        if (self.decLocator) {
	          // NOTE: Unstable.
	          button &= 3;
	          pos.x -= 32;
	          pos.y -= 32;
	          if (button === 0) button = 2;
	          else if (button === 1) button = 4;
	          else if (button === 2) button = 6;
	          else if (button === 3) button = 3;
	          self.send('\x1b['
	            + button
	            + ';'
	            + (button === 3 ? 4 : 0)
	            + ';'
	            + pos.y
	            + ';'
	            + pos.x
	            + ';'
	            + (pos.page || 0)
	            + '&w');
	          return;
	        }
	
	        if (self.urxvtMouse) {
	          pos.x -= 32;
	          pos.y -= 32;
	          pos.x++;
	          pos.y++;
	          self.send('\x1b[' + button + ';' + pos.x + ';' + pos.y + 'M');
	          return;
	        }
	
	        if (self.sgrMouse) {
	          pos.x -= 32;
	          pos.y -= 32;
	          self.send('\x1b[<'
	            + ((button & 3) === 3 ? button & ~3 : button)
	            + ';'
	            + pos.x
	            + ';'
	            + pos.y
	            + ((button & 3) === 3 ? 'm' : 'M'));
	          return;
	        }
	
	        var data = [];
	
	        encode(data, button);
	        encode(data, pos.x);
	        encode(data, pos.y);
	
	        self.send('\x1b[M' + String.fromCharCode.apply(String, data));
	      }
	
	      function getButton(ev) {
	        var button
	          , shift
	          , meta
	          , ctrl
	          , mod;
	
	        // two low bits:
	        // 0 = left
	        // 1 = middle
	        // 2 = right
	        // 3 = release
	        // wheel up/down:
	        // 1, and 2 - with 64 added
	        switch (ev.type) {
	          case 'mousedown':
	            button = ev.button != null
	              ? +ev.button
	              : ev.which != null
	                ? ev.which - 1
	                : null;
	
	            if (self.isMSIE) {
	              button = button === 1 ? 0 : button === 4 ? 1 : button;
	            }
	            break;
	          case 'mouseup':
	            button = 3;
	            break;
	          case 'DOMMouseScroll':
	            button = ev.detail < 0
	              ? 64
	              : 65;
	            break;
	          case 'mousewheel':
	            button = ev.wheelDeltaY > 0
	              ? 64
	              : 65;
	            break;
	        }
	
	        // next three bits are the modifiers:
	        // 4 = shift, 8 = meta, 16 = control
	        shift = ev.shiftKey ? 4 : 0;
	        meta = ev.metaKey ? 8 : 0;
	        ctrl = ev.ctrlKey ? 16 : 0;
	        mod = shift | meta | ctrl;
	
	        // no mods
	        if (self.vt200Mouse) {
	          // ctrl only
	          mod &= ctrl;
	        } else if (!self.normalMouse) {
	          mod = 0;
	        }
	
	        // increment to SP
	        button = (32 + (mod << 2)) + button;
	
	        return button;
	      }
	
	      // mouse coordinates measured in cols/rows
	      function getCoords(ev) {
	        var x, y, w, h, el;
	
	        // ignore browsers without pageX for now
	        if (ev.pageX == null) return;
	
	        x = ev.pageX;
	        y = ev.pageY;
	        el = self.element;
	
	        // should probably check offsetParent
	        // but this is more portable
	        while (el && el !== self.document.documentElement) {
	          x -= el.offsetLeft;
	          y -= el.offsetTop;
	          el = 'offsetParent' in el
	            ? el.offsetParent
	            : el.parentNode;
	        }
	
	        // convert to cols/rows
	        w = self.element.clientWidth;
	        h = self.element.clientHeight;
	        x = Math.round((x / w) * self.cols);
	        y = Math.round((y / h) * self.rows);
	
	        // be sure to avoid sending
	        // bad positions to the program
	        if (x < 0) x = 0;
	        if (x > self.cols) x = self.cols;
	        if (y < 0) y = 0;
	        if (y > self.rows) y = self.rows;
	
	        // xterm sends raw bytes and
	        // starts at 32 (SP) for each.
	        x += 32;
	        y += 32;
	
	        return {
	          x: x,
	          y: y,
	          type: ev.type === wheelEvent
	            ? 'mousewheel'
	            : ev.type
	        };
	      }
	
	      on(el, 'mousedown', function(ev) {
	        if (!self.mouseEvents) return;
	
	        // send the button
	        sendButton(ev);
	
	        // ensure focus
	        self.focus();
	
	        // fix for odd bug
	        //if (self.vt200Mouse && !self.normalMouse) {
	        if (self.vt200Mouse) {
	          sendButton({ __proto__: ev, type: 'mouseup' });
	          return self.cancel(ev);
	        }
	
	        // bind events
	        if (self.normalMouse) on(self.document, 'mousemove', sendMove);
	
	        // x10 compatibility mode can't send button releases
	        if (!self.x10Mouse) {
	          on(self.document, 'mouseup', function up(ev) {
	            sendButton(ev);
	            if (self.normalMouse) off(self.document, 'mousemove', sendMove);
	            off(self.document, 'mouseup', up);
	            return self.cancel(ev);
	          });
	        }
	
	        return self.cancel(ev);
	      });
	
	      //if (self.normalMouse) {
	      //  on(self.document, 'mousemove', sendMove);
	      //}
	
	      on(el, wheelEvent, function(ev) {
	        if (!self.mouseEvents) return;
	        if (self.x10Mouse
	            || self.vt300Mouse
	            || self.decLocator) return;
	        sendButton(ev);
	        return self.cancel(ev);
	      });
	
	      // allow mousewheel scrolling in
	      // the shell for example
	      on(el, wheelEvent, function(ev) {
	        if (self.mouseEvents) return;
	        if (self.applicationKeypad) return;
	        if (ev.type === 'DOMMouseScroll') {
	          self.scrollDisp(ev.detail < 0 ? -1 : 1);
	        } else {
	          self.scrollDisp(ev.wheelDeltaY > 0 ? -1 : 1);
	        }
	        return self.cancel(ev);
	      });
	    };
	
	    /**
	     * Destroy Terminal
	     */
	
	    Terminal.prototype.destroy = function() {
	      this.readable = false;
	      this.writable = false;
	      this._events = {};
	      this.handler = function() {};
	      this.write = function() {};
	      if (this.element.parentNode) {
	        this.element.parentNode.removeChild(this.element);
	      }
	      //this.emit('close');
	    };
	
	
	    /*
	     * Rendering Engine
	     *
	     * In the screen buffer, each character
	     * is stored as a an array with a character
	     * and a 32-bit integer.
	     * First value: a utf-16 character.
	     * Second value:
	     * Next 9 bits: background color (0-511).
	     * Next 9 bits: foreground color (0-511).
	     * Next 14 bits: a mask for misc. flags:
	     *   1=bold, 2=underline, 4=blink, 8=inverse, 16=invisible
	    */
	    Terminal.prototype.refresh = function(start, end) {
	      var x, y, i, line, out, ch, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;
	
	      if (end - start >= this.rows / 2) {
	        parent = this.element.parentNode;
	        if (parent) parent.removeChild(this.element);
	      }
	
	      width = this.cols;
	      y = start;
	
	      if (end >= this.lines.length) {
	        this.log('`end` is too large. Most likely a bad CSR.');
	        end = this.lines.length - 1;
	      }
	
	      for (; y <= end; y++) {
	        row = y + this.ydisp;
	
	        line = this.lines[row];
	        out = '';
	
	        if (y === this.y
	            && this.cursorState
	            && (this.ydisp === this.ybase)
	            && !this.cursorHidden) {
	          x = this.x;
	        } else {
	          x = -1;
	        }
	
	        attr = this.defAttr;
	        i = 0;
	
	        for (; i < width; i++) {
	          data = line[i][0];
	          ch = line[i][1];
	
	          if (i === x) data = -1;
	
	          if (data !== attr) {
	            if (attr !== this.defAttr) {
	              out += '</span>';
	            }
	            if (data !== this.defAttr) {
	              if (data === -1) {
	                out += '<span class="reverse-video terminal-cursor">';
	              } else {
	                out += '<span class="';
	
	                bg = data & 0x1ff;
	                fg = (data >> 9) & 0x1ff;
	                flags = data >> 18;
	
	                // bold
	                if (flags & 1) {
	                  if (!Terminal.brokenBold) {
	                    out += ' xterm-bold ';
	                  }
	                  // See: XTerm*boldColors
	                  if (fg < 8) fg += 8;
	                }
	
	                // underline
	                if (flags & 2) {
	                  out += ' xterm-underline ';
	                }
	
	                // blink
	                if (flags & 4) {
	                    out += ' xterm-blink ';
	                }
	
	                // inverse
	                if (flags & 8) {
	                  bg = (data >> 9) & 0x1ff;
	                  fg = data & 0x1ff;
	                  // Should inverse just be before the
	                  // above boldColors effect instead?
	                  if ((flags & 1) && fg < 8) fg += 8;
	                }
	
	                // invisible
	                if (flags & 16) {
	                  out += ' xterm-hidden ';
	                }
	
	                if (bg !== 256) {
	                  out += ' xterm-bg-color-' + bg + ' ';
	                }
	
	                if (fg !== 257) {
	                  out += ' xterm-color-' + fg + ' ';
	                }
	
	                out += '">';
	              }
	            }
	          }
	
	          switch (ch) {
	            case '&':
	              out += '&amp;';
	              break;
	            case '<':
	              out += '&lt;';
	              break;
	            case '>':
	              out += '&gt;';
	              break;
	            default:
	              if (ch <= ' ') {
	                out += '&nbsp;';
	              } else {
	                if (isWide(ch)) i++;
	                out += ch;
	              }
	              break;
	          }
	
	          attr = data;
	        }
	
	        if (attr !== this.defAttr) {
	          out += '</span>';
	        }
	
	        this.children[y].innerHTML = out;
	      }
	
	      if (parent) {
	        parent.appendChild(this.element);
	      }
	
	      /*
	      *  Return focus to previously focused element
	      */
	      focused.focus();
	      this.emit('refresh', {element: this.element, start: start, end: end});
	    };
	
	    Terminal.prototype._cursorBlink = function() {
	      if (Terminal.focus !== this) return;
	      this.cursorState ^= 1;
	      this.refresh(this.y, this.y);
	    };
	
	    Terminal.prototype.showCursor = function() {
	      if (!this.cursorState) {
	        this.cursorState = 1;
	        this.refresh(this.y, this.y);
	      } else {
	        // Temporarily disabled:
	        // this.refreshBlink();
	      }
	    };
	
	    Terminal.prototype.startBlink = function() {
	      if (!this.cursorBlink) return;
	      var self = this;
	      this._blinker = function() {
	        self._cursorBlink();
	      };
	      this._blink = setInterval(this._blinker, 500);
	    };
	
	    Terminal.prototype.refreshBlink = function() {
	      if (!this.cursorBlink) return;
	      clearInterval(this._blink);
	      this._blink = setInterval(this._blinker, 500);
	    };
	
	    Terminal.prototype.scroll = function() {
	      var row;
	
	      if (++this.ybase === this.scrollback) {
	        this.ybase = this.ybase / 2 | 0;
	        this.lines = this.lines.slice(-(this.ybase + this.rows) + 1);
	      }
	
	      this.ydisp = this.ybase;
	
	      // last line
	      row = this.ybase + this.rows - 1;
	
	      // subtract the bottom scroll region
	      row -= this.rows - 1 - this.scrollBottom;
	
	      if (row === this.lines.length) {
	        // potential optimization:
	        // pushing is faster than splicing
	        // when they amount to the same
	        // behavior.
	        this.lines.push(this.blankLine());
	      } else {
	        // add our new line
	        this.lines.splice(row, 0, this.blankLine());
	      }
	
	      if (this.scrollTop !== 0) {
	        if (this.ybase !== 0) {
	          this.ybase--;
	          this.ydisp = this.ybase;
	        }
	        this.lines.splice(this.ybase + this.scrollTop, 1);
	      }
	
	      // this.maxRange();
	      this.updateRange(this.scrollTop);
	      this.updateRange(this.scrollBottom);
	    };
	
	    Terminal.prototype.scrollDisp = function(disp) {
	      this.ydisp += disp;
	
	      if (this.ydisp > this.ybase) {
	        this.ydisp = this.ybase;
	      } else if (this.ydisp < 0) {
	        this.ydisp = 0;
	      }
	
	      this.refresh(0, this.rows - 1);
	    };
	
	    Terminal.prototype.write = function(data) {
	      var l = data.length, i = 0, j, cs, ch;
	
	      this.refreshStart = this.y;
	      this.refreshEnd = this.y;
	
	      if (this.ybase !== this.ydisp) {
	        this.ydisp = this.ybase;
	        this.maxRange();
	      }
	
	      for (; i < l; i++) {
	        ch = data[i];
	        switch (this.state) {
	          case normal:
	            switch (ch) {
	              case '\x07':
	                this.bell();
	                break;
	
	              // '\n', '\v', '\f'
	              case '\n':
	              case '\x0b':
	              case '\x0c':
	                if (this.convertEol) {
	                  this.x = 0;
	                }
	                this.y++;
	                if (this.y > this.scrollBottom) {
	                  this.y--;
	                  this.scroll();
	                }
	                break;
	
	              // '\r'
	              case '\r':
	                this.x = 0;
	                break;
	
	              // '\b'
	              case '\x08':
	                if (this.x > 0) {
	                  this.x--;
	                }
	                break;
	
	              // '\t'
	              case '\t':
	                this.x = this.nextStop();
	                break;
	
	              // shift out
	              case '\x0e':
	                this.setgLevel(1);
	                break;
	
	              // shift in
	              case '\x0f':
	                this.setgLevel(0);
	                break;
	
	              // '\e'
	              case '\x1b':
	                this.state = escaped;
	                break;
	
	              default:
	                // ' '
	                if (ch >= ' ') {
	                  if (this.charset && this.charset[ch]) {
	                    ch = this.charset[ch];
	                  }
	
	                  if (this.x >= this.cols) {
	                    this.x = 0;
	                    this.y++;
	                    if (this.y > this.scrollBottom) {
	                      this.y--;
	                      this.scroll();
	                    }
	                  }
	
	                  this.lines[this.y + this.ybase][this.x] = [this.curAttr, ch];
	                  this.x++;
	                  this.updateRange(this.y);
	
	                  if (isWide(ch)) {
	                    j = this.y + this.ybase;
	                    if (this.cols < 2 || this.x >= this.cols) {
	                      this.lines[j][this.x - 1] = [this.curAttr, ' '];
	                      break;
	                    }
	                    this.lines[j][this.x] = [this.curAttr, ' '];
	                    this.x++;
	                  }
	                }
	                break;
	            }
	            break;
	          case escaped:
	            switch (ch) {
	              // ESC [ Control Sequence Introducer ( CSI is 0x9b).
	              case '[':
	                this.params = [];
	                this.currentParam = 0;
	                this.state = csi;
	                break;
	
	              // ESC ] Operating System Command ( OSC is 0x9d).
	              case ']':
	                this.params = [];
	                this.currentParam = 0;
	                this.state = osc;
	                break;
	
	              // ESC P Device Control String ( DCS is 0x90).
	              case 'P':
	                this.params = [];
	                this.currentParam = 0;
	                this.state = dcs;
	                break;
	
	              // ESC _ Application Program Command ( APC is 0x9f).
	              case '_':
	                this.state = ignore;
	                break;
	
	              // ESC ^ Privacy Message ( PM is 0x9e).
	              case '^':
	                this.state = ignore;
	                break;
	
	              // ESC c Full Reset (RIS).
	              case 'c':
	                this.reset();
	                break;
	
	              // ESC E Next Line ( NEL is 0x85).
	              // ESC D Index ( IND is 0x84).
	              case 'E':
	                this.x = 0;
	                ;
	              case 'D':
	                this.index();
	                break;
	
	              // ESC M Reverse Index ( RI is 0x8d).
	              case 'M':
	                this.reverseIndex();
	                break;
	
	              // ESC % Select default/utf-8 character set.
	              // @ = default, G = utf-8
	              case '%':
	                //this.charset = null;
	                this.setgLevel(0);
	                this.setgCharset(0, Terminal.charsets.US);
	                this.state = normal;
	                i++;
	                break;
	
	              // ESC (,),*,+,-,. Designate G0-G2 Character Set.
	              case '(': // <-- this seems to get all the attention
	              case ')':
	              case '*':
	              case '+':
	              case '-':
	              case '.':
	                switch (ch) {
	                  case '(':
	                    this.gcharset = 0;
	                    break;
	                  case ')':
	                    this.gcharset = 1;
	                    break;
	                  case '*':
	                    this.gcharset = 2;
	                    break;
	                  case '+':
	                    this.gcharset = 3;
	                    break;
	                  case '-':
	                    this.gcharset = 1;
	                    break;
	                  case '.':
	                    this.gcharset = 2;
	                    break;
	                }
	                this.state = charset;
	                break;
	
	              // Designate G3 Character Set (VT300).
	              // A = ISO Latin-1 Supplemental.
	              // Not implemented.
	              case '/':
	                this.gcharset = 3;
	                this.state = charset;
	                i--;
	                break;
	
	              // ESC N
	              // Single Shift Select of G2 Character Set
	              // ( SS2 is 0x8e). This affects next character only.
	              case 'N':
	                break;
	              // ESC O
	              // Single Shift Select of G3 Character Set
	              // ( SS3 is 0x8f). This affects next character only.
	              case 'O':
	                break;
	              // ESC n
	              // Invoke the G2 Character Set as GL (LS2).
	              case 'n':
	                this.setgLevel(2);
	                break;
	              // ESC o
	              // Invoke the G3 Character Set as GL (LS3).
	              case 'o':
	                this.setgLevel(3);
	                break;
	              // ESC |
	              // Invoke the G3 Character Set as GR (LS3R).
	              case '|':
	                this.setgLevel(3);
	                break;
	              // ESC }
	              // Invoke the G2 Character Set as GR (LS2R).
	              case '}':
	                this.setgLevel(2);
	                break;
	              // ESC ~
	              // Invoke the G1 Character Set as GR (LS1R).
	              case '~':
	                this.setgLevel(1);
	                break;
	
	              // ESC 7 Save Cursor (DECSC).
	              case '7':
	                this.saveCursor();
	                this.state = normal;
	                break;
	
	              // ESC 8 Restore Cursor (DECRC).
	              case '8':
	                this.restoreCursor();
	                this.state = normal;
	                break;
	
	              // ESC # 3 DEC line height/width
	              case '#':
	                this.state = normal;
	                i++;
	                break;
	
	              // ESC H Tab Set (HTS is 0x88).
	              case 'H':
	                this.tabSet();
	                break;
	
	              // ESC = Application Keypad (DECPAM).
	              case '=':
	                this.log('Serial port requested application keypad.');
	                this.applicationKeypad = true;
	                this.state = normal;
	                break;
	
	              // ESC > Normal Keypad (DECPNM).
	              case '>':
	                this.log('Switching back to normal keypad.');
	                this.applicationKeypad = false;
	                this.state = normal;
	                break;
	
	              default:
	                this.state = normal;
	                this.error('Unknown ESC control: %s.', ch);
	                break;
	            }
	            break;
	
	          case charset:
	            switch (ch) {
	              case '0': // DEC Special Character and Line Drawing Set.
	                cs = Terminal.charsets.SCLD;
	                break;
	              case 'A': // UK
	                cs = Terminal.charsets.UK;
	                break;
	              case 'B': // United States (USASCII).
	                cs = Terminal.charsets.US;
	                break;
	              case '4': // Dutch
	                cs = Terminal.charsets.Dutch;
	                break;
	              case 'C': // Finnish
	              case '5':
	                cs = Terminal.charsets.Finnish;
	                break;
	              case 'R': // French
	                cs = Terminal.charsets.French;
	                break;
	              case 'Q': // FrenchCanadian
	                cs = Terminal.charsets.FrenchCanadian;
	                break;
	              case 'K': // German
	                cs = Terminal.charsets.German;
	                break;
	              case 'Y': // Italian
	                cs = Terminal.charsets.Italian;
	                break;
	              case 'E': // NorwegianDanish
	              case '6':
	                cs = Terminal.charsets.NorwegianDanish;
	                break;
	              case 'Z': // Spanish
	                cs = Terminal.charsets.Spanish;
	                break;
	              case 'H': // Swedish
	              case '7':
	                cs = Terminal.charsets.Swedish;
	                break;
	              case '=': // Swiss
	                cs = Terminal.charsets.Swiss;
	                break;
	              case '/': // ISOLatin (actually /A)
	                cs = Terminal.charsets.ISOLatin;
	                i++;
	                break;
	              default: // Default
	                cs = Terminal.charsets.US;
	                break;
	            }
	            this.setgCharset(this.gcharset, cs);
	            this.gcharset = null;
	            this.state = normal;
	            break;
	
	          case osc:
	            // OSC Ps ; Pt ST
	            // OSC Ps ; Pt BEL
	            //   Set Text Parameters.
	            if (ch === '\x1b' || ch === '\x07') {
	              if (ch === '\x1b') i++;
	
	              this.params.push(this.currentParam);
	
	              switch (this.params[0]) {
	                case 0:
	                case 1:
	                case 2:
	                  if (this.params[1]) {
	                    this.title = this.params[1];
	                    this.handleTitle(this.title);
	                  }
	                  break;
	                case 3:
	                  // set X property
	                  break;
	                case 4:
	                case 5:
	                  // change dynamic colors
	                  break;
	                case 10:
	                case 11:
	                case 12:
	                case 13:
	                case 14:
	                case 15:
	                case 16:
	                case 17:
	                case 18:
	                case 19:
	                  // change dynamic ui colors
	                  break;
	                case 46:
	                  // change log file
	                  break;
	                case 50:
	                  // dynamic font
	                  break;
	                case 51:
	                  // emacs shell
	                  break;
	                case 52:
	                  // manipulate selection data
	                  break;
	                case 104:
	                case 105:
	                case 110:
	                case 111:
	                case 112:
	                case 113:
	                case 114:
	                case 115:
	                case 116:
	                case 117:
	                case 118:
	                  // reset colors
	                  break;
	              }
	
	              this.params = [];
	              this.currentParam = 0;
	              this.state = normal;
	            } else {
	              if (!this.params.length) {
	                if (ch >= '0' && ch <= '9') {
	                  this.currentParam =
	                    this.currentParam * 10 + ch.charCodeAt(0) - 48;
	                } else if (ch === ';') {
	                  this.params.push(this.currentParam);
	                  this.currentParam = '';
	                }
	              } else {
	                this.currentParam += ch;
	              }
	            }
	            break;
	
	          case csi:
	            // '?', '>', '!'
	            if (ch === '?' || ch === '>' || ch === '!') {
	              this.prefix = ch;
	              break;
	            }
	
	            // 0 - 9
	            if (ch >= '0' && ch <= '9') {
	              this.currentParam = this.currentParam * 10 + ch.charCodeAt(0) - 48;
	              break;
	            }
	
	            // '$', '"', ' ', '\''
	            if (ch === '$' || ch === '"' || ch === ' ' || ch === '\'') {
	              this.postfix = ch;
	              break;
	            }
	
	            this.params.push(this.currentParam);
	            this.currentParam = 0;
	
	            // ';'
	            if (ch === ';') break;
	
	            this.state = normal;
	
	            switch (ch) {
	              // CSI Ps A
	              // Cursor Up Ps Times (default = 1) (CUU).
	              case 'A':
	                this.cursorUp(this.params);
	                break;
	
	              // CSI Ps B
	              // Cursor Down Ps Times (default = 1) (CUD).
	              case 'B':
	                this.cursorDown(this.params);
	                break;
	
	              // CSI Ps C
	              // Cursor Forward Ps Times (default = 1) (CUF).
	              case 'C':
	                this.cursorForward(this.params);
	                break;
	
	              // CSI Ps D
	              // Cursor Backward Ps Times (default = 1) (CUB).
	              case 'D':
	                this.cursorBackward(this.params);
	                break;
	
	              // CSI Ps ; Ps H
	              // Cursor Position [row;column] (default = [1,1]) (CUP).
	              case 'H':
	                this.cursorPos(this.params);
	                break;
	
	              // CSI Ps J  Erase in Display (ED).
	              case 'J':
	                this.eraseInDisplay(this.params);
	                break;
	
	              // CSI Ps K  Erase in Line (EL).
	              case 'K':
	                this.eraseInLine(this.params);
	                break;
	
	              // CSI Pm m  Character Attributes (SGR).
	              case 'm':
	                if (!this.prefix) {
	                  this.charAttributes(this.params);
	                }
	                break;
	
	              // CSI Ps n  Device Status Report (DSR).
	              case 'n':
	                if (!this.prefix) {
	                  this.deviceStatus(this.params);
	                }
	                break;
	
	              /**
	               * Additions
	               */
	
	              // CSI Ps @
	              // Insert Ps (Blank) Character(s) (default = 1) (ICH).
	              case '@':
	                this.insertChars(this.params);
	                break;
	
	              // CSI Ps E
	              // Cursor Next Line Ps Times (default = 1) (CNL).
	              case 'E':
	                this.cursorNextLine(this.params);
	                break;
	
	              // CSI Ps F
	              // Cursor Preceding Line Ps Times (default = 1) (CNL).
	              case 'F':
	                this.cursorPrecedingLine(this.params);
	                break;
	
	              // CSI Ps G
	              // Cursor Character Absolute  [column] (default = [row,1]) (CHA).
	              case 'G':
	                this.cursorCharAbsolute(this.params);
	                break;
	
	              // CSI Ps L
	              // Insert Ps Line(s) (default = 1) (IL).
	              case 'L':
	                this.insertLines(this.params);
	                break;
	
	              // CSI Ps M
	              // Delete Ps Line(s) (default = 1) (DL).
	              case 'M':
	                this.deleteLines(this.params);
	                break;
	
	              // CSI Ps P
	              // Delete Ps Character(s) (default = 1) (DCH).
	              case 'P':
	                this.deleteChars(this.params);
	                break;
	
	              // CSI Ps X
	              // Erase Ps Character(s) (default = 1) (ECH).
	              case 'X':
	                this.eraseChars(this.params);
	                break;
	
	              // CSI Pm `  Character Position Absolute
	              //   [column] (default = [row,1]) (HPA).
	              case '`':
	                this.charPosAbsolute(this.params);
	                break;
	
	              // 141 61 a * HPR -
	              // Horizontal Position Relative
	              case 'a':
	                this.HPositionRelative(this.params);
	                break;
	
	              // CSI P s c
	              // Send Device Attributes (Primary DA).
	              // CSI > P s c
	              // Send Device Attributes (Secondary DA)
	              case 'c':
	                this.sendDeviceAttributes(this.params);
	                break;
	
	              // CSI Pm d
	              // Line Position Absolute  [row] (default = [1,column]) (VPA).
	              case 'd':
	                this.linePosAbsolute(this.params);
	                break;
	
	              // 145 65 e * VPR - Vertical Position Relative
	              case 'e':
	                this.VPositionRelative(this.params);
	                break;
	
	              // CSI Ps ; Ps f
	              //   Horizontal and Vertical Position [row;column] (default =
	              //   [1,1]) (HVP).
	              case 'f':
	                this.HVPosition(this.params);
	                break;
	
	              // CSI Pm h  Set Mode (SM).
	              // CSI ? Pm h - mouse escape codes, cursor escape codes
	              case 'h':
	                this.setMode(this.params);
	                break;
	
	              // CSI Pm l  Reset Mode (RM).
	              // CSI ? Pm l
	              case 'l':
	                this.resetMode(this.params);
	                break;
	
	              // CSI Ps ; Ps r
	              //   Set Scrolling Region [top;bottom] (default = full size of win-
	              //   dow) (DECSTBM).
	              // CSI ? Pm r
	              case 'r':
	                this.setScrollRegion(this.params);
	                break;
	
	              // CSI s
	              //   Save cursor (ANSI.SYS).
	              case 's':
	                this.saveCursor(this.params);
	                break;
	
	              // CSI u
	              //   Restore cursor (ANSI.SYS).
	              case 'u':
	                this.restoreCursor(this.params);
	                break;
	
	              /**
	               * Lesser Used
	               */
	
	              // CSI Ps I
	              // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).
	              case 'I':
	                this.cursorForwardTab(this.params);
	                break;
	
	              // CSI Ps S  Scroll up Ps lines (default = 1) (SU).
	              case 'S':
	                this.scrollUp(this.params);
	                break;
	
	              // CSI Ps T  Scroll down Ps lines (default = 1) (SD).
	              // CSI Ps ; Ps ; Ps ; Ps ; Ps T
	              // CSI > Ps; Ps T
	              case 'T':
	                // if (this.prefix === '>') {
	                //   this.resetTitleModes(this.params);
	                //   break;
	                // }
	                // if (this.params.length > 2) {
	                //   this.initMouseTracking(this.params);
	                //   break;
	                // }
	                if (this.params.length < 2 && !this.prefix) {
	                  this.scrollDown(this.params);
	                }
	                break;
	
	              // CSI Ps Z
	              // Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).
	              case 'Z':
	                this.cursorBackwardTab(this.params);
	                break;
	
	              // CSI Ps b  Repeat the preceding graphic character Ps times (REP).
	              case 'b':
	                this.repeatPrecedingCharacter(this.params);
	                break;
	
	              // CSI Ps g  Tab Clear (TBC).
	              case 'g':
	                this.tabClear(this.params);
	                break;
	
	              // CSI Pm i  Media Copy (MC).
	              // CSI ? Pm i
	              // case 'i':
	              //   this.mediaCopy(this.params);
	              //   break;
	
	              // CSI Pm m  Character Attributes (SGR).
	              // CSI > Ps; Ps m
	              // case 'm': // duplicate
	              //   if (this.prefix === '>') {
	              //     this.setResources(this.params);
	              //   } else {
	              //     this.charAttributes(this.params);
	              //   }
	              //   break;
	
	              // CSI Ps n  Device Status Report (DSR).
	              // CSI > Ps n
	              // case 'n': // duplicate
	              //   if (this.prefix === '>') {
	              //     this.disableModifiers(this.params);
	              //   } else {
	              //     this.deviceStatus(this.params);
	              //   }
	              //   break;
	
	              // CSI > Ps p  Set pointer mode.
	              // CSI ! p   Soft terminal reset (DECSTR).
	              // CSI Ps$ p
	              //   Request ANSI mode (DECRQM).
	              // CSI ? Ps$ p
	              //   Request DEC private mode (DECRQM).
	              // CSI Ps ; Ps " p
	              case 'p':
	                switch (this.prefix) {
	                  // case '>':
	                  //   this.setPointerMode(this.params);
	                  //   break;
	                  case '!':
	                    this.softReset(this.params);
	                    break;
	                  // case '?':
	                  //   if (this.postfix === '$') {
	                  //     this.requestPrivateMode(this.params);
	                  //   }
	                  //   break;
	                  // default:
	                  //   if (this.postfix === '"') {
	                  //     this.setConformanceLevel(this.params);
	                  //   } else if (this.postfix === '$') {
	                  //     this.requestAnsiMode(this.params);
	                  //   }
	                  //   break;
	                }
	                break;
	
	              // CSI Ps q  Load LEDs (DECLL).
	              // CSI Ps SP q
	              // CSI Ps " q
	              // case 'q':
	              //   if (this.postfix === ' ') {
	              //     this.setCursorStyle(this.params);
	              //     break;
	              //   }
	              //   if (this.postfix === '"') {
	              //     this.setCharProtectionAttr(this.params);
	              //     break;
	              //   }
	              //   this.loadLEDs(this.params);
	              //   break;
	
	              // CSI Ps ; Ps r
	              //   Set Scrolling Region [top;bottom] (default = full size of win-
	              //   dow) (DECSTBM).
	              // CSI ? Pm r
	              // CSI Pt; Pl; Pb; Pr; Ps$ r
	              // case 'r': // duplicate
	              //   if (this.prefix === '?') {
	              //     this.restorePrivateValues(this.params);
	              //   } else if (this.postfix === '$') {
	              //     this.setAttrInRectangle(this.params);
	              //   } else {
	              //     this.setScrollRegion(this.params);
	              //   }
	              //   break;
	
	              // CSI s     Save cursor (ANSI.SYS).
	              // CSI ? Pm s
	              // case 's': // duplicate
	              //   if (this.prefix === '?') {
	              //     this.savePrivateValues(this.params);
	              //   } else {
	              //     this.saveCursor(this.params);
	              //   }
	              //   break;
	
	              // CSI Ps ; Ps ; Ps t
	              // CSI Pt; Pl; Pb; Pr; Ps$ t
	              // CSI > Ps; Ps t
	              // CSI Ps SP t
	              // case 't':
	              //   if (this.postfix === '$') {
	              //     this.reverseAttrInRectangle(this.params);
	              //   } else if (this.postfix === ' ') {
	              //     this.setWarningBellVolume(this.params);
	              //   } else {
	              //     if (this.prefix === '>') {
	              //       this.setTitleModeFeature(this.params);
	              //     } else {
	              //       this.manipulateWindow(this.params);
	              //     }
	              //   }
	              //   break;
	
	              // CSI u     Restore cursor (ANSI.SYS).
	              // CSI Ps SP u
	              // case 'u': // duplicate
	              //   if (this.postfix === ' ') {
	              //     this.setMarginBellVolume(this.params);
	              //   } else {
	              //     this.restoreCursor(this.params);
	              //   }
	              //   break;
	
	              // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v
	              // case 'v':
	              //   if (this.postfix === '$') {
	              //     this.copyRectagle(this.params);
	              //   }
	              //   break;
	
	              // CSI Pt ; Pl ; Pb ; Pr ' w
	              // case 'w':
	              //   if (this.postfix === '\'') {
	              //     this.enableFilterRectangle(this.params);
	              //   }
	              //   break;
	
	              // CSI Ps x  Request Terminal Parameters (DECREQTPARM).
	              // CSI Ps x  Select Attribute Change Extent (DECSACE).
	              // CSI Pc; Pt; Pl; Pb; Pr$ x
	              // case 'x':
	              //   if (this.postfix === '$') {
	              //     this.fillRectangle(this.params);
	              //   } else {
	              //     this.requestParameters(this.params);
	              //     //this.__(this.params);
	              //   }
	              //   break;
	
	              // CSI Ps ; Pu ' z
	              // CSI Pt; Pl; Pb; Pr$ z
	              // case 'z':
	              //   if (this.postfix === '\'') {
	              //     this.enableLocatorReporting(this.params);
	              //   } else if (this.postfix === '$') {
	              //     this.eraseRectangle(this.params);
	              //   }
	              //   break;
	
	              // CSI Pm ' {
	              // CSI Pt; Pl; Pb; Pr$ {
	              // case '{':
	              //   if (this.postfix === '\'') {
	              //     this.setLocatorEvents(this.params);
	              //   } else if (this.postfix === '$') {
	              //     this.selectiveEraseRectangle(this.params);
	              //   }
	              //   break;
	
	              // CSI Ps ' |
	              // case '|':
	              //   if (this.postfix === '\'') {
	              //     this.requestLocatorPosition(this.params);
	              //   }
	              //   break;
	
	              // CSI P m SP }
	              // Insert P s Column(s) (default = 1) (DECIC), VT420 and up.
	              // case '}':
	              //   if (this.postfix === ' ') {
	              //     this.insertColumns(this.params);
	              //   }
	              //   break;
	
	              // CSI P m SP ~
	              // Delete P s Column(s) (default = 1) (DECDC), VT420 and up
	              // case '~':
	              //   if (this.postfix === ' ') {
	              //     this.deleteColumns(this.params);
	              //   }
	              //   break;
	
	              default:
	                this.error('Unknown CSI code: %s.', ch);
	                break;
	            }
	
	            this.prefix = '';
	            this.postfix = '';
	            break;
	
	          case dcs:
	            if (ch === '\x1b' || ch === '\x07') {
	              if (ch === '\x1b') i++;
	
	              switch (this.prefix) {
	                // User-Defined Keys (DECUDK).
	                case '':
	                  break;
	
	                // Request Status String (DECRQSS).
	                // test: echo -e '\eP$q"p\e\\'
	                case '$q':
	                  var pt = this.currentParam
	                    , valid = false;
	
	                  switch (pt) {
	                    // DECSCA
	                    case '"q':
	                      pt = '0"q';
	                      break;
	
	                    // DECSCL
	                    case '"p':
	                      pt = '61"p';
	                      break;
	
	                    // DECSTBM
	                    case 'r':
	                      pt = ''
	                        + (this.scrollTop + 1)
	                        + ';'
	                        + (this.scrollBottom + 1)
	                        + 'r';
	                      break;
	
	                    // SGR
	                    case 'm':
	                      pt = '0m';
	                      break;
	
	                    default:
	                      this.error('Unknown DCS Pt: %s.', pt);
	                      pt = '';
	                      break;
	                  }
	
	                  this.send('\x1bP' + +valid + '$r' + pt + '\x1b\\');
	                  break;
	
	                // Set Termcap/Terminfo Data (xterm, experimental).
	                case '+p':
	                  break;
	
	                // Request Termcap/Terminfo String (xterm, experimental)
	                // Regular xterm does not even respond to this sequence.
	                // This can cause a small glitch in vim.
	                // test: echo -ne '\eP+q6b64\e\\'
	                case '+q':
	                  var pt = this.currentParam
	                    , valid = false;
	
	                  this.send('\x1bP' + +valid + '+r' + pt + '\x1b\\');
	                  break;
	
	                default:
	                  this.error('Unknown DCS prefix: %s.', this.prefix);
	                  break;
	              }
	
	              this.currentParam = 0;
	              this.prefix = '';
	              this.state = normal;
	            } else if (!this.currentParam) {
	              if (!this.prefix && ch !== '$' && ch !== '+') {
	                this.currentParam = ch;
	              } else if (this.prefix.length === 2) {
	                this.currentParam = ch;
	              } else {
	                this.prefix += ch;
	              }
	            } else {
	              this.currentParam += ch;
	            }
	            break;
	
	          case ignore:
	            // For PM and APC.
	            if (ch === '\x1b' || ch === '\x07') {
	              if (ch === '\x1b') i++;
	              this.state = normal;
	            }
	            break;
	        }
	      }
	
	      this.updateRange(this.y);
	      this.refresh(this.refreshStart, this.refreshEnd);
	    };
	
	    Terminal.prototype.writeln = function(data) {
	      this.write(data + '\r\n');
	    };
	
	    // Key Resources:
	    // https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent
	    Terminal.prototype.keyDown = function(ev) {
	      var self = this, key;
	
	      switch (ev.keyCode) {
	        // backspace
	        case 8:
	          if (ev.shiftKey) {
	            key = '\x08'; // ^H
	            break;
	          }
	          key = '\x7f'; // ^?
	          break;
	        // tab
	        case 9:
	          if (ev.shiftKey) {
	            key = '\x1b[Z';
	            break;
	          }
	          key = '\t';
	          this.cancel(ev, true);
	          break;
	        // return/enter
	        case 13:
	          key = '\r';
	          this.cancel(ev, true);
	          break;
	        // escape
	        case 27:
	          key = '\x1b';
	          this.cancel(ev, true);
	          break;
	        // left-arrow
	        case 37:
	          if (ev.altKey) {
	            this.cancel(ev, true);
	            key = '\x1bb' // Jump a word back
	            break;
	          } else if (this.applicationCursor) {
	            key = '\x1bOD'; // SS3 as ^[O for 7-bit
	            break;
	          }
	          key = '\x1b[D';
	          break;
	        // right-arrow
	        case 39:
	          if (ev.altKey) {
	            this.cancel(ev, true);
	            key = '\x1bf' // Jump a word forward
	            break;
	          } else if (this.applicationCursor) {
	            key = '\x1bOC';
	            break;
	          }
	          key = '\x1b[C';
	          break;
	        // up-arrow
	        case 38:
	          if (this.applicationCursor) {
	            key = '\x1bOA';
	            break;
	          }
	          if (ev.ctrlKey) {
	            this.scrollDisp(-1);
	            return this.cancel(ev);
	          } else {
	            key = '\x1b[A';
	          }
	          break;
	        // down-arrow
	        case 40:
	          if (this.applicationCursor) {
	            key = '\x1bOB';
	            break;
	          }
	          if (ev.ctrlKey) {
	            this.scrollDisp(1);
	            return this.cancel(ev);
	          } else {
	            key = '\x1b[B';
	          }
	          break;
	        // delete
	        case 46:
	          key = '\x1b[3~';
	          break;
	        // insert
	        case 45:
	          key = '\x1b[2~';
	          break;
	        // home
	        case 36:
	          if (this.applicationKeypad) {
	            key = '\x1bOH';
	            break;
	          }
	          key = '\x1bOH';
	          break;
	        // end
	        case 35:
	          if (this.applicationKeypad) {
	            key = '\x1bOF';
	            break;
	          }
	          key = '\x1bOF';
	          break;
	        // page up
	        case 33:
	          if (ev.shiftKey) {
	            this.scrollDisp(-(this.rows - 1));
	            return this.cancel(ev);
	          } else {
	            key = '\x1b[5~';
	          }
	          break;
	        // page down
	        case 34:
	          if (ev.shiftKey) {
	            this.scrollDisp(this.rows - 1);
	            return this.cancel(ev);
	          } else {
	            key = '\x1b[6~';
	          }
	          break;
	        // F1
	        case 112:
	          key = '\x1bOP';
	          break;
	        // F2
	        case 113:
	          key = '\x1bOQ';
	          break;
	        // F3
	        case 114:
	          key = '\x1bOR';
	          break;
	        // F4
	        case 115:
	          key = '\x1bOS';
	          break;
	        // F5
	        case 116:
	          key = '\x1b[15~';
	          break;
	        // F6
	        case 117:
	          key = '\x1b[17~';
	          break;
	        // F7
	        case 118:
	          key = '\x1b[18~';
	          break;
	        // F8
	        case 119:
	          key = '\x1b[19~';
	          break;
	        // F9
	        case 120:
	          key = '\x1b[20~';
	          break;
	        // F10
	        case 121:
	          key = '\x1b[21~';
	          break;
	        // F11
	        case 122:
	          key = '\x1b[23~';
	          break;
	        // F12
	        case 123:
	          key = '\x1b[24~';
	          break;
	        default:
	          // a-z and space
	          if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {
	            if (ev.keyCode >= 65 && ev.keyCode <= 90) {
	              key = String.fromCharCode(ev.keyCode - 64);
	            } else if (ev.keyCode === 32) {
	              // NUL
	              key = String.fromCharCode(0);
	            } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {
	              // escape, file sep, group sep, record sep, unit sep
	              key = String.fromCharCode(ev.keyCode - 51 + 27);
	            } else if (ev.keyCode === 56) {
	              // delete
	              key = String.fromCharCode(127);
	            } else if (ev.keyCode === 219) {
	              // ^[ - escape
	              key = String.fromCharCode(27);
	            } else if (ev.keyCode === 221) {
	              // ^] - group sep
	              key = String.fromCharCode(29);
	            }
	          } else if ((!this.isMac && ev.altKey) || (this.isMac && ev.metaKey)) {
	            if (ev.keyCode >= 65 && ev.keyCode <= 90) {
	              key = '\x1b' + String.fromCharCode(ev.keyCode + 32);
	            } else if (ev.keyCode === 192) {
	              key = '\x1b`';
	            } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {
	              key = '\x1b' + (ev.keyCode - 48);
	            }
	          }
	          break;
	      }
	
	      if (!key || (this.isMac && ev.metaKey)) {
	        return true;
	      }
	
	      this.emit('keydown', ev);
	      this.emit('key', key, ev);
	      this.showCursor();
	      this.handler(key);
	
	      return this.cancel(ev);
	    };
	
	    Terminal.prototype.setgLevel = function(g) {
	      this.glevel = g;
	      this.charset = this.charsets[g];
	    };
	
	    Terminal.prototype.setgCharset = function(g, charset) {
	      this.charsets[g] = charset;
	      if (this.glevel === g) {
	        this.charset = charset;
	      }
	    };
	
	    Terminal.prototype.keyPress = function(ev) {
	      var key;
	
	      this.cancel(ev);
	
	      if (ev.charCode) {
	        key = ev.charCode;
	      } else if (ev.which == null) {
	        key = ev.keyCode;
	      } else if (ev.which !== 0 && ev.charCode !== 0) {
	        key = ev.which;
	      } else {
	        return false;
	      }
	
	      if (!key || ev.ctrlKey || ev.altKey || ev.metaKey) {
	        return false;
	      }
	
	      key = String.fromCharCode(key);
	
	      this.emit('keypress', key, ev);
	      this.emit('key', key, ev);
	      this.showCursor();
	      this.handler(key);
	
	      return false;
	    };
	
	    Terminal.prototype.send = function(data) {
	      var self = this;
	
	      if (!this.queue) {
	        setTimeout(function() {
	          self.handler(self.queue);
	          self.queue = '';
	        }, 1);
	      }
	
	      this.queue += data;
	    };
	
	    Terminal.prototype.bell = function() {
	      if (!this.visualBell) return;
	      var self = this;
	      this.element.style.borderColor = 'white';
	      setTimeout(function() {
	        self.element.style.borderColor = '';
	      }, 10);
	      if (this.popOnBell) this.focus();
	    };
	
	    Terminal.prototype.log = function() {
	      if (!this.debug) return;
	      if (!this.context.console || !this.context.console.log) return;
	      var args = Array.prototype.slice.call(arguments);
	      this.context.console.log.apply(this.context.console, args);
	    };
	
	    Terminal.prototype.error = function() {
	      if (!this.debug) return;
	      if (!this.context.console || !this.context.console.error) return;
	      var args = Array.prototype.slice.call(arguments);
	      this.context.console.error.apply(this.context.console, args);
	    };
	
	    Terminal.prototype.resize = function(x, y) {
	      var line
	        , el
	        , i
	        , j
	        , ch;
	
	      if (x < 1) x = 1;
	      if (y < 1) y = 1;
	
	      // resize cols
	      j = this.cols;
	      if (j < x) {
	        ch = [this.defAttr, ' ']; // does xterm use the default attr?
	        i = this.lines.length;
	        while (i--) {
	          while (this.lines[i].length < x) {
	            this.lines[i].push(ch);
	          }
	        }
	      } else if (j > x) {
	        i = this.lines.length;
	        while (i--) {
	          while (this.lines[i].length > x) {
	            this.lines[i].pop();
	          }
	        }
	      }
	      this.setupStops(j);
	      this.cols = x;
	
	      // resize rows
	      j = this.rows;
	      if (j < y) {
	        el = this.element;
	        while (j++ < y) {
	          if (this.lines.length < y + this.ybase) {
	            this.lines.push(this.blankLine());
	          }
	          if (this.children.length < y) {
	            this.insertRow();
	          }
	        }
	      } else if (j > y) {
	        while (j-- > y) {
	          if (this.lines.length > y + this.ybase) {
	            this.lines.shift();
	          }
	          if (this.children.length > y) {
	            el = this.children.shift();
	            if (!el) continue;
	            el.parentNode.removeChild(el);
	          }
	        }
	      }
	      this.rows = y;
	
	      /*
	      *  Make sure that the cursor stays on screen
	      */
	      if (this.y >= y) {
	        this.y = y - 1;
	      }
	
	      if (this.x >= x) {
	        this.x = x - 1;
	      }
	
	      this.scrollTop = 0;
	      this.scrollBottom = y - 1;
	
	      this.refresh(0, this.rows - 1);
	
	      this.normal = null;
	
	      this.emit('resize', {terminal: this, cols: x, rows: y});
	    };
	
	    Terminal.prototype.updateRange = function(y) {
	      if (y < this.refreshStart) this.refreshStart = y;
	      if (y > this.refreshEnd) this.refreshEnd = y;
	      // if (y > this.refreshEnd) {
	      //   this.refreshEnd = y;
	      //   if (y > this.rows - 1) {
	      //     this.refreshEnd = this.rows - 1;
	      //   }
	      // }
	    };
	
	    Terminal.prototype.maxRange = function() {
	      this.refreshStart = 0;
	      this.refreshEnd = this.rows - 1;
	    };
	
	    Terminal.prototype.setupStops = function(i) {
	      if (i != null) {
	        if (!this.tabs[i]) {
	          i = this.prevStop(i);
	        }
	      } else {
	        this.tabs = {};
	        i = 0;
	      }
	
	      for (; i < this.cols; i += 8) {
	        this.tabs[i] = true;
	      }
	    };
	
	    Terminal.prototype.prevStop = function(x) {
	      if (x == null) x = this.x;
	      while (!this.tabs[--x] && x > 0);
	      return x >= this.cols
	        ? this.cols - 1
	        : x < 0 ? 0 : x;
	    };
	
	    Terminal.prototype.nextStop = function(x) {
	      if (x == null) x = this.x;
	      while (!this.tabs[++x] && x < this.cols);
	      return x >= this.cols
	        ? this.cols - 1
	        : x < 0 ? 0 : x;
	    };
	
	    Terminal.prototype.eraseRight = function(x, y) {
	      var line = this.lines[this.ybase + y]
	        , ch = [this.eraseAttr(), ' ']; // xterm
	
	
	      for (; x < this.cols; x++) {
	        line[x] = ch;
	      }
	
	      this.updateRange(y);
	    };
	
	    Terminal.prototype.eraseLeft = function(x, y) {
	      var line = this.lines[this.ybase + y]
	        , ch = [this.eraseAttr(), ' ']; // xterm
	
	      x++;
	      while (x--) line[x] = ch;
	
	      this.updateRange(y);
	    };
	
	    Terminal.prototype.eraseLine = function(y) {
	      this.eraseRight(0, y);
	    };
	
	    Terminal.prototype.blankLine = function(cur) {
	      var attr = cur
	        ? this.eraseAttr()
	        : this.defAttr;
	
	      var ch = [attr, ' ']
	        , line = []
	        , i = 0;
	
	      for (; i < this.cols; i++) {
	        line[i] = ch;
	      }
	
	      return line;
	    };
	
	    Terminal.prototype.ch = function(cur) {
	      return cur
	        ? [this.eraseAttr(), ' ']
	        : [this.defAttr, ' '];
	    };
	
	    Terminal.prototype.is = function(term) {
	      var name = this.termName;
	      return (name + '').indexOf(term) === 0;
	    };
	
	    Terminal.prototype.handler = function(data) {
	      this.emit('data', data);
	    };
	
	    Terminal.prototype.handleTitle = function(title) {
	      this.emit('title', title);
	    };
	
	    /**
	     * ESC
	     */
	
	    // ESC D Index (IND is 0x84).
	    Terminal.prototype.index = function() {
	      this.y++;
	      if (this.y > this.scrollBottom) {
	        this.y--;
	        this.scroll();
	      }
	      this.state = normal;
	    };
	
	    // ESC M Reverse Index (RI is 0x8d).
	    Terminal.prototype.reverseIndex = function() {
	      var j;
	      this.y--;
	      if (this.y < this.scrollTop) {
	        this.y++;
	        // possibly move the code below to term.reverseScroll();
	        // test: echo -ne '\e[1;1H\e[44m\eM\e[0m'
	        // blankLine(true) is xterm/linux behavior
	        this.lines.splice(this.y + this.ybase, 0, this.blankLine(true));
	        j = this.rows - 1 - this.scrollBottom;
	        this.lines.splice(this.rows - 1 + this.ybase - j + 1, 1);
	        // this.maxRange();
	        this.updateRange(this.scrollTop);
	        this.updateRange(this.scrollBottom);
	      }
	      this.state = normal;
	    };
	
	    // ESC c Full Reset (RIS).
	    Terminal.prototype.reset = function() {
	      this.options.rows = this.rows;
	      this.options.cols = this.cols;
	      Terminal.call(this, this.options);
	      this.refresh(0, this.rows - 1);
	    };
	
	    // ESC H Tab Set (HTS is 0x88).
	    Terminal.prototype.tabSet = function() {
	      this.tabs[this.x] = true;
	      this.state = normal;
	    };
	
	    /**
	     * CSI
	     */
	
	    // CSI Ps A
	    // Cursor Up Ps Times (default = 1) (CUU).
	    Terminal.prototype.cursorUp = function(params) {
	      var param = params[0];
	      if (param < 1) param = 1;
	      this.y -= param;
	      if (this.y < 0) this.y = 0;
	    };
	
	    // CSI Ps B
	    // Cursor Down Ps Times (default = 1) (CUD).
	    Terminal.prototype.cursorDown = function(params) {
	      var param = params[0];
	      if (param < 1) param = 1;
	      this.y += param;
	      if (this.y >= this.rows) {
	        this.y = this.rows - 1;
	      }
	    };
	
	    // CSI Ps C
	    // Cursor Forward Ps Times (default = 1) (CUF).
	    Terminal.prototype.cursorForward = function(params) {
	      var param = params[0];
	      if (param < 1) param = 1;
	      this.x += param;
	      if (this.x >= this.cols) {
	        this.x = this.cols - 1;
	      }
	    };
	
	    // CSI Ps D
	    // Cursor Backward Ps Times (default = 1) (CUB).
	    Terminal.prototype.cursorBackward = function(params) {
	      var param = params[0];
	      if (param < 1) param = 1;
	      this.x -= param;
	      if (this.x < 0) this.x = 0;
	    };
	
	    // CSI Ps ; Ps H
	    // Cursor Position [row;column] (default = [1,1]) (CUP).
	    Terminal.prototype.cursorPos = function(params) {
	      var row, col;
	
	      row = params[0] - 1;
	
	      if (params.length >= 2) {
	        col = params[1] - 1;
	      } else {
	        col = 0;
	      }
	
	      if (row < 0) {
	        row = 0;
	      } else if (row >= this.rows) {
	        row = this.rows - 1;
	      }
	
	      if (col < 0) {
	        col = 0;
	      } else if (col >= this.cols) {
	        col = this.cols - 1;
	      }
	
	      this.x = col;
	      this.y = row;
	    };
	
	    // CSI Ps J  Erase in Display (ED).
	    //     Ps = 0  -> Erase Below (default).
	    //     Ps = 1  -> Erase Above.
	    //     Ps = 2  -> Erase All.
	    //     Ps = 3  -> Erase Saved Lines (xterm).
	    // CSI ? Ps J
	    //   Erase in Display (DECSED).
	    //     Ps = 0  -> Selective Erase Below (default).
	    //     Ps = 1  -> Selective Erase Above.
	    //     Ps = 2  -> Selective Erase All.
	    Terminal.prototype.eraseInDisplay = function(params) {
	      var j;
	      switch (params[0]) {
	        case 0:
	          this.eraseRight(this.x, this.y);
	          j = this.y + 1;
	          for (; j < this.rows; j++) {
	            this.eraseLine(j);
	          }
	          break;
	        case 1:
	          this.eraseLeft(this.x, this.y);
	          j = this.y;
	          while (j--) {
	            this.eraseLine(j);
	          }
	          break;
	        case 2:
	          j = this.rows;
	          while (j--) this.eraseLine(j);
	          break;
	        case 3:
	          ; // no saved lines
	          break;
	      }
	    };
	
	    // CSI Ps K  Erase in Line (EL).
	    //     Ps = 0  -> Erase to Right (default).
	    //     Ps = 1  -> Erase to Left.
	    //     Ps = 2  -> Erase All.
	    // CSI ? Ps K
	    //   Erase in Line (DECSEL).
	    //     Ps = 0  -> Selective Erase to Right (default).
	    //     Ps = 1  -> Selective Erase to Left.
	    //     Ps = 2  -> Selective Erase All.
	    Terminal.prototype.eraseInLine = function(params) {
	      switch (params[0]) {
	        case 0:
	          this.eraseRight(this.x, this.y);
	          break;
	        case 1:
	          this.eraseLeft(this.x, this.y);
	          break;
	        case 2:
	          this.eraseLine(this.y);
	          break;
	      }
	    };
	
	    // CSI Pm m  Character Attributes (SGR).
	    //     Ps = 0  -> Normal (default).
	    //     Ps = 1  -> Bold.
	    //     Ps = 4  -> Underlined.
	    //     Ps = 5  -> Blink (appears as Bold).
	    //     Ps = 7  -> Inverse.
	    //     Ps = 8  -> Invisible, i.e., hidden (VT300).
	    //     Ps = 2 2  -> Normal (neither bold nor faint).
	    //     Ps = 2 4  -> Not underlined.
	    //     Ps = 2 5  -> Steady (not blinking).
	    //     Ps = 2 7  -> Positive (not inverse).
	    //     Ps = 2 8  -> Visible, i.e., not hidden (VT300).
	    //     Ps = 3 0  -> Set foreground color to Black.
	    //     Ps = 3 1  -> Set foreground color to Red.
	    //     Ps = 3 2  -> Set foreground color to Green.
	    //     Ps = 3 3  -> Set foreground color to Yellow.
	    //     Ps = 3 4  -> Set foreground color to Blue.
	    //     Ps = 3 5  -> Set foreground color to Magenta.
	    //     Ps = 3 6  -> Set foreground color to Cyan.
	    //     Ps = 3 7  -> Set foreground color to White.
	    //     Ps = 3 9  -> Set foreground color to default (original).
	    //     Ps = 4 0  -> Set background color to Black.
	    //     Ps = 4 1  -> Set background color to Red.
	    //     Ps = 4 2  -> Set background color to Green.
	    //     Ps = 4 3  -> Set background color to Yellow.
	    //     Ps = 4 4  -> Set background color to Blue.
	    //     Ps = 4 5  -> Set background color to Magenta.
	    //     Ps = 4 6  -> Set background color to Cyan.
	    //     Ps = 4 7  -> Set background color to White.
	    //     Ps = 4 9  -> Set background color to default (original).
	
	    //   If 16-color support is compiled, the following apply.  Assume
	    //   that xterm's resources are set so that the ISO color codes are
	    //   the first 8 of a set of 16.  Then the aixterm colors are the
	    //   bright versions of the ISO colors:
	    //     Ps = 9 0  -> Set foreground color to Black.
	    //     Ps = 9 1  -> Set foreground color to Red.
	    //     Ps = 9 2  -> Set foreground color to Green.
	    //     Ps = 9 3  -> Set foreground color to Yellow.
	    //     Ps = 9 4  -> Set foreground color to Blue.
	    //     Ps = 9 5  -> Set foreground color to Magenta.
	    //     Ps = 9 6  -> Set foreground color to Cyan.
	    //     Ps = 9 7  -> Set foreground color to White.
	    //     Ps = 1 0 0  -> Set background color to Black.
	    //     Ps = 1 0 1  -> Set background color to Red.
	    //     Ps = 1 0 2  -> Set background color to Green.
	    //     Ps = 1 0 3  -> Set background color to Yellow.
	    //     Ps = 1 0 4  -> Set background color to Blue.
	    //     Ps = 1 0 5  -> Set background color to Magenta.
	    //     Ps = 1 0 6  -> Set background color to Cyan.
	    //     Ps = 1 0 7  -> Set background color to White.
	
	    //   If xterm is compiled with the 16-color support disabled, it
	    //   supports the following, from rxvt:
	    //     Ps = 1 0 0  -> Set foreground and background color to
	    //     default.
	
	    //   If 88- or 256-color support is compiled, the following apply.
	    //     Ps = 3 8  ; 5  ; Ps -> Set foreground color to the second
	    //     Ps.
	    //     Ps = 4 8  ; 5  ; Ps -> Set background color to the second
	    //     Ps.
	    Terminal.prototype.charAttributes = function(params) {
	      // Optimize a single SGR0.
	      if (params.length === 1 && params[0] === 0) {
	        this.curAttr = this.defAttr;
	        return;
	      }
	
	      var l = params.length
	        , i = 0
	        , flags = this.curAttr >> 18
	        , fg = (this.curAttr >> 9) & 0x1ff
	        , bg = this.curAttr & 0x1ff
	        , p;
	
	      for (; i < l; i++) {
	        p = params[i];
	        if (p >= 30 && p <= 37) {
	          // fg color 8
	          fg = p - 30;
	        } else if (p >= 40 && p <= 47) {
	          // bg color 8
	          bg = p - 40;
	        } else if (p >= 90 && p <= 97) {
	          // fg color 16
	          p += 8;
	          fg = p - 90;
	        } else if (p >= 100 && p <= 107) {
	          // bg color 16
	          p += 8;
	          bg = p - 100;
	        } else if (p === 0) {
	          // default
	          flags = this.defAttr >> 18;
	          fg = (this.defAttr >> 9) & 0x1ff;
	          bg = this.defAttr & 0x1ff;
	          // flags = 0;
	          // fg = 0x1ff;
	          // bg = 0x1ff;
	        } else if (p === 1) {
	          // bold text
	          flags |= 1;
	        } else if (p === 4) {
	          // underlined text
	          flags |= 2;
	        } else if (p === 5) {
	          // blink
	          flags |= 4;
	        } else if (p === 7) {
	          // inverse and positive
	          // test with: echo -e '\e[31m\e[42mhello\e[7mworld\e[27mhi\e[m'
	          flags |= 8;
	        } else if (p === 8) {
	          // invisible
	          flags |= 16;
	        } else if (p === 22) {
	          // not bold
	          flags &= ~1;
	        } else if (p === 24) {
	          // not underlined
	          flags &= ~2;
	        } else if (p === 25) {
	          // not blink
	          flags &= ~4;
	        } else if (p === 27) {
	          // not inverse
	          flags &= ~8;
	        } else if (p === 28) {
	          // not invisible
	          flags &= ~16;
	        } else if (p === 39) {
	          // reset fg
	          fg = (this.defAttr >> 9) & 0x1ff;
	        } else if (p === 49) {
	          // reset bg
	          bg = this.defAttr & 0x1ff;
	        } else if (p === 38) {
	          // fg color 256
	          if (params[i + 1] === 2) {
	            i += 2;
	            fg = matchColor(
	              params[i] & 0xff,
	              params[i + 1] & 0xff,
	              params[i + 2] & 0xff);
	            if (fg === -1) fg = 0x1ff;
	            i += 2;
	          } else if (params[i + 1] === 5) {
	            i += 2;
	            p = params[i] & 0xff;
	            fg = p;
	          }
	        } else if (p === 48) {
	          // bg color 256
	          if (params[i + 1] === 2) {
	            i += 2;
	            bg = matchColor(
	              params[i] & 0xff,
	              params[i + 1] & 0xff,
	              params[i + 2] & 0xff);
	            if (bg === -1) bg = 0x1ff;
	            i += 2;
	          } else if (params[i + 1] === 5) {
	            i += 2;
	            p = params[i] & 0xff;
	            bg = p;
	          }
	        } else if (p === 100) {
	          // reset fg/bg
	          fg = (this.defAttr >> 9) & 0x1ff;
	          bg = this.defAttr & 0x1ff;
	        } else {
	          this.error('Unknown SGR attribute: %d.', p);
	        }
	      }
	
	      this.curAttr = (flags << 18) | (fg << 9) | bg;
	    };
	
	    // CSI Ps n  Device Status Report (DSR).
	    //     Ps = 5  -> Status Report.  Result (``OK'') is
	    //   CSI 0 n
	    //     Ps = 6  -> Report Cursor Position (CPR) [row;column].
	    //   Result is
	    //   CSI r ; c R
	    // CSI ? Ps n
	    //   Device Status Report (DSR, DEC-specific).
	    //     Ps = 6  -> Report Cursor Position (CPR) [row;column] as CSI
	    //     ? r ; c R (assumes page is zero).
	    //     Ps = 1 5  -> Report Printer status as CSI ? 1 0  n  (ready).
	    //     or CSI ? 1 1  n  (not ready).
	    //     Ps = 2 5  -> Report UDK status as CSI ? 2 0  n  (unlocked)
	    //     or CSI ? 2 1  n  (locked).
	    //     Ps = 2 6  -> Report Keyboard status as
	    //   CSI ? 2 7  ;  1  ;  0  ;  0  n  (North American).
	    //   The last two parameters apply to VT400 & up, and denote key-
	    //   board ready and LK01 respectively.
	    //     Ps = 5 3  -> Report Locator status as
	    //   CSI ? 5 3  n  Locator available, if compiled-in, or
	    //   CSI ? 5 0  n  No Locator, if not.
	    Terminal.prototype.deviceStatus = function(params) {
	      if (!this.prefix) {
	        switch (params[0]) {
	          case 5:
	            // status report
	            this.send('\x1b[0n');
	            break;
	          case 6:
	            // cursor position
	            this.send('\x1b['
	              + (this.y + 1)
	              + ';'
	              + (this.x + 1)
	              + 'R');
	            break;
	        }
	      } else if (this.prefix === '?') {
	        // modern xterm doesnt seem to
	        // respond to any of these except ?6, 6, and 5
	        switch (params[0]) {
	          case 6:
	            // cursor position
	            this.send('\x1b[?'
	              + (this.y + 1)
	              + ';'
	              + (this.x + 1)
	              + 'R');
	            break;
	          case 15:
	            // no printer
	            // this.send('\x1b[?11n');
	            break;
	          case 25:
	            // dont support user defined keys
	            // this.send('\x1b[?21n');
	            break;
	          case 26:
	            // north american keyboard
	            // this.send('\x1b[?27;1;0;0n');
	            break;
	          case 53:
	            // no dec locator/mouse
	            // this.send('\x1b[?50n');
	            break;
	        }
	      }
	    };
	
	    /**
	     * Additions
	     */
	
	    // CSI Ps @
	    // Insert Ps (Blank) Character(s) (default = 1) (ICH).
	    Terminal.prototype.insertChars = function(params) {
	      var param, row, j, ch;
	
	      param = params[0];
	      if (param < 1) param = 1;
	
	      row = this.y + this.ybase;
	      j = this.x;
	      ch = [this.eraseAttr(), ' ']; // xterm
	
	      while (param-- && j < this.cols) {
	        this.lines[row].splice(j++, 0, ch);
	        this.lines[row].pop();
	      }
	    };
	
	    // CSI Ps E
	    // Cursor Next Line Ps Times (default = 1) (CNL).
	    // same as CSI Ps B ?
	    Terminal.prototype.cursorNextLine = function(params) {
	      var param = params[0];
	      if (param < 1) param = 1;
	      this.y += param;
	      if (this.y >= this.rows) {
	        this.y = this.rows - 1;
	      }
	      this.x = 0;
	    };
	
	    // CSI Ps F
	    // Cursor Preceding Line Ps Times (default = 1) (CNL).
	    // reuse CSI Ps A ?
	    Terminal.prototype.cursorPrecedingLine = function(params) {
	      var param = params[0];
	      if (param < 1) param = 1;
	      this.y -= param;
	      if (this.y < 0) this.y = 0;
	      this.x = 0;
	    };
	
	    // CSI Ps G
	    // Cursor Character Absolute  [column] (default = [row,1]) (CHA).
	    Terminal.prototype.cursorCharAbsolute = function(params) {
	      var param = params[0];
	      if (param < 1) param = 1;
	      this.x = param - 1;
	    };
	
	    // CSI Ps L
	    // Insert Ps Line(s) (default = 1) (IL).
	    Terminal.prototype.insertLines = function(params) {
	      var param, row, j;
	
	      param = params[0];
	      if (param < 1) param = 1;
	      row = this.y + this.ybase;
	
	      j = this.rows - 1 - this.scrollBottom;
	      j = this.rows - 1 + this.ybase - j + 1;
	
	      while (param--) {
	        // test: echo -e '\e[44m\e[1L\e[0m'
	        // blankLine(true) - xterm/linux behavior
	        this.lines.splice(row, 0, this.blankLine(true));
	        this.lines.splice(j, 1);
	      }
	
	      // this.maxRange();
	      this.updateRange(this.y);
	      this.updateRange(this.scrollBottom);
	    };
	
	    // CSI Ps M
	    // Delete Ps Line(s) (default = 1) (DL).
	    Terminal.prototype.deleteLines = function(params) {
	      var param, row, j;
	
	      param = params[0];
	      if (param < 1) param = 1;
	      row = this.y + this.ybase;
	
	      j = this.rows - 1 - this.scrollBottom;
	      j = this.rows - 1 + this.ybase - j;
	
	      while (param--) {
	        // test: echo -e '\e[44m\e[1M\e[0m'
	        // blankLine(true) - xterm/linux behavior
	        this.lines.splice(j + 1, 0, this.blankLine(true));
	        this.lines.splice(row, 1);
	      }
	
	      // this.maxRange();
	      this.updateRange(this.y);
	      this.updateRange(this.scrollBottom);
	    };
	
	    // CSI Ps P
	    // Delete Ps Character(s) (default = 1) (DCH).
	    Terminal.prototype.deleteChars = function(params) {
	      var param, row, ch;
	
	      param = params[0];
	      if (param < 1) param = 1;
	
	      row = this.y + this.ybase;
	      ch = [this.eraseAttr(), ' ']; // xterm
	
	      while (param--) {
	        this.lines[row].splice(this.x, 1);
	        this.lines[row].push(ch);
	      }
	    };
	
	    // CSI Ps X
	    // Erase Ps Character(s) (default = 1) (ECH).
	    Terminal.prototype.eraseChars = function(params) {
	      var param, row, j, ch;
	
	      param = params[0];
	      if (param < 1) param = 1;
	
	      row = this.y + this.ybase;
	      j = this.x;
	      ch = [this.eraseAttr(), ' ']; // xterm
	
	      while (param-- && j < this.cols) {
	        this.lines[row][j++] = ch;
	      }
	    };
	
	    // CSI Pm `  Character Position Absolute
	    //   [column] (default = [row,1]) (HPA).
	    Terminal.prototype.charPosAbsolute = function(params) {
	      var param = params[0];
	      if (param < 1) param = 1;
	      this.x = param - 1;
	      if (this.x >= this.cols) {
	        this.x = this.cols - 1;
	      }
	    };
	
	    // 141 61 a * HPR -
	    // Horizontal Position Relative
	    // reuse CSI Ps C ?
	    Terminal.prototype.HPositionRelative = function(params) {
	      var param = params[0];
	      if (param < 1) param = 1;
	      this.x += param;
	      if (this.x >= this.cols) {
	        this.x = this.cols - 1;
	      }
	    };
	
	    // CSI Ps c  Send Device Attributes (Primary DA).
	    //     Ps = 0  or omitted -> request attributes from terminal.  The
	    //     response depends on the decTerminalID resource setting.
	    //     -> CSI ? 1 ; 2 c  (``VT100 with Advanced Video Option'')
	    //     -> CSI ? 1 ; 0 c  (``VT101 with No Options'')
	    //     -> CSI ? 6 c  (``VT102'')
	    //     -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c  (``VT220'')
	    //   The VT100-style response parameters do not mean anything by
	    //   themselves.  VT220 parameters do, telling the host what fea-
	    //   tures the terminal supports:
	    //     Ps = 1  -> 132-columns.
	    //     Ps = 2  -> Printer.
	    //     Ps = 6  -> Selective erase.
	    //     Ps = 8  -> User-defined keys.
	    //     Ps = 9  -> National replacement character sets.
	    //     Ps = 1 5  -> Technical characters.
	    //     Ps = 2 2  -> ANSI color, e.g., VT525.
	    //     Ps = 2 9  -> ANSI text locator (i.e., DEC Locator mode).
	    // CSI > Ps c
	    //   Send Device Attributes (Secondary DA).
	    //     Ps = 0  or omitted -> request the terminal's identification
	    //     code.  The response depends on the decTerminalID resource set-
	    //     ting.  It should apply only to VT220 and up, but xterm extends
	    //     this to VT100.
	    //     -> CSI  > Pp ; Pv ; Pc c
	    //   where Pp denotes the terminal type
	    //     Pp = 0  -> ``VT100''.
	    //     Pp = 1  -> ``VT220''.
	    //   and Pv is the firmware version (for xterm, this was originally
	    //   the XFree86 patch number, starting with 95).  In a DEC termi-
	    //   nal, Pc indicates the ROM cartridge registration number and is
	    //   always zero.
	    // More information:
	    //   xterm/charproc.c - line 2012, for more information.
	    //   vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)
	    Terminal.prototype.sendDeviceAttributes = function(params) {
	      if (params[0] > 0) return;
	
	      if (!this.prefix) {
	        if (this.is('xterm')
	            || this.is('rxvt-unicode')
	            || this.is('screen')) {
	          this.send('\x1b[?1;2c');
	        } else if (this.is('linux')) {
	          this.send('\x1b[?6c');
	        }
	      } else if (this.prefix === '>') {
	        // xterm and urxvt
	        // seem to spit this
	        // out around ~370 times (?).
	        if (this.is('xterm')) {
	          this.send('\x1b[>0;276;0c');
	        } else if (this.is('rxvt-unicode')) {
	          this.send('\x1b[>85;95;0c');
	        } else if (this.is('linux')) {
	          // not supported by linux console.
	          // linux console echoes parameters.
	          this.send(params[0] + 'c');
	        } else if (this.is('screen')) {
	          this.send('\x1b[>83;40003;0c');
	        }
	      }
	    };
	
	    // CSI Pm d
	    // Line Position Absolute  [row] (default = [1,column]) (VPA).
	    Terminal.prototype.linePosAbsolute = function(params) {
	      var param = params[0];
	      if (param < 1) param = 1;
	      this.y = param - 1;
	      if (this.y >= this.rows) {
	        this.y = this.rows - 1;
	      }
	    };
	
	    // 145 65 e * VPR - Vertical Position Relative
	    // reuse CSI Ps B ?
	    Terminal.prototype.VPositionRelative = function(params) {
	      var param = params[0];
	      if (param < 1) param = 1;
	      this.y += param;
	      if (this.y >= this.rows) {
	        this.y = this.rows - 1;
	      }
	    };
	
	    // CSI Ps ; Ps f
	    //   Horizontal and Vertical Position [row;column] (default =
	    //   [1,1]) (HVP).
	    Terminal.prototype.HVPosition = function(params) {
	      if (params[0] < 1) params[0] = 1;
	      if (params[1] < 1) params[1] = 1;
	
	      this.y = params[0] - 1;
	      if (this.y >= this.rows) {
	        this.y = this.rows - 1;
	      }
	
	      this.x = params[1] - 1;
	      if (this.x >= this.cols) {
	        this.x = this.cols - 1;
	      }
	    };
	
	    // CSI Pm h  Set Mode (SM).
	    //     Ps = 2  -> Keyboard Action Mode (AM).
	    //     Ps = 4  -> Insert Mode (IRM).
	    //     Ps = 1 2  -> Send/receive (SRM).
	    //     Ps = 2 0  -> Automatic Newline (LNM).
	    // CSI ? Pm h
	    //   DEC Private Mode Set (DECSET).
	    //     Ps = 1  -> Application Cursor Keys (DECCKM).
	    //     Ps = 2  -> Designate USASCII for character sets G0-G3
	    //     (DECANM), and set VT100 mode.
	    //     Ps = 3  -> 132 Column Mode (DECCOLM).
	    //     Ps = 4  -> Smooth (Slow) Scroll (DECSCLM).
	    //     Ps = 5  -> Reverse Video (DECSCNM).
	    //     Ps = 6  -> Origin Mode (DECOM).
	    //     Ps = 7  -> Wraparound Mode (DECAWM).
	    //     Ps = 8  -> Auto-repeat Keys (DECARM).
	    //     Ps = 9  -> Send Mouse X & Y on button press.  See the sec-
	    //     tion Mouse Tracking.
	    //     Ps = 1 0  -> Show toolbar (rxvt).
	    //     Ps = 1 2  -> Start Blinking Cursor (att610).
	    //     Ps = 1 8  -> Print form feed (DECPFF).
	    //     Ps = 1 9  -> Set print extent to full screen (DECPEX).
	    //     Ps = 2 5  -> Show Cursor (DECTCEM).
	    //     Ps = 3 0  -> Show scrollbar (rxvt).
	    //     Ps = 3 5  -> Enable font-shifting functions (rxvt).
	    //     Ps = 3 8  -> Enter Tektronix Mode (DECTEK).
	    //     Ps = 4 0  -> Allow 80 -> 132 Mode.
	    //     Ps = 4 1  -> more(1) fix (see curses resource).
	    //     Ps = 4 2  -> Enable Nation Replacement Character sets (DECN-
	    //     RCM).
	    //     Ps = 4 4  -> Turn On Margin Bell.
	    //     Ps = 4 5  -> Reverse-wraparound Mode.
	    //     Ps = 4 6  -> Start Logging.  This is normally disabled by a
	    //     compile-time option.
	    //     Ps = 4 7  -> Use Alternate Screen Buffer.  (This may be dis-
	    //     abled by the titeInhibit resource).
	    //     Ps = 6 6  -> Application keypad (DECNKM).
	    //     Ps = 6 7  -> Backarrow key sends backspace (DECBKM).
	    //     Ps = 1 0 0 0  -> Send Mouse X & Y on button press and
	    //     release.  See the section Mouse Tracking.
	    //     Ps = 1 0 0 1  -> Use Hilite Mouse Tracking.
	    //     Ps = 1 0 0 2  -> Use Cell Motion Mouse Tracking.
	    //     Ps = 1 0 0 3  -> Use All Motion Mouse Tracking.
	    //     Ps = 1 0 0 4  -> Send FocusIn/FocusOut events.
	    //     Ps = 1 0 0 5  -> Enable Extended Mouse Mode.
	    //     Ps = 1 0 1 0  -> Scroll to bottom on tty output (rxvt).
	    //     Ps = 1 0 1 1  -> Scroll to bottom on key press (rxvt).
	    //     Ps = 1 0 3 4  -> Interpret "meta" key, sets eighth bit.
	    //     (enables the eightBitInput resource).
	    //     Ps = 1 0 3 5  -> Enable special modifiers for Alt and Num-
	    //     Lock keys.  (This enables the numLock resource).
	    //     Ps = 1 0 3 6  -> Send ESC   when Meta modifies a key.  (This
	    //     enables the metaSendsEscape resource).
	    //     Ps = 1 0 3 7  -> Send DEL from the editing-keypad Delete
	    //     key.
	    //     Ps = 1 0 3 9  -> Send ESC  when Alt modifies a key.  (This
	    //     enables the altSendsEscape resource).
	    //     Ps = 1 0 4 0  -> Keep selection even if not highlighted.
	    //     (This enables the keepSelection resource).
	    //     Ps = 1 0 4 1  -> Use the CLIPBOARD selection.  (This enables
	    //     the selectToClipboard resource).
	    //     Ps = 1 0 4 2  -> Enable Urgency window manager hint when
	    //     Control-G is received.  (This enables the bellIsUrgent
	    //     resource).
	    //     Ps = 1 0 4 3  -> Enable raising of the window when Control-G
	    //     is received.  (enables the popOnBell resource).
	    //     Ps = 1 0 4 7  -> Use Alternate Screen Buffer.  (This may be
	    //     disabled by the titeInhibit resource).
	    //     Ps = 1 0 4 8  -> Save cursor as in DECSC.  (This may be dis-
	    //     abled by the titeInhibit resource).
	    //     Ps = 1 0 4 9  -> Save cursor as in DECSC and use Alternate
	    //     Screen Buffer, clearing it first.  (This may be disabled by
	    //     the titeInhibit resource).  This combines the effects of the 1
	    //     0 4 7  and 1 0 4 8  modes.  Use this with terminfo-based
	    //     applications rather than the 4 7  mode.
	    //     Ps = 1 0 5 0  -> Set terminfo/termcap function-key mode.
	    //     Ps = 1 0 5 1  -> Set Sun function-key mode.
	    //     Ps = 1 0 5 2  -> Set HP function-key mode.
	    //     Ps = 1 0 5 3  -> Set SCO function-key mode.
	    //     Ps = 1 0 6 0  -> Set legacy keyboard emulation (X11R6).
	    //     Ps = 1 0 6 1  -> Set VT220 keyboard emulation.
	    //     Ps = 2 0 0 4  -> Set bracketed paste mode.
	    // Modes:
	    //   http://vt100.net/docs/vt220-rm/chapter4.html
	    Terminal.prototype.setMode = function(params) {
	      if (typeof params === 'object') {
	        var l = params.length
	          , i = 0;
	
	        for (; i < l; i++) {
	          this.setMode(params[i]);
	        }
	
	        return;
	      }
	
	      if (!this.prefix) {
	        switch (params) {
	          case 4:
	            this.insertMode = true;
	            break;
	          case 20:
	            //this.convertEol = true;
	            break;
	        }
	      } else if (this.prefix === '?') {
	        switch (params) {
	          case 1:
	            this.applicationCursor = true;
	            break;
	          case 2:
	            this.setgCharset(0, Terminal.charsets.US);
	            this.setgCharset(1, Terminal.charsets.US);
	            this.setgCharset(2, Terminal.charsets.US);
	            this.setgCharset(3, Terminal.charsets.US);
	            // set VT100 mode here
	            break;
	          case 3: // 132 col mode
	            this.savedCols = this.cols;
	            this.resize(132, this.rows);
	            break;
	          case 6:
	            this.originMode = true;
	            break;
	          case 7:
	            this.wraparoundMode = true;
	            break;
	          case 12:
	            // this.cursorBlink = true;
	            break;
	          case 66:
	            this.log('Serial port requested application keypad.');
	            this.applicationKeypad = true;
	            break;
	          case 9: // X10 Mouse
	            // no release, no motion, no wheel, no modifiers.
	          case 1000: // vt200 mouse
	            // no motion.
	            // no modifiers, except control on the wheel.
	          case 1002: // button event mouse
	          case 1003: // any event mouse
	            // any event - sends motion events,
	            // even if there is no button held down.
	            this.x10Mouse = params === 9;
	            this.vt200Mouse = params === 1000;
	            this.normalMouse = params > 1000;
	            this.mouseEvents = true;
	            this.element.style.cursor = 'default';
	            this.log('Binding to mouse events.');
	            break;
	          case 1004: // send focusin/focusout events
	            // focusin: ^[[I
	            // focusout: ^[[O
	            this.sendFocus = true;
	            break;
	          case 1005: // utf8 ext mode mouse
	            this.utfMouse = true;
	            // for wide terminals
	            // simply encodes large values as utf8 characters
	            break;
	          case 1006: // sgr ext mode mouse
	            this.sgrMouse = true;
	            // for wide terminals
	            // does not add 32 to fields
	            // press: ^[[<b;x;yM
	            // release: ^[[<b;x;ym
	            break;
	          case 1015: // urxvt ext mode mouse
	            this.urxvtMouse = true;
	            // for wide terminals
	            // numbers for fields
	            // press: ^[[b;x;yM
	            // motion: ^[[b;x;yT
	            break;
	          case 25: // show cursor
	            this.cursorHidden = false;
	            break;
	          case 1049: // alt screen buffer cursor
	            //this.saveCursor();
	            ; // FALL-THROUGH
	          case 47: // alt screen buffer
	          case 1047: // alt screen buffer
	            if (!this.normal) {
	              var normal = {
	                lines: this.lines,
	                ybase: this.ybase,
	                ydisp: this.ydisp,
	                x: this.x,
	                y: this.y,
	                scrollTop: this.scrollTop,
	                scrollBottom: this.scrollBottom,
	                tabs: this.tabs
	                // XXX save charset(s) here?
	                // charset: this.charset,
	                // glevel: this.glevel,
	                // charsets: this.charsets
	              };
	              this.reset();
	              this.normal = normal;
	              this.showCursor();
	            }
	            break;
	        }
	      }
	    };
	
	    // CSI Pm l  Reset Mode (RM).
	    //     Ps = 2  -> Keyboard Action Mode (AM).
	    //     Ps = 4  -> Replace Mode (IRM).
	    //     Ps = 1 2  -> Send/receive (SRM).
	    //     Ps = 2 0  -> Normal Linefeed (LNM).
	    // CSI ? Pm l
	    //   DEC Private Mode Reset (DECRST).
	    //     Ps = 1  -> Normal Cursor Keys (DECCKM).
	    //     Ps = 2  -> Designate VT52 mode (DECANM).
	    //     Ps = 3  -> 80 Column Mode (DECCOLM).
	    //     Ps = 4  -> Jump (Fast) Scroll (DECSCLM).
	    //     Ps = 5  -> Normal Video (DECSCNM).
	    //     Ps = 6  -> Normal Cursor Mode (DECOM).
	    //     Ps = 7  -> No Wraparound Mode (DECAWM).
	    //     Ps = 8  -> No Auto-repeat Keys (DECARM).
	    //     Ps = 9  -> Don't send Mouse X & Y on button press.
	    //     Ps = 1 0  -> Hide toolbar (rxvt).
	    //     Ps = 1 2  -> Stop Blinking Cursor (att610).
	    //     Ps = 1 8  -> Don't print form feed (DECPFF).
	    //     Ps = 1 9  -> Limit print to scrolling region (DECPEX).
	    //     Ps = 2 5  -> Hide Cursor (DECTCEM).
	    //     Ps = 3 0  -> Don't show scrollbar (rxvt).
	    //     Ps = 3 5  -> Disable font-shifting functions (rxvt).
	    //     Ps = 4 0  -> Disallow 80 -> 132 Mode.
	    //     Ps = 4 1  -> No more(1) fix (see curses resource).
	    //     Ps = 4 2  -> Disable Nation Replacement Character sets (DEC-
	    //     NRCM).
	    //     Ps = 4 4  -> Turn Off Margin Bell.
	    //     Ps = 4 5  -> No Reverse-wraparound Mode.
	    //     Ps = 4 6  -> Stop Logging.  (This is normally disabled by a
	    //     compile-time option).
	    //     Ps = 4 7  -> Use Normal Screen Buffer.
	    //     Ps = 6 6  -> Numeric keypad (DECNKM).
	    //     Ps = 6 7  -> Backarrow key sends delete (DECBKM).
	    //     Ps = 1 0 0 0  -> Don't send Mouse X & Y on button press and
	    //     release.  See the section Mouse Tracking.
	    //     Ps = 1 0 0 1  -> Don't use Hilite Mouse Tracking.
	    //     Ps = 1 0 0 2  -> Don't use Cell Motion Mouse Tracking.
	    //     Ps = 1 0 0 3  -> Don't use All Motion Mouse Tracking.
	    //     Ps = 1 0 0 4  -> Don't send FocusIn/FocusOut events.
	    //     Ps = 1 0 0 5  -> Disable Extended Mouse Mode.
	    //     Ps = 1 0 1 0  -> Don't scroll to bottom on tty output
	    //     (rxvt).
	    //     Ps = 1 0 1 1  -> Don't scroll to bottom on key press (rxvt).
	    //     Ps = 1 0 3 4  -> Don't interpret "meta" key.  (This disables
	    //     the eightBitInput resource).
	    //     Ps = 1 0 3 5  -> Disable special modifiers for Alt and Num-
	    //     Lock keys.  (This disables the numLock resource).
	    //     Ps = 1 0 3 6  -> Don't send ESC  when Meta modifies a key.
	    //     (This disables the metaSendsEscape resource).
	    //     Ps = 1 0 3 7  -> Send VT220 Remove from the editing-keypad
	    //     Delete key.
	    //     Ps = 1 0 3 9  -> Don't send ESC  when Alt modifies a key.
	    //     (This disables the altSendsEscape resource).
	    //     Ps = 1 0 4 0  -> Do not keep selection when not highlighted.
	    //     (This disables the keepSelection resource).
	    //     Ps = 1 0 4 1  -> Use the PRIMARY selection.  (This disables
	    //     the selectToClipboard resource).
	    //     Ps = 1 0 4 2  -> Disable Urgency window manager hint when
	    //     Control-G is received.  (This disables the bellIsUrgent
	    //     resource).
	    //     Ps = 1 0 4 3  -> Disable raising of the window when Control-
	    //     G is received.  (This disables the popOnBell resource).
	    //     Ps = 1 0 4 7  -> Use Normal Screen Buffer, clearing screen
	    //     first if in the Alternate Screen.  (This may be disabled by
	    //     the titeInhibit resource).
	    //     Ps = 1 0 4 8  -> Restore cursor as in DECRC.  (This may be
	    //     disabled by the titeInhibit resource).
	    //     Ps = 1 0 4 9  -> Use Normal Screen Buffer and restore cursor
	    //     as in DECRC.  (This may be disabled by the titeInhibit
	    //     resource).  This combines the effects of the 1 0 4 7  and 1 0
	    //     4 8  modes.  Use this with terminfo-based applications rather
	    //     than the 4 7  mode.
	    //     Ps = 1 0 5 0  -> Reset terminfo/termcap function-key mode.
	    //     Ps = 1 0 5 1  -> Reset Sun function-key mode.
	    //     Ps = 1 0 5 2  -> Reset HP function-key mode.
	    //     Ps = 1 0 5 3  -> Reset SCO function-key mode.
	    //     Ps = 1 0 6 0  -> Reset legacy keyboard emulation (X11R6).
	    //     Ps = 1 0 6 1  -> Reset keyboard emulation to Sun/PC style.
	    //     Ps = 2 0 0 4  -> Reset bracketed paste mode.
	    Terminal.prototype.resetMode = function(params) {
	      if (typeof params === 'object') {
	        var l = params.length
	          , i = 0;
	
	        for (; i < l; i++) {
	          this.resetMode(params[i]);
	        }
	
	        return;
	      }
	
	      if (!this.prefix) {
	        switch (params) {
	          case 4:
	            this.insertMode = false;
	            break;
	          case 20:
	            //this.convertEol = false;
	            break;
	        }
	      } else if (this.prefix === '?') {
	        switch (params) {
	          case 1:
	            this.applicationCursor = false;
	            break;
	          case 3:
	            if (this.cols === 132 && this.savedCols) {
	              this.resize(this.savedCols, this.rows);
	            }
	            delete this.savedCols;
	            break;
	          case 6:
	            this.originMode = false;
	            break;
	          case 7:
	            this.wraparoundMode = false;
	            break;
	          case 12:
	            // this.cursorBlink = false;
	            break;
	          case 66:
	            this.log('Switching back to normal keypad.');
	            this.applicationKeypad = false;
	            break;
	          case 9: // X10 Mouse
	          case 1000: // vt200 mouse
	          case 1002: // button event mouse
	          case 1003: // any event mouse
	            this.x10Mouse = false;
	            this.vt200Mouse = false;
	            this.normalMouse = false;
	            this.mouseEvents = false;
	            this.element.style.cursor = '';
	            break;
	          case 1004: // send focusin/focusout events
	            this.sendFocus = false;
	            break;
	          case 1005: // utf8 ext mode mouse
	            this.utfMouse = false;
	            break;
	          case 1006: // sgr ext mode mouse
	            this.sgrMouse = false;
	            break;
	          case 1015: // urxvt ext mode mouse
	            this.urxvtMouse = false;
	            break;
	          case 25: // hide cursor
	            this.cursorHidden = true;
	            break;
	          case 1049: // alt screen buffer cursor
	            ; // FALL-THROUGH
	          case 47: // normal screen buffer
	          case 1047: // normal screen buffer - clearing it first
	            if (this.normal) {
	              this.lines = this.normal.lines;
	              this.ybase = this.normal.ybase;
	              this.ydisp = this.normal.ydisp;
	              this.x = this.normal.x;
	              this.y = this.normal.y;
	              this.scrollTop = this.normal.scrollTop;
	              this.scrollBottom = this.normal.scrollBottom;
	              this.tabs = this.normal.tabs;
	              this.normal = null;
	              // if (params === 1049) {
	              //   this.x = this.savedX;
	              //   this.y = this.savedY;
	              // }
	              this.refresh(0, this.rows - 1);
	              this.showCursor();
	            }
	            break;
	        }
	      }
	    };
	
	    // CSI Ps ; Ps r
	    //   Set Scrolling Region [top;bottom] (default = full size of win-
	    //   dow) (DECSTBM).
	    // CSI ? Pm r
	    Terminal.prototype.setScrollRegion = function(params) {
	      if (this.prefix) return;
	      this.scrollTop = (params[0] || 1) - 1;
	      this.scrollBottom = (params[1] || this.rows) - 1;
	      this.x = 0;
	      this.y = 0;
	    };
	
	    // CSI s
	    //   Save cursor (ANSI.SYS).
	    Terminal.prototype.saveCursor = function(params) {
	      this.savedX = this.x;
	      this.savedY = this.y;
	    };
	
	    // CSI u
	    //   Restore cursor (ANSI.SYS).
	    Terminal.prototype.restoreCursor = function(params) {
	      this.x = this.savedX || 0;
	      this.y = this.savedY || 0;
	    };
	
	    /**
	     * Lesser Used
	     */
	
	    // CSI Ps I
	    //   Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).
	    Terminal.prototype.cursorForwardTab = function(params) {
	      var param = params[0] || 1;
	      while (param--) {
	        this.x = this.nextStop();
	      }
	    };
	
	    // CSI Ps S  Scroll up Ps lines (default = 1) (SU).
	    Terminal.prototype.scrollUp = function(params) {
	      var param = params[0] || 1;
	      while (param--) {
	        this.lines.splice(this.ybase + this.scrollTop, 1);
	        this.lines.splice(this.ybase + this.scrollBottom, 0, this.blankLine());
	      }
	      // this.maxRange();
	      this.updateRange(this.scrollTop);
	      this.updateRange(this.scrollBottom);
	    };
	
	    // CSI Ps T  Scroll down Ps lines (default = 1) (SD).
	    Terminal.prototype.scrollDown = function(params) {
	      var param = params[0] || 1;
	      while (param--) {
	        this.lines.splice(this.ybase + this.scrollBottom, 1);
	        this.lines.splice(this.ybase + this.scrollTop, 0, this.blankLine());
	      }
	      // this.maxRange();
	      this.updateRange(this.scrollTop);
	      this.updateRange(this.scrollBottom);
	    };
	
	    // CSI Ps ; Ps ; Ps ; Ps ; Ps T
	    //   Initiate highlight mouse tracking.  Parameters are
	    //   [func;startx;starty;firstrow;lastrow].  See the section Mouse
	    //   Tracking.
	    Terminal.prototype.initMouseTracking = function(params) {
	      // Relevant: DECSET 1001
	    };
	
	    // CSI > Ps; Ps T
	    //   Reset one or more features of the title modes to the default
	    //   value.  Normally, "reset" disables the feature.  It is possi-
	    //   ble to disable the ability to reset features by compiling a
	    //   different default for the title modes into xterm.
	    //     Ps = 0  -> Do not set window/icon labels using hexadecimal.
	    //     Ps = 1  -> Do not query window/icon labels using hexadeci-
	    //     mal.
	    //     Ps = 2  -> Do not set window/icon labels using UTF-8.
	    //     Ps = 3  -> Do not query window/icon labels using UTF-8.
	    //   (See discussion of "Title Modes").
	    Terminal.prototype.resetTitleModes = function(params) {
	      ;
	    };
	
	    // CSI Ps Z  Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).
	    Terminal.prototype.cursorBackwardTab = function(params) {
	      var param = params[0] || 1;
	      while (param--) {
	        this.x = this.prevStop();
	      }
	    };
	
	    // CSI Ps b  Repeat the preceding graphic character Ps times (REP).
	    Terminal.prototype.repeatPrecedingCharacter = function(params) {
	      var param = params[0] || 1
	        , line = this.lines[this.ybase + this.y]
	        , ch = line[this.x - 1] || [this.defAttr, ' '];
	
	      while (param--) line[this.x++] = ch;
	    };
	
	    // CSI Ps g  Tab Clear (TBC).
	    //     Ps = 0  -> Clear Current Column (default).
	    //     Ps = 3  -> Clear All.
	    // Potentially:
	    //   Ps = 2  -> Clear Stops on Line.
	    //   http://vt100.net/annarbor/aaa-ug/section6.html
	    Terminal.prototype.tabClear = function(params) {
	      var param = params[0];
	      if (param <= 0) {
	        delete this.tabs[this.x];
	      } else if (param === 3) {
	        this.tabs = {};
	      }
	    };
	
	    // CSI Pm i  Media Copy (MC).
	    //     Ps = 0  -> Print screen (default).
	    //     Ps = 4  -> Turn off printer controller mode.
	    //     Ps = 5  -> Turn on printer controller mode.
	    // CSI ? Pm i
	    //   Media Copy (MC, DEC-specific).
	    //     Ps = 1  -> Print line containing cursor.
	    //     Ps = 4  -> Turn off autoprint mode.
	    //     Ps = 5  -> Turn on autoprint mode.
	    //     Ps = 1  0  -> Print composed display, ignores DECPEX.
	    //     Ps = 1  1  -> Print all pages.
	    Terminal.prototype.mediaCopy = function(params) {
	      ;
	    };
	
	    // CSI > Ps; Ps m
	    //   Set or reset resource-values used by xterm to decide whether
	    //   to construct escape sequences holding information about the
	    //   modifiers pressed with a given key.  The first parameter iden-
	    //   tifies the resource to set/reset.  The second parameter is the
	    //   value to assign to the resource.  If the second parameter is
	    //   omitted, the resource is reset to its initial value.
	    //     Ps = 1  -> modifyCursorKeys.
	    //     Ps = 2  -> modifyFunctionKeys.
	    //     Ps = 4  -> modifyOtherKeys.
	    //   If no parameters are given, all resources are reset to their
	    //   initial values.
	    Terminal.prototype.setResources = function(params) {
	      ;
	    };
	
	    // CSI > Ps n
	    //   Disable modifiers which may be enabled via the CSI > Ps; Ps m
	    //   sequence.  This corresponds to a resource value of "-1", which
	    //   cannot be set with the other sequence.  The parameter identi-
	    //   fies the resource to be disabled:
	    //     Ps = 1  -> modifyCursorKeys.
	    //     Ps = 2  -> modifyFunctionKeys.
	    //     Ps = 4  -> modifyOtherKeys.
	    //   If the parameter is omitted, modifyFunctionKeys is disabled.
	    //   When modifyFunctionKeys is disabled, xterm uses the modifier
	    //   keys to make an extended sequence of functions rather than
	    //   adding a parameter to each function key to denote the modi-
	    //   fiers.
	    Terminal.prototype.disableModifiers = function(params) {
	      ;
	    };
	
	    // CSI > Ps p
	    //   Set resource value pointerMode.  This is used by xterm to
	    //   decide whether to hide the pointer cursor as the user types.
	    //   Valid values for the parameter:
	    //     Ps = 0  -> never hide the pointer.
	    //     Ps = 1  -> hide if the mouse tracking mode is not enabled.
	    //     Ps = 2  -> always hide the pointer.  If no parameter is
	    //     given, xterm uses the default, which is 1 .
	    Terminal.prototype.setPointerMode = function(params) {
	      ;
	    };
	
	    // CSI ! p   Soft terminal reset (DECSTR).
	    // http://vt100.net/docs/vt220-rm/table4-10.html
	    Terminal.prototype.softReset = function(params) {
	      this.cursorHidden = false;
	      this.insertMode = false;
	      this.originMode = false;
	      this.wraparoundMode = false; // autowrap
	      this.applicationKeypad = false; // ?
	      this.applicationCursor = false;
	      this.scrollTop = 0;
	      this.scrollBottom = this.rows - 1;
	      this.curAttr = this.defAttr;
	      this.x = this.y = 0; // ?
	      this.charset = null;
	      this.glevel = 0; // ??
	      this.charsets = [null]; // ??
	    };
	
	    // CSI Ps$ p
	    //   Request ANSI mode (DECRQM).  For VT300 and up, reply is
	    //     CSI Ps; Pm$ y
	    //   where Ps is the mode number as in RM, and Pm is the mode
	    //   value:
	    //     0 - not recognized
	    //     1 - set
	    //     2 - reset
	    //     3 - permanently set
	    //     4 - permanently reset
	    Terminal.prototype.requestAnsiMode = function(params) {
	      ;
	    };
	
	    // CSI ? Ps$ p
	    //   Request DEC private mode (DECRQM).  For VT300 and up, reply is
	    //     CSI ? Ps; Pm$ p
	    //   where Ps is the mode number as in DECSET, Pm is the mode value
	    //   as in the ANSI DECRQM.
	    Terminal.prototype.requestPrivateMode = function(params) {
	      ;
	    };
	
	    // CSI Ps ; Ps " p
	    //   Set conformance level (DECSCL).  Valid values for the first
	    //   parameter:
	    //     Ps = 6 1  -> VT100.
	    //     Ps = 6 2  -> VT200.
	    //     Ps = 6 3  -> VT300.
	    //   Valid values for the second parameter:
	    //     Ps = 0  -> 8-bit controls.
	    //     Ps = 1  -> 7-bit controls (always set for VT100).
	    //     Ps = 2  -> 8-bit controls.
	    Terminal.prototype.setConformanceLevel = function(params) {
	      ;
	    };
	
	    // CSI Ps q  Load LEDs (DECLL).
	    //     Ps = 0  -> Clear all LEDS (default).
	    //     Ps = 1  -> Light Num Lock.
	    //     Ps = 2  -> Light Caps Lock.
	    //     Ps = 3  -> Light Scroll Lock.
	    //     Ps = 2  1  -> Extinguish Num Lock.
	    //     Ps = 2  2  -> Extinguish Caps Lock.
	    //     Ps = 2  3  -> Extinguish Scroll Lock.
	    Terminal.prototype.loadLEDs = function(params) {
	      ;
	    };
	
	    // CSI Ps SP q
	    //   Set cursor style (DECSCUSR, VT520).
	    //     Ps = 0  -> blinking block.
	    //     Ps = 1  -> blinking block (default).
	    //     Ps = 2  -> steady block.
	    //     Ps = 3  -> blinking underline.
	    //     Ps = 4  -> steady underline.
	    Terminal.prototype.setCursorStyle = function(params) {
	      ;
	    };
	
	    // CSI Ps " q
	    //   Select character protection attribute (DECSCA).  Valid values
	    //   for the parameter:
	    //     Ps = 0  -> DECSED and DECSEL can erase (default).
	    //     Ps = 1  -> DECSED and DECSEL cannot erase.
	    //     Ps = 2  -> DECSED and DECSEL can erase.
	    Terminal.prototype.setCharProtectionAttr = function(params) {
	      ;
	    };
	
	    // CSI ? Pm r
	    //   Restore DEC Private Mode Values.  The value of Ps previously
	    //   saved is restored.  Ps values are the same as for DECSET.
	    Terminal.prototype.restorePrivateValues = function(params) {
	      ;
	    };
	
	    // CSI Pt; Pl; Pb; Pr; Ps$ r
	    //   Change Attributes in Rectangular Area (DECCARA), VT400 and up.
	    //     Pt; Pl; Pb; Pr denotes the rectangle.
	    //     Ps denotes the SGR attributes to change: 0, 1, 4, 5, 7.
	    // NOTE: xterm doesn't enable this code by default.
	    Terminal.prototype.setAttrInRectangle = function(params) {
	      var t = params[0]
	        , l = params[1]
	        , b = params[2]
	        , r = params[3]
	        , attr = params[4];
	
	      var line
	        , i;
	
	      for (; t < b + 1; t++) {
	        line = this.lines[this.ybase + t];
	        for (i = l; i < r; i++) {
	          line[i] = [attr, line[i][1]];
	        }
	      }
	
	      // this.maxRange();
	      this.updateRange(params[0]);
	      this.updateRange(params[2]);
	    };
	
	
	    // CSI Pc; Pt; Pl; Pb; Pr$ x
	    //   Fill Rectangular Area (DECFRA), VT420 and up.
	    //     Pc is the character to use.
	    //     Pt; Pl; Pb; Pr denotes the rectangle.
	    // NOTE: xterm doesn't enable this code by default.
	    Terminal.prototype.fillRectangle = function(params) {
	      var ch = params[0]
	        , t = params[1]
	        , l = params[2]
	        , b = params[3]
	        , r = params[4];
	
	      var line
	        , i;
	
	      for (; t < b + 1; t++) {
	        line = this.lines[this.ybase + t];
	        for (i = l; i < r; i++) {
	          line[i] = [line[i][0], String.fromCharCode(ch)];
	        }
	      }
	
	      // this.maxRange();
	      this.updateRange(params[1]);
	      this.updateRange(params[3]);
	    };
	
	    // CSI Ps ; Pu ' z
	    //   Enable Locator Reporting (DECELR).
	    //   Valid values for the first parameter:
	    //     Ps = 0  -> Locator disabled (default).
	    //     Ps = 1  -> Locator enabled.
	    //     Ps = 2  -> Locator enabled for one report, then disabled.
	    //   The second parameter specifies the coordinate unit for locator
	    //   reports.
	    //   Valid values for the second parameter:
	    //     Pu = 0  <- or omitted -> default to character cells.
	    //     Pu = 1  <- device physical pixels.
	    //     Pu = 2  <- character cells.
	    Terminal.prototype.enableLocatorReporting = function(params) {
	      var val = params[0] > 0;
	      //this.mouseEvents = val;
	      //this.decLocator = val;
	    };
	
	    // CSI Pt; Pl; Pb; Pr$ z
	    //   Erase Rectangular Area (DECERA), VT400 and up.
	    //     Pt; Pl; Pb; Pr denotes the rectangle.
	    // NOTE: xterm doesn't enable this code by default.
	    Terminal.prototype.eraseRectangle = function(params) {
	      var t = params[0]
	        , l = params[1]
	        , b = params[2]
	        , r = params[3];
	
	      var line
	        , i
	        , ch;
	
	      ch = [this.eraseAttr(), ' ']; // xterm?
	
	      for (; t < b + 1; t++) {
	        line = this.lines[this.ybase + t];
	        for (i = l; i < r; i++) {
	          line[i] = ch;
	        }
	      }
	
	      // this.maxRange();
	      this.updateRange(params[0]);
	      this.updateRange(params[2]);
	    };
	
	
	    // CSI P m SP }
	    // Insert P s Column(s) (default = 1) (DECIC), VT420 and up.
	    // NOTE: xterm doesn't enable this code by default.
	    Terminal.prototype.insertColumns = function() {
	      var param = params[0]
	        , l = this.ybase + this.rows
	        , ch = [this.eraseAttr(), ' '] // xterm?
	        , i;
	
	      while (param--) {
	        for (i = this.ybase; i < l; i++) {
	          this.lines[i].splice(this.x + 1, 0, ch);
	          this.lines[i].pop();
	        }
	      }
	
	      this.maxRange();
	    };
	
	    // CSI P m SP ~
	    // Delete P s Column(s) (default = 1) (DECDC), VT420 and up
	    // NOTE: xterm doesn't enable this code by default.
	    Terminal.prototype.deleteColumns = function() {
	      var param = params[0]
	        , l = this.ybase + this.rows
	        , ch = [this.eraseAttr(), ' '] // xterm?
	        , i;
	
	      while (param--) {
	        for (i = this.ybase; i < l; i++) {
	          this.lines[i].splice(this.x, 1);
	          this.lines[i].push(ch);
	        }
	      }
	
	      this.maxRange();
	    };
	
	
	    Terminal.prototype.copyBuffer = function(lines) {
	      var lines = lines || this.lines
	        , out = [];
	
	      for (var y = 0; y < lines.length; y++) {
	        out[y] = [];
	        for (var x = 0; x < lines[y].length; x++) {
	          out[y][x] = [lines[y][x][0], lines[y][x][1]];
	        }
	      }
	
	      return out;
	    };
	
	    Terminal.prototype.getCopyTextarea = function(text) {
	      var textarea = this._copyTextarea
	        , document = this.document;
	
	      if (!textarea) {
	        textarea = document.createElement('textarea');
	        textarea.style.position = 'absolute';
	        textarea.style.left = '-32000px';
	        textarea.style.top = '-32000px';
	        textarea.style.width = '0px';
	        textarea.style.height = '0px';
	        textarea.style.opacity = '0';
	        textarea.style.backgroundColor = 'transparent';
	        textarea.style.borderStyle = 'none';
	        textarea.style.outlineStyle = 'none';
	
	        document.getElementsByTagName('body')[0].appendChild(textarea);
	
	        this._copyTextarea = textarea;
	      }
	
	      return textarea;
	    };
	
	    // NOTE: Only works for primary selection on X11.
	    // Non-X11 users should use Ctrl-C instead.
	    Terminal.prototype.copyText = function(text) {
	      var self = this
	        , textarea = this.getCopyTextarea();
	
	      this.emit('copy', text);
	
	      textarea.focus();
	      textarea.textContent = text;
	      textarea.value = text;
	      textarea.setSelectionRange(0, text.length);
	
	      setTimeout(function() {
	        self.element.focus();
	        self.focus();
	      }, 1);
	    };
	
	    Terminal.prototype.keyPrefix = function(ev, key) {
	      if (key === 'k' || key === '&') {
	        this.destroy();
	      } else if (key === 'p' || key === ']') {
	        this.emit('request paste');
	      } else if (key === 'c') {
	        this.emit('request create');
	      } else if (key >= '0' && key <= '9') {
	        key = +key - 1;
	        if (!~key) key = 9;
	        this.emit('request term', key);
	      } else if (key === 'n') {
	        this.emit('request term next');
	      } else if (key === 'P') {
	        this.emit('request term previous');
	      } else if (key === ':') {
	        this.emit('request command mode');
	      }
	    };
	
	    Terminal.prototype.keySelect = function(ev, key) {
	      this.showCursor();
	
	      if (key === '\x04') { // ctrl-d
	        var y = this.ydisp + this.y;
	        if (this.ydisp === this.ybase) {
	          // Mimic vim behavior
	          this.y = Math.min(this.y + (this.rows - 1) / 2 | 0, this.rows - 1);
	          this.refresh(0, this.rows - 1);
	        } else {
	          this.scrollDisp((this.rows - 1) / 2 | 0);
	        }
	        return;
	      }
	
	      if (key === '\x15') { // ctrl-u
	        var y = this.ydisp + this.y;
	        if (this.ydisp === 0) {
	          // Mimic vim behavior
	          this.y = Math.max(this.y - (this.rows - 1) / 2 | 0, 0);
	          this.refresh(0, this.rows - 1);
	        } else {
	          this.scrollDisp(-(this.rows - 1) / 2 | 0);
	        }
	        return;
	      }
	
	      if (key === '\x06') { // ctrl-f
	        var y = this.ydisp + this.y;
	        this.scrollDisp(this.rows - 1);
	        return;
	      }
	
	      if (key === '\x02') { // ctrl-b
	        var y = this.ydisp + this.y;
	        this.scrollDisp(-(this.rows - 1));
	        return;
	      }
	
	      if (key === 'k' || key === '\x1b[A') {
	        var y = this.ydisp + this.y;
	        this.y--;
	        if (this.y < 0) {
	          this.y = 0;
	          this.scrollDisp(-1);
	        }
	        this.refresh(this.y, this.y + 1);
	        return;
	      }
	
	      if (key === 'j' || key === '\x1b[B') {
	        var y = this.ydisp + this.y;
	        this.y++;
	        if (this.y >= this.rows) {
	          this.y = this.rows - 1;
	          this.scrollDisp(1);
	        }
	        this.refresh(this.y - 1, this.y);
	        return;
	      }
	
	      if (key === 'h' || key === '\x1b[D') {
	        var x = this.x;
	        this.x--;
	        if (this.x < 0) {
	          this.x = 0;
	        }
	        this.refresh(this.y, this.y);
	        return;
	      }
	
	      if (key === 'l' || key === '\x1b[C') {
	        var x = this.x;
	        this.x++;
	        if (this.x >= this.cols) {
	          this.x = this.cols - 1;
	        }
	        this.refresh(this.y, this.y);
	        return;
	      }
	
	      if (key === 'w' || key === 'W') {
	        var ox = this.x;
	        var oy = this.y;
	        var oyd = this.ydisp;
	
	        var x = this.x;
	        var y = this.y;
	        var yb = this.ydisp;
	        var saw_space = false;
	
	        for (;;) {
	          var line = this.lines[yb + y];
	          while (x < this.cols) {
	            if (line[x][1] <= ' ') {
	              saw_space = true;
	            } else if (saw_space) {
	              break;
	            }
	            x++;
	          }
	          if (x >= this.cols) x = this.cols - 1;
	          if (x === this.cols - 1 && line[x][1] <= ' ') {
	            x = 0;
	            if (++y >= this.rows) {
	              y--;
	              if (++yb > this.ybase) {
	                yb = this.ybase;
	                x = this.x;
	                break;
	              }
	            }
	            continue;
	          }
	          break;
	        }
	
	        this.x = x, this.y = y;
	        this.scrollDisp(-this.ydisp + yb);
	
	        return;
	      }
	
	      if (key === 'b' || key === 'B') {
	        var ox = this.x;
	        var oy = this.y;
	        var oyd = this.ydisp;
	
	        var x = this.x;
	        var y = this.y;
	        var yb = this.ydisp;
	
	        for (;;) {
	          var line = this.lines[yb + y];
	          var saw_space = x > 0 && line[x][1] > ' ' && line[x - 1][1] > ' ';
	          while (x >= 0) {
	            if (line[x][1] <= ' ') {
	              if (saw_space && (x + 1 < this.cols && line[x + 1][1] > ' ')) {
	                x++;
	                break;
	              } else {
	                saw_space = true;
	              }
	            }
	            x--;
	          }
	          if (x < 0) x = 0;
	          if (x === 0 && (line[x][1] <= ' ' || !saw_space)) {
	            x = this.cols - 1;
	            if (--y < 0) {
	              y++;
	              if (--yb < 0) {
	                yb++;
	                x = 0;
	                break;
	              }
	            }
	            continue;
	          }
	          break;
	        }
	
	        this.x = x, this.y = y;
	        this.scrollDisp(-this.ydisp + yb);
	
	        return;
	      }
	
	      if (key === 'e' || key === 'E') {
	        var x = this.x + 1;
	        var y = this.y;
	        var yb = this.ydisp;
	        if (x >= this.cols) x--;
	
	        for (;;) {
	          var line = this.lines[yb + y];
	          while (x < this.cols) {
	            if (line[x][1] <= ' ') {
	              x++;
	            } else {
	              break;
	            }
	          }
	          while (x < this.cols) {
	            if (line[x][1] <= ' ') {
	              if (x - 1 >= 0 && line[x - 1][1] > ' ') {
	                x--;
	                break;
	              }
	            }
	            x++;
	          }
	          if (x >= this.cols) x = this.cols - 1;
	          if (x === this.cols - 1 && line[x][1] <= ' ') {
	            x = 0;
	            if (++y >= this.rows) {
	              y--;
	              if (++yb > this.ybase) {
	                yb = this.ybase;
	                break;
	              }
	            }
	            continue;
	          }
	          break;
	        }
	
	        this.x = x, this.y = y;
	        this.scrollDisp(-this.ydisp + yb);
	
	        return;
	      }
	
	      if (key === '^' || key === '0') {
	        var ox = this.x;
	
	        if (key === '0') {
	          this.x = 0;
	        } else if (key === '^') {
	          var line = this.lines[this.ydisp + this.y];
	          var x = 0;
	          while (x < this.cols) {
	            if (line[x][1] > ' ') {
	              break;
	            }
	            x++;
	          }
	          if (x >= this.cols) x = this.cols - 1;
	          this.x = x;
	        }
	
	        this.refresh(this.y, this.y);
	        return;
	      }
	
	      if (key === '$') {
	        var ox = this.x;
	        var line = this.lines[this.ydisp + this.y];
	        var x = this.cols - 1;
	        while (x >= 0) {
	          x--;
	        }
	        if (x < 0) x = 0;
	        this.x = x;
	        this.refresh(this.y, this.y);
	        return;
	      }
	
	      if (key === 'g' || key === 'G') {
	        var ox = this.x;
	        var oy = this.y;
	        var oyd = this.ydisp;
	        if (key === 'g') {
	          this.x = 0, this.y = 0;
	          this.scrollDisp(-this.ydisp);
	        } else if (key === 'G') {
	          this.x = 0, this.y = this.rows - 1;
	          this.scrollDisp(this.ybase);
	        }
	        return;
	      }
	
	      if (key === 'H' || key === 'M' || key === 'L') {
	        var ox = this.x;
	        var oy = this.y;
	        if (key === 'H') {
	          this.x = 0, this.y = 0;
	        } else if (key === 'M') {
	          this.x = 0, this.y = this.rows / 2 | 0;
	        } else if (key === 'L') {
	          this.x = 0, this.y = this.rows - 1;
	        }
	        this.refresh(oy, oy);
	        this.refresh(this.y, this.y);
	        return;
	      }
	
	      if (key === '{' || key === '}') {
	        var ox = this.x;
	        var oy = this.y;
	        var oyd = this.ydisp;
	
	        var line;
	        var saw_full = false;
	        var found = false;
	        var first_is_space = -1;
	        var y = this.y + (key === '{' ? -1 : 1);
	        var yb = this.ydisp;
	        var i;
	
	        if (key === '{') {
	          if (y < 0) {
	            y++;
	            if (yb > 0) yb--;
	          }
	        } else if (key === '}') {
	          if (y >= this.rows) {
	            y--;
	            if (yb < this.ybase) yb++;
	          }
	        }
	
	        for (;;) {
	          line = this.lines[yb + y];
	
	          for (i = 0; i < this.cols; i++) {
	            if (line[i][1] > ' ') {
	              if (first_is_space === -1) {
	                first_is_space = 0;
	              }
	              saw_full = true;
	              break;
	            } else if (i === this.cols - 1) {
	              if (first_is_space === -1) {
	                first_is_space = 1;
	              } else if (first_is_space === 0) {
	                found = true;
	              } else if (first_is_space === 1) {
	                if (saw_full) found = true;
	              }
	              break;
	            }
	          }
	
	          if (found) break;
	
	          if (key === '{') {
	            y--;
	            if (y < 0) {
	              y++;
	              if (yb > 0) yb--;
	              else break;
	            }
	          } else if (key === '}') {
	            y++;
	            if (y >= this.rows) {
	              y--;
	              if (yb < this.ybase) yb++;
	              else break;
	            }
	          }
	        }
	
	        if (!found) {
	          if (key === '{') {
	            y = 0;
	            yb = 0;
	          } else if (key === '}') {
	            y = this.rows - 1;
	            yb = this.ybase;
	          }
	        }
	
	        this.x = 0, this.y = y;
	        this.scrollDisp(-this.ydisp + yb);
	
	        return;
	      }
	
	      return false;
	    };
	
	    /**
	     * Character Sets
	     */
	
	    Terminal.charsets = {};
	
	    // DEC Special Character and Line Drawing Set.
	    // http://vt100.net/docs/vt102-ug/table5-13.html
	    // A lot of curses apps use this if they see TERM=xterm.
	    // testing: echo -e '\e(0a\e(B'
	    // The xterm output sometimes seems to conflict with the
	    // reference above. xterm seems in line with the reference
	    // when running vttest however.
	    // The table below now uses xterm's output from vttest.
	    Terminal.charsets.SCLD = { // (0
	      '`': '\u25c6', // '◆'
	      'a': '\u2592', // '▒'
	      'b': '\u0009', // '\t'
	      'c': '\u000c', // '\f'
	      'd': '\u000d', // '\r'
	      'e': '\u000a', // '\n'
	      'f': '\u00b0', // '°'
	      'g': '\u00b1', // '±'
	      'h': '\u2424', // '\u2424' (NL)
	      'i': '\u000b', // '\v'
	      'j': '\u2518', // '┘'
	      'k': '\u2510', // '┐'
	      'l': '\u250c', // '┌'
	      'm': '\u2514', // '└'
	      'n': '\u253c', // '┼'
	      'o': '\u23ba', // '⎺'
	      'p': '\u23bb', // '⎻'
	      'q': '\u2500', // '─'
	      'r': '\u23bc', // '⎼'
	      's': '\u23bd', // '⎽'
	      't': '\u251c', // '├'
	      'u': '\u2524', // '┤'
	      'v': '\u2534', // '┴'
	      'w': '\u252c', // '┬'
	      'x': '\u2502', // '│'
	      'y': '\u2264', // '≤'
	      'z': '\u2265', // '≥'
	      '{': '\u03c0', // 'π'
	      '|': '\u2260', // '≠'
	      '}': '\u00a3', // '£'
	      '~': '\u00b7'  // '·'
	    };
	
	    Terminal.charsets.UK = null; // (A
	    Terminal.charsets.US = null; // (B (USASCII)
	    Terminal.charsets.Dutch = null; // (4
	    Terminal.charsets.Finnish = null; // (C or (5
	    Terminal.charsets.French = null; // (R
	    Terminal.charsets.FrenchCanadian = null; // (Q
	    Terminal.charsets.German = null; // (K
	    Terminal.charsets.Italian = null; // (Y
	    Terminal.charsets.NorwegianDanish = null; // (E or (6
	    Terminal.charsets.Spanish = null; // (Z
	    Terminal.charsets.Swedish = null; // (H or (7
	    Terminal.charsets.Swiss = null; // (=
	    Terminal.charsets.ISOLatin = null; // /A
	
	    /**
	     * Helpers
	     */
	
	    function on(el, type, handler, capture) {
	      if (!Array.isArray(el)) {
	        el = [el];
	      }
	      el.forEach(function (element) {
	        element.addEventListener(type, handler, capture || false);
	      });
	    }
	
	    function off(el, type, handler, capture) {
	      el.removeEventListener(type, handler, capture || false);
	    }
	
	    function cancel(ev, force) {
	      if (!this.cancelEvents && !force) {
	        return;
	      }
	      ev.preventDefault();
	      ev.stopPropagation();
	      return false;
	    }
	
	    function inherits(child, parent) {
	      function f() {
	        this.constructor = child;
	      }
	      f.prototype = parent.prototype;
	      child.prototype = new f;
	    }
	
	    // if bold is broken, we can't
	    // use it in the terminal.
	    function isBoldBroken(document) {
	      var body = document.getElementsByTagName('body')[0];
	      var el = document.createElement('span');
	      el.innerHTML = 'hello world';
	      body.appendChild(el);
	      var w1 = el.scrollWidth;
	      el.style.fontWeight = 'bold';
	      var w2 = el.scrollWidth;
	      body.removeChild(el);
	      return w1 !== w2;
	    }
	
	    var String = this.String;
	    var setTimeout = this.setTimeout;
	    var setInterval = this.setInterval;
	
	    function indexOf(obj, el) {
	      var i = obj.length;
	      while (i--) {
	        if (obj[i] === el) return i;
	      }
	      return -1;
	    }
	
	    function isWide(ch) {
	      if (ch <= '\uff00') return false;
	      return (ch >= '\uff01' && ch <= '\uffbe')
	          || (ch >= '\uffc2' && ch <= '\uffc7')
	          || (ch >= '\uffca' && ch <= '\uffcf')
	          || (ch >= '\uffd2' && ch <= '\uffd7')
	          || (ch >= '\uffda' && ch <= '\uffdc')
	          || (ch >= '\uffe0' && ch <= '\uffe6')
	          || (ch >= '\uffe8' && ch <= '\uffee');
	    }
	
	    function matchColor(r1, g1, b1) {
	      var hash = (r1 << 16) | (g1 << 8) | b1;
	
	      if (matchColor._cache[hash] != null) {
	        return matchColor._cache[hash];
	      }
	
	      var ldiff = Infinity
	        , li = -1
	        , i = 0
	        , c
	        , r2
	        , g2
	        , b2
	        , diff;
	
	      for (; i < Terminal.vcolors.length; i++) {
	        c = Terminal.vcolors[i];
	        r2 = c[0];
	        g2 = c[1];
	        b2 = c[2];
	
	        diff = matchColor.distance(r1, g1, b1, r2, g2, b2);
	
	        if (diff === 0) {
	          li = i;
	          break;
	        }
	
	        if (diff < ldiff) {
	          ldiff = diff;
	          li = i;
	        }
	      }
	
	      return matchColor._cache[hash] = li;
	    }
	
	    matchColor._cache = {};
	
	    // http://stackoverflow.com/questions/1633828
	    matchColor.distance = function(r1, g1, b1, r2, g2, b2) {
	      return Math.pow(30 * (r1 - r2), 2)
	        + Math.pow(59 * (g1 - g2), 2)
	        + Math.pow(11 * (b1 - b2), 2);
	    };
	
	    function each(obj, iter, con) {
	      if (obj.forEach) return obj.forEach(iter, con);
	      for (var i = 0; i < obj.length; i++) {
	        iter.call(con, obj[i], i, obj);
	      }
	    }
	
	    function keys(obj) {
	      if (Object.keys) return Object.keys(obj);
	      var key, keys = [];
	      for (key in obj) {
	        if (Object.prototype.hasOwnProperty.call(obj, key)) {
	          keys.push(key);
	        }
	      }
	      return keys;
	    }
	
	    /**
	     * Expose
	     */
	
	    Terminal.EventEmitter = EventEmitter;
	    Terminal.inherits = inherits;
	    Terminal.on = on;
	    Terminal.off = off;
	    Terminal.cancel = cancel;
	
	    return Terminal;
	});


/***/ },
/* 422 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var docmanager_1 = __webpack_require__(274);
	var phosphor_disposable_1 = __webpack_require__(8);
	var index_1 = __webpack_require__(423);
	var WIDGET_MIMETYPE = 'application/vnd.jupyter.widget';
	/**
	 * The widget manager provider.
	 */
	exports.widgetManagerExtension = {
	    id: 'jupyter.extensions.widgetManager',
	    requires: [docmanager_1.DocumentRegistry],
	    activate: activateWidgetExtension
	};
	var IPyWidgetExtension = (function () {
	    function IPyWidgetExtension() {
	    }
	    /**
	     * Create a new extension object.
	     */
	    IPyWidgetExtension.prototype.createNew = function (nb, model, context) {
	        var wManager = new index_1.WidgetManager(context);
	        var wRenderer = new index_1.WidgetRenderer(wManager);
	        nb.content.rendermime.addRenderer(WIDGET_MIMETYPE, wRenderer, 0);
	        return new phosphor_disposable_1.DisposableDelegate(function () {
	            nb.content.rendermime.removeRenderer(WIDGET_MIMETYPE);
	            wRenderer.dispose();
	            wManager.dispose();
	        });
	    };
	    return IPyWidgetExtension;
	}());
	exports.IPyWidgetExtension = IPyWidgetExtension;
	/**
	 * Activate the widget extension.
	 */
	function activateWidgetExtension(app, registry) {
	    registry.registerExtension('Notebook', new IPyWidgetExtension());
	}


/***/ },
/* 423 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var jupyter_js_widgets_1 = __webpack_require__(424);
	var phosphor_panel_1 = __webpack_require__(18);
	var phosphor_widget_1 = __webpack_require__(20);
	__webpack_require__(452);
	__webpack_require__(468);
	/**
	 * The class name added to an BackboneViewWrapper widget.
	 */
	var BACKBONEVIEWWRAPPER_CLASS = 'jp-BackboneViewWrapper';
	/**
	 * A phosphor widget which wraps a `Backbone` view instance.
	 */
	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 = this;
	        _super.call(this);
	        view.on('remove', function () {
	            _this.dispose();
	            console.log('View removed', view);
	        });
	        this.addClass(BACKBONEVIEWWRAPPER_CLASS);
	        this.node.appendChild(view.el);
	    }
	    return BackboneViewWrapper;
	}(phosphor_widget_1.Widget));
	exports.BackboneViewWrapper = BackboneViewWrapper;
	/**
	 * A widget manager that returns phosphor widgets.
	 */
	var WidgetManager = (function (_super) {
	    __extends(WidgetManager, _super);
	    function WidgetManager(context) {
	        var _this = this;
	        _super.call(this);
	        this._context = context;
	        var newKernel = function (kernel) {
	            if (_this._commRegistration) {
	                _this._commRegistration.dispose();
	            }
	            _this._commRegistration = kernel.registerCommTarget(_this.comm_target_name, function (comm, msg) { _this.handle_comm_open(comm, msg); });
	        };
	        context.kernelChanged.connect(function (sender, kernel) {
	            _this.validateVersion();
	            newKernel(kernel);
	        });
	        if (context.kernel) {
	            this.validateVersion();
	            newKernel(context.kernel);
	        }
	    }
	    /**
	     * Return a phosphor widget representing the view
	     */
	    WidgetManager.prototype.display_view = function (msg, view, options) {
	        return new BackboneViewWrapper(view);
	    };
	    /**
	     * Handle when a comm is opened.
	     */
	    WidgetManager.prototype.handle_comm_open = function (comm, msg) {
	        // Convert jupyter-js-services comm to old comm
	        // so that widget models use it compatibly
	        var oldComm = new jupyter_js_widgets_1.shims.services.Comm(comm);
	        return _super.prototype.handle_comm_open.call(this, oldComm, msg);
	    };
	    /**
	     * Create a comm.
	     */
	    WidgetManager.prototype._create_comm = function (target_name, model_id, data) {
	        var comm = this._context.kernel.connectToComm(target_name, model_id);
	        comm.open(); // should we open it???
	        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.kernel.commInfo({ target: 'jupyter.widget' }).then(function (reply) {
	            return reply.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;
	    };
	    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'];
	        this._manager = widgetManager;
	    }
	    /**
	     * Render a widget mimetype.
	     */
	    WidgetRenderer.prototype.render = function (mimetype, data) {
	        var _this = this;
	        // data is a model id
	        var w = new phosphor_panel_1.Panel();
	        this._manager.get_model(data).then(function (model) {
	            return _this._manager.display_model(void 0, model, void 0);
	        }).then(function (view) {
	            w.addChild(view);
	        });
	        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;


/***/ },
/* 424 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(global) {// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	
	// HACK: node bootstrap requires this.
	global.jQuery = global.$ = __webpack_require__(425);
	
	module.exports = {
	    shims: {
	        services: __webpack_require__(427)
	    }
	};
	
	var loadedModules = [
	    __webpack_require__(430),
	    __webpack_require__(434),
	    __webpack_require__(435),
	    __webpack_require__(428),
	    __webpack_require__(436),
	    __webpack_require__(437),
	    __webpack_require__(438),
	    __webpack_require__(439),
	    __webpack_require__(440),
	    __webpack_require__(441),
	    __webpack_require__(442),
	    __webpack_require__(446),
	    __webpack_require__(443),
	    __webpack_require__(447),
	    __webpack_require__(448),
	    __webpack_require__(449),
	    __webpack_require__(450),
	    __webpack_require__(451),
	];
	
	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'] = __webpack_require__(433).version;
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

/***/ },
/* 425 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(global) {// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	
	// TODO: REMOVE ALL JQUERY FROM THE CODEBASE
	// Update March 2016: JQuery removed from most widgets, only
	// still used in slider (jquery-ui) in widget_int.js.
	
	var $;
	if (typeof window !== 'undefined' && window['$']) {
	    $ = window['$'];
	} else {
	    $ = __webpack_require__(426);
	    global.jQuery = $; // Required for bootstrap to load correctly
	}
	module.exports = $;
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

/***/ },
/* 426 */
/***/ function(module, exports, __webpack_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;
	}));


/***/ },
/* 427 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	
	/**
	 * This module defines shims for jupyter-js-services that allows you to use the
	 * old comm API.  Use this, jupyter-js-services, and the widget base manager to
	 * embed live widgets in a context outside of the notebook.
	 */
	'use strict';
	
	var utils = __webpack_require__(428);
	var _ = __webpack_require__(429);
	
	/**
	 * Public constructor
	 * @param  {IKernel} jsServicesKernel - jupyter-js-services IKernel instance
	 */
	var CommManager = function(jsServicesKernel) {
	    this.targets = {};
	    this.init_kernel(jsServicesKernel);
	};
	
	/**
	 * Hookup kernel events.
	 * @param  {IKernel} jsServicesKernel - jupyter-js-services 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));
	    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 handle = this.jsServicesKernel.registerCommTarget(target_name, function(jsServicesComm, msg) {
	        // Create the comm.
	        var comm = new Comm(jsServicesComm);
	
	        // 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];
	};
	
	
	/**
	 * Public constructor
	 * @param  {IComm} jsServicesComm - jupyter-js-services IComm instance
	 */
	var Comm = function(jsServicesComm) {
	    this.jsServicesComm = jsServicesComm;
	};
	
	/**
	 * Comm id
	 * @return {string}
	 */
	Object.defineProperty(Comm.prototype, 'comm_id', {
	    get: function() {
	        return this.jsServicesComm.commId;
	    }
	});
	
	/**
	 * Target name
	 * @return {string}
	 */
	Object.defineProperty(Comm.prototype, 'target_name', {
	    get: function() {
	        return this.jsServicesComm.targetName;
	    }
	});
	
	/**
	 * Opens a sibling comm in the backend
	 * @param  {object} data
	 * @param  {object} callbacks
	 * @param  {object} metadata
	 * @return {string} msg id
	 */
	Comm.prototype.open = function (data, callbacks, metadata) {
	    var future = this.jsServicesComm.open(data, metadata);
	    this._hookupCallbacks(future, callbacks);
	    return future.msgId;
	};
	
	/**
	 * Sends a message to the sibling comm in the backend
	 * @param  {object} data
	 * @param  {object} callbacks
	 * @param  {object} metadata
	 * @param  {(ArrayBuffer | ArrayBufferView)[]} buffers
	 * @return {string} msg id
	 */
	Comm.prototype.send = function (data, callbacks, metadata, buffers) {
	    var future = this.jsServicesComm.send(data, metadata, buffers);
	    this._hookupCallbacks(future, callbacks);
	    return future.msgId;
	};
	
	/**
	 * Closes the sibling comm in the backend
	 * @param  {object} data
	 * @param  {object} callbacks
	 * @param  {object} metadata
	 * @return {string} msg id
	 */
	Comm.prototype.close = function (data, callbacks, metadata) {
	    var future = this.jsServicesComm.close(data, metadata);
	    this._hookupCallbacks(future, callbacks);
	    return future.msgId;
	};
	
	/**
	 * Register a message handler
	 * @param  {(object) => void} callback - signature of f(msg)
	 */
	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  {(object) => void} callback - signature of f(msg)
	 */
	Comm.prototype.on_close = function (callback) {
	    this.jsServicesComm.onClose = callback.bind(this);
	};
	
	/**
	 * Hooks callback object up with jupyter-js-services IKernelFuture
	 * @param  {IKernelFuture} future - jupyter-js-services IKernelFuture instance
	 * @param  {object} 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.msg_type === 'status') {
	                    callbacks.iopub.status(msg);
	                } else if (callbacks.iopub.clear_output && msg.msg_type === 'clear_output') {
	                    callbacks.iopub.clear_output(msg);
	                } else if (callbacks.iopub.output) {
	                    switch(msg.msg_type) {
	                        case 'display_data':
	                        case 'execute_result':
	                            callbacks.iopub.output(msg);
	                            break;
	                    };
	                }
	            }
	        };
	    }
	};
	
	module.exports = {
	    'CommManager': CommManager,
	    'Comm': Comm
	};


/***/ },
/* 428 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	
	// TODO: ATTEMPT TO KILL THIS MODULE USING THIRD PARTY LIBRARIES WHEN IPYWIDGETS
	// IS CONVERTED TO NODE COMMONJS.
	'use strict';
	
	
	/**
	 * 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('');
	}
	
	/**
	 * 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`.
	 */
	function WrappedError(message, error){
	    var tmp = Error.apply(this, [message]);
	
	    // Copy the properties of the error over to this.
	    var properties = Object.getOwnPropertyNames(tmp);
	    for (var i = 0; i < properties.length; i++) {
	        this[properties[i]] = tmp[properties[i]];
	    }
	
	    // 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(tmp);
	
	    return this;
	}
	WrappedError.prototype = Object.create(Error.prototype, {});
	
	
	/**
	 * Tries to load a class
	 *
	 * Tries to load a class from a module using require.js, if a module
	 * is specified, otherwise tries to load a class from the global
	 * registry, if the global registry is provided.
	 *
	 * The optional require_error argument is a function that takes the success
	 * handler and returns a requirejs error handler, which may call the success
	 * handler with a fallback module.
	 *
	 */
	function loadClass(class_name, module_name, registry, require_error) {
	    return new Promise(function(resolve, reject) {
	
	        // Try loading the view module using require.js
	        if (module_name) {
	
	            // If the module is jupyter-js-widgets, we can just self import.
	            var modulePromise;
	            var requirejsDefined = typeof window !== 'undefined' && window.requirejs;
	            if (requirejsDefined) {
	                if (module_name !== 'jupyter-js-widgets' || window.requirejs.defined('jupyter-js-widgets')) {
	                    modulePromise = new Promise(function(innerResolve, innerReject) {
	                        var success_callback = function(module) {
	                            innerResolve(module);
	                        };
	                        var failure_callback = require_error ? require_error(success_callback) : innerReject;
	                        window.require([module_name], success_callback, failure_callback);
	                    });
	                } else if (module_name === 'jupyter-js-widgets') {
	                    modulePromise = Promise.resolve(__webpack_require__(424));
	                }
	            } else if (module_name === 'jupyter-js-widgets') {
	                modulePromise = Promise.resolve(__webpack_require__(424));
	            } else {
	                // FUTURE: Investigate dynamic loading methods other than require.js.
	                throw new Error(['In order to use third party widgets, you ',
	                    'must have require.js loaded on the page.'].join(''));
	            }
	
	            modulePromise.then(function(module) {
	                if (module[class_name] === undefined) {
	                    reject(new Error('Class '+class_name+' not found in module '+module_name));
	                } else {
	                    resolve(module[class_name]);
	                }
	            });
	        } else {
	            if (registry && registry[class_name]) {
	                resolve(registry[class_name]);
	            } else {
	                reject(new Error('Class '+class_name+' not found in registry '));
	            }
	        }
	    });
	}
	
	/**
	 * 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;
	    });
	}
	
	/**
	 * 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);
	    };
	}
	
	/**
	 * 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) {
	      MathJax.Hub.Queue(['Typeset', MathJax.Hub, element]);
	    }
	}
	
	/**
	 * escape text to HTML
	 */
	var escape_html = function(text) {
	    var esc  = document.createElement('div');
	    esc.textContent = text;
	    return esc.innerHTML;
	};
	
	module.exports = {
	    uuid: uuid,
	    WrappedError: WrappedError,
	    loadClass: loadClass,
	    resolvePromisesDict: resolvePromisesDict,
	    reject: reject,
	    typeset: typeset,
	    escape_html: escape_html
	};


/***/ },
/* 429 */
/***/ function(module, exports, __webpack_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));


/***/ },
/* 430 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var _ = __webpack_require__(429);
	var Backbone = __webpack_require__(431);
	var utils = __webpack_require__(428);
	var semver = __webpack_require__(432);
	
	//--------------------------------------------------------------------
	// ManagerBase class
	//--------------------------------------------------------------------
	var ManagerBase = function() {
	    /**
	     * Public constructor
	     */
	    ManagerBase._managers.push(this);
	
	    this.comm_target_name = 'jupyter.widget';
	    this.version_comm_target_name = 'jupyter.widget.version';
	    this._models = {}; /* Dictionary of model ids and model instance promises */
	};
	
	//--------------------------------------------------------------------
	// Class level
	//--------------------------------------------------------------------
	ManagerBase._model_types = {}; /* Dictionary of model type names (target_name) and model types. */
	ManagerBase._view_types = {}; /* Dictionary of view names and view types. */
	ManagerBase._managers = []; /* List of widget managers */
	
	// TODO: Remove me in ipywidgets 6.0
	ManagerBase.register_widget_model = function (model_name, model_type) {
	    /**
	     * Registers a widget model by name.
	     */
	    console.warn('register_widget_model is deprecated.  Models and views should be linked to their backend counterparts using the require.js load path (see the `_view_module` and `_model_module` traits)');
	    ManagerBase._model_types[model_name] = model_type;
	};
	
	// TODO: Remove me in ipywidgets 6.0
	ManagerBase.register_widget_view = function (view_name, view_type) {
	    /**
	     * Registers a widget view by name.
	     */
	    console.warn('register_widget_view is deprecated.  Models and views should be linked to their backend counterparts using the require.js load path (see the `_view_module` and `_model_module` traits)');
	    ManagerBase._view_types[view_name] = view_type;
	};
	
	//--------------------------------------------------------------------
	// Instance level
	//--------------------------------------------------------------------
	ManagerBase.prototype.display_model = function(msg, model, options) {
	    /**
	     * Displays a view for a particular model.
	     */
	    options = options || {};
	    options.root = true; // This element is being displayed not as a child of another.
	
	    return this.create_view(model, options).then(_.bind(function(view) {
	        return this.display_view(msg, view, options);
	    }, this)).catch(utils.reject('Could not create view', true));
	};
	
	ManagerBase.prototype.display_view = function(msg, view, options) {
	    throw new Error('Manager.display_view not implemented');
	};
	
	ManagerBase.prototype.setViewOptions = function(options) {
	    /**
	     * Modifies view options. Generally overloaded in custom widget manager
	     * implementations.
	     */
	    return options || {};
	};
	
	ManagerBase.prototype.require_error = function (success_callback) {
	    /**
	     * Takes a requirejs success handler and returns a requirejs error handler.
	     * The default implementation just throws the original error.
	     */
	    return function(err) {
	        throw err;
	    };
	};
	
	ManagerBase.prototype.create_view = function(model, 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.
	     */
	    var that = this;
	    model.state_change = model.state_change.then(function() {
	
	        return utils.loadClass(
	            model.get('_view_name'),
	            model.get('_view_module'),
	            ManagerBase._view_types,
	            that.require_error
	        ).then(function(ViewType) {
	            var view = new ViewType({
	                model: model,
	                options: that.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;
	};
	
	ManagerBase.prototype.callbacks = function (view) {
	    /**
	     * callback handlers specific a view
	     */
	    return {};
	};
	
	ManagerBase.prototype.get_model = function (model_id) {
	    /**
	     * Get a promise for a model by model id.
	     */
	    return this._models[model_id];
	};
	
	ManagerBase.prototype.handle_comm_open = function (comm, msg) {
	    /**
	     * Handle when a comm is opened.
	     */
	    return this.new_model({
	        model_name: msg.content.data._model_name,
	        model_module: msg.content.data._model_module,
	        comm: comm
	    }, msg.content.data).catch(utils.reject('Could not create a model.', true));
	};
	
	/**
	 * Create a comm and new widget model.
	 * @param  {Object} options - same options as new_model but, comm is not
	 *                          required and additional options are available.
	 * @param  {Object} serialized_state - serialized model attributes.
	 * @return {Promise<WidgetModel>}
	 */
	ManagerBase.prototype.new_widget = function(options, 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,
	            {
	                widget_class: options.widget_class,
	                target_name: 'jupyter.widget'
	            }
	        );
	    }
	    // 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.
	    var that = this;
	    return commPromise.then(function(comm) {
	        // Comm Promise Resolved.
	        options_clone.comm = comm;
	        return that.new_model(options_clone, serialized_state);
	    }, function() {
	        // Comm Promise Rejected.
	        if (!options_clone.model_id) {
	            options_clone.model_id = utils.uuid();
	        }
	        return that.new_model(options_clone, serialized_state);
	    });
	};
	
	/**
	 * Validate the version of the Javascript against the version requested by
	 * the backend.
	 * @return {Promise<Boolean>} Whether or not the versions are okay
	 */
	ManagerBase.prototype.validateVersion = function() {
	    return this._create_comm(this.version_comm_target_name, undefined, {}).then((function(comm) {
	        return new Promise((function(resolve, reject) {
	            comm.on_msg((function(msg) {
	                var version = __webpack_require__(433).version;
	                var requirement = msg.content.data.version;
	                var validated = semver.satisfies(version, requirement);
	                comm.send({'validated': validated});
	                if (validated) {
	                    console.info('Widget backend and frontend versions are compatible');
	                }
	                resolve(validated);
	            }).bind(this));
	            setTimeout(function() {
	                reject(new Error('Timeout while trying to cross validate the widget frontend and backend versions.'));
	            }, 3000);
	        }).bind(this));
	    }).bind(this));
	};
	
	ManagerBase.prototype.new_model = function(options, 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.
	     *
	     * Example
	     * --------
	     * JS:
	     * Jupyter.notebook.kernel.widget_manager.new_model({
	     *      model_name: 'WidgetModel',
	     *      widget_class: 'Jupyter.IntSlider'
	     *  })
	     *  .then(function(model) { console.log('Create success!', model); },
	     *  _.bind(console.error, console));
	     *
	     * Parameters
	     * ----------
	     * options: dictionary
	     *  Dictionary of options with the following contents:
	     *      model_name: string
	     *          Target name of the widget model to create.
	     *      model_module: (optional) string
	     *          Module name of the widget model to create.
	     *      widget_class: (optional) string
	     *          Target name of the widget in the back-end.
	     *      comm: (optional) Comm
	     *           Comm object associated with the widget.
	     *      model_id: (optional) string
	     *           If not provided, the comm id is used.
	     * serialized_state: dictionary
	     *  Dictionary of the attribute values for the model.
	     *
	     * Either a comm or a model_id must be provided.
	     */
	    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 model_promise = utils.loadClass(options.model_name,
	                                        options.model_module,
	                                        ManagerBase._model_types,
	                                        that.require_error)
	        .then(function(ModelType) {
	            return ModelType._deserialize_state(serialized_state || {}, that).then(function(attributes) {
	                var widget_model = new ModelType(that, model_id, options.comm, attributes);
	                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;
	            });
	    }, function(error) {
	        delete that._models[model_id];
	        var wrapped_error = new utils.WrappedError('Could not create model', error);
	        return Promise.reject(wrapped_error);
	    });
	    this._models[model_id] = model_promise;
	    return model_promise;
	};
	
	/**
	
	 * Close all widgets and empty the widget state.
	 * @param  {boolean} commlessOnly should only commless widgets be removed
	 * @return {Promise}              promise that resolves when the widget state is
	 *                                cleared.
	 */
	ManagerBase.prototype.clear_state = function(commlessOnly) {
	    var that = this;
	    return utils.resolvePromisesDict(this._models).then(function(models) {
	        Object.keys(models).forEach(function(id) {
	            if (!commlessOnly || models[id].comm) {
	                models[id].close();
	            }
	        });
	        that._models = {};
	    });
	};
	
	ManagerBase.prototype.get_state = function(options) {
	    /**
	     * Asynchronously get the state of the widget manager.
	     *
	     * This includes all of the widget models.
	     *
	     * Parameters
	     * ----------
	     * options: dictionary
	     *  Dictionary of options with the following contents:
	     *      only_displayed: (optional) boolean=false
	     *          Only return models with one or more displayed views.
	     *      not_live: (optional) boolean=false
	     *          Include models that have comms with severed connections.
	     *      drop_defaults: (optional) boolean=false
	     *          Drop model attributed that are equal to their default values.
	     *
	     * Returns
	     * -------
	     * Promise for a state dictionary
	     */
	    var that = this;
	    return utils.resolvePromisesDict(this._models).then(function(models) {
	        var state = {};
	
	        for (var model_id in models) {
	            if (models.hasOwnProperty(model_id)) {
	                var model = models[model_id];
	
	                // If the model has one or more views defined for it,
	                // consider it displayed.
	                var displayed_flag = !(options && options.only_displayed) || Object.keys(model.views).length > 0;
	                var live_flag = (options && options.not_live) || model.comm_live;
	                if (displayed_flag && live_flag) {
	                    state[model_id] = utils.resolvePromisesDict({
	                        model_name: model.name,
	                        model_module: model.module,
	                        state: model.constructor._serialize_state(model.get_state(options.drop_defaults), that),
	                        views: utils.resolvePromisesDict(model.views).then(function (views) {
	                            return _.values(views).filter(function(view) {
	                                    return view.options !== undefined && view.options.root;
	                            }).map(function (view) {
	                                return that.filterViewOptions(view.options);
	                            });
	                        })
	                    });
	                }
	            }
	        }
	        return utils.resolvePromisesDict(state);
	    }).catch(utils.reject('Could not get state of widget manager', true));
	};
	
	ManagerBase.prototype.filterViewOptions = function(options) {
	    /**
	     * Returns the keys of view options that must be stored in the serialized
	     * widget manager state.
	     *
	     * This is meant to be overloaded in custom managers, which may register
	     * the cell index.
	     */
	    return {};
	};
	
	ManagerBase.prototype.set_state = function(state, displayOptions) {
	    /**
	     * Set the widget manager state.
	     *
	     * 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.
	     */
	    var that = this;
	
	    // Recreate all the widget models for the given widget manager state.
	    var all_models = that._get_comm_info().then(function(live_comms) {
	        return Promise.all(_.map(Object.keys(state), function (model_id) {
	
	            // If the model has already been created, set it's state and then
	            // return it.
	            if (that._models[model_id]) {
	                return that._models[model_id].then(function(model) {
	                    return model.constructor._deserialize_state(state[model_id].state || {}, that).then(function(attributes) {
	                        model.set_state(attributes);
	                        return model;
	                    });
	                });
	            }
	
	            if (live_comms.hasOwnProperty(model_id)) {  // live comm
	                return that._create_comm(that.comm_target_name, model_id).then(function(new_comm) {
	                    return that.new_model({
	                        comm: new_comm,
	                        model_name: state[model_id].model_name,
	                        model_module: state[model_id].model_module
	                    });
	                });
	            } else { // dead comm
	                return that.new_model({
	                    model_id: model_id,
	                    model_name: state[model_id].model_name,
	                    model_module: state[model_id].model_module
	                }, state[model_id].state);
	            }
	        }));
	    });
	
	    // Display all the views
	    return all_models.then(function(models) {
	        return Promise.all(_.map(models, function(model) {
	            // Display the views of the model.
	            if (state[model.id] !== undefined) {
	                // Display the model using the display options merged with the
	                // options.
	                if (displayOptions && displayOptions.displayOnce && state[model.id].views && state[model.id].views.length) {
	                    return that.display_model(undefined, model, _.extend({}, displayOptions));
	                } else {
	                    // Display the model using the display options merged with the
	                    // options.
	                    return Promise.all(_.map(state[model.id].views, function(options) {
	                        return that.display_model(undefined, model, _.extend({}, options, displayOptions));
	                    }));
	                }
	            }
	        }));
	    }).catch(utils.reject('Could not set widget manager state.', true));
	};
	
	ManagerBase.prototype._create_comm = function(comm_target_name, model_id, data) {
	    return Promise.reject('No backend.');
	};
	
	ManagerBase.prototype._get_comm_info = function() {
	    return Promise.reject('No backend.');
	};
	
	module.exports = {
	    ManagerBase: ManagerBase
	};


/***/ },
/* 431 */
/***/ function(module, exports, __webpack_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__ = [__webpack_require__(429), __webpack_require__(426), 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; }())))

/***/ },
/* 432 */
/***/ function(module, exports, __webpack_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.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;
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(15)))

/***/ },
/* 433 */
/***/ function(module, exports) {

	module.exports = {
		"_args": [
			[
				"jupyter-js-widgets@2.0.0-dev.0",
				"/Users/jgrout6/projects/app/merge/jupyterlab"
			]
		],
		"_from": "jupyter-js-widgets@2.0.0-dev.0",
		"_id": "jupyter-js-widgets@2.0.0-dev.0",
		"_inCache": true,
		"_installable": true,
		"_location": "/jupyter-js-widgets",
		"_nodeVersion": "5.10.1",
		"_npmOperationalInternal": {
			"host": "packages-12-west.internal.npmjs.com",
			"tmp": "tmp/jupyter-js-widgets-2.0.0-dev.0.tgz_1464815912939_0.32718819100409746"
		},
		"_npmUser": {
			"email": "jason@jasongrout.org",
			"name": "jasongrout"
		},
		"_npmVersion": "3.8.3",
		"_phantomChildren": {
			"underscore": "1.8.3"
		},
		"_requested": {
			"name": "jupyter-js-widgets",
			"raw": "jupyter-js-widgets@2.0.0-dev.0",
			"rawSpec": "2.0.0-dev.0",
			"scope": null,
			"spec": "2.0.0-dev.0",
			"type": "version"
		},
		"_requiredBy": [
			"/jupyterlab"
		],
		"_shasum": "fec27d0c53665cc4dd08b3e85caa0c3353930fd4",
		"_shrinkwrap": null,
		"_spec": "jupyter-js-widgets@2.0.0-dev.0",
		"_where": "/Users/jgrout6/projects/app/merge/jupyterlab",
		"author": {
			"name": "Project Jupyter"
		},
		"bugs": {
			"url": "https://github.com/ipython/ipywidgets/issues"
		},
		"dependencies": {
			"backbone": "1.2.0",
			"bootstrap": "^3.3.5",
			"d3-format": "^0.5.1",
			"jquery": "^2.1.4",
			"jquery-ui": "^1.10.5",
			"lolex": "^1.4.0",
			"phosphor-tabs": "^1.0.0-rc.2",
			"phosphor-widget": "^1.0.0-rc.1",
			"scriptjs": "^2.5.8",
			"semver": "^5.1.0",
			"underscore": "^1.8.3"
		},
		"description": "Jupyter interactive widgets",
		"devDependencies": {
			"babel-core": "^6.4.0",
			"babel-loader": "^6.2.1",
			"babel-preset-es2015": "^6.3.13",
			"bower": "^1.5.3",
			"chai": "^3.4.1",
			"clean-css": "^3.4.6",
			"css-loader": "^0.23.1",
			"es6-promise": "^3.1.2",
			"file-loader": "^0.8.5",
			"font-awesome": "^4.5.0",
			"json-loader": "^0.5.4",
			"karma": "^0.13.15",
			"karma-chai": "^0.1.0",
			"karma-chrome-launcher": "^0.2.2",
			"karma-firefox-launcher": "^0.1.7",
			"karma-mocha": "^0.2.1",
			"karma-mocha-reporter": "^1.1.3",
			"karma-sinon-chai": "^1.1.0",
			"karma-webpack": "^1.7.0",
			"less": "^2.7.0",
			"mocha": "^2.3.4",
			"npm-run-all": "^1.5.1",
			"rimraf": "^2.4.1",
			"sinon": "^1.17.2",
			"sinon-chai": "^2.8.0",
			"spawn-sync": "^1.0.14",
			"style-loader": "^0.13.1",
			"url-loader": "^0.5.7",
			"webpack": "^1.12.11"
		},
		"directories": {},
		"dist": {
			"shasum": "fec27d0c53665cc4dd08b3e85caa0c3353930fd4",
			"tarball": "https://registry.npmjs.org/jupyter-js-widgets/-/jupyter-js-widgets-2.0.0-dev.0.tgz"
		},
		"homepage": "https://github.com/ipython/ipywidgets#readme",
		"license": "BSD-3-Clause",
		"main": "src/index.js",
		"maintainers": [
			{
				"email": "bussonniermatthias@gmail.com",
				"name": "carreau"
			},
			{
				"email": "jason@jasongrout.org",
				"name": "jasongrout"
			},
			{
				"email": "jon.freder@gmail.com",
				"name": "jdfreder"
			},
			{
				"email": "benjaminrk@gmail.com",
				"name": "minrk"
			},
			{
				"email": "rgbkrk@gmail.com",
				"name": "rgbkrk"
			},
			{
				"email": "sylvain.corlay@gmail.com",
				"name": "sylvaincorlay"
			}
		],
		"name": "jupyter-js-widgets",
		"optionalDependencies": {},
		"readme": "ERROR: No README data found!",
		"repository": {
			"type": "git",
			"url": "git+https://github.com/ipython/ipywidgets.git"
		},
		"scripts": {
			"build": "npm run css && webpack",
			"css": "npm run precss && npm run css:less && npm run css:cleancss",
			"css:cleancss": "cleancss --source-map --skip-restructuring -o ./css/widgets.min.css ./css/widgets.css",
			"css:less": "lessc --include-path=./node_modules ./less/widgets.less ./css/widgets.css",
			"precss": "rimraf ./css/",
			"prepublish": "npm run build",
			"test": "npm run test:unit && npm run test:examples",
			"test:example:web1": "cd examples/web && npm install && npm run test:default",
			"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/web3 && 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",
			"test:unit:default": "karma start karma.conf.js --log-level debug",
			"test:unit:firefox": "npm run test:unit:default -- --browsers Firefox"
		},
		"version": "2.0.0-dev.0"
	};

/***/ },
/* 434 */
/***/ function(module, exports) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	
	function generateEmbedScript(widgetState, imageDataUrl) {
	  return [
	      '<img src=' + imageDataUrl + ' class="jupyter-widget">',
	      '<script type="application/vnd.jupyter-embedded-widgets">' + JSON.stringify(widgetState) + '</script>'
	  ].join('\n');
	}
	
	module.exports = {
	  generateEmbedScript: generateEmbedScript,
	};


/***/ },
/* 435 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	
	var manager = __webpack_require__(430);
	
	var EmbedManager = exports.EmbedManager = function() {
	    manager.ManagerBase.call(this);
	};
	EmbedManager.prototype = Object.create(manager.ManagerBase.prototype);
	
	EmbedManager.prototype.display_widget_state = function(models, el) {
	    return this.set_state(models, { el: el, displayOnce: true });
	};
	
	EmbedManager.prototype.display_view = function(msg, view, options) {
	    return Promise.resolve(view).then(function(view) {
	        options.el.appendChild(view.el);
	        view.trigger('displayed');
	        view.on('remove', function() {
	            console.log('View removed', view);
	        });
	        return view;
	    });
	};
	
	EmbedManager.prototype._get_comm_info = function() {
	    return Promise.resolve({});
	};
	
	EmbedManager.prototype.require_error = function(success_callback) {
	    /**
	     * Takes a requirejs success handler and returns a requirejs error handler
	     * that attempts loading the module from npmcdn. 
	     */
	    return function(err) {
	        var failedId = err.requireModules && err.requireModules[0];
	        if (failedId) {
	            window.require(['https://npmcdn.com/' + failedId + '/dist/index.js'], success_callback);
	        } else {
	            throw err;
	        }
	    };
	};


/***/ },
/* 436 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var utils = __webpack_require__(428);
	var managerBase = __webpack_require__(430);
	var _ = __webpack_require__(429);
	var Backbone = __webpack_require__(431);
	
	
	var unpack_models = function unpack_models(value, manager) {
	    /**
	     * Replace model ids with models recursively.
	     */
	    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);
	    }
	};
	
	var WidgetModel = Backbone.Model.extend({
	
	    defaults: {
	        _model_module: "jupyter-js-widgets",
	        _model_name: "WidgetModel",
	        _view_module: "jupyter-js-widgets",
	        _view_name: null,
	        msg_throttle: 3
	    },
	
	    constructor: function (widget_manager, model_id, comm, attributes) {
	        /**
	         * Constructor
	         *
	         * Creates a WidgetModel instance.
	         *
	         * Parameters
	         * ----------
	         * widget_manager : WidgetManager instance
	         * model_id : string
	         *      An ID unique to this model.
	         * comm : Comm instance (optional)
	         */
	        this.widget_manager = widget_manager;
	        this.state_change = Promise.resolve();
	        this._buffered_state_diff = {};
	        this.pending_msgs = 0;
	        this.msg_buffer = null;
	        this.state_lock = null;
	        this.id = model_id;
	
	        // Force backbone to think that the model has already been
	        // synced with the server.  As of backbone 1.1, backbone
	        // ignores `patch` if it thinks the model has never been
	        // pushed.
	        this.isNew = function() { return false; };
	
	        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;
	        }
	
	        WidgetModel.__super__.constructor.apply(this, [attributes]);
	    },
	
	    send: function (content, callbacks, buffers) {
	        /**
	         * Send a custom msg over the comm.
	         */
	        if (this.comm !== undefined) {
	            var data = {method: 'custom', content: content};
	            this.comm.send(data, callbacks, {}, buffers);
	            this.pending_msgs++;
	        }
	    },
	
	    close: function(comm_closed) {
	        /**
	         * Close model
	         */
	        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_comm_closed: function (msg) {
	        /**
	         * Handle when a widget is closed.
	         */
	        this.trigger('comm:close');
	        this.close(true);
	    },
	
	    _handle_comm_msg: function (msg) {
	        /**
	         * Handle incoming comm msg.
	         */
	        var method = msg.content.data.method;
	        var that = this;
	        switch (method) {
	            case 'update':
	                this.state_change = this.state_change
	                    .then(function() {
	                        var state = msg.content.data.state || {};
	                        var buffer_keys = msg.content.data.buffers || [];
	                        var buffers = msg.buffers || [];
	                        for (var i=0; i<buffer_keys.length; i++) {
	                            state[buffer_keys[i]] = buffers[i];
	                        }
	                        return that.constructor._deserialize_state(state, that.widget_manager);
	                    }).then(function(state) {
	                        that.set_state(state);
	                    }).catch(utils.reject('Could not process update msg for model id: ' + String(that.id), true))
	                return this.state_change;
	            case 'custom':
	                this.trigger('msg:custom', msg.content.data.content, msg.buffers);
	                return Promise.resolve();
	            case 'display':
	                this.state_change = this.state_change.then(function() {
	                    that.widget_manager.display_model(msg, that);
	                }).catch(utils.reject('Could not process display view msg', true));
	                return this.state_change;
	        }
	    },
	
	    set_state: function (state) {
	        // Handles when a widget is updated from the backend.
	        this.state_lock = state;
	        try {
	            this.set(state);
	            this.state_lock = null;
	        } catch(e) {
	            console.error('Error setting state:', e.message);
	        }
	    },
	
	    get_state: function(drop_defaults) {
	        /**
	         * Get the serializable state of the model.
	         *
	         * If drop_default is thruthy, attributes that are equal to their default
	         * values are dropped.
	         */
	        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: function (msg, callbacks) {
	        /**
	         * Handle status msgs.
	         *
	         * execution_state : ('busy', 'idle', 'starting')
	         */
	        if (this.comm !== undefined) {
	            if (msg.content.execution_state ==='idle') {
	                // Send buffer if this message caused another message to be
	                // throttled.
	                if (this.msg_buffer !== null &&
	                    (this.get('msg_throttle') || 1) === this.pending_msgs) {
	                    var data = {
	                        method: 'backbone',
	                        sync_method: 'update',
	                        sync_data: this.msg_buffer
	                    };
	                    this.comm.send(data, callbacks);
	                    this.msg_buffer = null;
	                } else {
	                    --this.pending_msgs;
	                }
	            }
	        }
	    },
	
	    callbacks: function(view) {
	        /**
	         * Create msg callbacks for a comm msg.
	         */
	        var callbacks = this.widget_manager.callbacks(view);
	
	        if (callbacks.iopub === undefined) {
	            callbacks.iopub = {};
	        }
	
	        var that = this;
	        callbacks.iopub.status = function (msg) {
	            that._handle_status(msg, callbacks);
	        };
	        return callbacks;
	    },
	
	    set: function(key, val, options) {
	        /**
	         * Set a value.
	         */
	        var return_value = WidgetModel.__super__.set.apply(this, arguments);
	
	        // Backbone only remembers the diff of the most recent set()
	        // operation.  Calling set multiple times in a row results in a
	        // loss of diff information.  Here we keep our own running diff.
	        //
	        // However, we don't buffer the initial state comming from the
	        // backend or the default values specified in `defaults`.
	        //
	        this._buffered_state_diff = _.extend(this._buffered_state_diff, this.changedAttributes() || {});
	        return return_value;
	    },
	
	    sync: function (method, model, options) {
	        /**
	         * 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.
	         *
	         */
	        var error = options.error || function() {
	            console.error('Backbone sync error:', arguments);
	        };
	        if (this.comm === undefined) {
	            error();
	            return false;
	        }
	
	        var attrs = (method === 'patch') ? options.attrs : model.get_state(options);
	
	        // 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, (but we only delete them if the value
	        // hasn't changed from the value stored in the state_lock).
	        if (this.state_lock !== null) {
	            var keys = Object.keys(this.state_lock);
	            for (var i=0; i<keys.length; i++) {
	                var key = keys[i];
	                if (attrs[key] === this.state_lock[key]) {
	                    delete attrs[key];
	                }
	            }
	        }
	
	        if (_.size(attrs) > 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 || {}, attrs);
	                        break;
	                    case 'update':
	                    case 'create':
	                        this.msg_buffer = attrs;
	                        break;
	                    default:
	                        error();
	                        return false;
	                }
	                this.msg_buffer_callbacks = callbacks;
	
	            } else {
	                // We haven't exceeded the throttle, send the message like
	                // normal.
	                this.send_sync_message(attrs, callbacks);
	                this.pending_msgs++;
	            }
	        }
	        // Since the comm is a one-way communication, assume the message
	        // arrived.  Don't call success since we don't have a model back from the server
	        // this means we miss out on the 'sync' event.
	        this._buffered_state_diff = {};
	    },
	
	    send_sync_message: function(attrs, callbacks) {
	        // prepare and send a comm message syncing attrs
	        var that = this;
	        // first, build a state dictionary with key=the attribute and the value
	        // being the value or the promise of the serialized value
	        var serializers = this.constructor.serializers;
	        if (serializers) {
	            for (var k in attrs) {
	                if (serializers[k] && serializers[k].serialize) {
	                    attrs[k] = (serializers[k].serialize)(attrs[k], this);
	                }
	            }
	        }
	        utils.resolvePromisesDict(attrs).then(function(state) {
	            // get binary values, then send
	            var keys = Object.keys(state);
	            var buffers = [];
	            var buffer_keys = [];
	            for (var i=0; i<keys.length; i++) {
	                var key = keys[i];
	                var value = state[key];
	                if (value) {
	                    if (value.buffer instanceof ArrayBuffer
	                        || value instanceof ArrayBuffer) {
	                        buffers.push(value);
	                        buffer_keys.push(key);
	                        delete state[key];
	                    }
	                }
	            }
	            that.comm.send({
	                method: 'backbone',
	                sync_data: state,
	                buffer_keys: buffer_keys
	            }, callbacks, {}, buffers);
	        }).catch(function(error) {
	            that.pending_msgs--;
	            return (utils.reject('Could not send widget sync message', true))(error);
	        });
	    },
	
	    save_changes: function(callbacks) {
	        /**
	         * Push this model's state to the back-end
	         *
	         * This invokes a Backbone.Sync.
	         */
	        if (this.comm_live) {
	            this.save(this._buffered_state_diff, {patch: true, callbacks: callbacks});
	        }
	    },
	
	    on_some_change: function(keys, callback, context) {
	        /**
	         * 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.
	         */
	        this.on('change', function() {
	            if (keys.some(this.hasChanged, this)) {
	                callback.apply(context, arguments);
	            }
	        }, this);
	    },
	
	    toJSON: function(options) {
	        /**
	         * Serialize the model.  See the deserialization function at the top of this file
	         * and the kernel-side serializer/deserializer.
	         */
	        return 'IPY_MODEL_' + this.id;
	    }
	}, {
	    _deserialize_state: function(state, manager) {
	        /**
	         * 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.
	         */
	        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);
	    },
	
	    _serialize_state: function(state, manager) {
	        /**
	         * Returns a promise for the serialized state. The second argument
	         * is an instance of widget 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);
	    }
	});
	
	
	var WidgetViewMixin = {
	    initialize: function(parameters) {
	        /**
	         * Public constructor.
	         */
	        this.listenTo(this.model, 'change', this.update, this);
	
	        this.options = parameters.options;
	        /**
	         * this.displayed is a promise that resolves when the view is
	         * inserted in the DOM.
	         */
	        var that = this;
	        this.displayed = new Promise(function(resolve, reject) {
	            that.once('displayed', resolve);
	        });
	    },
	
	    update: function() {
	        /**
	         * Triggered on model change.
	         *
	         * Update view to be consistent with this.model
	         */
	    },
	
	    create_child_view: function(child_model, options) {
	        /**
	         * Create and promise that resolves to a child view of a given model
	         */
	        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));
	    },
	
	    callbacks: function(){
	        /**
	         * Create msg callbacks for a comm msg.
	         */
	        return this.model.callbacks(this);
	    },
	
	    render: function(){
	        /**
	         * Render the view.
	         *
	         * By default, this is only called the first time the view is created
	         */
	    },
	
	    send: function (content, buffers) {
	        /**
	         * Send a custom msg associated with this view.
	         */
	        this.model.send(content, this.callbacks(), buffers);
	    },
	
	    touch: function () {
	        this.model.save_changes(this.callbacks());
	    },
	
	    remove: function () {
	        // Raise a remove event when the view is removed.
	        WidgetView.__super__.remove.apply(this, arguments);
	        this.trigger('remove');
	    }
	};
	
	var DOMWidgetModel = WidgetModel.extend({
	    defaults: _.extend({}, WidgetModel.prototype.defaults, {
	        layout: undefined,
	        _dom_classes: [],
	    }),
	}, {
	    serializers: _.extend({
	        layout: {deserialize: unpack_models},
	    }, WidgetModel.serializers)
	});
	
	var DOMWidgetViewMixin = {
	    initialize: function (parameters) {
	        /**
	         * Public constructor
	         */
	        WidgetViewMixin.initialize.apply(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);
	
	        this.layoutPromise = Promise.resolve();
	        this.listenTo(this.model, 'change:layout', function(model, value) {
	            this.setLayout(value, model.previous('layout'));
	        });
	
	        this.displayed.then(_.bind(function() {
	            this.update_classes([], this.model.get('_dom_classes'));
	            this.setLayout(this.model.get('layout'));
	        }, this));
	    },
	
	    setLayout: function(layout, oldLayout) {
	        var that = this;
	        if (layout) {
	            this.layoutPromise = this.layoutPromise.then(function(oldLayoutView) {
	                if (oldLayoutView) {
	                    oldLayoutView.unlayout();
	                }
	
	                return that.create_child_view(layout).then(function(view) {
	                    // Trigger the displayed event of the child view.
	                    return that.displayed.then(function() {
	                        view.trigger('displayed', that);
	                        return view;
	                    });
	                }).catch(utils.reject('Could not add LayoutView to DOMWidgetView', true));
	            });
	        }
	    },
	
	    update_classes: function (old_classes, new_classes, el) {
	        /**
	         * Update the DOM classes applied to an element, default to this.el.
	         */
	        if (el===undefined) {
	            el = this.el;
	        }
	        _.difference(old_classes, new_classes).map(function(c) {
	            if (el.classList) { // classList is not supported by IE for svg elements
	                el.classList.remove(c);
	            } else {
	                el.setAttribute('class', el.getAttribute('class').replace(c, ''));
	            }
	        });
	        _.difference(new_classes, old_classes).map(function(c) {
	            if (el.classList) { // classList is not supported by IE for svg elements
	                el.classList.add(c);
	            } else {
	                el.setAttribute('class', el.getAttribute('class').concat(' ', c));
	            }
	        });
	    },
	
	    update_mapped_classes: function(class_map, trait_name, el) {
	        /**
	         * 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.
	         */
	        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);
	    },
	
	    typeset: function(element, text){
	        this.displayed.then(function() {utils.typeset(element, text);});
	    }
	};
	
	
	var ViewList = function(create_view, remove_view, context) {
	    /**
	     * - create_view and remove_view are default functions called when adding or removing views
	     * - create_view takes a model 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.
	     */
	
	    this.initialize.apply(this, arguments);
	};
	
	_.extend(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();};
	    },
	
	    update: function(new_models, create_view, remove_view, context) {
	        /**
	         * 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) {...});`
	         */
	        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])));
	        }
	        // make a copy of the input array
	        this._models = new_models.slice();
	    },
	
	    remove: function() {
	        /**
	         * removes every view in the list; convenience function for `.update([])`
	         * that should be faster
	         * returns a promise that resolves after this removal is done
	         */
	        var that = this;
	        return Promise.all(this.views).then(function(views) {
	            for (var i = 0; i < that.views.length; i++) {
	                that._remove_view.call(that._handler_context, views[i]);
	            }
	            that.views = [];
	            that._models = [];
	        });
	    }
	});
	
	// For backwards compatibility.
	var WidgetView = Backbone.View.extend(WidgetViewMixin);
	var DOMWidgetView = WidgetView.extend(DOMWidgetViewMixin);
	
	var widget = {
	    unpack_models: unpack_models,
	    WidgetModel: WidgetModel,
	    WidgetViewMixin: WidgetViewMixin,
	    DOMWidgetViewMixin: DOMWidgetViewMixin,
	    ViewList: ViewList,
	    DOMWidgetModel: DOMWidgetModel,
	
	    // For backwards compatibility.
	    WidgetView: WidgetView,
	    DOMWidgetView: DOMWidgetView
	};
	
	module.exports = widget;


/***/ },
/* 437 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var widget = __webpack_require__(436);
	var _ = __webpack_require__(429);
	var Backbone = __webpack_require__(431);
	
	/**
	 * css properties exposed by the layout widget with their default values.
	 */
	var css_properties = {
	    align_content: '',
	    align_items: '',
	    align_self: '',
	    border: '',
	    bottom: '',
	    display: '',
	    flex: '',
	    flex_flow: '',
	    height: '',
	    justify_content: '',
	    left: '',
	    margin: '',
	    max_height: '',
	    max_width: '',
	    min_height: '',
	    min_width: '',
	    overflow: '',
	    order: '',
	    padding: '',
	    right: '',
	    top: '',
	    visibility: '',
	    width: ''
	};
	
	/**
	 * Represents a group of CSS style attributes
	 */
	var LayoutModel = widget.WidgetModel.extend({
	    defaults: _.extend({}, widget.WidgetModel.prototype.defaults, {
	        _model_name: 'LayoutModel',
	        _view_name: 'LayoutView'
	    }, css_properties)
	});
	
	var LayoutView = widget.WidgetView.extend({
	
	    /**
	     * Public constructor
	     */
	    initialize: function() {
	        LayoutView.__super__.initialize.apply(this, arguments);
	        // Register the traits that live on the Python side
	        this._traitNames = [];
	        this.registerTraits(Object.keys(css_properties));
	    },
	
	    /**
	     * Register CSS traits that are known by the model
	     * @param  {...string[]} traits
	     */
	    registerTraits: function() {
	
	        // Expand any args that are arrays
	        _.flatten(Array.prototype.slice.call(arguments))
	
	            // Call registerTrait on each trait
	            .forEach(_.bind(this.registerTrait, this));
	    },
	
	    /**
	     * Register a CSS trait that is known by the model
	     * @param  {string} trait
	     */
	    registerTrait: function(trait) {
	        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);
	        }, this);
	
	        // Set the initial value on display.
	        this.displayed.then(_.bind(function() {
	            this.handleChange(trait, this.model.get(trait));
	        }, this));
	    },
	
	    /**
	     * Get the the name of the css property from the trait name
	     * @param  {string} model attribute name
	     * @return {string} css property name.
	     */
	    css_name: function(trait) {
	        return trait.replace('_', '-');
	    },
	
	
	    /**
	     * Handles when a trait value changes
	     * @param  {string} trait
	     * @param  {object} value
	     */
	    handleChange: function(trait, value) {
	        this.displayed.then(_.bind(function(parent) {
	            if (parent) {
	                parent.el.style[this.css_name(trait)] = value;
	            } else {
	                console.warn('Style not applied because a parent view doesn\'t exist');
	            }
	        }, this));
	    },
	
	    /**
	     * Remove the styling from the parent view.
	     */
	    unlayout: function() {
	        this._traitNames.forEach(function(trait) {
	            this.displayed.then(_.bind(function(parent) {
	                if (parent) {
	                    parent.el.style[this.css_name(trait)] = '';
	                } else {
	                    console.warn('Style not removed because a parent view doesn\'t exist');
	                }
	            }, this));
	        }, this);
	    }
	});
	
	module.exports = {
	    LayoutView: LayoutView,
	    LayoutModel: LayoutModel
	};


/***/ },
/* 438 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var widget = __webpack_require__(436);
	var _ = __webpack_require__(429);
	
	var BaseLinkModel = widget.WidgetModel.extend({
	
	    defaults: _.extend({}, widget.WidgetModel.prototype.defaults, {
	        target: undefined,
	        source: undefined
	    }),
	
	    update_value: function(source, target) {
	        if (this.updating) {
	            return;
	        }
	        this.updating = true;
	        try {
	            if (target[0]) {
	                target[0].set(target[1], source[0].get(source[1]));
	                target[0].save_changes();
	            }
	        } finally {
	            this.updating = false;
	        }
	    },
	
	    cleanup: function() {
	        // Stop listening to 'change' and 'destroy' events of the source and target
	        if (this.source) {
	            this.stopListening(this.source[0], 'change:' + this.source[1], null, this);
	            this.stopListening(this.source[0], 'destroy', null, this);
	        }
	        if (this.target) {
	            this.stopListening(this.target[0], 'change:' + this.target[1], null, this);
	            this.stopListening(this.target[0], 'destroy', null, this);
	        }
	    }
	
	}, {
	
	    serializers: _.extend({
	        target: {deserialize: widget.unpack_models},
	        source: {deserialize: widget.unpack_models}
	    }, widget.WidgetModel.serializers)
	
	});
	
	var LinkModel = BaseLinkModel.extend({
	
	    defaults: _.extend({}, BaseLinkModel.prototype.defaults, {
	        _model_name: 'LinkModel'
	    }),
	
	    initialize: function() {
	        this.on('change', this.update_bindings, this);
	        this.update_bindings();
	    },
	
	    update_bindings: function() {
	        this.cleanup();
	        this.source = this.get('source');
	        this.target = this.get('target');
	        if (this.source) {
	            this.listenTo(this.source[0], 'change:' + this.source[1], function() {
	                this.update_value(this.source, this.target);
	            }, this);
	            this.update_value(this.source, this.target);
	            this.listenToOnce(this.source[0], 'destroy', this.cleanup, this);
	        }
	        if (this.target) {
	            this.listenTo(this.target[0], 'change:' + this.target[1], function() {
	                this.update_value(this.target, this.source);
	            }, this);
	            this.listenToOnce(this.target[0], 'destroy', this.cleanup, this);
	        }
	    }
	});
	
	var DirectionalLinkModel = BaseLinkModel.extend({
	
	    defaults: _.extend({}, BaseLinkModel.prototype.defaults, {
	        _model_name: 'DirectionalLinkModel'
	    }),
	
	    initialize: function() {
	        this.on('change', this.update_bindings, this);
	        this.update_bindings();
	    },
	
	    update_bindings: function() {
	        this.cleanup();
	        this.source = this.get('source');
	        this.target = this.get('target');
	        if (this.source) {
	            this.listenTo(this.source[0], 'change:' + this.source[1], function() {
	                this.update_value(this.source, this.target);
	            }, this);
	            this.update_value(this.source, this.target);
	            this.listenToOnce(this.source[0], 'destroy', this.cleanup, this);
	        }
	        if (this.target) {
	            this.listenToOnce(this.target[0], 'destroy', this.cleanup, this);
	        }
	    }
	
	});
	
	module.exports = {
	    LinkModel: LinkModel,
	    DirectionalLinkModel: DirectionalLinkModel
	};


/***/ },
/* 439 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var widget = __webpack_require__(436);
	var _ = __webpack_require__(429);
	
	var BoolModel = widget.DOMWidgetModel.extend({
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        value: false,
	        description: '',
	        disabled: false,
	        _model_name: 'BoolModel'
	    })
	});
	
	var CheckboxModel = BoolModel.extend({
	    defaults: _.extend({}, BoolModel.prototype.defaults, {
	        _view_name: 'CheckboxView',
	        _model_name: 'CheckboxModel'
	    })
	});
	
	var CheckboxView = widget.DOMWidgetView.extend({
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-hbox');
	        this.el.classList.add('widget-checkbox');
	
	        this.checkbox = document.createElement('input');
	        this.checkbox.setAttribute('type', 'checkbox');
	        this.el.appendChild(this.checkbox);
	
	        this.label = document.createElement('div');
	        this.label.classList.add('widget-label');
	        this.label.style.display = 'none';
	        this.el.appendChild(this.label);
	
	        this.update(); // Set defaults.
	    },
	
	    update_attr: function(name, value) { // TODO: Deprecated in 5.0
	        /**
	         * Set a css attr of the widget view.
	         */
	        if (name === 'padding' || name === 'margin') {
	            this.el.style[name] = value;
	        } else {
	            this.checkbox.style[name] = value;
	        }
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'click input[type="checkbox"]': '_handle_click'
	    },
	
	    _handle_click: function() {
	        /**
	         * Handles when the checkbox is clicked.
	         *
	         * Calling model.set will trigger all of the other views of the
	         * model to update.
	         */
	        var value = this.model.get('value');
	        this.model.set('value', !value, {updated_view: this});
	        this.touch();
	    },
	
	    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.
	         */
	        this.checkbox.checked = this.model.get('value');
	
	        if (options === undefined || options.updated_view != this) {
	            this.checkbox.disabled = this.model.get('disabled');
	
	            var description = this.model.get('description');
	            if (description.trim().length === 0) {
	                this.label.style.display = 'none';
	            } else {
	                this.typeset(this.label, description);
	                this.label.style.display = '';
	            }
	        }
	        return CheckboxView.__super__.update.apply(this);
	    }
	});
	
	var ToggleButtonModel = BoolModel.extend({
	    defaults: _.extend({}, BoolModel.prototype.defaults, {
	        _view_name: 'ToggleButtonView',
	        _model_name: 'ToggleButtonModel',
	        tooltip: '',
	        icon: '',
	        button_style: ''
	    })
	});
	
	var ToggleButtonView = widget.DOMWidgetView.extend({
	    initialize: function() {
	        /**
	         * Called when view is instantiated.
	         */
	        this.setElement(document.createElement('button'));
	        ToggleButtonView.__super__.initialize.apply(this, arguments);
	    },
	
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.className = 'jupyter-widgets widget-toggle-button';
	        this.listenTo(this.model, 'change:button_style', this.update_button_style, this);
	        this.update_button_style();
	        this.update(); // Set defaults.
	    },
	
	    update_button_style: function() {
	        var class_map = {
	            primary: ['mod-primary'],
	            success: ['mod-success'],
	            info: ['mod-info'],
	            warning: ['mod-warning'],
	            danger: ['mod-danger']
	        };
	        this.update_mapped_classes(class_map, 'button_style');
	    },
	
	    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 (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 ToggleButtonView.__super__.update.apply(this);
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'click': '_handle_click'
	    },
	
	    _handle_click: function(event) {
	        /**
	         * Handles and validates user input.
	         *
	         * Calling model.set will trigger all of the other views of the
	         * model to update.
	         */
	        event.preventDefault();
	        var value = this.model.get('value');
	        this.model.set('value', !value, {updated_view: this});
	        this.touch();
	    }
	});
	
	var ValidModel = BoolModel.extend({
	    defaults: _.extend({}, BoolModel.prototype.defaults, {
	        readout: 'Invalid',
	        _view_name: 'ValidView',
	        _model_name: 'ValidModel'
	    })
	});
	
	var ValidView = widget.DOMWidgetView.extend({
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-valid');
	        this.update();
	    },
	
	    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.
	         */
	        this.el.textContent = '';
	        this.el.classList.remove('mod-valid');
	        this.el.classList.remove('mod-invalid');
	
	        var icon = document.createElement('i');
	        this.el.appendChild(icon);
	
	        if (this.model.get('value')) {
	            this.el.classList.add('mod-valid');
	        } else {
	            var readout = document.createTextNode(this.model.get('readout'));
	            this.el.classList.add('mod-invalid');
	            this.el.appendChild(readout);
	        }
	    }
	});
	
	module.exports = {
	    BoolModel: BoolModel,
	    CheckboxModel: CheckboxModel,
	    CheckboxView: CheckboxView,
	    ToggleButtonModel: ToggleButtonModel,
	    ToggleButtonView: ToggleButtonView,
	    ValidModel: ValidModel,
	    ValidView: ValidView
	};


/***/ },
/* 440 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var widget = __webpack_require__(436);
	var _ = __webpack_require__(429);
	
	var ButtonModel = widget.DOMWidgetModel.extend({
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        description: '',
	        tooltip: '',
	        disabled: false,
	        icon: '',
	        button_style: '',
	        _view_name: 'ButtonView',
	        _model_name: 'ButtonModel'
	    })
	});
	
	var ButtonView = widget.DOMWidgetView.extend({
	    initialize: function() {
	        /**
	         * Called when view is instantiated.
	         */
	        this.setElement(document.createElement('button'));
	        ButtonView.__super__.initialize.apply(this, arguments);
	    },
	
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.className = 'jupyter-widgets widget-button';
	        this.listenTo(
	            this.model,
	            'change:button_style',
	            this.update_button_style,
	            this
	        );
	        this.update_button_style();
	        this.update(); // Set defaults.
	    },
	
	    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.
	         */
	        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);
	                this.el.appendChild(i);
	            }
	            this.el.appendChild(document.createTextNode(description));
	        }
	        return ButtonView.__super__.update.apply(this);
	    },
	
	    update_button_style: function() {
	        var class_map = {
	            primary: ['mod-primary'],
	            success: ['mod-success'],
	            info: ['mod-info'],
	            warning: ['mod-warning'],
	            danger: ['mod-danger']
	        };
	        this.update_mapped_classes(class_map, 'button_style');
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'click': '_handle_click'
	    },
	
	    _handle_click: function(event) {
	        /**
	         * Handles when the button is clicked.
	         */
	        event.preventDefault();
	        this.send({event: 'click'});
	    }
	});
	
	module.exports = {
	    ButtonView: ButtonView,
	    ButtonModel: ButtonModel
	};


/***/ },
/* 441 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var widget = __webpack_require__(436);
	var utils = __webpack_require__(428);
	var _ = __webpack_require__(429);
	
	var BoxModel = widget.DOMWidgetModel.extend({
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        _view_name: 'BoxView',
	        _model_name: 'BoxModel',
	        children: [],
	        box_style: '',
	        overflow_x: '',
	        overflow_y: ''
	    })
	}, {
	    serializers: _.extend({
	        children: {deserialize: widget.unpack_models},
	    }, widget.DOMWidgetModel.serializers)
	});
	
	var ProxyModel = widget.DOMWidgetModel.extend({
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        _view_name: 'ProxyView',
	        _model_name: 'ProxyModel',
	        child: null
	    })
	}, {
	    serializers: _.extend({
	        child: {deserialize: widget.unpack_models}
	    }, widget.DOMWidgetModel.serializers)
	});
	
	var ProxyView = widget.DOMWidgetView.extend({
	    initialize: function() {
	        // Public constructor
	        ProxyView.__super__.initialize.apply(this, arguments);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-container');
	        this.box = this.el;
	        this.child_promise = Promise.resolve();
	    },
	
	    render: function() {
	        var that = this;
	        var child_view = this.set_child(this.model.get('child'));
	        this.listenTo(this.model, 'change:child', function(model, value) {
	            this.set_child(value);
	        });
	        return child_view;
	    },
	
	    remove: function() {
	        ProxyView.__super__.remove.apply(this, arguments);
	        var that = this;
	        this.child_promise.then(function() {
	            if (that.child) {
	                that.child.remove();
	            }
	        });
	    },
	
	    set_child: function(value) {
	        if (this.child) {
	            this.child.remove();
	        }
	        if (value) {
	            var that = this;
	            this.child_promise = this.child_promise.then(function() {
	                return that.create_child_view(value).then(function(view) {
	                    if (!that.box) {
	                        console.error('Widget place holder does not exist');
	                        return;
	                    }
	                    while (that.box.firstChild) {
	                        that.box.removeChild(that.box.firstChild);
	                    }
	                    that.box.appendChild(view.el);
	
	                    // Trigger the displayed event of the child view.
	                    that.displayed.then(function() {
	                        view.trigger('displayed', that);
	                    });
	                    that.child = view;
	                    that.trigger('child:created');
	                }).catch(utils.reject('Could not add child view to proxy', true));
	            });
	        }
	        return this.child_promise;
	    },
	
	    /**
	     * Set a CSS attr of the view
	     * @param  {string} name
	     * @param  {object} value
	     */
	    update_attr: function(name, value) { // TODO: Deprecated in 5.0
	        this.box.style[name] = value;
	    }
	});
	
	var PlaceProxyModel = ProxyModel.extend({
	    defaults: _.extend({}, ProxyModel.prototype.defaults, {
	        _view_name: 'PlaceProxyView',
	        _model_name: 'PlaceProxyModel',
	        selector: ''
	    })
	});
	
	var PlaceProxyView = ProxyView.extend({
	    initialize: function() {
	        PlaceProxyView.__super__.initialize.apply(this, arguments);
	        this.update_selector(this.model, this.model.get('selector'));
	        this.listenTo(this.model, 'change:selector', this.update_selector);
	    },
	
	    update_selector: function(model, selector) {
	        this.box = selector && document.querySelector(selector) || this.el;
	        this.set_child(this.model.get('child'));
	    }
	});
	
	var BoxView = widget.DOMWidgetView.extend({
	    initialize: function() {
	        /**
	         * Public constructor
	         */
	        BoxView.__super__.initialize.apply(this, arguments);
	        this.children_views = new widget.ViewList(this.add_child_model, null, this);
	        this.listenTo(this.model, 'change:children', function(model, value) {
	            this.children_views.update(value);
	        }, this);
	        this.listenTo(this.model, 'change:overflow_x', this.update_overflow_x, this);
	        this.listenTo(this.model, 'change:overflow_y', this.update_overflow_y, this);
	        this.listenTo(this.model, 'change:box_style', this.update_box_style, this);
	    },
	
	    update_attr: function(name, value) { // TODO: Deprecated in 5.0
	        /**
	         * Set a css attr of the widget view.
	         */
	        this.box.style[name] = value;
	    },
	
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-container');
	        this.el.classList.add('widget-box');
	        this.box = this.el;
	
	        this.children_views.update(this.model.get('children'));
	        this.update_overflow_x();
	        this.update_overflow_y();
	        this.update_box_style();
	    },
	
	    update_overflow_x: function() {
	        /**
	         * Called when the x-axis overflow setting is changed.
	         */
	        this.box.style.overflowX = this.model.get('overflow_x');
	    },
	
	    update_overflow_y: function() {
	        /**
	         * Called when the y-axis overflow setting is changed.
	         */
	        this.box.style.overflowY = this.model.get('overflow_y');
	    },
	
	    update_box_style: function() {
	        var class_map = {
	            success: ['alert', 'alert-success'],
	            info: ['alert', 'alert-info'],
	            warning: ['alert', 'alert-warning'],
	            danger: ['alert', 'alert-danger']
	        };
	        this.update_mapped_classes(class_map, 'box_style', this.box);
	    },
	
	    add_child_model: function(model) {
	        /**
	         * Called when a model is added to the children list.
	         */
	        var that = this;
	        // we insert a dummy element so the order is preserved when we add
	        // the rendered content later.
	        var dummy = document.createElement('div');
	        that.box.appendChild(dummy);
	
	        return this.create_child_view(model).then(function(view) {
	            that.box.replaceChild(view.el, dummy);
	
	            // Trigger the displayed event of the child view.
	            that.displayed.then(function() {
	                view.trigger('displayed', that);
	            });
	            return view;
	        }).catch(utils.reject('Could not add child view to box', true));
	    },
	
	    remove: function() {
	        /**
	         * We remove this widget before removing the children as an optimization
	         * we want to remove the entire container from the DOM first before
	         * removing each individual child separately.
	         */
	        BoxView.__super__.remove.apply(this, arguments);
	        this.children_views.remove();
	    }
	});
	
	var FlexBoxModel = BoxModel.extend({ // TODO: Deprecated in 5.0 (entire model)
	    defaults: _.extend({}, BoxModel.prototype.defaults, {
	        _view_name: 'FlexBoxView',
	        _model_name: 'FlexBoxModel',
	        orientation: 'vertical',
	        pack: 'start',
	        alignt: 'start'
	    })
	});
	
	var FlexBoxView = BoxView.extend({ // TODO: Deprecated in 5.0 (entire view)
	    render: function() {
	        FlexBoxView.__super__.render.apply(this);
	        this.listenTo(this.model, 'change:orientation', this.update_orientation, this);
	        this.listenTo(this.model, 'change:flex', this._flex_changed, this);
	        this.listenTo(this.model, 'change:pack', this._pack_changed, this);
	        this.listenTo(this.model, 'change:align', this._align_changed, this);
	        this._flex_changed();
	        this._pack_changed();
	        this._align_changed();
	        this.update_orientation();
	    },
	
	    update_orientation: function() {
	        var orientation = this.model.get('orientation');
	        if (orientation == 'vertical') {
	            this.box.classList.remove('hbox');
	            this.box.classList.add('vbox');
	        } else {
	            this.box.classList.remove('vbox');
	            this.box.classList.add('hbox');
	        }
	    },
	
	    _flex_changed: function() {
	        if (this.model.previous('flex')) {
	            this.box.classList.remove('box-flex' + this.model.previous('flex'));
	        }
	        this.box.classList.add('box-flex' + this.model.get('flex'));
	    },
	
	    _pack_changed: function() {
	        if (this.model.previous('pack')) {
	            this.box.classList.remove(this.model.previous('pack'));
	        }
	        this.box.classList.add(this.model.get('pack'));
	    },
	
	    _align_changed: function() {
	        if (this.model.previous('align')) {
	            this.box.classList.remove('align-' + this.model.previous('align'));
	        }
	        this.box.classList.add('align-' + this.model.get('align'));
	    }
	});
	
	module.exports = {
	    BoxModel: BoxModel,
	    BoxView: BoxView,
	    FlexBoxModel: FlexBoxModel, // TODO: Deprecated in 5.0
	    FlexBoxView: FlexBoxView, // TODO: Deprecated in 5.0
	    ProxyModel: ProxyModel,
	    ProxyView: ProxyView,
	    PlaceProxyModel: PlaceProxyModel,
	    PlaceProxyView: PlaceProxyView
	};


/***/ },
/* 442 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var _ = __webpack_require__(429);
	var widget = __webpack_require__(436);
	var int_widgets = __webpack_require__(443);
	var d3format = __webpack_require__(444).format;
	
	
	var FloatModel = widget.DOMWidgetModel.extend({
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        _model_name: "FloatModel",
	        value: 0,
	        disabled: false,
	        description: ""
	    }),
	});
	
	
	var BoundedFloatModel = FloatModel.extend({
	    defaults: _.extend({}, FloatModel.prototype.defaults, {
	        _model_name: "BoundedFloatModel",
	        step: 1.0,
	        max: 100.0,
	        min: 0.0
	    }),
	});
	
	
	var FloatSliderModel = BoundedFloatModel.extend({
	    defaults: _.extend({}, BoundedFloatModel.prototype.defaults, {
	        _model_name: "FloatSliderModel",
	        _view_name: "FloatSliderView",
	        orientation: "horizontal",
	        _range: false,
	        readout: true,
	        readout_format: '.2f',
	        slider_color: null,
	        continuous_update: true
	    }),
	
	    initialize: function () {
	        FloatSliderModel.__super__.initialize.apply(this, arguments);
	        this.on('change:readout_format', this.update_readout_format, this);
	        this.update_readout_format();
	    },
	
	    update_readout_format: function() {
	        this.readout_formatter = d3format(this.get('readout_format'));
	    }
	});
	
	
	var IntSliderView = int_widgets.IntSliderView;
	var IntTextView = int_widgets.IntTextView;
	
	var FloatSliderView = IntSliderView.extend({
	    _parse_value: parseFloat,
	
	    // matches: whitespace?, float, whitespace?, [-:], whitespace?, float
	    _range_regex: /^\s*([+-]?(?:\d*\.?\d+|\d+\.)(?:[eE][+-]?\d+)?)\s*[-:]\s*([+-]?(?:\d*\.?\d+|\d+\.)(?:[eE][+-]?\d+)?)/,
	
	    _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 x;
	    },
	});
	
	
	var FloatTextModel = FloatModel.extend({
	    defaults: _.extend({}, FloatModel.prototype.defaults, {
	        _model_name: "FloatTextModel",
	        _view_name: "FloatTextView"
	    }),
	});
	
	
	var FloatTextView = IntTextView.extend({
	    _parse_value: parseFloat
	});
	
	
	module.exports = {
	    FloatSliderModel: FloatSliderModel,
	    FloatTextModel: FloatTextModel,
	    FloatSliderView: FloatSliderView,
	    FloatTextView: FloatTextView
	};


/***/ },
/* 443 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var widget = __webpack_require__(436);
	var _ = __webpack_require__(429);
	var $ = __webpack_require__(426);
	var d3format = __webpack_require__(444).format;
	
	__webpack_require__(445);
	
	
	var IntModel = widget.DOMWidgetModel.extend({
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        _model_name: 'IntModel',
	        value: 0,
	        disabled: false,
	        description: ''
	    })
	});
	
	var BoundedIntModel = IntModel.extend({
	    defaults: _.extend({}, IntModel.prototype.defaults, {
	        _model_name: 'BoundedIntModel',
	        step: 1,
	        max: 100,
	        min: 0
	    })
	});
	
	var IntSliderModel = BoundedIntModel.extend({
	    defaults: _.extend({}, BoundedIntModel.prototype.defaults, {
	        _model_name: 'IntSliderModel',
	        _view_name: 'IntSliderView',
	        orientation: 'horizontal',
	        _range: false,
	        readout: true,
	        readout_format: 'd',
	        slider_color: null,
	        continuous_update: true
	    }),
	
	    initialize: function () {
	        IntSliderModel.__super__.initialize.apply(this, arguments);
	        this.on('change:readout_format', this.update_readout_format, this);
	        this.update_readout_format();
	    },
	
	    update_readout_format: function() {
	        this.readout_formatter = d3format(this.get('readout_format'));
	    }
	});
	
	var IntSliderView = widget.DOMWidgetView.extend({
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-hbox');
	        this.el.classList.add('widget-hslider');
	
	        this.label = document.createElement('div');
	        this.el.appendChild(this.label);
	        this.label.classList.add('widget-label');
	        this.label.style.display = 'none';
	
	        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 = $('<div />')
	            .addClass('slider-container')
	            .append(this.$slider);
	        this.$el.append(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';
	
	        this.listenTo(this.model, 'change:slider_color', function(sender, value) {
	            this.$slider.find('a').css('background', value);
	        }, this);
	        this.listenTo(this.model, 'change:description', function(sender, value) {
	            this.updateDescription();
	        }, this);
	
	        this.$slider.find('a').css('background', this.model.get('slider_color'));
	
	        // Set defaults.
	        this.update();
	        this.updateDescription();
	    },
	
	    update_attr: function(name, value) { // TODO: Deprecated in 5.0
	        /**
	         * Set a css attr of the widget view.
	         */
	        if (name == 'color') {
	            this.readout.style[name] = value;
	        } else if (name.substring(0, 4) == 'font') {
	            this.readout.style[name] = value;
	        } else if (name.substring(0, 6) == 'border') {
	            this.$slider.find('a').css(name, value);
	            this.$slider_container.css(name, value);
	        } else if (name == 'background') {
	            this.$slider_container.css(name, value);
	        } else {
	            this.el.style[name] = value;
	        }
	    },
	
	    updateDescription: function(options) {
	        var description = this.model.get('description');
	        if (description.length === 0) {
	            this.label.style.display = 'none';
	        } else {
	            this.typeset(this.label, description);
	            this.label.style.display = '';
	        }
	    },
	
	    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 = this;
	            that.$slider.slider({});
	
	            _.each(jquery_slider_keys, function(key, i) {
	                var model_value = that.model.get(key);
	                if (model_value !== undefined) {
	                    that.$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);
	            }
	
	            var range_value = this.model.get('_range');
	            if (range_value !== undefined) {
	                this.$slider.slider('option', 'range', range_value);
	            }
	
	            // 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');
	            var min = this.model.get('min');
	            var max = this.model.get('max');
	            if (this.model.get('_range')) {
	                this.$slider.slider('option', 'values', [min, min]);
	            } else {
	                this.$slider.slider('option', 'value', min);
	            }
	            this.$slider.slider('option', 'orientation', orientation);
	            var value = this.model.get('value');
	            if (this.model.get('_range')) {
	                // values for the range case are validated python-side in
	                // _Bounded{Int,Float}RangeWidget._validate
	                this.$slider.slider('option', 'values', value);
	                this.readout.textContent = this.valueToString(value);
	            } else {
	                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();
	            }
	
	            // Use the right CSS classes for vertical & horizontal sliders
	            if (orientation=='vertical') {
	                this.el.classList.remove('widget-hslider');
	                this.el.classList.add('widget-vslider');
	                this.el.classList.remove('widget-hbox');
	                this.el.classList.add('widget-vbox');
	            } else {
	                this.el.classList.remove('widget-vslider');
	                this.el.classList.add('widget-hslider');
	                this.el.classList.remove('widget-vbox');
	                this.el.classList.add('widget-hbox');
	            }
	
	            var readout = this.model.get('readout');
	            if (readout) {
	                this.readout.style.display = '';
	                this.displayed.then(function() {
	                    if (that.readout_overflow()) {
	                        that.readout.classList.add('overflow');
	                    } else {
	                        that.readout.classList.remove('overflow');
	                    }
	                });
	            } else {
	                this.readout.style.display = 'none';
	            }
	
	        }
	        return IntSliderView.__super__.update.apply(this);
	    },
	
	    /**
	     * Returns true if the readout box content overflows.
	     */
	    readout_overflow: function() {
	        return this.readout.scrollWidth > this.readout.clientWidth;
	    },
	
	    /**
	     * Write value to a string
	     * @param  {number|number[]} value
	     * @return {string}
	     */
	    valueToString: function(value) {
	        var format = this.model.readout_formatter;
	        if (this.model.get('_range')) {
	            return value.map(function (v) {
	                return format(v);
	            }).join('-');
	        } else {
	            return format(value);
	        }
	    },
	
	    /**
	     * Parse value from a string
	     * @param  {string} text
	     * @return {number|number[]} value
	     */
	    stringToValue: function(text) {
	        if (this.model.get('_range')) {
	            // range case
	            // 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;
	            }
	
	        } else {
	            return this._parse_value(text);
	        }
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'slide': 'handleSliderChange',
	        'slidestop': 'handleSliderChanged',
	        'blur [contentEditable=true]': 'handleTextChange',
	        'keydown [contentEditable=true]': 'handleKeyDown'
	    },
	
	    handleKeyDown: function(e) {
	        if (e.keyCode == 13) { /* keyboard keycodes `enter` */
	            e.preventDefault();
	            this.handleTextChange();
	        }
	    },
	
	    handleTextChange: function() {
	        /**
	         * this handles the entry of text into the contentEditable label
	         * first, the value is checked if it contains a parseable number
	         *      (or pair of numbers, for the _range case)
	         * 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
	         *
	         * the step size is not enforced
	         */
	        var value = this.stringToValue(this.readout.textContent);
	        var vmin = this.model.get('min');
	        var vmax = this.model.get('max');
	        if (this.model.get('_range')) {
	            // 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'));
	                }
	            }
	        } else {
	
	            // single value case
	            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'));
	                }
	            }
	        }
	    },
	
	    _parse_value: parseInt,
	
	    _range_regex: /^\s*([+-]?\d+)\s*[-:]\s*([+-]?\d+)/,
	
	    /**
	     * Called when the slider value is changing.
	     */
	    handleSliderChange: function(e, ui) {
	        var actual_value;
	        if (this.model.get('_range')) {
	            actual_value = ui.values.map(this._validate_slide_value);
	            this.readout.textContent = this.valueToString(actual_value);
	        } else {
	            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.
	     */
	    handleSliderChanged: function(e, ui) {
	        var actual_value;
	        if (this.model.get('_range')) {
	            actual_value = ui.values.map(this._validate_slide_value);
	        } else {
	            actual_value = this._validate_slide_value(ui.value);
	        }
	        this.model.set('value', actual_value, {updated_view: this});
	        this.touch();
	    },
	
	    _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);
	    }
	});
	
	var IntTextModel = IntModel.extend({
	    defaults: _.extend({}, IntModel.prototype.defaults, {
	        _model_name: 'IntTextModel',
	        _view_name: 'IntTextView'
	    })
	});
	
	var IntTextView = widget.DOMWidgetView.extend({
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-hbox');
	        this.el.classList.add('widget-text');
	
	        this.label = document.createElement('div');
	        this.el.appendChild(this.label);
	        this.label.className = 'widget-label';
	        this.label.style.display = 'none';
	
	        this.textbox = document.createElement('input');
	        this.textbox.setAttribute('type', 'text');
	        this.textbox.className = 'form-control';
	        this.el.appendChild(this.textbox);
	
	        this.listenTo(this.model, 'change:description', function(sender, value) {
	            this.updateDescription();
	        }, this);
	
	        this.update(); // Set defaults.
	        this.updateDescription();
	    },
	
	    updateDescription: function() {
	        var description = this.model.get('description');
	        if (description.length === 0) {
	            this.label.style.display = 'none';
	        } else {
	            this.typeset(this.label, description);
	            this.label.style.display = '';
	        }
	    },
	
	    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) {
	            var value = this.model.get('value');
	            if (this._parse_value(this.textbox.value != value)) {
	                this.textbox.value = value;
	            }
	
	            var disabled = this.model.get('disabled');
	            if (disabled) {
	                this.textbox.setAttribute('disabled', disabled);
	            } else {
	                this.textbox.removeAttribute('disabled');
	            }
	        }
	        return IntTextView.__super__.update.apply(this);
	    },
	
	    update_attr: function(name, value) { // TODO: Deprecated in 5.0
	        /**
	         * Set a css attr of the widget view.
	         */
	        if (name == 'padding' || name == 'margin') {
	            this.el.style[name] = value;
	        } else {
	            this.textbox.style[name] = value;
	        }
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'keyup input'  : 'handleChanging',
	        'paste input'  : 'handleChanging',
	        'cut input'    : 'handleChanging',
	
	        // Fires only when control is validated or looses focus.
	        'change input' : 'handleChanged'
	    },
	
	    handleChanging: function(e) {
	        /**
	         * Handles and validates user input.
	         *
	         * Try to parse value as an int.
	         */
	        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)) {
	            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();
	            }
	        }
	    },
	
	    handleChanged: function(e) {
	        /**
	         * Applies validated input.
	         */
	        if (e.target.value.trim() === '' || e.target.value !== this.model.get('value')) {
	            e.target.value = this.model.get('value');
	        }
	    },
	
	    _parse_value: parseInt
	});
	
	var ProgressModel = BoundedIntModel.extend({
	    defaults: _.extend({}, BoundedIntModel.prototype.defaults, {
	        _model_name: 'ProgressModel',
	        _view_name: 'ProgressView',
	        orientation: 'horizontal',
	        bar_style: ''
	    })
	});
	
	var ProgressView = widget.DOMWidgetView.extend({
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        var orientation = this.model.get('orientation');
	        var className = orientation === 'horizontal' ? 'widget-hprogress'
	            : 'widget-vprogress';
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add(className);
	
	        this.label = document.createElement('div');
	        this.el.appendChild(this.label);
	        this.label.classList.add('widget-label');
	        this.label.style.display = 'none';
	
	        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 = 0;
	        this.bar.style.left = 0;
	        this.progress.appendChild(this.bar);
	
	        // Set defaults.
	        this.update();
	        this.updateDescription();
	
	        this.listenTo(this.model, 'change:bar_style', this.update_bar_style, this);
	        this.listenTo(this.model, 'change:description', function(sender, value) {
	            this.updateDescription();
	        }, this);
	
	        this.update_bar_style();
	    },
	
	    updateDescription: function() {
	        var description = this.model.get('description');
	        if (description.length === 0) {
	            this.label.style.display = 'none';
	        } else {
	            this.typeset(this.label, description);
	            this.label.style.display = '';
	        }
	    },
	
	    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 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-vbox');
	            this.el.classList.remove('widget-vprogress');
	
	            this.el.classList.add('widget-hbox');
	            this.el.classList.add('widget-hprogress');
	
	            this.bar.style.width = percent + '%';
	            this.bar.style.height = '100%';
	        } else {
	            this.el.classList.remove('widget-hbox');
	            this.el.classList.remove('widget-hprogress');
	
	            this.el.classList.add('widget-vbox');
	            this.el.classList.add('widget-hprogress');
	
	            this.bar.style.width = '100%';
	            this.bar.style.height = percent + '%';
	        }
	        return ProgressView.__super__.update.apply(this);
	    },
	
	    update_bar_style: function() {
	        var class_map = {
	            success: ['progress-bar-success'],
	            info: ['progress-bar-info'],
	            warning: ['progress-bar-warning'],
	            danger: ['progress-bar-danger']
	        };
	        this.update_mapped_classes(class_map, 'bar_style', this.bar);
	    },
	
	    update_attr: function(name, value) { // TODO: Deprecated in 5.0
	        /**
	         * Set a css attr of the widget view.
	         */
	        if (name == 'color') {
	            this.bar.style.background = value;
	        } else if (name.substring(0, 6) == 'border' || name == 'background') {
	            this.progress.style[name] = value;
	        } else {
	            this.el.style[name] = value;
	        }
	    }
	});
	
	module.exports = {
	    IntModel: IntModel,
	    BoundedIntModel: BoundedIntModel,
	    IntSliderModel: IntSliderModel,
	    IntSliderView: IntSliderView,
	    IntTextModel: IntTextModel,
	    IntTextView: IntTextView,
	    ProgressModel: ProgressModel,
	    ProgressView: ProgressView
	};


/***/ },
/* 444 */
/***/ function(module, exports, __webpack_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;
	
	}));

/***/ },
/* 445 */
/***/ function(module, exports, __webpack_require__) {

	var jQuery = __webpack_require__(426);
	
	/*! jQuery UI - v1.10.3 - 2013-05-03
	* http://jqueryui.com
	* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
	* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
	(function( $, undefined ) {
	
	var uuid = 0,
		runiqueId = /^ui-id-\d+$/;
	
	// $.ui might exist from components with no dependencies, e.g., $.ui.position
	$.ui = $.ui || {};
	
	$.extend( $.ui, {
		version: "1.10.3",
	
		keyCode: {
			BACKSPACE: 8,
			COMMA: 188,
			DELETE: 46,
			DOWN: 40,
			END: 35,
			ENTER: 13,
			ESCAPE: 27,
			HOME: 36,
			LEFT: 37,
			NUMPAD_ADD: 107,
			NUMPAD_DECIMAL: 110,
			NUMPAD_DIVIDE: 111,
			NUMPAD_ENTER: 108,
			NUMPAD_MULTIPLY: 106,
			NUMPAD_SUBTRACT: 109,
			PAGE_DOWN: 34,
			PAGE_UP: 33,
			PERIOD: 190,
			RIGHT: 39,
			SPACE: 32,
			TAB: 9,
			UP: 38
		}
	});
	
	// plugins
	$.fn.extend({
		focus: (function( orig ) {
			return function( delay, fn ) {
				return typeof delay === "number" ?
					this.each(function() {
						var elem = this;
						setTimeout(function() {
							$( elem ).focus();
							if ( fn ) {
								fn.call( elem );
							}
						}, delay );
					}) :
					orig.apply( this, arguments );
			};
		})( $.fn.focus ),
	
		scrollParent: function() {
			var scrollParent;
			if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
				scrollParent = this.parents().filter(function() {
					return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
				}).eq(0);
			} else {
				scrollParent = this.parents().filter(function() {
					return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
				}).eq(0);
			}
	
			return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
		},
	
		zIndex: function( zIndex ) {
			if ( zIndex !== undefined ) {
				return this.css( "zIndex", zIndex );
			}
	
			if ( this.length ) {
				var elem = $( this[ 0 ] ), position, value;
				while ( elem.length && elem[ 0 ] !== document ) {
					// Ignore z-index if position is set to a value where z-index is ignored by the browser
					// This makes behavior of this function consistent across browsers
					// WebKit always returns auto if the element is positioned
					position = elem.css( "position" );
					if ( position === "absolute" || position === "relative" || position === "fixed" ) {
						// IE returns 0 when zIndex is not specified
						// other browsers return a string
						// we ignore the case of nested elements with an explicit value of 0
						// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
						value = parseInt( elem.css( "zIndex" ), 10 );
						if ( !isNaN( value ) && value !== 0 ) {
							return value;
						}
					}
					elem = elem.parent();
				}
			}
	
			return 0;
		},
	
		uniqueId: function() {
			return this.each(function() {
				if ( !this.id ) {
					this.id = "ui-id-" + (++uuid);
				}
			});
		},
	
		removeUniqueId: function() {
			return this.each(function() {
				if ( runiqueId.test( this.id ) ) {
					$( this ).removeAttr( "id" );
				}
			});
		}
	});
	
	// selectors
	function focusable( element, isTabIndexNotNaN ) {
		var map, mapName, img,
			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 + "]" )[0];
			return !!img && visible( img );
		}
		return ( /input|select|textarea|button|object/.test( nodeName ) ?
			!element.disabled :
			"a" === nodeName ?
				element.href || isTabIndexNotNaN :
				isTabIndexNotNaN) &&
			// the element and all of its ancestors must be visible
			visible( element );
	}
	
	function visible( element ) {
		return $.expr.filters.visible( element ) &&
			!$( element ).parents().addBack().filter(function() {
				return $.css( this, "visibility" ) === "hidden";
			}).length;
	}
	
	$.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 ] );
			},
	
		focusable: function( element ) {
			return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
		},
	
		tabbable: function( element ) {
			var tabIndex = $.attr( element, "tabindex" ),
				isTabIndexNaN = isNaN( tabIndex );
			return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
		}
	});
	
	// support: jQuery <1.8
	if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
		$.each( [ "Width", "Height" ], function( i, name ) {
			var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
				type = name.toLowerCase(),
				orig = {
					innerWidth: $.fn.innerWidth,
					innerHeight: $.fn.innerHeight,
					outerWidth: $.fn.outerWidth,
					outerHeight: $.fn.outerHeight
				};
	
			function reduce( elem, size, border, margin ) {
				$.each( side, function() {
					size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
					if ( border ) {
						size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
					}
					if ( margin ) {
						size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
					}
				});
				return size;
			}
	
			$.fn[ "inner" + name ] = function( size ) {
				if ( size === undefined ) {
					return orig[ "inner" + name ].call( this );
				}
	
				return this.each(function() {
					$( this ).css( type, reduce( this, size ) + "px" );
				});
			};
	
			$.fn[ "outer" + name] = function( size, margin ) {
				if ( typeof size !== "number" ) {
					return orig[ "outer" + name ].call( this, size );
				}
	
				return this.each(function() {
					$( this).css( type, reduce( this, size, true, margin ) + "px" );
				});
			};
		});
	}
	
	// support: jQuery <1.8
	if ( !$.fn.addBack ) {
		$.fn.addBack = function( selector ) {
			return this.add( selector == null ?
				this.prevObject : this.prevObject.filter( selector )
			);
		};
	}
	
	// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
	if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
		$.fn.removeData = (function( removeData ) {
			return function( key ) {
				if ( arguments.length ) {
					return removeData.call( this, $.camelCase( key ) );
				} else {
					return removeData.call( this );
				}
			};
		})( $.fn.removeData );
	}
	
	
	
	
	
	// deprecated
	$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
	
	$.support.selectstart = "onselectstart" in document.createElement( "div" );
	$.fn.extend({
		disableSelection: function() {
			return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
				".ui-disableSelection", function( event ) {
					event.preventDefault();
				});
		},
	
		enableSelection: function() {
			return this.unbind( ".ui-disableSelection" );
		}
	});
	
	$.extend( $.ui, {
		// $.ui.plugin is deprecated. Use $.widget() extensions instead.
		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 ) {
				var i,
					set = instance.plugins[ name ];
				if ( !set || !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 );
					}
				}
			}
		},
	
		// only used by resizable
		hasScroll: function( el, a ) {
	
			//If overflow is hidden, the element might have extra content, but the user wants to hide it
			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;
		}
	});
	
	})( jQuery );
	
	(function( $, undefined ) {
	
	var uuid = 0,
		slice = Array.prototype.slice,
		_cleanData = $.cleanData;
	$.cleanData = function( elems ) {
		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
			try {
				$( elem ).triggerHandler( "remove" );
			// http://bugs.jquery.com/ticket/8235
			} catch( e ) {}
		}
		_cleanData( elems );
	};
	
	$.widget = function( name, base, prototype ) {
		var fullName, existingConstructor, constructor, basePrototype,
			// proxiedPrototype allows the provided prototype to remain unmodified
			// so that it can be used as a mixin for multiple widgets (#8876)
			proxiedPrototype = {},
			namespace = name.split( "." )[ 0 ];
	
		name = name.split( "." )[ 1 ];
		fullName = namespace + "-" + name;
	
		if ( !prototype ) {
			prototype = base;
			base = $.Widget;
		}
	
		// 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() {
				var _super = function() {
						return base.prototype[ prop ].apply( this, arguments );
					},
					_superApply = function( args ) {
						return base.prototype[ prop ].apply( this, args );
					};
				return function() {
					var __super = this._super,
						__superApply = this._superApply,
						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
		}, 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 );
	};
	
	$.widget.extend = function( target ) {
		var input = slice.call( arguments, 1 ),
			inputIndex = 0,
			inputLength = input.length,
			key,
			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",
				args = slice.call( arguments, 1 ),
				returnValue = this;
	
			// allow multiple hashes to be passed on init
			options = !isMethodCall && args.length ?
				$.widget.extend.apply( null, [ options ].concat(args) ) :
				options;
	
			if ( isMethodCall ) {
				this.each(function() {
					var methodValue,
						instance = $.data( this, fullName );
					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 {
				this.each(function() {
					var instance = $.data( this, fullName );
					if ( instance ) {
						instance.option( options || {} )._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: {
			disabled: false,
	
			// callbacks
			create: null
		},
		_createWidget: function( options, element ) {
			element = $( element || this.defaultElement || this )[ 0 ];
			this.element = $( element );
			this.uuid = uuid++;
			this.eventNamespace = "." + this.widgetName + this.uuid;
			this.options = $.widget.extend( {},
				this.options,
				this._getCreateOptions(),
				options );
	
			this.bindings = $();
			this.hoverable = $();
			this.focusable = $();
	
			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._create();
			this._trigger( "create", null, this._getCreateEventData() );
			this._init();
		},
		_getCreateOptions: $.noop,
		_getCreateEventData: $.noop,
		_create: $.noop,
		_init: $.noop,
	
		destroy: function() {
			this._destroy();
			// we can probably remove the unbind calls in 2.0
			// all event bindings should go through this._on()
			this.element
				.unbind( this.eventNamespace )
				// 1.9 BC for #7810
				// TODO remove dual storage
				.removeData( this.widgetName )
				.removeData( this.widgetFullName )
				// support: jquery <1.6.3
				// http://bugs.jquery.com/ticket/9413
				.removeData( $.camelCase( this.widgetFullName ) );
			this.widget()
				.unbind( this.eventNamespace )
				.removeAttr( "aria-disabled" )
				.removeClass(
					this.widgetFullName + "-disabled " +
					"ui-state-disabled" );
	
			// clean up events and states
			this.bindings.unbind( this.eventNamespace );
			this.hoverable.removeClass( "ui-state-hover" );
			this.focusable.removeClass( "ui-state-focus" );
		},
		_destroy: $.noop,
	
		widget: function() {
			return this.element;
		},
	
		option: function( key, value ) {
			var options = key,
				parts,
				curOption,
				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 ( value === undefined ) {
						return curOption[ key ] === undefined ? null : curOption[ key ];
					}
					curOption[ key ] = value;
				} else {
					if ( value === undefined ) {
						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 ) {
			this.options[ key ] = value;
	
			if ( key === "disabled" ) {
				this.widget()
					.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
					.attr( "aria-disabled", value );
				this.hoverable.removeClass( "ui-state-hover" );
				this.focusable.removeClass( "ui-state-focus" );
			}
	
			return this;
		},
	
		enable: function() {
			return this._setOption( "disabled", false );
		},
		disable: function() {
			return this._setOption( "disabled", true );
		},
	
		_on: function( suppressDisabledCheck, element, handlers ) {
			var delegateElement,
				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 {
				// accept selectors, DOM elements
				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*(.*)$/ ),
					eventName = match[1] + instance.eventNamespace,
					selector = match[2];
				if ( selector ) {
					delegateElement.delegate( selector, eventName, handlerProxy );
				} else {
					element.bind( eventName, handlerProxy );
				}
			});
		},
	
		_off: function( element, eventName ) {
			eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
			element.unbind( eventName ).undelegate( eventName );
		},
	
		_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 ) {
					$( event.currentTarget ).addClass( "ui-state-hover" );
				},
				mouseleave: function( event ) {
					$( event.currentTarget ).removeClass( "ui-state-hover" );
				}
			});
		},
	
		_focusable: function( element ) {
			this.focusable = this.focusable.add( element );
			this._on( element, {
				focusin: function( event ) {
					$( event.currentTarget ).addClass( "ui-state-focus" );
				},
				focusout: function( event ) {
					$( event.currentTarget ).removeClass( "ui-state-focus" );
				}
			});
		},
	
		_trigger: function( type, event, data ) {
			var prop, orig,
				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,
				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();
				});
			}
		};
	});
	
	})( jQuery );
	
	(function( $, undefined ) {
	
	var mouseHandled = false;
	$( document ).mouseup( function() {
		mouseHandled = false;
	});
	
	$.widget("ui.mouse", {
		version: "1.10.3",
		options: {
			cancel: "input,textarea,button,select,option",
			distance: 1,
			delay: 0
		},
		_mouseInit: function() {
			var that = this;
	
			this.element
				.bind("mousedown."+this.widgetName, function(event) {
					return that._mouseDown(event);
				})
				.bind("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.unbind("."+this.widgetName);
			if ( this._mouseMoveDelegate ) {
				$(document)
					.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
					.unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
			}
		},
	
		_mouseDown: function(event) {
			// don't let more than one widget handle mouseStart
			if( mouseHandled ) { return; }
	
			// 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);
			};
			$(document)
				.bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
				.bind("mouseup."+this.widgetName, this._mouseUpDelegate);
	
			event.preventDefault();
	
			mouseHandled = true;
			return true;
		},
	
		_mouseMove: function(event) {
			// 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);
			}
	
			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) {
			$(document)
				.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
				.unbind("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);
			}
	
			return false;
		},
	
		_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; }
	});
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.widget("ui.draggable", $.ui.mouse, {
		version: "1.10.3",
		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" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
				this.element[0].style.position = "relative";
			}
			if (this.options.addClasses){
				this.element.addClass("ui-draggable");
			}
			if (this.options.disabled){
				this.element.addClass("ui-draggable-disabled");
			}
	
			this._mouseInit();
	
		},
	
		_destroy: function() {
			this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
			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;
			}
	
			$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
				$("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
				.css({
					width: this.offsetWidth+"px", height: this.offsetHeight+"px",
					position: "absolute", opacity: "0.001", zIndex: 1000
				})
				.css($(this).offset())
				.appendTo("body");
			});
	
			return true;
	
		},
	
		_mouseStart: function(event) {
	
			var o = this.options;
	
			//Create and append the visible helper
			this.helper = this._createHelper(event);
	
			this.helper.addClass("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();
			this.offsetParent = this.helper.offsetParent();
			this.offsetParentCssPosition = this.offsetParent.css( "position" );
	
			//The element's absolute position on the page minus margins
			this.offset = this.positionAbs = this.element.offset();
			this.offset = {
				top: this.offset.top - this.margins.top,
				left: this.offset.left - this.margins.left
			};
	
			//Reset scroll cache
			this.offset.scroll = false;
	
			$.extend(this.offset, {
				click: { //Where the click happened, relative to the element
					left: event.pageX - this.offset.left,
					top: event.pageY - this.offset.top
				},
				parent: this._getParentOffset(),
				relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
			});
	
			//Generate the original position
			this.originalPosition = this.position = this._generatePosition(event);
			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);
			}
	
	
			this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
	
			//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;
		},
	
		_mouseDrag: function(event, noPropagation) {
			// reset any necessary cached properties (see #5009)
			if ( this.offsetParentCssPosition === "fixed" ) {
				this.offset.parent = this._getParentOffset();
			}
	
			//Compute the helpers position
			this.position = this._generatePosition(event);
			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({});
					return false;
				}
				this.position = ui.position;
			}
	
			if(!this.options.axis || this.options.axis !== "y") {
				this.helper[0].style.left = this.position.left+"px";
			}
			if(!this.options.axis || this.options.axis !== "x") {
				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 the original element is no longer in the DOM don't bother to continue (see #8269)
			if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
				return 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) {
			//Remove frame helpers
			$("div.ui-draggable-iframeFix").each(function() {
				this.parentNode.removeChild(this);
			});
	
			//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
			if( $.ui.ddmanager ) {
				$.ui.ddmanager.dragStop(this, event);
			}
	
			return $.ui.mouse.prototype._mouseUp.call(this, event);
		},
	
		cancel: function() {
	
			if(this.helper.is(".ui-draggable-dragging")) {
				this._mouseUp({});
			} else {
				this._clear();
			}
	
			return this;
	
		},
	
		_getHandle: function(event) {
			return this.options.handle ?
				!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
				true;
		},
	
		_createHelper: function(event) {
	
			var o = this.options,
				helper = $.isFunction(o.helper) ? $(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));
			}
	
			if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
				helper.css("position", "absolute");
			}
	
			return helper;
	
		},
	
		_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;
			}
		},
	
		_getParentOffset: function() {
	
			//Get the offsetParent and cache its position
			var po = this.offsetParent.offset();
	
			// 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();
			}
	
			//This needs to be actually done for all browsers, since pageX/pageY includes this information
			//Ugly IE fix
			if((this.offsetParent[0] === document.body) ||
				(this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
				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") {
				var p = this.element.position();
				return {
					top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
					left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
				};
			} else {
				return { top: 0, left: 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 over, c, ce,
				o = this.options;
	
			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;
			}
	
			over = c.css( "overflow" ) !== "hidden";
	
			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 ) ,
				( over ? 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,
				( over ? 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.relative_container = c;
		},
	
		_convertPositionTo: function(d, pos) {
	
			if(!pos) {
				pos = this.position;
			}
	
			var mod = d === "absolute" ? 1 : -1,
				scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
	
			//Cache the scroll
			if (!this.offset.scroll) {
				this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
			}
	
			return {
				top: (
					pos.top	+																// The absolute mouse position
					this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
					this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
					( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
				),
				left: (
					pos.left +																// The absolute mouse position
					this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
					this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
					( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
				)
			};
	
		},
	
		_generatePosition: function(event) {
	
			var containment, co, top, left,
				o = this.options,
				scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
				pageX = event.pageX,
				pageY = event.pageY;
	
			//Cache the scroll
			if (!this.offset.scroll) {
				this.offset.scroll = {top : scroll.scrollTop(), left : scroll.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 ( this.originalPosition ) {
				if ( this.containment ) {
					if ( this.relative_container ){
						co = this.relative_container.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;
				}
	
			}
	
			return {
				top: (
					pageY -																	// The absolute mouse position
					this.offset.click.top	-												// Click offset (relative to the element)
					this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
					this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
					( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
				),
				left: (
					pageX -																	// The absolute mouse position
					this.offset.click.left -												// Click offset (relative to the element)
					this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
					this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
					( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
				)
			};
	
		},
	
		_clear: function() {
			this.helper.removeClass("ui-draggable-dragging");
			if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
				this.helper.remove();
			}
			this.helper = null;
			this.cancelHelperRemoval = false;
		},
	
		// From now on bulk stuff - mainly helpers
	
		_trigger: function(type, event, ui) {
			ui = ui || this._uiHash();
			$.ui.plugin.call(this, type, [event, ui]);
			//The absolute position has to be recalculated after plugins
			if(type === "drag") {
				this.positionAbs = this._convertPositionTo("absolute");
			}
			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) {
	
			var inst = $(this).data("ui-draggable"), o = inst.options,
				uiSortable = $.extend({}, ui, { item: inst.element });
			inst.sortables = [];
			$(o.connectToSortable).each(function() {
				var sortable = $.data(this, "ui-sortable");
				if (sortable && !sortable.options.disabled) {
					inst.sortables.push({
						instance: sortable,
						shouldRevert: sortable.options.revert
					});
					sortable.refreshPositions();	// Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
					sortable._trigger("activate", event, uiSortable);
				}
			});
	
		},
		stop: function(event, ui) {
	
			//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
			var inst = $(this).data("ui-draggable"),
				uiSortable = $.extend({}, ui, { item: inst.element });
	
			$.each(inst.sortables, function() {
				if(this.instance.isOver) {
	
					this.instance.isOver = 0;
	
					inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
					this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
	
					//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
					if(this.shouldRevert) {
						this.instance.options.revert = this.shouldRevert;
					}
	
					//Trigger the stop of the sortable
					this.instance._mouseStop(event);
	
					this.instance.options.helper = this.instance.options._helper;
	
					//If the helper has been the original item, restore properties in the sortable
					if(inst.options.helper === "original") {
						this.instance.currentItem.css({ top: "auto", left: "auto" });
					}
	
				} else {
					this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
					this.instance._trigger("deactivate", event, uiSortable);
				}
	
			});
	
		},
		drag: function(event, ui) {
	
			var inst = $(this).data("ui-draggable"), that = this;
	
			$.each(inst.sortables, function() {
	
				var innermostIntersecting = false,
					thisSortable = this;
	
				//Copy over some variables to allow calling the sortable's native _intersectsWith
				this.instance.positionAbs = inst.positionAbs;
				this.instance.helperProportions = inst.helperProportions;
				this.instance.offset.click = inst.offset.click;
	
				if(this.instance._intersectsWith(this.instance.containerCache)) {
					innermostIntersecting = true;
					$.each(inst.sortables, function () {
						this.instance.positionAbs = inst.positionAbs;
						this.instance.helperProportions = inst.helperProportions;
						this.instance.offset.click = inst.offset.click;
						if (this !== thisSortable &&
							this.instance._intersectsWith(this.instance.containerCache) &&
							$.contains(thisSortable.instance.element[0], this.instance.element[0])
						) {
							innermostIntersecting = false;
						}
						return innermostIntersecting;
					});
				}
	
	
				if(innermostIntersecting) {
					//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
					if(!this.instance.isOver) {
	
						this.instance.isOver = 1;
						//Now we fake the start of dragging for the sortable instance,
						//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
						//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
						this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
						this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
						this.instance.options.helper = function() { return ui.helper[0]; };
	
						event.target = this.instance.currentItem[0];
						this.instance._mouseCapture(event, true);
						this.instance._mouseStart(event, true, true);
	
						//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
						this.instance.offset.click.top = inst.offset.click.top;
						this.instance.offset.click.left = inst.offset.click.left;
						this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
						this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
	
						inst._trigger("toSortable", event);
						inst.dropped = this.instance.element; //draggable revert needs that
						//hack so receive/update callbacks work (mostly)
						inst.currentItem = inst.element;
						this.instance.fromOutside = inst;
	
					}
	
					//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
					if(this.instance.currentItem) {
						this.instance._mouseDrag(event);
					}
	
				} 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(this.instance.isOver) {
	
						this.instance.isOver = 0;
						this.instance.cancelHelperRemoval = true;
	
						//Prevent reverting on this forced stop
						this.instance.options.revert = false;
	
						// The out event needs to be triggered independently
						this.instance._trigger("out", event, this.instance._uiHash(this.instance));
	
						this.instance._mouseStop(event, true);
						this.instance.options.helper = this.instance.options._helper;
	
						//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
						this.instance.currentItem.remove();
						if(this.instance.placeholder) {
							this.instance.placeholder.remove();
						}
	
						inst._trigger("fromSortable", event);
						inst.dropped = false; //draggable revert needs that
					}
	
				}
	
			});
	
		}
	});
	
	$.ui.plugin.add("draggable", "cursor", {
		start: function() {
			var t = $("body"), o = $(this).data("ui-draggable").options;
			if (t.css("cursor")) {
				o._cursor = t.css("cursor");
			}
			t.css("cursor", o.cursor);
		},
		stop: function() {
			var o = $(this).data("ui-draggable").options;
			if (o._cursor) {
				$("body").css("cursor", o._cursor);
			}
		}
	});
	
	$.ui.plugin.add("draggable", "opacity", {
		start: function(event, ui) {
			var t = $(ui.helper), o = $(this).data("ui-draggable").options;
			if(t.css("opacity")) {
				o._opacity = t.css("opacity");
			}
			t.css("opacity", o.opacity);
		},
		stop: function(event, ui) {
			var o = $(this).data("ui-draggable").options;
			if(o._opacity) {
				$(ui.helper).css("opacity", o._opacity);
			}
		}
	});
	
	$.ui.plugin.add("draggable", "scroll", {
		start: function() {
			var i = $(this).data("ui-draggable");
			if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
				i.overflowOffset = i.scrollParent.offset();
			}
		},
		drag: function( event ) {
	
			var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
	
			if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
	
				if(!o.axis || o.axis !== "x") {
					if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
						i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
					} else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
						i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
					}
				}
	
				if(!o.axis || o.axis !== "y") {
					if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
						i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
					} else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
						i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].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() {
	
			var i = $(this).data("ui-draggable"),
				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) {
	
			var ts, bs, ls, rs, l, r, t, b, i, first,
				inst = $(this).data("ui-draggable"),
				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;
				r = l + inst.snapElements[i].width;
				t = inst.snapElements[i].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 - inst.margins.top;
					}
					if(bs) {
						ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
					}
					if(ls) {
						ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
					}
					if(rs) {
						ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.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 - inst.margins.top;
					}
					if(bs) {
						ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
					}
					if(ls) {
						ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
					}
					if(rs) {
						ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.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() {
			var min,
				o = this.data("ui-draggable").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) {
			var t = $(ui.helper), o = $(this).data("ui-draggable").options;
			if(t.css("zIndex")) {
				o._zIndex = t.css("zIndex");
			}
			t.css("zIndex", o.zIndex);
		},
		stop: function(event, ui) {
			var o = $(this).data("ui-draggable").options;
			if(o._zIndex) {
				$(ui.helper).css("zIndex", o._zIndex);
			}
		}
	});
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	function isOverAxis( x, reference, size ) {
		return ( x > reference ) && ( x < ( reference + size ) );
	}
	
	$.widget("ui.droppable", {
		version: "1.10.3",
		widgetEventPrefix: "drop",
		options: {
			accept: "*",
			activeClass: false,
			addClasses: true,
			greedy: false,
			hoverClass: false,
			scope: "default",
			tolerance: "intersect",
	
			// callbacks
			activate: null,
			deactivate: null,
			drop: null,
			out: null,
			over: null
		},
		_create: function() {
	
			var o = this.options,
				accept = o.accept;
	
			this.isover = false;
			this.isout = true;
	
			this.accept = $.isFunction(accept) ? accept : function(d) {
				return d.is(accept);
			};
	
			//Store the droppable's proportions
			this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
	
			// Add the reference and positions to the manager
			$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
			$.ui.ddmanager.droppables[o.scope].push(this);
	
			(o.addClasses && this.element.addClass("ui-droppable"));
	
		},
	
		_destroy: function() {
			var i = 0,
				drop = $.ui.ddmanager.droppables[this.options.scope];
	
			for ( ; i < drop.length; i++ ) {
				if ( drop[i] === this ) {
					drop.splice(i, 1);
				}
			}
	
			this.element.removeClass("ui-droppable ui-droppable-disabled");
		},
	
		_setOption: function(key, value) {
	
			if(key === "accept") {
				this.accept = $.isFunction(value) ? value : function(d) {
					return d.is(value);
				};
			}
			$.Widget.prototype._setOption.apply(this, arguments);
		},
	
		_activate: function(event) {
			var draggable = $.ui.ddmanager.current;
			if(this.options.activeClass) {
				this.element.addClass(this.options.activeClass);
			}
			if(draggable){
				this._trigger("activate", event, this.ui(draggable));
			}
		},
	
		_deactivate: function(event) {
			var draggable = $.ui.ddmanager.current;
			if(this.options.activeClass) {
				this.element.removeClass(this.options.activeClass);
			}
			if(draggable){
				this._trigger("deactivate", event, this.ui(draggable));
			}
		},
	
		_over: function(event) {
	
			var draggable = $.ui.ddmanager.current;
	
			// Bail if draggable and droppable are same element
			if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
				return;
			}
	
			if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
				if(this.options.hoverClass) {
					this.element.addClass(this.options.hoverClass);
				}
				this._trigger("over", event, this.ui(draggable));
			}
	
		},
	
		_out: function(event) {
	
			var draggable = $.ui.ddmanager.current;
	
			// Bail if draggable and droppable are same element
			if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
				return;
			}
	
			if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
				if(this.options.hoverClass) {
					this.element.removeClass(this.options.hoverClass);
				}
				this._trigger("out", event, this.ui(draggable));
			}
	
		},
	
		_drop: function(event,custom) {
	
			var draggable = custom || $.ui.ddmanager.current,
				childrenIntersection = false;
	
			// Bail if draggable and droppable are same element
			if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
				return false;
			}
	
			this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
				var inst = $.data(this, "ui-droppable");
				if(
					inst.options.greedy &&
					!inst.options.disabled &&
					inst.options.scope === draggable.options.scope &&
					inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
					$.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
				) { childrenIntersection = true; return false; }
			});
			if(childrenIntersection) {
				return false;
			}
	
			if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
				if(this.options.activeClass) {
					this.element.removeClass(this.options.activeClass);
				}
				if(this.options.hoverClass) {
					this.element.removeClass(this.options.hoverClass);
				}
				this._trigger("drop", event, this.ui(draggable));
				return this.element;
			}
	
			return false;
	
		},
	
		ui: function(c) {
			return {
				draggable: (c.currentItem || c.element),
				helper: c.helper,
				position: c.position,
				offset: c.positionAbs
			};
		}
	
	});
	
	$.ui.intersect = function(draggable, droppable, toleranceMode) {
	
		if (!droppable.offset) {
			return false;
		}
	
		var draggableLeft, draggableTop,
			x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
			y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
			l = droppable.offset.left, r = l + droppable.proportions.width,
			t = droppable.offset.top, b = t + droppable.proportions.height;
	
		switch (toleranceMode) {
			case "fit":
				return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
			case "intersect":
				return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
					x2 - (draggable.helperProportions.width / 2) < r && // Left Half
					t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
					y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
			case "pointer":
				draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
				draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
				return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
			case "touch":
				return (
					(y1 >= t && y1 <= b) ||	// Top edge touching
					(y2 >= t && y2 <= b) ||	// Bottom edge touching
					(y1 < t && y2 > b)		// Surrounded vertically
				) && (
					(x1 >= l && x1 <= r) ||	// Left edge touching
					(x2 >= l && x2 <= r) ||	// Right edge touching
					(x1 < l && x2 > r)		// Surrounded horizontally
				);
			default:
				return false;
			}
	
	};
	
	/*
		This manager tracks offsets of draggables and droppables
	*/
	$.ui.ddmanager = {
		current: null,
		droppables: { "default": [] },
		prepareOffsets: function(t, event) {
	
			var i, j,
				m = $.ui.ddmanager.droppables[t.options.scope] || [],
				type = event ? event.type : null, // workaround for #2317
				list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
	
			droppablesLoop: for (i = 0; i < m.length; i++) {
	
				//No disabled and non-accepted
				if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
					continue;
				}
	
				// Filter out elements in the current dragged item
				for (j=0; j < list.length; j++) {
					if(list[j] === m[i].element[0]) {
						m[i].proportions.height = 0;
						continue droppablesLoop;
					}
				}
	
				m[i].visible = m[i].element.css("display") !== "none";
				if(!m[i].visible) {
					continue;
				}
	
				//Activate the droppable if used directly from draggables
				if(type === "mousedown") {
					m[i]._activate.call(m[i], event);
				}
	
				m[i].offset = m[i].element.offset();
				m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
	
			}
	
		},
		drop: function(draggable, event) {
	
			var dropped = false;
			// Create a copy of the droppables in case the list changes during the drop (#9116)
			$.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
	
				if(!this.options) {
					return;
				}
				if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
					dropped = this._drop.call(this, event) || dropped;
				}
	
				if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
					this.isout = true;
					this.isover = false;
					this._deactivate.call(this, event);
				}
	
			});
			return dropped;
	
		},
		dragStart: function( draggable, event ) {
			//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
			draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
				if( !draggable.options.refreshPositions ) {
					$.ui.ddmanager.prepareOffsets( draggable, event );
				}
			});
		},
		drag: function(draggable, event) {
	
			//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
			if(draggable.options.refreshPositions) {
				$.ui.ddmanager.prepareOffsets(draggable, event);
			}
	
			//Run through all droppables and check their positions based on specific tolerance options
			$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
	
				if(this.options.disabled || this.greedyChild || !this.visible) {
					return;
				}
	
				var parentInstance, scope, parent,
					intersects = $.ui.intersect(draggable, this, this.options.tolerance),
					c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
				if(!c) {
					return;
				}
	
				if (this.options.greedy) {
					// find droppable parents with same scope
					scope = this.options.scope;
					parent = this.element.parents(":data(ui-droppable)").filter(function () {
						return $.data(this, "ui-droppable").options.scope === scope;
					});
	
					if (parent.length) {
						parentInstance = $.data(parent[0], "ui-droppable");
						parentInstance.greedyChild = (c === "isover");
					}
				}
	
				// we just moved into a greedy child
				if (parentInstance && c === "isover") {
					parentInstance.isover = false;
					parentInstance.isout = true;
					parentInstance._out.call(parentInstance, event);
				}
	
				this[c] = true;
				this[c === "isout" ? "isover" : "isout"] = false;
				this[c === "isover" ? "_over" : "_out"].call(this, event);
	
				// we just moved out of a greedy child
				if (parentInstance && c === "isout") {
					parentInstance.isout = false;
					parentInstance.isover = true;
					parentInstance._over.call(parentInstance, event);
				}
			});
	
		},
		dragStop: function( draggable, event ) {
			draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
			//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
			if( !draggable.options.refreshPositions ) {
				$.ui.ddmanager.prepareOffsets( draggable, event );
			}
		}
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	function num(v) {
		return parseInt(v, 10) || 0;
	}
	
	function isNumber(value) {
		return !isNaN(parseInt(value, 10));
	}
	
	$.widget("ui.resizable", $.ui.mouse, {
		version: "1.10.3",
		widgetEventPrefix: "resize",
		options: {
			alsoResize: false,
			animate: false,
			animateDuration: "slow",
			animateEasing: "swing",
			aspectRatio: false,
			autoHide: false,
			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
		},
		_create: function() {
	
			var n, i, handle, axis, hname,
				that = this,
				o = this.options;
			this.element.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)) {
	
				//Create a wrapper element and set the wrapper to the new current internal element
				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")
					})
				);
	
				//Overwrite the original this.element
				this.element = this.element.parent().data(
					"ui-resizable", this.element.data("ui-resizable")
				);
	
				this.elementIsWrapper = true;
	
				//Move margins to the wrapper
				this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
				this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
	
				//Prevent Safari textarea resize
				this.originalResizeStyle = this.originalElement.css("resize");
				this.originalElement.css("resize", "none");
	
				//Push the actual element to our proportionallyResize internal array
				this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
	
				// avoid IE jump (hard set the margin)
				this.originalElement.css({ margin: this.originalElement.css("margin") });
	
				// fix handlers offset
				this._proportionallyResize();
	
			}
	
			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" });
			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 class='ui-resizable-handle " + hname + "'></div>");
	
					// Apply zIndex to all handles - see #7960
					axis.css({ zIndex: o.zIndex });
	
					//TODO : What's going on here?
					if ("se" === handle) {
						axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
					}
	
					//Insert into internal handles object and append to element
					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.handles[i], this.element).show();
					}
	
					//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
					if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
	
						axis = $(this.handles[i], this.element);
	
						//Checking the correct pad and border
						padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
	
						//The padding type i have to apply...
						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();
	
					}
	
					//TODO: What's that good for? There's not anything to be executed left
					if(!$(this.handles[i]).length) {
						continue;
					}
				}
			};
	
			//TODO: make renderAxis a prototype function
			this._renderAxis(this.element);
	
			this._handles = $(".ui-resizable-handle", this.element)
				.disableSelection();
	
			//Matching axis name
			this._handles.mouseover(function() {
				if (!that.resizing) {
					if (this.className) {
						axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
					}
					//Axis, default = se
					that.axis = axis && axis[1] ? axis[1] : "se";
				}
			});
	
			//If we want to auto hide the elements
			if (o.autoHide) {
				this._handles.hide();
				$(this.element)
					.addClass("ui-resizable-autohide")
					.mouseenter(function() {
						if (o.disabled) {
							return;
						}
						$(this).removeClass("ui-resizable-autohide");
						that._handles.show();
					})
					.mouseleave(function(){
						if (o.disabled) {
							return;
						}
						if (!that.resizing) {
							$(this).addClass("ui-resizable-autohide");
							that._handles.hide();
						}
					});
			}
	
			//Initialize the mouse interaction
			this._mouseInit();
	
		},
	
		_destroy: function() {
	
			this._mouseDestroy();
	
			var wrapper,
				_destroy = function(exp) {
					$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
						.removeData("resizable").removeData("ui-resizable").unbind(".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;
		},
	
		_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,
				iniPos = this.element.position(),
				el = this.element;
	
			this.resizing = true;
	
			// bugfix for http://dev.jquery.com/ticket/1749
			if ( (/absolute/).test( el.css("position") ) ) {
				el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
			} else if (el.is(".ui-draggable")) {
				el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
			}
	
			this._renderProxy();
	
			curleft = num(this.helper.css("left"));
			curtop = num(this.helper.css("top"));
	
			if (o.containment) {
				curleft += $(o.containment).scrollLeft() || 0;
				curtop += $(o.containment).scrollTop() || 0;
			}
	
			//Store needed variables
			this.offset = this.helper.offset();
			this.position = { left: curleft, top: curtop };
			this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
			this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
			this.originalPosition = { left: curleft, top: curtop };
			this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
			this.originalMousePosition = { left: event.pageX, top: event.pageY };
	
			//Aspect Ratio
			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);
	
			el.addClass("ui-resizable-resizing");
			this._propagate("start", event);
			return true;
		},
	
		_mouseDrag: function(event) {
	
			//Increase performance, avoid regex
			var data,
				el = this.helper, props = {},
				smp = this.originalMousePosition,
				a = this.axis,
				prevTop = this.position.top,
				prevLeft = this.position.left,
				prevWidth = this.size.width,
				prevHeight = this.size.height,
				dx = (event.pageX-smp.left)||0,
				dy = (event.pageY-smp.top)||0,
				trigger = this._change[a];
	
			if (!trigger) {
				return false;
			}
	
			// Calculate the attrs that will be change
			data = trigger.apply(this, [event, dx, dy]);
	
			// Put this in the mouseDrag handler since the user can start pressing shift while resizing
			this._updateVirtualBoundaries(event.shiftKey);
			if (this._aspectRatio || event.shiftKey) {
				data = this._updateRatio(data, event);
			}
	
			data = this._respectSize(data, event);
	
			this._updateCache(data);
	
			// plugins callbacks need to be called first
			this._propagate("resize", event);
	
			if (this.position.top !== prevTop) {
				props.top = this.position.top + "px";
			}
			if (this.position.left !== prevLeft) {
				props.left = this.position.left + "px";
			}
			if (this.size.width !== prevWidth) {
				props.width = this.size.width + "px";
			}
			if (this.size.height !== prevHeight) {
				props.height = this.size.height + "px";
			}
			el.css(props);
	
			if (!this._helper && this._proportionallyResizeElements.length) {
				this._proportionallyResize();
			}
	
			// Call the user callback if the element was resized
			if ( ! $.isEmptyObject(props) ) {
				this._trigger("resize", event, this.ui());
			}
	
			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 && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
				soffsetw = ista ? 0 : that.sizeDiff.width;
	
				s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
				left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
				top = (parseInt(that.element.css("top"), 10) + (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.element.removeClass("ui-resizable-resizing");
	
			this._propagate("stop", event);
	
			if (this._helper) {
				this.helper.remove();
			}
	
			return false;
	
		},
	
		_updateVirtualBoundaries: function(forceAspectRatio) {
			var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
				o = this.options;
	
			b = {
				minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
				maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
				minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
				maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
			};
	
			if(this._aspectRatio || forceAspectRatio) {
				// We want to create an enclosing box whose aspect ration is the requested one
				// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
				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 (isNumber(data.left)) {
				this.position.left = data.left;
			}
			if (isNumber(data.top)) {
				this.position.top = data.top;
			}
			if (isNumber(data.height)) {
				this.size.height = data.height;
			}
			if (isNumber(data.width)) {
				this.size.width = data.width;
			}
		},
	
		_updateRatio: function( data ) {
	
			var cpos = this.position,
				csize = this.size,
				a = this.axis;
	
			if (isNumber(data.height)) {
				data.width = (data.height * this.aspectRatio);
			} else if (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 = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
				isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
				dw = this.originalPosition.left + this.originalSize.width,
				dh = this.position.top + this.size.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;
		},
	
		_proportionallyResize: function() {
	
			if (!this._proportionallyResizeElements.length) {
				return;
			}
	
			var i, j, borders, paddings, prel,
				element = this.helper || this.element;
	
			for ( i=0; i < this._proportionallyResizeElements.length; i++) {
	
				prel = this._proportionallyResizeElements[i];
	
				if (!this.borderDif) {
					this.borderDif = [];
					borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
					paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
	
					for ( j = 0; j < borders.length; j++ ) {
						this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
					}
				}
	
				prel.css({
					height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
					width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 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.helper.addClass(this._helper).css({
					width: this.element.outerWidth() - 1,
					height: this.element.outerHeight() - 1,
					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).data("ui-resizable"),
				o = that.options,
				pr = that._proportionallyResizeElements,
				ista = pr.length && (/textarea/i).test(pr[0].nodeName),
				soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
				soffsetw = ista ? 0 : that.sizeDiff.width,
				style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
				left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
				top = (parseInt(that.element.css("top"), 10) + (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: parseInt(that.element.css("width"), 10),
							height: parseInt(that.element.css("height"), 10),
							top: parseInt(that.element.css("top"), 10),
							left: parseInt(that.element.css("left"), 10)
						};
	
						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).data("ui-resizable"),
				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
				};
			}
	
			// i'm a node, so compute top, left, right, bottom
			else {
				element = $(ce);
				p = [];
				$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = 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 = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
				height = ($.ui.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).data("ui-resizable"),
				o = that.options,
				co = that.containerOffset, cp = that.position,
				pRatio = that._aspectRatio || event.shiftKey,
				cop = { top:0, left:0 }, ce = that.containerElement;
	
			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;
				}
				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;
				}
				that.position.top = that._helper ? co.top : 0;
			}
	
			that.offset.left = that.parentData.left+that.position.left;
			that.offset.top = that.parentData.top+that.position.top;
	
			woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
			hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
	
			isParent = that.containerElement.get(0) === that.element.parent().get(0);
			isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
	
			if(isParent && isOffsetRelative) {
				woset -= that.parentData.left;
			}
	
			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;
				}
			}
	
			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;
				}
			}
		},
	
		stop: function(){
			var that = $(this).data("ui-resizable"),
				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).data("ui-resizable"),
				o = that.options,
				_store = function (exp) {
					$(exp).each(function() {
						var el = $(this);
						el.data("ui-resizable-alsoresize", {
							width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
							left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
						});
					});
				};
	
			if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
				if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
				else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
			}else{
				_store(o.alsoResize);
			}
		},
	
		resize: function (event, ui) {
			var that = $(this).data("ui-resizable"),
				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
				},
	
				_alsoResize = function (exp, c) {
					$(exp).each(function() {
						var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
							css = c && c.length ? c : 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);
					});
				};
	
			if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
				$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
			}else{
				_alsoResize(o.alsoResize);
			}
		},
	
		stop: function () {
			$(this).removeData("resizable-alsoresize");
		}
	});
	
	$.ui.plugin.add("resizable", "ghost", {
	
		start: function() {
	
			var that = $(this).data("ui-resizable"), o = that.options, 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 })
				.addClass("ui-resizable-ghost")
				.addClass(typeof o.ghost === "string" ? o.ghost : "");
	
			that.ghost.appendTo(that.helper);
	
		},
	
		resize: function(){
			var that = $(this).data("ui-resizable");
			if (that.ghost) {
				that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
			}
		},
	
		stop: function() {
			var that = $(this).data("ui-resizable");
			if (that.ghost && that.helper) {
				that.helper.get(0).removeChild(that.ghost.get(0));
			}
		}
	
	});
	
	$.ui.plugin.add("resizable", "grid", {
	
		resize: function() {
			var that = $(this).data("ui-resizable"),
				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 = newWidth + gridX;
			}
			if (isMinHeight) {
				newHeight = newHeight + gridY;
			}
			if (isMaxWidth) {
				newWidth = newWidth - gridX;
			}
			if (isMaxHeight) {
				newHeight = 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 {
				that.size.width = newWidth;
				that.size.height = newHeight;
				that.position.top = op.top - oy;
				that.position.left = op.left - ox;
			}
		}
	
	});
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.widget("ui.selectable", $.ui.mouse, {
		version: "1.10.3",
		options: {
			appendTo: "body",
			autoRefresh: true,
			distance: 0,
			filter: "*",
			tolerance: "touch",
	
			// callbacks
			selected: null,
			selecting: null,
			start: null,
			stop: null,
			unselected: null,
			unselecting: null
		},
		_create: function() {
			var selectees,
				that = this;
	
			this.element.addClass("ui-selectable");
	
			this.dragged = false;
	
			// cache selectee children based on filter
			this.refresh = function() {
				selectees = $(that.options.filter, that.element[0]);
				selectees.addClass("ui-selectee");
				selectees.each(function() {
					var $this = $(this),
						pos = $this.offset();
					$.data(this, "selectable-item", {
						element: this,
						$element: $this,
						left: pos.left,
						top: pos.top,
						right: pos.left + $this.outerWidth(),
						bottom: pos.top + $this.outerHeight(),
						startselected: false,
						selected: $this.hasClass("ui-selected"),
						selecting: $this.hasClass("ui-selecting"),
						unselecting: $this.hasClass("ui-unselecting")
					});
				});
			};
			this.refresh();
	
			this.selectees = selectees.addClass("ui-selectee");
	
			this._mouseInit();
	
			this.helper = $("<div class='ui-selectable-helper'></div>");
		},
	
		_destroy: function() {
			this.selectees
				.removeClass("ui-selectee")
				.removeData("selectable-item");
			this.element
				.removeClass("ui-selectable ui-selectable-disabled");
			this._mouseDestroy();
		},
	
		_mouseStart: function(event) {
			var that = this,
				options = this.options;
	
			this.opos = [event.pageX, event.pageY];
	
			if (this.options.disabled) {
				return;
			}
	
			this.selectees = $(options.filter, this.element[0]);
	
			this._trigger("start", event);
	
			$(options.appendTo).append(this.helper);
			// position helper (lasso)
			this.helper.css({
				"left": event.pageX,
				"top": event.pageY,
				"width": 0,
				"height": 0
			});
	
			if (options.autoRefresh) {
				this.refresh();
			}
	
			this.selectees.filter(".ui-selected").each(function() {
				var selectee = $.data(this, "selectable-item");
				selectee.startselected = true;
				if (!event.metaKey && !event.ctrlKey) {
					selectee.$element.removeClass("ui-selected");
					selectee.selected = false;
					selectee.$element.addClass("ui-unselecting");
					selectee.unselecting = true;
					// selectable UNSELECTING callback
					that._trigger("unselecting", event, {
						unselecting: selectee.element
					});
				}
			});
	
			$(event.target).parents().addBack().each(function() {
				var doSelect,
					selectee = $.data(this, "selectable-item");
				if (selectee) {
					doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
					selectee.$element
						.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
						.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
					selectee.unselecting = !doSelect;
					selectee.selecting = doSelect;
					selectee.selected = doSelect;
					// selectable (UN)SELECTING callback
					if (doSelect) {
						that._trigger("selecting", event, {
							selecting: selectee.element
						});
					} else {
						that._trigger("unselecting", event, {
							unselecting: selectee.element
						});
					}
					return false;
				}
			});
	
		},
	
		_mouseDrag: function(event) {
	
			this.dragged = true;
	
			if (this.options.disabled) {
				return;
			}
	
			var tmp,
				that = this,
				options = this.options,
				x1 = this.opos[0],
				y1 = this.opos[1],
				x2 = event.pageX,
				y2 = event.pageY;
	
			if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
			if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
			this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
	
			this.selectees.each(function() {
				var selectee = $.data(this, "selectable-item"),
					hit = false;
	
				//prevent helper from being selected if appendTo: selectable
				if (!selectee || selectee.element === that.element[0]) {
					return;
				}
	
				if (options.tolerance === "touch") {
					hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
				} else if (options.tolerance === "fit") {
					hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
				}
	
				if (hit) {
					// SELECT
					if (selectee.selected) {
						selectee.$element.removeClass("ui-selected");
						selectee.selected = false;
					}
					if (selectee.unselecting) {
						selectee.$element.removeClass("ui-unselecting");
						selectee.unselecting = false;
					}
					if (!selectee.selecting) {
						selectee.$element.addClass("ui-selecting");
						selectee.selecting = true;
						// selectable SELECTING callback
						that._trigger("selecting", event, {
							selecting: selectee.element
						});
					}
				} else {
					// UNSELECT
					if (selectee.selecting) {
						if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
							selectee.$element.removeClass("ui-selecting");
							selectee.selecting = false;
							selectee.$element.addClass("ui-selected");
							selectee.selected = true;
						} else {
							selectee.$element.removeClass("ui-selecting");
							selectee.selecting = false;
							if (selectee.startselected) {
								selectee.$element.addClass("ui-unselecting");
								selectee.unselecting = true;
							}
							// selectable UNSELECTING callback
							that._trigger("unselecting", event, {
								unselecting: selectee.element
							});
						}
					}
					if (selectee.selected) {
						if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
							selectee.$element.removeClass("ui-selected");
							selectee.selected = false;
	
							selectee.$element.addClass("ui-unselecting");
							selectee.unselecting = true;
							// selectable UNSELECTING callback
							that._trigger("unselecting", event, {
								unselecting: selectee.element
							});
						}
					}
				}
			});
	
			return false;
		},
	
		_mouseStop: function(event) {
			var that = this;
	
			this.dragged = false;
	
			$(".ui-unselecting", this.element[0]).each(function() {
				var selectee = $.data(this, "selectable-item");
				selectee.$element.removeClass("ui-unselecting");
				selectee.unselecting = false;
				selectee.startselected = false;
				that._trigger("unselected", event, {
					unselected: selectee.element
				});
			});
			$(".ui-selecting", this.element[0]).each(function() {
				var selectee = $.data(this, "selectable-item");
				selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
				selectee.selecting = false;
				selectee.selected = true;
				selectee.startselected = true;
				that._trigger("selected", event, {
					selected: selectee.element
				});
			});
			this._trigger("stop", event);
	
			this.helper.remove();
	
			return false;
		}
	
	});
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	/*jshint loopfunc: true */
	
	function isOverAxis( x, reference, size ) {
		return ( x > reference ) && ( x < ( reference + size ) );
	}
	
	function isFloating(item) {
		return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
	}
	
	$.widget("ui.sortable", $.ui.mouse, {
		version: "1.10.3",
		widgetEventPrefix: "sort",
		ready: false,
		options: {
			appendTo: "parent",
			axis: false,
			connectWith: false,
			containment: false,
			cursor: "auto",
			cursorAt: false,
			dropOnEmpty: true,
			forcePlaceholderSize: false,
			forceHelperSize: false,
			grid: false,
			handle: false,
			helper: "original",
			items: "> *",
			opacity: false,
			placeholder: false,
			revert: false,
			scroll: true,
			scrollSensitivity: 20,
			scrollSpeed: 20,
			scope: "default",
			tolerance: "intersect",
			zIndex: 1000,
	
			// callbacks
			activate: null,
			beforeStop: null,
			change: null,
			deactivate: null,
			out: null,
			over: null,
			receive: null,
			remove: null,
			sort: null,
			start: null,
			stop: null,
			update: null
		},
		_create: function() {
	
			var o = this.options;
			this.containerCache = {};
			this.element.addClass("ui-sortable");
	
			//Get the items
			this.refresh();
	
			//Let's determine if the items are being displayed horizontally
			this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
	
			//Let's determine the parent's offset
			this.offset = this.element.offset();
	
			//Initialize mouse events for interaction
			this._mouseInit();
	
			//We're ready to go
			this.ready = true;
	
		},
	
		_destroy: function() {
			this.element
				.removeClass("ui-sortable ui-sortable-disabled");
			this._mouseDestroy();
	
			for ( var i = this.items.length - 1; i >= 0; i-- ) {
				this.items[i].item.removeData(this.widgetName + "-item");
			}
	
			return this;
		},
	
		_setOption: function(key, value){
			if ( key === "disabled" ) {
				this.options[ key ] = value;
	
				this.widget().toggleClass( "ui-sortable-disabled", !!value );
			} else {
				// Don't call widget base _setOption for disable as it adds ui-state-disabled class
				$.Widget.prototype._setOption.apply(this, arguments);
			}
		},
	
		_mouseCapture: function(event, overrideHandle) {
			var currentItem = null,
				validHandle = false,
				that = this;
	
			if (this.reverting) {
				return false;
			}
	
			if(this.options.disabled || this.options.type === "static") {
				return false;
			}
	
			//We have to refresh the items data once first
			this._refreshItems(event);
	
			//Find out if the clicked node (or one of its parents) is a actual item in this.items
			$(event.target).parents().each(function() {
				if($.data(this, that.widgetName + "-item") === that) {
					currentItem = $(this);
					return false;
				}
			});
			if($.data(event.target, that.widgetName + "-item") === that) {
				currentItem = $(event.target);
			}
	
			if(!currentItem) {
				return false;
			}
			if(this.options.handle && !overrideHandle) {
				$(this.options.handle, currentItem).find("*").addBack().each(function() {
					if(this === event.target) {
						validHandle = true;
					}
				});
				if(!validHandle) {
					return false;
				}
			}
	
			this.currentItem = currentItem;
			this._removeCurrentsFromItems();
			return true;
	
		},
	
		_mouseStart: function(event, overrideHandle, noActivation) {
	
			var i, body,
				o = this.options;
	
			this.currentContainer = this;
	
			//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
			this.refreshPositions();
	
			//Create and append the visible helper
			this.helper = this._createHelper(event);
	
			//Cache the helper size
			this._cacheHelperProportions();
	
			/*
			 * - Position generation -
			 * This block generates everything position related - it's the core of draggables.
			 */
	
			//Cache the margins of the original element
			this._cacheMargins();
	
			//Get the next scrolling parent
			this.scrollParent = this.helper.scrollParent();
	
			//The element's absolute position on the page minus margins
			this.offset = this.currentItem.offset();
			this.offset = {
				top: this.offset.top - this.margins.top,
				left: this.offset.left - this.margins.left
			};
	
			$.extend(this.offset, {
				click: { //Where the click happened, relative to the element
					left: event.pageX - this.offset.left,
					top: event.pageY - this.offset.top
				},
				parent: this._getParentOffset(),
				relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
			});
	
			// Only after we got the offset, we can change the helper's position to absolute
			// TODO: Still need to figure out a way to make relative sorting possible
			this.helper.css("position", "absolute");
			this.cssPosition = this.helper.css("position");
	
			//Generate the original position
			this.originalPosition = this._generatePosition(event);
			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));
	
			//Cache the former DOM position
			this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
	
			//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
			if(this.helper[0] !== this.currentItem[0]) {
				this.currentItem.hide();
			}
	
			//Create the placeholder
			this._createPlaceholder();
	
			//Set a containment if given in the options
			if(o.containment) {
				this._setContainment();
			}
	
			if( o.cursor && o.cursor !== "auto" ) { // cursor option
				body = this.document.find( "body" );
	
				// support: IE
				this.storedCursor = body.css( "cursor" );
				body.css( "cursor", o.cursor );
	
				this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
			}
	
			if(o.opacity) { // opacity option
				if (this.helper.css("opacity")) {
					this._storedOpacity = this.helper.css("opacity");
				}
				this.helper.css("opacity", o.opacity);
			}
	
			if(o.zIndex) { // zIndex option
				if (this.helper.css("zIndex")) {
					this._storedZIndex = this.helper.css("zIndex");
				}
				this.helper.css("zIndex", o.zIndex);
			}
	
			//Prepare scrolling
			if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
				this.overflowOffset = this.scrollParent.offset();
			}
	
			//Call callbacks
			this._trigger("start", event, this._uiHash());
	
			//Recache the helper size
			if(!this._preserveHelperProportions) {
				this._cacheHelperProportions();
			}
	
	
			//Post "activate" events to possible containers
			if( !noActivation ) {
				for ( i = this.containers.length - 1; i >= 0; i-- ) {
					this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
				}
			}
	
			//Prepare possible droppables
			if($.ui.ddmanager) {
				$.ui.ddmanager.current = this;
			}
	
			if ($.ui.ddmanager && !o.dropBehaviour) {
				$.ui.ddmanager.prepareOffsets(this, event);
			}
	
			this.dragging = true;
	
			this.helper.addClass("ui-sortable-helper");
			this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
			return true;
	
		},
	
		_mouseDrag: function(event) {
			var i, item, itemElement, intersection,
				o = this.options,
				scrolled = false;
	
			//Compute the helpers position
			this.position = this._generatePosition(event);
			this.positionAbs = this._convertPositionTo("absolute");
	
			if (!this.lastPositionAbs) {
				this.lastPositionAbs = this.positionAbs;
			}
	
			//Do scrolling
			if(this.options.scroll) {
				if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
	
					if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
						this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
					} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
						this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
					}
	
					if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
						this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
					} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
						this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
					}
	
				} else {
	
					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(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(this, event);
				}
			}
	
			//Regenerate the absolute position used for position checks
			this.positionAbs = this._convertPositionTo("absolute");
	
			//Set the helper position
			if(!this.options.axis || this.options.axis !== "y") {
				this.helper[0].style.left = this.position.left+"px";
			}
			if(!this.options.axis || this.options.axis !== "x") {
				this.helper[0].style.top = this.position.top+"px";
			}
	
			//Rearrange
			for (i = this.items.length - 1; i >= 0; i--) {
	
				//Cache variables and intersection, continue if no intersection
				item = this.items[i];
				itemElement = item.item[0];
				intersection = this._intersectsWithPointer(item);
				if (!intersection) {
					continue;
				}
	
				// Only put the placeholder inside the current Container, skip all
				// items form other containers. This works because when moving
				// an item from one container to another the
				// currentContainer is switched before the placeholder is moved.
				//
				// Without this moving items in "sub-sortables" can cause the placeholder to jitter
				// beetween the outer and inner container.
				if (item.instance !== this.currentContainer) {
					continue;
				}
	
				// cannot intersect with itself
				// no useless actions that have been done before
				// no action if the item moved is the parent of the item checked
				if (itemElement !== this.currentItem[0] &&
					this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
					!$.contains(this.placeholder[0], itemElement) &&
					(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
				) {
	
					this.direction = intersection === 1 ? "down" : "up";
	
					if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
						this._rearrange(event, item);
					} else {
						break;
					}
	
					this._trigger("change", event, this._uiHash());
					break;
				}
			}
	
			//Post events to containers
			this._contactContainers(event);
	
			//Interconnect with droppables
			if($.ui.ddmanager) {
				$.ui.ddmanager.drag(this, event);
			}
	
			//Call callbacks
			this._trigger("sort", event, this._uiHash());
	
			this.lastPositionAbs = this.positionAbs;
			return false;
	
		},
	
		_mouseStop: function(event, noPropagation) {
	
			if(!event) {
				return;
			}
	
			//If we are using droppables, inform the manager about the drop
			if ($.ui.ddmanager && !this.options.dropBehaviour) {
				$.ui.ddmanager.drop(this, event);
			}
	
			if(this.options.revert) {
				var that = this,
					cur = this.placeholder.offset(),
					axis = this.options.axis,
					animation = {};
	
				if ( !axis || axis === "x" ) {
					animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
				}
				if ( !axis || axis === "y" ) {
					animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
				}
				this.reverting = true;
				$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
					that._clear(event);
				});
			} else {
				this._clear(event, noPropagation);
			}
	
			return false;
	
		},
	
		cancel: function() {
	
			if(this.dragging) {
	
				this._mouseUp({ target: null });
	
				if(this.options.helper === "original") {
					this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
				} else {
					this.currentItem.show();
				}
	
				//Post deactivating events to containers
				for (var i = this.containers.length - 1; i >= 0; i--){
					this.containers[i]._trigger("deactivate", null, this._uiHash(this));
					if(this.containers[i].containerCache.over) {
						this.containers[i]._trigger("out", null, this._uiHash(this));
						this.containers[i].containerCache.over = 0;
					}
				}
	
			}
	
			if (this.placeholder) {
				//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
				if(this.placeholder[0].parentNode) {
					this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
				}
				if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
					this.helper.remove();
				}
	
				$.extend(this, {
					helper: null,
					dragging: false,
					reverting: false,
					_noFinalSort: null
				});
	
				if(this.domPosition.prev) {
					$(this.domPosition.prev).after(this.currentItem);
				} else {
					$(this.domPosition.parent).prepend(this.currentItem);
				}
			}
	
			return this;
	
		},
	
		serialize: function(o) {
	
			var items = this._getItemsAsjQuery(o && o.connected),
				str = [];
			o = o || {};
	
			$(items).each(function() {
				var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
				if (res) {
					str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
				}
			});
	
			if(!str.length && o.key) {
				str.push(o.key + "=");
			}
	
			return str.join("&");
	
		},
	
		toArray: function(o) {
	
			var items = this._getItemsAsjQuery(o && o.connected),
				ret = [];
	
			o = o || {};
	
			items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
			return ret;
	
		},
	
		/* Be careful with the following core functions */
		_intersectsWith: function(item) {
	
			var x1 = this.positionAbs.left,
				x2 = x1 + this.helperProportions.width,
				y1 = this.positionAbs.top,
				y2 = y1 + this.helperProportions.height,
				l = item.left,
				r = l + item.width,
				t = item.top,
				b = t + item.height,
				dyClick = this.offset.click.top,
				dxClick = this.offset.click.left,
				isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
				isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
				isOverElement = isOverElementHeight && isOverElementWidth;
	
			if ( this.options.tolerance === "pointer" ||
				this.options.forcePointerForContainers ||
				(this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
			) {
				return isOverElement;
			} else {
	
				return (l < x1 + (this.helperProportions.width / 2) && // Right Half
					x2 - (this.helperProportions.width / 2) < r && // Left Half
					t < y1 + (this.helperProportions.height / 2) && // Bottom Half
					y2 - (this.helperProportions.height / 2) < b ); // Top Half
	
			}
		},
	
		_intersectsWithPointer: function(item) {
	
			var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
				isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
				isOverElement = isOverElementHeight && isOverElementWidth,
				verticalDirection = this._getDragVerticalDirection(),
				horizontalDirection = this._getDragHorizontalDirection();
	
			if (!isOverElement) {
				return false;
			}
	
			return this.floating ?
				( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
				: ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
	
		},
	
		_intersectsWithSides: function(item) {
	
			var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
				isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
				verticalDirection = this._getDragVerticalDirection(),
				horizontalDirection = this._getDragHorizontalDirection();
	
			if (this.floating && horizontalDirection) {
				return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
			} else {
				return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
			}
	
		},
	
		_getDragVerticalDirection: function() {
			var delta = this.positionAbs.top - this.lastPositionAbs.top;
			return delta !== 0 && (delta > 0 ? "down" : "up");
		},
	
		_getDragHorizontalDirection: function() {
			var delta = this.positionAbs.left - this.lastPositionAbs.left;
			return delta !== 0 && (delta > 0 ? "right" : "left");
		},
	
		refresh: function(event) {
			this._refreshItems(event);
			this.refreshPositions();
			return this;
		},
	
		_connectWith: function() {
			var options = this.options;
			return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
		},
	
		_getItemsAsjQuery: function(connected) {
	
			var i, j, cur, inst,
				items = [],
				queries = [],
				connectWith = this._connectWith();
	
			if(connectWith && connected) {
				for (i = connectWith.length - 1; i >= 0; i--){
					cur = $(connectWith[i]);
					for ( j = cur.length - 1; j >= 0; j--){
						inst = $.data(cur[j], this.widgetFullName);
						if(inst && inst !== this && !inst.options.disabled) {
							queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
						}
					}
				}
			}
	
			queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
	
			for (i = queries.length - 1; i >= 0; i--){
				queries[i][0].each(function() {
					items.push(this);
				});
			}
	
			return $(items);
	
		},
	
		_removeCurrentsFromItems: function() {
	
			var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
	
			this.items = $.grep(this.items, function (item) {
				for (var j=0; j < list.length; j++) {
					if(list[j] === item.item[0]) {
						return false;
					}
				}
				return true;
			});
	
		},
	
		_refreshItems: function(event) {
	
			this.items = [];
			this.containers = [this];
	
			var i, j, cur, inst, targetData, _queries, item, queriesLength,
				items = this.items,
				queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
				connectWith = this._connectWith();
	
			if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
				for (i = connectWith.length - 1; i >= 0; i--){
					cur = $(connectWith[i]);
					for (j = cur.length - 1; j >= 0; j--){
						inst = $.data(cur[j], this.widgetFullName);
						if(inst && inst !== this && !inst.options.disabled) {
							queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
							this.containers.push(inst);
						}
					}
				}
			}
	
			for (i = queries.length - 1; i >= 0; i--) {
				targetData = queries[i][1];
				_queries = queries[i][0];
	
				for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
					item = $(_queries[j]);
	
					item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
	
					items.push({
						item: item,
						instance: targetData,
						width: 0, height: 0,
						left: 0, top: 0
					});
				}
			}
	
		},
	
		refreshPositions: function(fast) {
	
			//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
			if(this.offsetParent && this.helper) {
				this.offset.parent = this._getParentOffset();
			}
	
			var i, item, t, p;
	
			for (i = this.items.length - 1; i >= 0; i--){
				item = this.items[i];
	
				//We ignore calculating positions of all connected containers when we're not over them
				if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
					continue;
				}
	
				t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
	
				if (!fast) {
					item.width = t.outerWidth();
					item.height = t.outerHeight();
				}
	
				p = t.offset();
				item.left = p.left;
				item.top = p.top;
			}
	
			if(this.options.custom && this.options.custom.refreshContainers) {
				this.options.custom.refreshContainers.call(this);
			} else {
				for (i = this.containers.length - 1; i >= 0; i--){
					p = this.containers[i].element.offset();
					this.containers[i].containerCache.left = p.left;
					this.containers[i].containerCache.top = p.top;
					this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
					this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
				}
			}
	
			return this;
		},
	
		_createPlaceholder: function(that) {
			that = that || this;
			var className,
				o = that.options;
	
			if(!o.placeholder || o.placeholder.constructor === String) {
				className = o.placeholder;
				o.placeholder = {
					element: function() {
	
						var nodeName = that.currentItem[0].nodeName.toLowerCase(),
							element = $( "<" + nodeName + ">", that.document[0] )
								.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
								.removeClass("ui-sortable-helper");
	
						if ( nodeName === "tr" ) {
							that.currentItem.children().each(function() {
								$( "<td>&#160;</td>", that.document[0] )
									.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
									.appendTo( element );
							});
						} else if ( nodeName === "img" ) {
							element.attr( "src", that.currentItem.attr( "src" ) );
						}
	
						if ( !className ) {
							element.css( "visibility", "hidden" );
						}
	
						return element;
					},
					update: function(container, p) {
	
						// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
						// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
						if(className && !o.forcePlaceholderSize) {
							return;
						}
	
						//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
						if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
						if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
					}
				};
			}
	
			//Create the placeholder
			that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
	
			//Append it after the actual current item
			that.currentItem.after(that.placeholder);
	
			//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
			o.placeholder.update(that, that.placeholder);
	
		},
	
		_contactContainers: function(event) {
			var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
				innermostContainer = null,
				innermostIndex = null;
	
			// get innermost container that intersects with item
			for (i = this.containers.length - 1; i >= 0; i--) {
	
				// never consider a container that's located within the item itself
				if($.contains(this.currentItem[0], this.containers[i].element[0])) {
					continue;
				}
	
				if(this._intersectsWith(this.containers[i].containerCache)) {
	
					// if we've already found a container and it's more "inner" than this, then continue
					if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
						continue;
					}
	
					innermostContainer = this.containers[i];
					innermostIndex = i;
	
				} else {
					// container doesn't intersect. trigger "out" event if necessary
					if(this.containers[i].containerCache.over) {
						this.containers[i]._trigger("out", event, this._uiHash(this));
						this.containers[i].containerCache.over = 0;
					}
				}
	
			}
	
			// if no intersecting containers found, return
			if(!innermostContainer) {
				return;
			}
	
			// move the item into the container if it's not there already
			if(this.containers.length === 1) {
				if (!this.containers[innermostIndex].containerCache.over) {
					this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
					this.containers[innermostIndex].containerCache.over = 1;
				}
			} else {
	
				//When entering a new container, we will find the item with the least distance and append our item near it
				dist = 10000;
				itemWithLeastDistance = null;
				floating = innermostContainer.floating || isFloating(this.currentItem);
				posProperty = floating ? "left" : "top";
				sizeProperty = floating ? "width" : "height";
				base = this.positionAbs[posProperty] + this.offset.click[posProperty];
				for (j = this.items.length - 1; j >= 0; j--) {
					if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
						continue;
					}
					if(this.items[j].item[0] === this.currentItem[0]) {
						continue;
					}
					if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
						continue;
					}
					cur = this.items[j].item.offset()[posProperty];
					nearBottom = false;
					if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
						nearBottom = true;
						cur += this.items[j][sizeProperty];
					}
	
					if(Math.abs(cur - base) < dist) {
						dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
						this.direction = nearBottom ? "up": "down";
					}
				}
	
				//Check if dropOnEmpty is enabled
				if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
					return;
				}
	
				if(this.currentContainer === this.containers[innermostIndex]) {
					return;
				}
	
				itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
				this._trigger("change", event, this._uiHash());
				this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
				this.currentContainer = this.containers[innermostIndex];
	
				//Update the placeholder
				this.options.placeholder.update(this.currentContainer, this.placeholder);
	
				this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
				this.containers[innermostIndex].containerCache.over = 1;
			}
	
	
		},
	
		_createHelper: function(event) {
	
			var o = this.options,
				helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
	
			//Add the helper to the DOM if that didn't happen already
			if(!helper.parents("body").length) {
				$(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
			}
	
			if(helper[0] === this.currentItem[0]) {
				this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
			}
	
			if(!helper[0].style.width || o.forceHelperSize) {
				helper.width(this.currentItem.width());
			}
			if(!helper[0].style.height || o.forceHelperSize) {
				helper.height(this.currentItem.height());
			}
	
			return helper;
	
		},
	
		_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;
			}
		},
	
		_getParentOffset: function() {
	
	
			//Get the offsetParent and cache its position
			this.offsetParent = this.helper.offsetParent();
			var po = this.offsetParent.offset();
	
			// 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();
			}
	
			// This needs to be actually done for all browsers, since pageX/pageY includes this information
			// with an ugly IE fix
			if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
				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") {
				var p = this.currentItem.position();
				return {
					top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
					left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
				};
			} else {
				return { top: 0, left: 0 };
			}
	
		},
	
		_cacheMargins: function() {
			this.margins = {
				left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
				top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
			};
		},
	
		_cacheHelperProportions: function() {
			this.helperProportions = {
				width: this.helper.outerWidth(),
				height: this.helper.outerHeight()
			};
		},
	
		_setContainment: function() {
	
			var ce, co, over,
				o = this.options;
			if(o.containment === "parent") {
				o.containment = this.helper[0].parentNode;
			}
			if(o.containment === "document" || o.containment === "window") {
				this.containment = [
					0 - this.offset.relative.left - this.offset.parent.left,
					0 - this.offset.relative.top - this.offset.parent.top,
					$(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
					($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
				];
			}
	
			if(!(/^(document|window|parent)$/).test(o.containment)) {
				ce = $(o.containment)[0];
				co = $(o.containment).offset();
				over = ($(ce).css("overflow") !== "hidden");
	
				this.containment = [
					co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
					co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
					co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
					co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
				];
			}
	
		},
	
		_convertPositionTo: function(d, pos) {
	
			if(!pos) {
				pos = this.position;
			}
			var mod = d === "absolute" ? 1 : -1,
				scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
				scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
	
			return {
				top: (
					pos.top	+																// The absolute mouse position
					this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
					this.offset.parent.top * mod -											// The offsetParent's offset without borders (offset + border)
					( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
				),
				left: (
					pos.left +																// The absolute mouse position
					this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
					this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
					( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
				)
			};
	
		},
	
		_generatePosition: function(event) {
	
			var top, left,
				o = this.options,
				pageX = event.pageX,
				pageY = event.pageY,
				scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
	
			// This is another very weird special case that only happens for relative elements:
			// 1. If the css position is relative
			// 2. and the scroll parent is the document or similar to the offset parent
			// we have to refresh the relative offset during the scroll so there are no jumps
			if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
				this.offset.relative = this._getRelativeOffset();
			}
	
			/*
			 * - Position constraining -
			 * Constrain the position to a mix of grid, containment.
			 */
	
			if(this.originalPosition) { //If we are not dragging yet, we won't check for options
	
				if(this.containment) {
					if(event.pageX - this.offset.click.left < this.containment[0]) {
						pageX = this.containment[0] + this.offset.click.left;
					}
					if(event.pageY - this.offset.click.top < this.containment[1]) {
						pageY = this.containment[1] + this.offset.click.top;
					}
					if(event.pageX - this.offset.click.left > this.containment[2]) {
						pageX = this.containment[2] + this.offset.click.left;
					}
					if(event.pageY - this.offset.click.top > this.containment[3]) {
						pageY = this.containment[3] + this.offset.click.top;
					}
				}
	
				if(o.grid) {
					top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
					pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
	
					left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
					pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
				}
	
			}
	
			return {
				top: (
					pageY -																// The absolute mouse position
					this.offset.click.top -													// Click offset (relative to the element)
					this.offset.relative.top	-											// Only for relative positioned nodes: Relative offset from element to offset parent
					this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
					( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
				),
				left: (
					pageX -																// The absolute mouse position
					this.offset.click.left -												// Click offset (relative to the element)
					this.offset.relative.left	-											// Only for relative positioned nodes: Relative offset from element to offset parent
					this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
					( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
				)
			};
	
		},
	
		_rearrange: function(event, i, a, hardRefresh) {
	
			a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
	
			//Various things done here to improve the performance:
			// 1. we create a setTimeout, that calls refreshPositions
			// 2. on the instance, we have a counter variable, that get's higher after every append
			// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
			// 4. this lets only the last addition to the timeout stack through
			this.counter = this.counter ? ++this.counter : 1;
			var counter = this.counter;
	
			this._delay(function() {
				if(counter === this.counter) {
					this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
				}
			});
	
		},
	
		_clear: function(event, noPropagation) {
	
			this.reverting = false;
			// We delay all events that have to be triggered to after the point where the placeholder has been removed and
			// everything else normalized again
			var i,
				delayedTriggers = [];
	
			// We first have to update the dom position of the actual currentItem
			// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
			if(!this._noFinalSort && this.currentItem.parent().length) {
				this.placeholder.before(this.currentItem);
			}
			this._noFinalSort = null;
	
			if(this.helper[0] === this.currentItem[0]) {
				for(i in this._storedCSS) {
					if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
						this._storedCSS[i] = "";
					}
				}
				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
			} else {
				this.currentItem.show();
			}
	
			if(this.fromOutside && !noPropagation) {
				delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
			}
			if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
				delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
			}
	
			// Check if the items Container has Changed and trigger appropriate
			// events.
			if (this !== this.currentContainer) {
				if(!noPropagation) {
					delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
					delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
					delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
				}
			}
	
	
			//Post events to containers
			for (i = this.containers.length - 1; i >= 0; i--){
				if(!noPropagation) {
					delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
				}
				if(this.containers[i].containerCache.over) {
					delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
					this.containers[i].containerCache.over = 0;
				}
			}
	
			//Do what was originally in plugins
			if ( this.storedCursor ) {
				this.document.find( "body" ).css( "cursor", this.storedCursor );
				this.storedStylesheet.remove();
			}
			if(this._storedOpacity) {
				this.helper.css("opacity", this._storedOpacity);
			}
			if(this._storedZIndex) {
				this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
			}
	
			this.dragging = false;
			if(this.cancelHelperRemoval) {
				if(!noPropagation) {
					this._trigger("beforeStop", event, this._uiHash());
					for (i=0; i < delayedTriggers.length; i++) {
						delayedTriggers[i].call(this, event);
					} //Trigger all delayed events
					this._trigger("stop", event, this._uiHash());
				}
	
				this.fromOutside = false;
				return false;
			}
	
			if(!noPropagation) {
				this._trigger("beforeStop", event, this._uiHash());
			}
	
			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
			this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
	
			if(this.helper[0] !== this.currentItem[0]) {
				this.helper.remove();
			}
			this.helper = null;
	
			if(!noPropagation) {
				for (i=0; i < delayedTriggers.length; i++) {
					delayedTriggers[i].call(this, event);
				} //Trigger all delayed events
				this._trigger("stop", event, this._uiHash());
			}
	
			this.fromOutside = false;
			return true;
	
		},
	
		_trigger: function() {
			if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
				this.cancel();
			}
		},
	
		_uiHash: function(_inst) {
			var inst = _inst || this;
			return {
				helper: inst.helper,
				placeholder: inst.placeholder || $([]),
				position: inst.position,
				originalPosition: inst.originalPosition,
				offset: inst.positionAbs,
				item: inst.currentItem,
				sender: _inst ? _inst.element : null
			};
		}
	
	});
	
	})(jQuery);
	
	(function($, undefined) {
	
	var dataSpace = "ui-effects-";
	
	$.effects = {
		effect: {}
	};
	
	/*!
	 * jQuery Color Animations v2.1.2
	 * https://github.com/jquery/jquery-color
	 *
	 * Copyright 2013 jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 *
	 * Date: Wed Jan 16 08:47:09 2013 -0600
	 */
	(function( jQuery, undefined ) {
	
		var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
	
		// plusequals test for += 100 -= 100
		rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
		// a set of RE's that can match strings and generate color tuples.
		stringParsers = [{
				re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
				parse: function( execResult ) {
					return [
						execResult[ 1 ],
						execResult[ 2 ],
						execResult[ 3 ],
						execResult[ 4 ]
					];
				}
			}, {
				re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
				parse: function( execResult ) {
					return [
						execResult[ 1 ] * 2.55,
						execResult[ 2 ] * 2.55,
						execResult[ 3 ] * 2.55,
						execResult[ 4 ]
					];
				}
			}, {
				// this regex ignores A-F because it's compared against an already lowercased string
				re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
				parse: function( execResult ) {
					return [
						parseInt( execResult[ 1 ], 16 ),
						parseInt( execResult[ 2 ], 16 ),
						parseInt( execResult[ 3 ], 16 )
					];
				}
			}, {
				// this regex ignores A-F because it's compared against an already lowercased string
				re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
				parse: function( execResult ) {
					return [
						parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
						parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
						parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
					];
				}
			}, {
				re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
				space: "hsla",
				parse: function( execResult ) {
					return [
						execResult[ 1 ],
						execResult[ 2 ] / 100,
						execResult[ 3 ] / 100,
						execResult[ 4 ]
					];
				}
			}],
	
		// jQuery.Color( )
		color = jQuery.Color = function( color, green, blue, alpha ) {
			return new jQuery.Color.fn.parse( color, green, blue, alpha );
		},
		spaces = {
			rgba: {
				props: {
					red: {
						idx: 0,
						type: "byte"
					},
					green: {
						idx: 1,
						type: "byte"
					},
					blue: {
						idx: 2,
						type: "byte"
					}
				}
			},
	
			hsla: {
				props: {
					hue: {
						idx: 0,
						type: "degrees"
					},
					saturation: {
						idx: 1,
						type: "percent"
					},
					lightness: {
						idx: 2,
						type: "percent"
					}
				}
			}
		},
		propTypes = {
			"byte": {
				floor: true,
				max: 255
			},
			"percent": {
				max: 1
			},
			"degrees": {
				mod: 360,
				floor: true
			}
		},
		support = color.support = {},
	
		// element for support tests
		supportElem = jQuery( "<p>" )[ 0 ],
	
		// colors = jQuery.Color.names
		colors,
	
		// local aliases of functions called often
		each = jQuery.each;
	
	// determine rgba support immediately
	supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
	support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
	
	// define cache name and alpha properties
	// for rgba and hsla spaces
	each( spaces, function( spaceName, space ) {
		space.cache = "_" + spaceName;
		space.props.alpha = {
			idx: 3,
			type: "percent",
			def: 1
		};
	});
	
	function clamp( value, prop, allowEmpty ) {
		var type = propTypes[ prop.type ] || {};
	
		if ( value == null ) {
			return (allowEmpty || !prop.def) ? null : prop.def;
		}
	
		// ~~ is an short way of doing floor for positive numbers
		value = type.floor ? ~~value : parseFloat( value );
	
		// IE will pass in empty strings as value for alpha,
		// which will hit this case
		if ( isNaN( value ) ) {
			return prop.def;
		}
	
		if ( type.mod ) {
			// we add mod before modding to make sure that negatives values
			// get converted properly: -10 -> 350
			return (value + type.mod) % type.mod;
		}
	
		// for now all property types without mod have min and max
		return 0 > value ? 0 : type.max < value ? type.max : value;
	}
	
	function stringParse( string ) {
		var inst = color(),
			rgba = inst._rgba = [];
	
		string = string.toLowerCase();
	
		each( stringParsers, function( i, parser ) {
			var parsed,
				match = parser.re.exec( string ),
				values = match && parser.parse( match ),
				spaceName = parser.space || "rgba";
	
			if ( values ) {
				parsed = inst[ spaceName ]( values );
	
				// if this was an rgba parse the assignment might happen twice
				// oh well....
				inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
				rgba = inst._rgba = parsed._rgba;
	
				// exit each( stringParsers ) here because we matched
				return false;
			}
		});
	
		// Found a stringParser that handled it
		if ( rgba.length ) {
	
			// if this came from a parsed string, force "transparent" when alpha is 0
			// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
			if ( rgba.join() === "0,0,0,0" ) {
				jQuery.extend( rgba, colors.transparent );
			}
			return inst;
		}
	
		// named colors
		return colors[ string ];
	}
	
	color.fn = jQuery.extend( color.prototype, {
		parse: function( red, green, blue, alpha ) {
			if ( red === undefined ) {
				this._rgba = [ null, null, null, null ];
				return this;
			}
			if ( red.jquery || red.nodeType ) {
				red = jQuery( red ).css( green );
				green = undefined;
			}
	
			var inst = this,
				type = jQuery.type( red ),
				rgba = this._rgba = [];
	
			// more than 1 argument specified - assume ( red, green, blue, alpha )
			if ( green !== undefined ) {
				red = [ red, green, blue, alpha ];
				type = "array";
			}
	
			if ( type === "string" ) {
				return this.parse( stringParse( red ) || colors._default );
			}
	
			if ( type === "array" ) {
				each( spaces.rgba.props, function( key, prop ) {
					rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
				});
				return this;
			}
	
			if ( type === "object" ) {
				if ( red instanceof color ) {
					each( spaces, function( spaceName, space ) {
						if ( red[ space.cache ] ) {
							inst[ space.cache ] = red[ space.cache ].slice();
						}
					});
				} else {
					each( spaces, function( spaceName, space ) {
						var cache = space.cache;
						each( space.props, function( key, prop ) {
	
							// if the cache doesn't exist, and we know how to convert
							if ( !inst[ cache ] && space.to ) {
	
								// if the value was null, we don't need to copy it
								// if the key was alpha, we don't need to copy it either
								if ( key === "alpha" || red[ key ] == null ) {
									return;
								}
								inst[ cache ] = space.to( inst._rgba );
							}
	
							// this is the only case where we allow nulls for ALL properties.
							// call clamp with alwaysAllowEmpty
							inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
						});
	
						// everything defined but alpha?
						if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
							// use the default of 1
							inst[ cache ][ 3 ] = 1;
							if ( space.from ) {
								inst._rgba = space.from( inst[ cache ] );
							}
						}
					});
				}
				return this;
			}
		},
		is: function( compare ) {
			var is = color( compare ),
				same = true,
				inst = this;
	
			each( spaces, function( _, space ) {
				var localCache,
					isCache = is[ space.cache ];
				if (isCache) {
					localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
					each( space.props, function( _, prop ) {
						if ( isCache[ prop.idx ] != null ) {
							same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
							return same;
						}
					});
				}
				return same;
			});
			return same;
		},
		_space: function() {
			var used = [],
				inst = this;
			each( spaces, function( spaceName, space ) {
				if ( inst[ space.cache ] ) {
					used.push( spaceName );
				}
			});
			return used.pop();
		},
		transition: function( other, distance ) {
			var end = color( other ),
				spaceName = end._space(),
				space = spaces[ spaceName ],
				startColor = this.alpha() === 0 ? color( "transparent" ) : this,
				start = startColor[ space.cache ] || space.to( startColor._rgba ),
				result = start.slice();
	
			end = end[ space.cache ];
			each( space.props, function( key, prop ) {
				var index = prop.idx,
					startValue = start[ index ],
					endValue = end[ index ],
					type = propTypes[ prop.type ] || {};
	
				// if null, don't override start value
				if ( endValue === null ) {
					return;
				}
				// if null - use end
				if ( startValue === null ) {
					result[ index ] = endValue;
				} else {
					if ( type.mod ) {
						if ( endValue - startValue > type.mod / 2 ) {
							startValue += type.mod;
						} else if ( startValue - endValue > type.mod / 2 ) {
							startValue -= type.mod;
						}
					}
					result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
				}
			});
			return this[ spaceName ]( result );
		},
		blend: function( opaque ) {
			// if we are already opaque - return ourself
			if ( this._rgba[ 3 ] === 1 ) {
				return this;
			}
	
			var rgb = this._rgba.slice(),
				a = rgb.pop(),
				blend = color( opaque )._rgba;
	
			return color( jQuery.map( rgb, function( v, i ) {
				return ( 1 - a ) * blend[ i ] + a * v;
			}));
		},
		toRgbaString: function() {
			var prefix = "rgba(",
				rgba = jQuery.map( this._rgba, function( v, i ) {
					return v == null ? ( i > 2 ? 1 : 0 ) : v;
				});
	
			if ( rgba[ 3 ] === 1 ) {
				rgba.pop();
				prefix = "rgb(";
			}
	
			return prefix + rgba.join() + ")";
		},
		toHslaString: function() {
			var prefix = "hsla(",
				hsla = jQuery.map( this.hsla(), function( v, i ) {
					if ( v == null ) {
						v = i > 2 ? 1 : 0;
					}
	
					// catch 1 and 2
					if ( i && i < 3 ) {
						v = Math.round( v * 100 ) + "%";
					}
					return v;
				});
	
			if ( hsla[ 3 ] === 1 ) {
				hsla.pop();
				prefix = "hsl(";
			}
			return prefix + hsla.join() + ")";
		},
		toHexString: function( includeAlpha ) {
			var rgba = this._rgba.slice(),
				alpha = rgba.pop();
	
			if ( includeAlpha ) {
				rgba.push( ~~( alpha * 255 ) );
			}
	
			return "#" + jQuery.map( rgba, function( v ) {
	
				// default to 0 when nulls exist
				v = ( v || 0 ).toString( 16 );
				return v.length === 1 ? "0" + v : v;
			}).join("");
		},
		toString: function() {
			return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
		}
	});
	color.fn.parse.prototype = color.fn;
	
	// hsla conversions adapted from:
	// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
	
	function hue2rgb( p, q, h ) {
		h = ( h + 1 ) % 1;
		if ( h * 6 < 1 ) {
			return p + (q - p) * h * 6;
		}
		if ( h * 2 < 1) {
			return q;
		}
		if ( h * 3 < 2 ) {
			return p + (q - p) * ((2/3) - h) * 6;
		}
		return p;
	}
	
	spaces.hsla.to = function ( rgba ) {
		if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
			return [ null, null, null, rgba[ 3 ] ];
		}
		var r = rgba[ 0 ] / 255,
			g = rgba[ 1 ] / 255,
			b = rgba[ 2 ] / 255,
			a = rgba[ 3 ],
			max = Math.max( r, g, b ),
			min = Math.min( r, g, b ),
			diff = max - min,
			add = max + min,
			l = add * 0.5,
			h, s;
	
		if ( min === max ) {
			h = 0;
		} else if ( r === max ) {
			h = ( 60 * ( g - b ) / diff ) + 360;
		} else if ( g === max ) {
			h = ( 60 * ( b - r ) / diff ) + 120;
		} else {
			h = ( 60 * ( r - g ) / diff ) + 240;
		}
	
		// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
		// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
		if ( diff === 0 ) {
			s = 0;
		} else if ( l <= 0.5 ) {
			s = diff / add;
		} else {
			s = diff / ( 2 - add );
		}
		return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
	};
	
	spaces.hsla.from = function ( hsla ) {
		if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
			return [ null, null, null, hsla[ 3 ] ];
		}
		var h = hsla[ 0 ] / 360,
			s = hsla[ 1 ],
			l = hsla[ 2 ],
			a = hsla[ 3 ],
			q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
			p = 2 * l - q;
	
		return [
			Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
			Math.round( hue2rgb( p, q, h ) * 255 ),
			Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
			a
		];
	};
	
	
	each( spaces, function( spaceName, space ) {
		var props = space.props,
			cache = space.cache,
			to = space.to,
			from = space.from;
	
		// makes rgba() and hsla()
		color.fn[ spaceName ] = function( value ) {
	
			// generate a cache for this space if it doesn't exist
			if ( to && !this[ cache ] ) {
				this[ cache ] = to( this._rgba );
			}
			if ( value === undefined ) {
				return this[ cache ].slice();
			}
	
			var ret,
				type = jQuery.type( value ),
				arr = ( type === "array" || type === "object" ) ? value : arguments,
				local = this[ cache ].slice();
	
			each( props, function( key, prop ) {
				var val = arr[ type === "object" ? key : prop.idx ];
				if ( val == null ) {
					val = local[ prop.idx ];
				}
				local[ prop.idx ] = clamp( val, prop );
			});
	
			if ( from ) {
				ret = color( from( local ) );
				ret[ cache ] = local;
				return ret;
			} else {
				return color( local );
			}
		};
	
		// makes red() green() blue() alpha() hue() saturation() lightness()
		each( props, function( key, prop ) {
			// alpha is included in more than one space
			if ( color.fn[ key ] ) {
				return;
			}
			color.fn[ key ] = function( value ) {
				var vtype = jQuery.type( value ),
					fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
					local = this[ fn ](),
					cur = local[ prop.idx ],
					match;
	
				if ( vtype === "undefined" ) {
					return cur;
				}
	
				if ( vtype === "function" ) {
					value = value.call( this, cur );
					vtype = jQuery.type( value );
				}
				if ( value == null && prop.empty ) {
					return this;
				}
				if ( vtype === "string" ) {
					match = rplusequals.exec( value );
					if ( match ) {
						value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
					}
				}
				local[ prop.idx ] = value;
				return this[ fn ]( local );
			};
		});
	});
	
	// add cssHook and .fx.step function for each named hook.
	// accept a space separated string of properties
	color.hook = function( hook ) {
		var hooks = hook.split( " " );
		each( hooks, function( i, hook ) {
			jQuery.cssHooks[ hook ] = {
				set: function( elem, value ) {
					var parsed, curElem,
						backgroundColor = "";
	
					if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
						value = color( parsed || value );
						if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
							curElem = hook === "backgroundColor" ? elem.parentNode : elem;
							while (
								(backgroundColor === "" || backgroundColor === "transparent") &&
								curElem && curElem.style
							) {
								try {
									backgroundColor = jQuery.css( curElem, "backgroundColor" );
									curElem = curElem.parentNode;
								} catch ( e ) {
								}
							}
	
							value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
								backgroundColor :
								"_default" );
						}
	
						value = value.toRgbaString();
					}
					try {
						elem.style[ hook ] = value;
					} catch( e ) {
						// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
					}
				}
			};
			jQuery.fx.step[ hook ] = function( fx ) {
				if ( !fx.colorInit ) {
					fx.start = color( fx.elem, hook );
					fx.end = color( fx.end );
					fx.colorInit = true;
				}
				jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
			};
		});
	
	};
	
	color.hook( stepHooks );
	
	jQuery.cssHooks.borderColor = {
		expand: function( value ) {
			var expanded = {};
	
			each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
				expanded[ "border" + part + "Color" ] = value;
			});
			return expanded;
		}
	};
	
	// Basic color names only.
	// Usage of any of the other color names requires adding yourself or including
	// jquery.color.svg-names.js.
	colors = jQuery.Color.names = {
		// 4.1. Basic color keywords
		aqua: "#00ffff",
		black: "#000000",
		blue: "#0000ff",
		fuchsia: "#ff00ff",
		gray: "#808080",
		green: "#008000",
		lime: "#00ff00",
		maroon: "#800000",
		navy: "#000080",
		olive: "#808000",
		purple: "#800080",
		red: "#ff0000",
		silver: "#c0c0c0",
		teal: "#008080",
		white: "#ffffff",
		yellow: "#ffff00",
	
		// 4.2.3. "transparent" color keyword
		transparent: [ null, null, null, 0 ],
	
		_default: "#ffffff"
	};
	
	})( jQuery );
	
	
	/******************************************************************************/
	/****************************** CLASS ANIMATIONS ******************************/
	/******************************************************************************/
	(function() {
	
	var classAnimationActions = [ "add", "remove", "toggle" ],
		shorthandStyles = {
			border: 1,
			borderBottom: 1,
			borderColor: 1,
			borderLeft: 1,
			borderRight: 1,
			borderTop: 1,
			borderWidth: 1,
			margin: 1,
			padding: 1
		};
	
	$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
		$.fx.step[ prop ] = function( fx ) {
			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
				jQuery.style( fx.elem, prop, fx.end );
				fx.setAttr = true;
			}
		};
	});
	
	function getElementStyles( elem ) {
		var key, len,
			style = elem.ownerDocument.defaultView ?
				elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
				elem.currentStyle,
			styles = {};
	
		if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
			len = style.length;
			while ( len-- ) {
				key = style[ len ];
				if ( typeof style[ key ] === "string" ) {
					styles[ $.camelCase( key ) ] = style[ key ];
				}
			}
		// support: Opera, IE <9
		} else {
			for ( key in style ) {
				if ( typeof style[ key ] === "string" ) {
					styles[ key ] = style[ key ];
				}
			}
		}
	
		return styles;
	}
	
	
	function styleDifference( oldStyle, newStyle ) {
		var diff = {},
			name, value;
	
		for ( name in newStyle ) {
			value = newStyle[ name ];
			if ( oldStyle[ name ] !== value ) {
				if ( !shorthandStyles[ name ] ) {
					if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
						diff[ name ] = value;
					}
				}
			}
		}
	
		return diff;
	}
	
	// support: jQuery <1.8
	if ( !$.fn.addBack ) {
		$.fn.addBack = function( selector ) {
			return this.add( selector == null ?
				this.prevObject : this.prevObject.filter( selector )
			);
		};
	}
	
	$.effects.animateClass = function( value, duration, easing, callback ) {
		var o = $.speed( duration, easing, callback );
	
		return this.queue( function() {
			var animated = $( this ),
				baseClass = animated.attr( "class" ) || "",
				applyClassChange,
				allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
	
			// map the animated objects to store the original styles.
			allAnimations = allAnimations.map(function() {
				var el = $( this );
				return {
					el: el,
					start: getElementStyles( this )
				};
			});
	
			// apply class change
			applyClassChange = function() {
				$.each( classAnimationActions, function(i, action) {
					if ( value[ action ] ) {
						animated[ action + "Class" ]( value[ action ] );
					}
				});
			};
			applyClassChange();
	
			// map all animated objects again - calculate new styles and diff
			allAnimations = allAnimations.map(function() {
				this.end = getElementStyles( this.el[ 0 ] );
				this.diff = styleDifference( this.start, this.end );
				return this;
			});
	
			// apply original class
			animated.attr( "class", baseClass );
	
			// map all animated objects again - this time collecting a promise
			allAnimations = allAnimations.map(function() {
				var styleInfo = this,
					dfd = $.Deferred(),
					opts = $.extend({}, o, {
						queue: false,
						complete: function() {
							dfd.resolve( styleInfo );
						}
					});
	
				this.el.animate( this.diff, opts );
				return dfd.promise();
			});
	
			// once all animations have completed:
			$.when.apply( $, allAnimations.get() ).done(function() {
	
				// set the final class
				applyClassChange();
	
				// for each animated element,
				// clear all css properties that were animated
				$.each( arguments, function() {
					var el = this.el;
					$.each( this.diff, function(key) {
						el.css( key, "" );
					});
				});
	
				// this is guarnteed to be there if you use jQuery.speed()
				// it also handles dequeuing the next anim...
				o.complete.call( animated[ 0 ] );
			});
		});
	};
	
	$.fn.extend({
		addClass: (function( orig ) {
			return function( classNames, speed, easing, callback ) {
				return speed ?
					$.effects.animateClass.call( this,
						{ add: classNames }, speed, easing, callback ) :
					orig.apply( this, arguments );
			};
		})( $.fn.addClass ),
	
		removeClass: (function( orig ) {
			return function( classNames, speed, easing, callback ) {
				return arguments.length > 1 ?
					$.effects.animateClass.call( this,
						{ remove: classNames }, speed, easing, callback ) :
					orig.apply( this, arguments );
			};
		})( $.fn.removeClass ),
	
		toggleClass: (function( orig ) {
			return function( classNames, force, speed, easing, callback ) {
				if ( typeof force === "boolean" || force === undefined ) {
					if ( !speed ) {
						// without speed parameter
						return orig.apply( this, arguments );
					} else {
						return $.effects.animateClass.call( this,
							(force ? { add: classNames } : { remove: classNames }),
							speed, easing, callback );
					}
				} else {
					// without force parameter
					return $.effects.animateClass.call( this,
						{ toggle: classNames }, force, speed, easing );
				}
			};
		})( $.fn.toggleClass ),
	
		switchClass: function( remove, add, speed, easing, callback) {
			return $.effects.animateClass.call( this, {
				add: add,
				remove: remove
			}, speed, easing, callback );
		}
	});
	
	})();
	
	/******************************************************************************/
	/*********************************** EFFECTS **********************************/
	/******************************************************************************/
	
	(function() {
	
	$.extend( $.effects, {
		version: "1.10.3",
	
		// Saves a set of properties in a data storage
		save: function( element, set ) {
			for( var i=0; i < set.length; i++ ) {
				if ( set[ i ] !== null ) {
					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
				}
			}
		},
	
		// Restores a set of previously saved properties from a data storage
		restore: function( element, set ) {
			var val, i;
			for( i=0; i < set.length; i++ ) {
				if ( set[ i ] !== null ) {
					val = element.data( dataSpace + set[ i ] );
					// support: jQuery 1.6.2
					// http://bugs.jquery.com/ticket/9917
					// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
					// We can't differentiate between "" and 0 here, so we just assume
					// empty string since it's likely to be a more common value...
					if ( val === undefined ) {
						val = "";
					}
					element.css( set[ i ], val );
				}
			}
		},
	
		setMode: function( el, mode ) {
			if (mode === "toggle") {
				mode = el.is( ":hidden" ) ? "show" : "hide";
			}
			return mode;
		},
	
		// Translates a [top,left] array into a baseline value
		// this should be a little more flexible in the future to handle a string & hash
		getBaseline: function( origin, original ) {
			var y, x;
			switch ( origin[ 0 ] ) {
				case "top": y = 0; break;
				case "middle": y = 0.5; break;
				case "bottom": y = 1; break;
				default: y = origin[ 0 ] / original.height;
			}
			switch ( origin[ 1 ] ) {
				case "left": x = 0; break;
				case "center": x = 0.5; break;
				case "right": x = 1; break;
				default: x = origin[ 1 ] / original.width;
			}
			return {
				x: x,
				y: y
			};
		},
	
		// Wraps the element around a wrapper that copies position properties
		createWrapper: function( element ) {
	
			// if the element is already wrapped, return it
			if ( element.parent().is( ".ui-effects-wrapper" )) {
				return element.parent();
			}
	
			// wrap the element
			var props = {
					width: element.outerWidth(true),
					height: element.outerHeight(true),
					"float": element.css( "float" )
				},
				wrapper = $( "<div></div>" )
					.addClass( "ui-effects-wrapper" )
					.css({
						fontSize: "100%",
						background: "transparent",
						border: "none",
						margin: 0,
						padding: 0
					}),
				// Store the size in case width/height are defined in % - Fixes #5245
				size = {
					width: element.width(),
					height: element.height()
				},
				active = document.activeElement;
	
			// support: Firefox
			// Firefox incorrectly exposes anonymous content
			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
			try {
				active.id;
			} catch( e ) {
				active = document.body;
			}
	
			element.wrap( wrapper );
	
			// Fixes #7595 - Elements lose focus when wrapped.
			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
				$( active ).focus();
			}
	
			wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
	
			// transfer positioning properties to the wrapper
			if ( element.css( "position" ) === "static" ) {
				wrapper.css({ position: "relative" });
				element.css({ position: "relative" });
			} else {
				$.extend( props, {
					position: element.css( "position" ),
					zIndex: element.css( "z-index" )
				});
				$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
					props[ pos ] = element.css( pos );
					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
						props[ pos ] = "auto";
					}
				});
				element.css({
					position: "relative",
					top: 0,
					left: 0,
					right: "auto",
					bottom: "auto"
				});
			}
			element.css(size);
	
			return wrapper.css( props ).show();
		},
	
		removeWrapper: function( element ) {
			var active = document.activeElement;
	
			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
				element.parent().replaceWith( element );
	
				// Fixes #7595 - Elements lose focus when wrapped.
				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
					$( active ).focus();
				}
			}
	
	
			return element;
		},
	
		setTransition: function( element, list, factor, value ) {
			value = value || {};
			$.each( list, function( i, x ) {
				var unit = element.cssUnit( x );
				if ( unit[ 0 ] > 0 ) {
					value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
				}
			});
			return value;
		}
	});
	
	// return an effect options object for the given parameters:
	function _normalizeArguments( effect, options, speed, callback ) {
	
		// allow passing all options as the first parameter
		if ( $.isPlainObject( effect ) ) {
			options = effect;
			effect = effect.effect;
		}
	
		// convert to an object
		effect = { effect: effect };
	
		// catch (effect, null, ...)
		if ( options == null ) {
			options = {};
		}
	
		// catch (effect, callback)
		if ( $.isFunction( options ) ) {
			callback = options;
			speed = null;
			options = {};
		}
	
		// catch (effect, speed, ?)
		if ( typeof options === "number" || $.fx.speeds[ options ] ) {
			callback = speed;
			speed = options;
			options = {};
		}
	
		// catch (effect, options, callback)
		if ( $.isFunction( speed ) ) {
			callback = speed;
			speed = null;
		}
	
		// add options to effect
		if ( options ) {
			$.extend( effect, options );
		}
	
		speed = speed || options.duration;
		effect.duration = $.fx.off ? 0 :
			typeof speed === "number" ? speed :
			speed in $.fx.speeds ? $.fx.speeds[ speed ] :
			$.fx.speeds._default;
	
		effect.complete = callback || options.complete;
	
		return effect;
	}
	
	function standardAnimationOption( option ) {
		// Valid standard speeds (nothing, number, named speed)
		if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
			return true;
		}
	
		// Invalid strings - treat as "normal" speed
		if ( typeof option === "string" && !$.effects.effect[ option ] ) {
			return true;
		}
	
		// Complete callback
		if ( $.isFunction( option ) ) {
			return true;
		}
	
		// Options hash (but not naming an effect)
		if ( typeof option === "object" && !option.effect ) {
			return true;
		}
	
		// Didn't match any standard API
		return false;
	}
	
	$.fn.extend({
		effect: function( /* effect, options, speed, callback */ ) {
			var args = _normalizeArguments.apply( this, arguments ),
				mode = args.mode,
				queue = args.queue,
				effectMethod = $.effects.effect[ args.effect ];
	
			if ( $.fx.off || !effectMethod ) {
				// delegate to the original method (e.g., .show()) if possible
				if ( mode ) {
					return this[ mode ]( args.duration, args.complete );
				} else {
					return this.each( function() {
						if ( args.complete ) {
							args.complete.call( this );
						}
					});
				}
			}
	
			function run( next ) {
				var elem = $( this ),
					complete = args.complete,
					mode = args.mode;
	
				function done() {
					if ( $.isFunction( complete ) ) {
						complete.call( elem[0] );
					}
					if ( $.isFunction( next ) ) {
						next();
					}
				}
	
				// If the element already has the correct final state, delegate to
				// the core methods so the internal tracking of "olddisplay" works.
				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
					elem[ mode ]();
					done();
				} else {
					effectMethod.call( elem[0], args, done );
				}
			}
	
			return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
		},
	
		show: (function( orig ) {
			return function( option ) {
				if ( standardAnimationOption( option ) ) {
					return orig.apply( this, arguments );
				} else {
					var args = _normalizeArguments.apply( this, arguments );
					args.mode = "show";
					return this.effect.call( this, args );
				}
			};
		})( $.fn.show ),
	
		hide: (function( orig ) {
			return function( option ) {
				if ( standardAnimationOption( option ) ) {
					return orig.apply( this, arguments );
				} else {
					var args = _normalizeArguments.apply( this, arguments );
					args.mode = "hide";
					return this.effect.call( this, args );
				}
			};
		})( $.fn.hide ),
	
		toggle: (function( orig ) {
			return function( option ) {
				if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
					return orig.apply( this, arguments );
				} else {
					var args = _normalizeArguments.apply( this, arguments );
					args.mode = "toggle";
					return this.effect.call( this, args );
				}
			};
		})( $.fn.toggle ),
	
		// helper functions
		cssUnit: function(key) {
			var style = this.css( key ),
				val = [];
	
			$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
				if ( style.indexOf( unit ) > 0 ) {
					val = [ parseFloat( style ), unit ];
				}
			});
			return val;
		}
	});
	
	})();
	
	/******************************************************************************/
	/*********************************** EASING ***********************************/
	/******************************************************************************/
	
	(function() {
	
	// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
	
	var baseEasings = {};
	
	$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
		baseEasings[ name ] = function( p ) {
			return Math.pow( p, i + 2 );
		};
	});
	
	$.extend( baseEasings, {
		Sine: function ( p ) {
			return 1 - Math.cos( p * Math.PI / 2 );
		},
		Circ: function ( p ) {
			return 1 - Math.sqrt( 1 - p * p );
		},
		Elastic: function( p ) {
			return p === 0 || p === 1 ? p :
				-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
		},
		Back: function( p ) {
			return p * p * ( 3 * p - 2 );
		},
		Bounce: function ( p ) {
			var pow2,
				bounce = 4;
	
			while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
			return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
		}
	});
	
	$.each( baseEasings, function( name, easeIn ) {
		$.easing[ "easeIn" + name ] = easeIn;
		$.easing[ "easeOut" + name ] = function( p ) {
			return 1 - easeIn( 1 - p );
		};
		$.easing[ "easeInOut" + name ] = function( p ) {
			return p < 0.5 ?
				easeIn( p * 2 ) / 2 :
				1 - easeIn( p * -2 + 2 ) / 2;
		};
	});
	
	})();
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	var uid = 0,
		hideProps = {},
		showProps = {};
	
	hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
		hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
	showProps.height = showProps.paddingTop = showProps.paddingBottom =
		showProps.borderTopWidth = showProps.borderBottomWidth = "show";
	
	$.widget( "ui.accordion", {
		version: "1.10.3",
		options: {
			active: 0,
			animate: {},
			collapsible: false,
			event: "click",
			header: "> li > :first-child,> :not(li):even",
			heightStyle: "auto",
			icons: {
				activeHeader: "ui-icon-triangle-1-s",
				header: "ui-icon-triangle-1-e"
			},
	
			// callbacks
			activate: null,
			beforeActivate: null
		},
	
		_create: function() {
			var options = this.options;
			this.prevShow = this.prevHide = $();
			this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
				// ARIA
				.attr( "role", "tablist" );
	
			// don't allow collapsible: false and active: false / null
			if ( !options.collapsible && (options.active === false || options.active == null) ) {
				options.active = 0;
			}
	
			this._processPanels();
			// handle negative values
			if ( options.active < 0 ) {
				options.active += this.headers.length;
			}
			this._refresh();
		},
	
		_getCreateEventData: function() {
			return {
				header: this.active,
				panel: !this.active.length ? $() : this.active.next(),
				content: !this.active.length ? $() : this.active.next()
			};
		},
	
		_createIcons: function() {
			var icons = this.options.icons;
			if ( icons ) {
				$( "<span>" )
					.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
					.prependTo( this.headers );
				this.active.children( ".ui-accordion-header-icon" )
					.removeClass( icons.header )
					.addClass( icons.activeHeader );
				this.headers.addClass( "ui-accordion-icons" );
			}
		},
	
		_destroyIcons: function() {
			this.headers
				.removeClass( "ui-accordion-icons" )
				.children( ".ui-accordion-header-icon" )
					.remove();
		},
	
		_destroy: function() {
			var contents;
	
			// clean up main element
			this.element
				.removeClass( "ui-accordion ui-widget ui-helper-reset" )
				.removeAttr( "role" );
	
			// clean up headers
			this.headers
				.removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
				.removeAttr( "role" )
				.removeAttr( "aria-selected" )
				.removeAttr( "aria-controls" )
				.removeAttr( "tabIndex" )
				.each(function() {
					if ( /^ui-accordion/.test( this.id ) ) {
						this.removeAttribute( "id" );
					}
				});
			this._destroyIcons();
	
			// clean up content panels
			contents = this.headers.next()
				.css( "display", "" )
				.removeAttr( "role" )
				.removeAttr( "aria-expanded" )
				.removeAttr( "aria-hidden" )
				.removeAttr( "aria-labelledby" )
				.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
				.each(function() {
					if ( /^ui-accordion/.test( this.id ) ) {
						this.removeAttribute( "id" );
					}
				});
			if ( this.options.heightStyle !== "content" ) {
				contents.css( "height", "" );
			}
		},
	
		_setOption: function( key, value ) {
			if ( key === "active" ) {
				// _activate() will handle invalid values and update this.options
				this._activate( value );
				return;
			}
	
			if ( key === "event" ) {
				if ( this.options.event ) {
					this._off( this.headers, this.options.event );
				}
				this._setupEvents( value );
			}
	
			this._super( key, value );
	
			// setting collapsible: false while collapsed; open first panel
			if ( key === "collapsible" && !value && this.options.active === false ) {
				this._activate( 0 );
			}
	
			if ( key === "icons" ) {
				this._destroyIcons();
				if ( value ) {
					this._createIcons();
				}
			}
	
			// #5332 - opacity doesn't cascade to positioned elements in IE
			// so we need to add the disabled class to the headers and panels
			if ( key === "disabled" ) {
				this.headers.add( this.headers.next() )
					.toggleClass( "ui-state-disabled", !!value );
			}
		},
	
		_keydown: function( event ) {
			/*jshint maxcomplexity:15*/
			if ( event.altKey || event.ctrlKey ) {
				return;
			}
	
			var keyCode = $.ui.keyCode,
				length = this.headers.length,
				currentIndex = this.headers.index( event.target ),
				toFocus = false;
	
			switch ( event.keyCode ) {
				case keyCode.RIGHT:
				case keyCode.DOWN:
					toFocus = this.headers[ ( currentIndex + 1 ) % length ];
					break;
				case keyCode.LEFT:
				case keyCode.UP:
					toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
					break;
				case keyCode.SPACE:
				case keyCode.ENTER:
					this._eventHandler( event );
					break;
				case keyCode.HOME:
					toFocus = this.headers[ 0 ];
					break;
				case keyCode.END:
					toFocus = this.headers[ length - 1 ];
					break;
			}
	
			if ( toFocus ) {
				$( event.target ).attr( "tabIndex", -1 );
				$( toFocus ).attr( "tabIndex", 0 );
				toFocus.focus();
				event.preventDefault();
			}
		},
	
		_panelKeyDown : function( event ) {
			if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
				$( event.currentTarget ).prev().focus();
			}
		},
	
		refresh: function() {
			var options = this.options;
			this._processPanels();
	
			// was collapsed or no panel
			if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
				options.active = false;
				this.active = $();
			// active false only when collapsible is true
			} else if ( options.active === false ) {
				this._activate( 0 );
			// was active, but active panel is gone
			} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
				// all remaining panel are disabled
				if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
					options.active = false;
					this.active = $();
				// activate previous panel
				} else {
					this._activate( Math.max( 0, options.active - 1 ) );
				}
			// was active, active panel still exists
			} else {
				// make sure active index is correct
				options.active = this.headers.index( this.active );
			}
	
			this._destroyIcons();
	
			this._refresh();
		},
	
		_processPanels: function() {
			this.headers = this.element.find( this.options.header )
				.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
	
			this.headers.next()
				.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
				.filter(":not(.ui-accordion-content-active)")
				.hide();
		},
	
		_refresh: function() {
			var maxHeight,
				options = this.options,
				heightStyle = options.heightStyle,
				parent = this.element.parent(),
				accordionId = this.accordionId = "ui-accordion-" +
					(this.element.attr( "id" ) || ++uid);
	
			this.active = this._findActive( options.active )
				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
				.removeClass( "ui-corner-all" );
			this.active.next()
				.addClass( "ui-accordion-content-active" )
				.show();
	
			this.headers
				.attr( "role", "tab" )
				.each(function( i ) {
					var header = $( this ),
						headerId = header.attr( "id" ),
						panel = header.next(),
						panelId = panel.attr( "id" );
					if ( !headerId ) {
						headerId = accordionId + "-header-" + i;
						header.attr( "id", headerId );
					}
					if ( !panelId ) {
						panelId = accordionId + "-panel-" + i;
						panel.attr( "id", panelId );
					}
					header.attr( "aria-controls", panelId );
					panel.attr( "aria-labelledby", headerId );
				})
				.next()
					.attr( "role", "tabpanel" );
	
			this.headers
				.not( this.active )
				.attr({
					"aria-selected": "false",
					tabIndex: -1
				})
				.next()
					.attr({
						"aria-expanded": "false",
						"aria-hidden": "true"
					})
					.hide();
	
			// make sure at least one header is in the tab order
			if ( !this.active.length ) {
				this.headers.eq( 0 ).attr( "tabIndex", 0 );
			} else {
				this.active.attr({
					"aria-selected": "true",
					tabIndex: 0
				})
				.next()
					.attr({
						"aria-expanded": "true",
						"aria-hidden": "false"
					});
			}
	
			this._createIcons();
	
			this._setupEvents( options.event );
	
			if ( heightStyle === "fill" ) {
				maxHeight = parent.height();
				this.element.siblings( ":visible" ).each(function() {
					var elem = $( this ),
						position = elem.css( "position" );
	
					if ( position === "absolute" || position === "fixed" ) {
						return;
					}
					maxHeight -= elem.outerHeight( true );
				});
	
				this.headers.each(function() {
					maxHeight -= $( this ).outerHeight( true );
				});
	
				this.headers.next()
					.each(function() {
						$( this ).height( Math.max( 0, maxHeight -
							$( this ).innerHeight() + $( this ).height() ) );
					})
					.css( "overflow", "auto" );
			} else if ( heightStyle === "auto" ) {
				maxHeight = 0;
				this.headers.next()
					.each(function() {
						maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
					})
					.height( maxHeight );
			}
		},
	
		_activate: function( index ) {
			var active = this._findActive( index )[ 0 ];
	
			// trying to activate the already active panel
			if ( active === this.active[ 0 ] ) {
				return;
			}
	
			// trying to collapse, simulate a click on the currently active header
			active = active || this.active[ 0 ];
	
			this._eventHandler({
				target: active,
				currentTarget: active,
				preventDefault: $.noop
			});
		},
	
		_findActive: function( selector ) {
			return typeof selector === "number" ? this.headers.eq( selector ) : $();
		},
	
		_setupEvents: function( event ) {
			var events = {
				keydown: "_keydown"
			};
			if ( event ) {
				$.each( event.split(" "), function( index, eventName ) {
					events[ eventName ] = "_eventHandler";
				});
			}
	
			this._off( this.headers.add( this.headers.next() ) );
			this._on( this.headers, events );
			this._on( this.headers.next(), { keydown: "_panelKeyDown" });
			this._hoverable( this.headers );
			this._focusable( this.headers );
		},
	
		_eventHandler: function( event ) {
			var options = this.options,
				active = this.active,
				clicked = $( event.currentTarget ),
				clickedIsActive = clicked[ 0 ] === active[ 0 ],
				collapsing = clickedIsActive && options.collapsible,
				toShow = collapsing ? $() : clicked.next(),
				toHide = active.next(),
				eventData = {
					oldHeader: active,
					oldPanel: toHide,
					newHeader: collapsing ? $() : clicked,
					newPanel: toShow
				};
	
			event.preventDefault();
	
			if (
					// click on active header, but not collapsible
					( clickedIsActive && !options.collapsible ) ||
					// allow canceling activation
					( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
				return;
			}
	
			options.active = collapsing ? false : this.headers.index( clicked );
	
			// when the call to ._toggle() comes after the class changes
			// it causes a very odd bug in IE 8 (see #6720)
			this.active = clickedIsActive ? $() : clicked;
			this._toggle( eventData );
	
			// switch classes
			// corner classes on the previously active header stay after the animation
			active.removeClass( "ui-accordion-header-active ui-state-active" );
			if ( options.icons ) {
				active.children( ".ui-accordion-header-icon" )
					.removeClass( options.icons.activeHeader )
					.addClass( options.icons.header );
			}
	
			if ( !clickedIsActive ) {
				clicked
					.removeClass( "ui-corner-all" )
					.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
				if ( options.icons ) {
					clicked.children( ".ui-accordion-header-icon" )
						.removeClass( options.icons.header )
						.addClass( options.icons.activeHeader );
				}
	
				clicked
					.next()
					.addClass( "ui-accordion-content-active" );
			}
		},
	
		_toggle: function( data ) {
			var toShow = data.newPanel,
				toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
	
			// handle activating a panel during the animation for another activation
			this.prevShow.add( this.prevHide ).stop( true, true );
			this.prevShow = toShow;
			this.prevHide = toHide;
	
			if ( this.options.animate ) {
				this._animate( toShow, toHide, data );
			} else {
				toHide.hide();
				toShow.show();
				this._toggleComplete( data );
			}
	
			toHide.attr({
				"aria-expanded": "false",
				"aria-hidden": "true"
			});
			toHide.prev().attr( "aria-selected", "false" );
			// if we're switching panels, remove the old header from the tab order
			// if we're opening from collapsed state, remove the previous header from the tab order
			// if we're collapsing, then keep the collapsing header in the tab order
			if ( toShow.length && toHide.length ) {
				toHide.prev().attr( "tabIndex", -1 );
			} else if ( toShow.length ) {
				this.headers.filter(function() {
					return $( this ).attr( "tabIndex" ) === 0;
				})
				.attr( "tabIndex", -1 );
			}
	
			toShow
				.attr({
					"aria-expanded": "true",
					"aria-hidden": "false"
				})
				.prev()
					.attr({
						"aria-selected": "true",
						tabIndex: 0
					});
		},
	
		_animate: function( toShow, toHide, data ) {
			var total, easing, duration,
				that = this,
				adjust = 0,
				down = toShow.length &&
					( !toHide.length || ( toShow.index() < toHide.index() ) ),
				animate = this.options.animate || {},
				options = down && animate.down || animate,
				complete = function() {
					that._toggleComplete( data );
				};
	
			if ( typeof options === "number" ) {
				duration = options;
			}
			if ( typeof options === "string" ) {
				easing = options;
			}
			// fall back from options to animation in case of partial down settings
			easing = easing || options.easing || animate.easing;
			duration = duration || options.duration || animate.duration;
	
			if ( !toHide.length ) {
				return toShow.animate( showProps, duration, easing, complete );
			}
			if ( !toShow.length ) {
				return toHide.animate( hideProps, duration, easing, complete );
			}
	
			total = toShow.show().outerHeight();
			toHide.animate( hideProps, {
				duration: duration,
				easing: easing,
				step: function( now, fx ) {
					fx.now = Math.round( now );
				}
			});
			toShow
				.hide()
				.animate( showProps, {
					duration: duration,
					easing: easing,
					complete: complete,
					step: function( now, fx ) {
						fx.now = Math.round( now );
						if ( fx.prop !== "height" ) {
							adjust += fx.now;
						} else if ( that.options.heightStyle !== "content" ) {
							fx.now = Math.round( total - toHide.outerHeight() - adjust );
							adjust = 0;
						}
					}
				});
		},
	
		_toggleComplete: function( data ) {
			var toHide = data.oldPanel;
	
			toHide
				.removeClass( "ui-accordion-content-active" )
				.prev()
					.removeClass( "ui-corner-top" )
					.addClass( "ui-corner-all" );
	
			// Work around for rendering bug in IE (#5421)
			if ( toHide.length ) {
				toHide.parent()[0].className = toHide.parent()[0].className;
			}
	
			this._trigger( "activate", null, data );
		}
	});
	
	})( jQuery );
	
	(function( $, undefined ) {
	
	// used to prevent race conditions with remote data sources
	var requestIndex = 0;
	
	$.widget( "ui.autocomplete", {
		version: "1.10.3",
		defaultElement: "<input>",
		options: {
			appendTo: null,
			autoFocus: false,
			delay: 300,
			minLength: 1,
			position: {
				my: "left top",
				at: "left bottom",
				collision: "none"
			},
			source: null,
	
			// callbacks
			change: null,
			close: null,
			focus: null,
			open: null,
			response: null,
			search: null,
			select: null
		},
	
		pending: 0,
	
		_create: function() {
			// Some browsers only repeat keydown events, not keypress events,
			// so we use the suppressKeyPress flag to determine if we've already
			// handled the keydown event. #7269
			// Unfortunately the code for & in keypress is the same as the up arrow,
			// so we use the suppressKeyPressRepeat flag to avoid handling keypress
			// events when we know the keydown event was used to modify the
			// search term. #7799
			var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
				nodeName = this.element[0].nodeName.toLowerCase(),
				isTextarea = nodeName === "textarea",
				isInput = nodeName === "input";
	
			this.isMultiLine =
				// Textareas are always multi-line
				isTextarea ? true :
				// Inputs are always single-line, even if inside a contentEditable element
				// IE also treats inputs as contentEditable
				isInput ? false :
				// All other element types are determined by whether or not they're contentEditable
				this.element.prop( "isContentEditable" );
	
			this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
			this.isNewMenu = true;
	
			this.element
				.addClass( "ui-autocomplete-input" )
				.attr( "autocomplete", "off" );
	
			this._on( this.element, {
				keydown: function( event ) {
					/*jshint maxcomplexity:15*/
					if ( this.element.prop( "readOnly" ) ) {
						suppressKeyPress = true;
						suppressInput = true;
						suppressKeyPressRepeat = true;
						return;
					}
	
					suppressKeyPress = false;
					suppressInput = false;
					suppressKeyPressRepeat = false;
					var keyCode = $.ui.keyCode;
					switch( event.keyCode ) {
					case keyCode.PAGE_UP:
						suppressKeyPress = true;
						this._move( "previousPage", event );
						break;
					case keyCode.PAGE_DOWN:
						suppressKeyPress = true;
						this._move( "nextPage", event );
						break;
					case keyCode.UP:
						suppressKeyPress = true;
						this._keyEvent( "previous", event );
						break;
					case keyCode.DOWN:
						suppressKeyPress = true;
						this._keyEvent( "next", event );
						break;
					case keyCode.ENTER:
					case keyCode.NUMPAD_ENTER:
						// when menu is open and has focus
						if ( this.menu.active ) {
							// #6055 - Opera still allows the keypress to occur
							// which causes forms to submit
							suppressKeyPress = true;
							event.preventDefault();
							this.menu.select( event );
						}
						break;
					case keyCode.TAB:
						if ( this.menu.active ) {
							this.menu.select( event );
						}
						break;
					case keyCode.ESCAPE:
						if ( this.menu.element.is( ":visible" ) ) {
							this._value( this.term );
							this.close( event );
							// Different browsers have different default behavior for escape
							// Single press can mean undo or clear
							// Double press in IE means clear the whole form
							event.preventDefault();
						}
						break;
					default:
						suppressKeyPressRepeat = true;
						// search timeout should be triggered before the input value is changed
						this._searchTimeout( event );
						break;
					}
				},
				keypress: function( event ) {
					if ( suppressKeyPress ) {
						suppressKeyPress = false;
						if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
							event.preventDefault();
						}
						return;
					}
					if ( suppressKeyPressRepeat ) {
						return;
					}
	
					// replicate some key handlers to allow them to repeat in Firefox and Opera
					var keyCode = $.ui.keyCode;
					switch( event.keyCode ) {
					case keyCode.PAGE_UP:
						this._move( "previousPage", event );
						break;
					case keyCode.PAGE_DOWN:
						this._move( "nextPage", event );
						break;
					case keyCode.UP:
						this._keyEvent( "previous", event );
						break;
					case keyCode.DOWN:
						this._keyEvent( "next", event );
						break;
					}
				},
				input: function( event ) {
					if ( suppressInput ) {
						suppressInput = false;
						event.preventDefault();
						return;
					}
					this._searchTimeout( event );
				},
				focus: function() {
					this.selectedItem = null;
					this.previous = this._value();
				},
				blur: function( event ) {
					if ( this.cancelBlur ) {
						delete this.cancelBlur;
						return;
					}
	
					clearTimeout( this.searching );
					this.close( event );
					this._change( event );
				}
			});
	
			this._initSource();
			this.menu = $( "<ul>" )
				.addClass( "ui-autocomplete ui-front" )
				.appendTo( this._appendTo() )
				.menu({
					// disable ARIA support, the live region takes care of that
					role: null
				})
				.hide()
				.data( "ui-menu" );
	
			this._on( this.menu.element, {
				mousedown: function( event ) {
					// prevent moving focus out of the text field
					event.preventDefault();
	
					// IE doesn't prevent moving focus even with event.preventDefault()
					// so we set a flag to know when we should ignore the blur event
					this.cancelBlur = true;
					this._delay(function() {
						delete this.cancelBlur;
					});
	
					// clicking on the scrollbar causes focus to shift to the body
					// but we can't detect a mouseup or a click immediately afterward
					// so we have to track the next mousedown and close the menu if
					// the user clicks somewhere outside of the autocomplete
					var menuElement = this.menu.element[ 0 ];
					if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
						this._delay(function() {
							var that = this;
							this.document.one( "mousedown", function( event ) {
								if ( event.target !== that.element[ 0 ] &&
										event.target !== menuElement &&
										!$.contains( menuElement, event.target ) ) {
									that.close();
								}
							});
						});
					}
				},
				menufocus: function( event, ui ) {
					// support: Firefox
					// Prevent accidental activation of menu items in Firefox (#7024 #9118)
					if ( this.isNewMenu ) {
						this.isNewMenu = false;
						if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
							this.menu.blur();
	
							this.document.one( "mousemove", function() {
								$( event.target ).trigger( event.originalEvent );
							});
	
							return;
						}
					}
	
					var item = ui.item.data( "ui-autocomplete-item" );
					if ( false !== this._trigger( "focus", event, { item: item } ) ) {
						// use value to match what will end up in the input, if it was a key event
						if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
							this._value( item.value );
						}
					} else {
						// Normally the input is populated with the item's value as the
						// menu is navigated, causing screen readers to notice a change and
						// announce the item. Since the focus event was canceled, this doesn't
						// happen, so we update the live region so that screen readers can
						// still notice the change and announce it.
						this.liveRegion.text( item.value );
					}
				},
				menuselect: function( event, ui ) {
					var item = ui.item.data( "ui-autocomplete-item" ),
						previous = this.previous;
	
					// only trigger when focus was lost (click on menu)
					if ( this.element[0] !== this.document[0].activeElement ) {
						this.element.focus();
						this.previous = previous;
						// #6109 - IE triggers two focus events and the second
						// is asynchronous, so we need to reset the previous
						// term synchronously and asynchronously :-(
						this._delay(function() {
							this.previous = previous;
							this.selectedItem = item;
						});
					}
	
					if ( false !== this._trigger( "select", event, { item: item } ) ) {
						this._value( item.value );
					}
					// reset the term after the select event
					// this allows custom select handling to work properly
					this.term = this._value();
	
					this.close( event );
					this.selectedItem = item;
				}
			});
	
			this.liveRegion = $( "<span>", {
					role: "status",
					"aria-live": "polite"
				})
				.addClass( "ui-helper-hidden-accessible" )
				.insertBefore( this.element );
	
			// turning off autocomplete prevents the browser from remembering the
			// value when navigating through history, so we re-enable autocomplete
			// if the page is unloaded before the widget is destroyed. #7790
			this._on( this.window, {
				beforeunload: function() {
					this.element.removeAttr( "autocomplete" );
				}
			});
		},
	
		_destroy: function() {
			clearTimeout( this.searching );
			this.element
				.removeClass( "ui-autocomplete-input" )
				.removeAttr( "autocomplete" );
			this.menu.element.remove();
			this.liveRegion.remove();
		},
	
		_setOption: function( key, value ) {
			this._super( key, value );
			if ( key === "source" ) {
				this._initSource();
			}
			if ( key === "appendTo" ) {
				this.menu.element.appendTo( this._appendTo() );
			}
			if ( key === "disabled" && value && this.xhr ) {
				this.xhr.abort();
			}
		},
	
		_appendTo: function() {
			var element = this.options.appendTo;
	
			if ( element ) {
				element = element.jquery || element.nodeType ?
					$( element ) :
					this.document.find( element ).eq( 0 );
			}
	
			if ( !element ) {
				element = this.element.closest( ".ui-front" );
			}
	
			if ( !element.length ) {
				element = this.document[0].body;
			}
	
			return element;
		},
	
		_initSource: function() {
			var array, url,
				that = this;
			if ( $.isArray(this.options.source) ) {
				array = this.options.source;
				this.source = function( request, response ) {
					response( $.ui.autocomplete.filter( array, request.term ) );
				};
			} else if ( typeof this.options.source === "string" ) {
				url = this.options.source;
				this.source = function( request, response ) {
					if ( that.xhr ) {
						that.xhr.abort();
					}
					that.xhr = $.ajax({
						url: url,
						data: request,
						dataType: "json",
						success: function( data ) {
							response( data );
						},
						error: function() {
							response( [] );
						}
					});
				};
			} else {
				this.source = this.options.source;
			}
		},
	
		_searchTimeout: function( event ) {
			clearTimeout( this.searching );
			this.searching = this._delay(function() {
				// only search if the value has changed
				if ( this.term !== this._value() ) {
					this.selectedItem = null;
					this.search( null, event );
				}
			}, this.options.delay );
		},
	
		search: function( value, event ) {
			value = value != null ? value : this._value();
	
			// always save the actual value, not the one passed as an argument
			this.term = this._value();
	
			if ( value.length < this.options.minLength ) {
				return this.close( event );
			}
	
			if ( this._trigger( "search", event ) === false ) {
				return;
			}
	
			return this._search( value );
		},
	
		_search: function( value ) {
			this.pending++;
			this.element.addClass( "ui-autocomplete-loading" );
			this.cancelSearch = false;
	
			this.source( { term: value }, this._response() );
		},
	
		_response: function() {
			var that = this,
				index = ++requestIndex;
	
			return function( content ) {
				if ( index === requestIndex ) {
					that.__response( content );
				}
	
				that.pending--;
				if ( !that.pending ) {
					that.element.removeClass( "ui-autocomplete-loading" );
				}
			};
		},
	
		__response: function( content ) {
			if ( content ) {
				content = this._normalize( content );
			}
			this._trigger( "response", null, { content: content } );
			if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
				this._suggest( content );
				this._trigger( "open" );
			} else {
				// use ._close() instead of .close() so we don't cancel future searches
				this._close();
			}
		},
	
		close: function( event ) {
			this.cancelSearch = true;
			this._close( event );
		},
	
		_close: function( event ) {
			if ( this.menu.element.is( ":visible" ) ) {
				this.menu.element.hide();
				this.menu.blur();
				this.isNewMenu = true;
				this._trigger( "close", event );
			}
		},
	
		_change: function( event ) {
			if ( this.previous !== this._value() ) {
				this._trigger( "change", event, { item: this.selectedItem } );
			}
		},
	
		_normalize: function( items ) {
			// assume all items have the right format when the first item is complete
			if ( items.length && items[0].label && items[0].value ) {
				return items;
			}
			return $.map( items, function( item ) {
				if ( typeof item === "string" ) {
					return {
						label: item,
						value: item
					};
				}
				return $.extend({
					label: item.label || item.value,
					value: item.value || item.label
				}, item );
			});
		},
	
		_suggest: function( items ) {
			var ul = this.menu.element.empty();
			this._renderMenu( ul, items );
			this.isNewMenu = true;
			this.menu.refresh();
	
			// size and position menu
			ul.show();
			this._resizeMenu();
			ul.position( $.extend({
				of: this.element
			}, this.options.position ));
	
			if ( this.options.autoFocus ) {
				this.menu.next();
			}
		},
	
		_resizeMenu: function() {
			var ul = this.menu.element;
			ul.outerWidth( Math.max(
				// Firefox wraps long text (possibly a rounding bug)
				// so we add 1px to avoid the wrapping (#7513)
				ul.width( "" ).outerWidth() + 1,
				this.element.outerWidth()
			) );
		},
	
		_renderMenu: function( ul, items ) {
			var that = this;
			$.each( items, function( index, item ) {
				that._renderItemData( ul, item );
			});
		},
	
		_renderItemData: function( ul, item ) {
			return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
		},
	
		_renderItem: function( ul, item ) {
			return $( "<li>" )
				.append( $( "<a>" ).text( item.label ) )
				.appendTo( ul );
		},
	
		_move: function( direction, event ) {
			if ( !this.menu.element.is( ":visible" ) ) {
				this.search( null, event );
				return;
			}
			if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
					this.menu.isLastItem() && /^next/.test( direction ) ) {
				this._value( this.term );
				this.menu.blur();
				return;
			}
			this.menu[ direction ]( event );
		},
	
		widget: function() {
			return this.menu.element;
		},
	
		_value: function() {
			return this.valueMethod.apply( this.element, arguments );
		},
	
		_keyEvent: function( keyEvent, event ) {
			if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
				this._move( keyEvent, event );
	
				// prevents moving cursor to beginning/end of the text field in some browsers
				event.preventDefault();
			}
		}
	});
	
	$.extend( $.ui.autocomplete, {
		escapeRegex: function( value ) {
			return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
		},
		filter: function(array, term) {
			var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
			return $.grep( array, function(value) {
				return matcher.test( value.label || value.value || value );
			});
		}
	});
	
	
	// live region extension, adding a `messages` option
	// NOTE: This is an experimental API. We are still investigating
	// a full solution for string manipulation and internationalization.
	$.widget( "ui.autocomplete", $.ui.autocomplete, {
		options: {
			messages: {
				noResults: "No search results.",
				results: function( amount ) {
					return amount + ( amount > 1 ? " results are" : " result is" ) +
						" available, use up and down arrow keys to navigate.";
				}
			}
		},
	
		__response: function( content ) {
			var message;
			this._superApply( arguments );
			if ( this.options.disabled || this.cancelSearch ) {
				return;
			}
			if ( content && content.length ) {
				message = this.options.messages.results( content.length );
			} else {
				message = this.options.messages.noResults;
			}
			this.liveRegion.text( message );
		}
	});
	
	}( jQuery ));
	
	(function( $, undefined ) {
	
	var lastActive, startXPos, startYPos, clickDragged,
		baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
		stateClasses = "ui-state-hover ui-state-active ",
		typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
		formResetHandler = function() {
			var form = $( this );
			setTimeout(function() {
				form.find( ":ui-button" ).button( "refresh" );
			}, 1 );
		},
		radioGroup = function( radio ) {
			var name = radio.name,
				form = radio.form,
				radios = $( [] );
			if ( name ) {
				name = name.replace( /'/g, "\\'" );
				if ( form ) {
					radios = $( form ).find( "[name='" + name + "']" );
				} else {
					radios = $( "[name='" + name + "']", radio.ownerDocument )
						.filter(function() {
							return !this.form;
						});
				}
			}
			return radios;
		};
	
	$.widget( "ui.button", {
		version: "1.10.3",
		defaultElement: "<button>",
		options: {
			disabled: null,
			text: true,
			label: null,
			icons: {
				primary: null,
				secondary: null
			}
		},
		_create: function() {
			this.element.closest( "form" )
				.unbind( "reset" + this.eventNamespace )
				.bind( "reset" + this.eventNamespace, formResetHandler );
	
			if ( typeof this.options.disabled !== "boolean" ) {
				this.options.disabled = !!this.element.prop( "disabled" );
			} else {
				this.element.prop( "disabled", this.options.disabled );
			}
	
			this._determineButtonType();
			this.hasTitle = !!this.buttonElement.attr( "title" );
	
			var that = this,
				options = this.options,
				toggleButton = this.type === "checkbox" || this.type === "radio",
				activeClass = !toggleButton ? "ui-state-active" : "",
				focusClass = "ui-state-focus";
	
			if ( options.label === null ) {
				options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
			}
	
			this._hoverable( this.buttonElement );
	
			this.buttonElement
				.addClass( baseClasses )
				.attr( "role", "button" )
				.bind( "mouseenter" + this.eventNamespace, function() {
					if ( options.disabled ) {
						return;
					}
					if ( this === lastActive ) {
						$( this ).addClass( "ui-state-active" );
					}
				})
				.bind( "mouseleave" + this.eventNamespace, function() {
					if ( options.disabled ) {
						return;
					}
					$( this ).removeClass( activeClass );
				})
				.bind( "click" + this.eventNamespace, function( event ) {
					if ( options.disabled ) {
						event.preventDefault();
						event.stopImmediatePropagation();
					}
				});
	
			this.element
				.bind( "focus" + this.eventNamespace, function() {
					// no need to check disabled, focus won't be triggered anyway
					that.buttonElement.addClass( focusClass );
				})
				.bind( "blur" + this.eventNamespace, function() {
					that.buttonElement.removeClass( focusClass );
				});
	
			if ( toggleButton ) {
				this.element.bind( "change" + this.eventNamespace, function() {
					if ( clickDragged ) {
						return;
					}
					that.refresh();
				});
				// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
				// prevents issue where button state changes but checkbox/radio checked state
				// does not in Firefox (see ticket #6970)
				this.buttonElement
					.bind( "mousedown" + this.eventNamespace, function( event ) {
						if ( options.disabled ) {
							return;
						}
						clickDragged = false;
						startXPos = event.pageX;
						startYPos = event.pageY;
					})
					.bind( "mouseup" + this.eventNamespace, function( event ) {
						if ( options.disabled ) {
							return;
						}
						if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
							clickDragged = true;
						}
				});
			}
	
			if ( this.type === "checkbox" ) {
				this.buttonElement.bind( "click" + this.eventNamespace, function() {
					if ( options.disabled || clickDragged ) {
						return false;
					}
				});
			} else if ( this.type === "radio" ) {
				this.buttonElement.bind( "click" + this.eventNamespace, function() {
					if ( options.disabled || clickDragged ) {
						return false;
					}
					$( this ).addClass( "ui-state-active" );
					that.buttonElement.attr( "aria-pressed", "true" );
	
					var radio = that.element[ 0 ];
					radioGroup( radio )
						.not( radio )
						.map(function() {
							return $( this ).button( "widget" )[ 0 ];
						})
						.removeClass( "ui-state-active" )
						.attr( "aria-pressed", "false" );
				});
			} else {
				this.buttonElement
					.bind( "mousedown" + this.eventNamespace, function() {
						if ( options.disabled ) {
							return false;
						}
						$( this ).addClass( "ui-state-active" );
						lastActive = this;
						that.document.one( "mouseup", function() {
							lastActive = null;
						});
					})
					.bind( "mouseup" + this.eventNamespace, function() {
						if ( options.disabled ) {
							return false;
						}
						$( this ).removeClass( "ui-state-active" );
					})
					.bind( "keydown" + this.eventNamespace, function(event) {
						if ( options.disabled ) {
							return false;
						}
						if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
							$( this ).addClass( "ui-state-active" );
						}
					})
					// see #8559, we bind to blur here in case the button element loses
					// focus between keydown and keyup, it would be left in an "active" state
					.bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
						$( this ).removeClass( "ui-state-active" );
					});
	
				if ( this.buttonElement.is("a") ) {
					this.buttonElement.keyup(function(event) {
						if ( event.keyCode === $.ui.keyCode.SPACE ) {
							// TODO pass through original event correctly (just as 2nd argument doesn't work)
							$( this ).click();
						}
					});
				}
			}
	
			// TODO: pull out $.Widget's handling for the disabled option into
			// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
			// be overridden by individual plugins
			this._setOption( "disabled", options.disabled );
			this._resetButton();
		},
	
		_determineButtonType: function() {
			var ancestor, labelSelector, checked;
	
			if ( this.element.is("[type=checkbox]") ) {
				this.type = "checkbox";
			} else if ( this.element.is("[type=radio]") ) {
				this.type = "radio";
			} else if ( this.element.is("input") ) {
				this.type = "input";
			} else {
				this.type = "button";
			}
	
			if ( this.type === "checkbox" || this.type === "radio" ) {
				// we don't search against the document in case the element
				// is disconnected from the DOM
				ancestor = this.element.parents().last();
				labelSelector = "label[for='" + this.element.attr("id") + "']";
				this.buttonElement = ancestor.find( labelSelector );
				if ( !this.buttonElement.length ) {
					ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
					this.buttonElement = ancestor.filter( labelSelector );
					if ( !this.buttonElement.length ) {
						this.buttonElement = ancestor.find( labelSelector );
					}
				}
				this.element.addClass( "ui-helper-hidden-accessible" );
	
				checked = this.element.is( ":checked" );
				if ( checked ) {
					this.buttonElement.addClass( "ui-state-active" );
				}
				this.buttonElement.prop( "aria-pressed", checked );
			} else {
				this.buttonElement = this.element;
			}
		},
	
		widget: function() {
			return this.buttonElement;
		},
	
		_destroy: function() {
			this.element
				.removeClass( "ui-helper-hidden-accessible" );
			this.buttonElement
				.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
				.removeAttr( "role" )
				.removeAttr( "aria-pressed" )
				.html( this.buttonElement.find(".ui-button-text").html() );
	
			if ( !this.hasTitle ) {
				this.buttonElement.removeAttr( "title" );
			}
		},
	
		_setOption: function( key, value ) {
			this._super( key, value );
			if ( key === "disabled" ) {
				if ( value ) {
					this.element.prop( "disabled", true );
				} else {
					this.element.prop( "disabled", false );
				}
				return;
			}
			this._resetButton();
		},
	
		refresh: function() {
			//See #8237 & #8828
			var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
	
			if ( isDisabled !== this.options.disabled ) {
				this._setOption( "disabled", isDisabled );
			}
			if ( this.type === "radio" ) {
				radioGroup( this.element[0] ).each(function() {
					if ( $( this ).is( ":checked" ) ) {
						$( this ).button( "widget" )
							.addClass( "ui-state-active" )
							.attr( "aria-pressed", "true" );
					} else {
						$( this ).button( "widget" )
							.removeClass( "ui-state-active" )
							.attr( "aria-pressed", "false" );
					}
				});
			} else if ( this.type === "checkbox" ) {
				if ( this.element.is( ":checked" ) ) {
					this.buttonElement
						.addClass( "ui-state-active" )
						.attr( "aria-pressed", "true" );
				} else {
					this.buttonElement
						.removeClass( "ui-state-active" )
						.attr( "aria-pressed", "false" );
				}
			}
		},
	
		_resetButton: function() {
			if ( this.type === "input" ) {
				if ( this.options.label ) {
					this.element.val( this.options.label );
				}
				return;
			}
			var buttonElement = this.buttonElement.removeClass( typeClasses ),
				buttonText = $( "<span></span>", this.document[0] )
					.addClass( "ui-button-text" )
					.html( this.options.label )
					.appendTo( buttonElement.empty() )
					.text(),
				icons = this.options.icons,
				multipleIcons = icons.primary && icons.secondary,
				buttonClasses = [];
	
			if ( icons.primary || icons.secondary ) {
				if ( this.options.text ) {
					buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
				}
	
				if ( icons.primary ) {
					buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
				}
	
				if ( icons.secondary ) {
					buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
				}
	
				if ( !this.options.text ) {
					buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
	
					if ( !this.hasTitle ) {
						buttonElement.attr( "title", $.trim( buttonText ) );
					}
				}
			} else {
				buttonClasses.push( "ui-button-text-only" );
			}
			buttonElement.addClass( buttonClasses.join( " " ) );
		}
	});
	
	$.widget( "ui.buttonset", {
		version: "1.10.3",
		options: {
			items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
		},
	
		_create: function() {
			this.element.addClass( "ui-buttonset" );
		},
	
		_init: function() {
			this.refresh();
		},
	
		_setOption: function( key, value ) {
			if ( key === "disabled" ) {
				this.buttons.button( "option", key, value );
			}
	
			this._super( key, value );
		},
	
		refresh: function() {
			var rtl = this.element.css( "direction" ) === "rtl";
	
			this.buttons = this.element.find( this.options.items )
				.filter( ":ui-button" )
					.button( "refresh" )
				.end()
				.not( ":ui-button" )
					.button()
				.end()
				.map(function() {
					return $( this ).button( "widget" )[ 0 ];
				})
					.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
					.filter( ":first" )
						.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
					.end()
					.filter( ":last" )
						.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
					.end()
				.end();
		},
	
		_destroy: function() {
			this.element.removeClass( "ui-buttonset" );
			this.buttons
				.map(function() {
					return $( this ).button( "widget" )[ 0 ];
				})
					.removeClass( "ui-corner-left ui-corner-right" )
				.end()
				.button( "destroy" );
		}
	});
	
	}( jQuery ) );
	
	(function( $, undefined ) {
	
	$.extend($.ui, { datepicker: { version: "1.10.3" } });
	
	var PROP_NAME = "datepicker",
		instActive;
	
	/* Date picker manager.
	   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
	   Settings for (groups of) date pickers are maintained in an instance object,
	   allowing multiple different settings on the same page. */
	
	function Datepicker() {
		this._curInst = null; // The current instance in use
		this._keyEvent = false; // If the last event was a key event
		this._disabledInputs = []; // List of date picker inputs that have been disabled
		this._datepickerShowing = false; // True if the popup picker is showing , false if not
		this._inDialog = false; // True if showing within a "dialog", false if not
		this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
		this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
		this._appendClass = "ui-datepicker-append"; // The name of the append marker class
		this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
		this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
		this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
		this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
		this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
		this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
		this.regional = []; // Available regional settings, indexed by language code
		this.regional[""] = { // Default regional settings
			closeText: "Done", // Display text for close link
			prevText: "Prev", // Display text for previous month link
			nextText: "Next", // Display text for next month link
			currentText: "Today", // Display text for current month link
			monthNames: ["January","February","March","April","May","June",
				"July","August","September","October","November","December"], // Names of months for drop-down and formatting
			monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
			dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
			dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
			dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
			weekHeader: "Wk", // Column header for week of the year
			dateFormat: "mm/dd/yy", // See format options on parseDate
			firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
			isRTL: false, // True if right-to-left language, false if left-to-right
			showMonthAfterYear: false, // True if the year select precedes month, false for month then year
			yearSuffix: "" // Additional text to append to the year in the month headers
		};
		this._defaults = { // Global defaults for all the date picker instances
			showOn: "focus", // "focus" for popup on focus,
				// "button" for trigger button, or "both" for either
			showAnim: "fadeIn", // Name of jQuery animation for popup
			showOptions: {}, // Options for enhanced animations
			defaultDate: null, // Used when field is blank: actual date,
				// +/-number for offset from today, null for today
			appendText: "", // Display text following the input box, e.g. showing the format
			buttonText: "...", // Text for trigger button
			buttonImage: "", // URL for trigger button image
			buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
			hideIfNoPrevNext: false, // True to hide next/previous month links
				// if not applicable, false to just disable them
			navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
			gotoCurrent: false, // True if today link goes back to current selection instead
			changeMonth: false, // True if month can be selected directly, false if only prev/next
			changeYear: false, // True if year can be selected directly, false if only prev/next
			yearRange: "c-10:c+10", // Range of years to display in drop-down,
				// either relative to today's year (-nn:+nn), relative to currently displayed year
				// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
			showOtherMonths: false, // True to show dates in other months, false to leave blank
			selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
			showWeek: false, // True to show week of the year, false to not show it
			calculateWeek: this.iso8601Week, // How to calculate the week of the year,
				// takes a Date and returns the number of the week for it
			shortYearCutoff: "+10", // Short year values < this are in the current century,
				// > this are in the previous century,
				// string value starting with "+" for current year + value
			minDate: null, // The earliest selectable date, or null for no limit
			maxDate: null, // The latest selectable date, or null for no limit
			duration: "fast", // Duration of display/closure
			beforeShowDay: null, // Function that takes a date and returns an array with
				// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
				// [2] = cell title (optional), e.g. $.datepicker.noWeekends
			beforeShow: null, // Function that takes an input field and
				// returns a set of custom settings for the date picker
			onSelect: null, // Define a callback function when a date is selected
			onChangeMonthYear: null, // Define a callback function when the month or year is changed
			onClose: null, // Define a callback function when the datepicker is closed
			numberOfMonths: 1, // Number of months to show at a time
			showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
			stepMonths: 1, // Number of months to step back/forward
			stepBigMonths: 12, // Number of months to step back/forward for the big links
			altField: "", // Selector for an alternate field to store selected dates into
			altFormat: "", // The date format to use for the alternate field
			constrainInput: true, // The input is constrained by the current date format
			showButtonPanel: false, // True to show button panel, false to not show it
			autoSize: false, // True to size the input for the date format, false to leave as is
			disabled: false // The initial disabled state
		};
		$.extend(this._defaults, this.regional[""]);
		this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
	}
	
	$.extend(Datepicker.prototype, {
		/* Class name added to elements to indicate already configured with a date picker. */
		markerClassName: "hasDatepicker",
	
		//Keep track of the maximum number of rows displayed (see #7043)
		maxRows: 4,
	
		// TODO rename to "widget" when switching to widget factory
		_widgetDatepicker: function() {
			return this.dpDiv;
		},
	
		/* Override the default settings for all instances of the date picker.
		 * @param  settings  object - the new settings to use as defaults (anonymous object)
		 * @return the manager object
		 */
		setDefaults: function(settings) {
			extendRemove(this._defaults, settings || {});
			return this;
		},
	
		/* Attach the date picker to a jQuery selection.
		 * @param  target	element - the target input field or division or span
		 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
		 */
		_attachDatepicker: function(target, settings) {
			var nodeName, inline, inst;
			nodeName = target.nodeName.toLowerCase();
			inline = (nodeName === "div" || nodeName === "span");
			if (!target.id) {
				this.uuid += 1;
				target.id = "dp" + this.uuid;
			}
			inst = this._newInst($(target), inline);
			inst.settings = $.extend({}, settings || {});
			if (nodeName === "input") {
				this._connectDatepicker(target, inst);
			} else if (inline) {
				this._inlineDatepicker(target, inst);
			}
		},
	
		/* Create a new instance object. */
		_newInst: function(target, inline) {
			var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
			return {id: id, input: target, // associated target
				selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
				drawMonth: 0, drawYear: 0, // month being drawn
				inline: inline, // is datepicker inline or not
				dpDiv: (!inline ? this.dpDiv : // presentation div
				bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
		},
	
		/* Attach the date picker to an input field. */
		_connectDatepicker: function(target, inst) {
			var input = $(target);
			inst.append = $([]);
			inst.trigger = $([]);
			if (input.hasClass(this.markerClassName)) {
				return;
			}
			this._attachments(input, inst);
			input.addClass(this.markerClassName).keydown(this._doKeyDown).
				keypress(this._doKeyPress).keyup(this._doKeyUp);
			this._autoSize(inst);
			$.data(target, PROP_NAME, inst);
			//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
			if( inst.settings.disabled ) {
				this._disableDatepicker( target );
			}
		},
	
		/* Make attachments based on settings. */
		_attachments: function(input, inst) {
			var showOn, buttonText, buttonImage,
				appendText = this._get(inst, "appendText"),
				isRTL = this._get(inst, "isRTL");
	
			if (inst.append) {
				inst.append.remove();
			}
			if (appendText) {
				inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
				input[isRTL ? "before" : "after"](inst.append);
			}
	
			input.unbind("focus", this._showDatepicker);
	
			if (inst.trigger) {
				inst.trigger.remove();
			}
	
			showOn = this._get(inst, "showOn");
			if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
				input.focus(this._showDatepicker);
			}
			if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
				buttonText = this._get(inst, "buttonText");
				buttonImage = this._get(inst, "buttonImage");
				inst.trigger = $(this._get(inst, "buttonImageOnly") ?
					$("<img/>").addClass(this._triggerClass).
						attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
					$("<button type='button'></button>").addClass(this._triggerClass).
						html(!buttonImage ? buttonText : $("<img/>").attr(
						{ src:buttonImage, alt:buttonText, title:buttonText })));
				input[isRTL ? "before" : "after"](inst.trigger);
				inst.trigger.click(function() {
					if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
						$.datepicker._hideDatepicker();
					} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
						$.datepicker._hideDatepicker();
						$.datepicker._showDatepicker(input[0]);
					} else {
						$.datepicker._showDatepicker(input[0]);
					}
					return false;
				});
			}
		},
	
		/* Apply the maximum length for the date format. */
		_autoSize: function(inst) {
			if (this._get(inst, "autoSize") && !inst.inline) {
				var findMax, max, maxI, i,
					date = new Date(2009, 12 - 1, 20), // Ensure double digits
					dateFormat = this._get(inst, "dateFormat");
	
				if (dateFormat.match(/[DM]/)) {
					findMax = function(names) {
						max = 0;
						maxI = 0;
						for (i = 0; i < names.length; i++) {
							if (names[i].length > max) {
								max = names[i].length;
								maxI = i;
							}
						}
						return maxI;
					};
					date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
						"monthNames" : "monthNamesShort"))));
					date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
						"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
				}
				inst.input.attr("size", this._formatDate(inst, date).length);
			}
		},
	
		/* Attach an inline date picker to a div. */
		_inlineDatepicker: function(target, inst) {
			var divSpan = $(target);
			if (divSpan.hasClass(this.markerClassName)) {
				return;
			}
			divSpan.addClass(this.markerClassName).append(inst.dpDiv);
			$.data(target, PROP_NAME, inst);
			this._setDate(inst, this._getDefaultDate(inst), true);
			this._updateDatepicker(inst);
			this._updateAlternate(inst);
			//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
			if( inst.settings.disabled ) {
				this._disableDatepicker( target );
			}
			// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
			// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
			inst.dpDiv.css( "display", "block" );
		},
	
		/* Pop-up the date picker in a "dialog" box.
		 * @param  input element - ignored
		 * @param  date	string or Date - the initial date to display
		 * @param  onSelect  function - the function to call when a date is selected
		 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
		 * @param  pos int[2] - coordinates for the dialog's position within the screen or
		 *					event - with x/y coordinates or
		 *					leave empty for default (screen centre)
		 * @return the manager object
		 */
		_dialogDatepicker: function(input, date, onSelect, settings, pos) {
			var id, browserWidth, browserHeight, scrollX, scrollY,
				inst = this._dialogInst; // internal instance
	
			if (!inst) {
				this.uuid += 1;
				id = "dp" + this.uuid;
				this._dialogInput = $("<input type='text' id='" + id +
					"' style='position: absolute; top: -100px; width: 0px;'/>");
				this._dialogInput.keydown(this._doKeyDown);
				$("body").append(this._dialogInput);
				inst = this._dialogInst = this._newInst(this._dialogInput, false);
				inst.settings = {};
				$.data(this._dialogInput[0], PROP_NAME, inst);
			}
			extendRemove(inst.settings, settings || {});
			date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
			this._dialogInput.val(date);
	
			this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
			if (!this._pos) {
				browserWidth = document.documentElement.clientWidth;
				browserHeight = document.documentElement.clientHeight;
				scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
				scrollY = document.documentElement.scrollTop || document.body.scrollTop;
				this._pos = // should use actual width/height below
					[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
			}
	
			// move input on screen for focus, but hidden behind dialog
			this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
			inst.settings.onSelect = onSelect;
			this._inDialog = true;
			this.dpDiv.addClass(this._dialogClass);
			this._showDatepicker(this._dialogInput[0]);
			if ($.blockUI) {
				$.blockUI(this.dpDiv);
			}
			$.data(this._dialogInput[0], PROP_NAME, inst);
			return this;
		},
	
		/* Detach a datepicker from its control.
		 * @param  target	element - the target input field or division or span
		 */
		_destroyDatepicker: function(target) {
			var nodeName,
				$target = $(target),
				inst = $.data(target, PROP_NAME);
	
			if (!$target.hasClass(this.markerClassName)) {
				return;
			}
	
			nodeName = target.nodeName.toLowerCase();
			$.removeData(target, PROP_NAME);
			if (nodeName === "input") {
				inst.append.remove();
				inst.trigger.remove();
				$target.removeClass(this.markerClassName).
					unbind("focus", this._showDatepicker).
					unbind("keydown", this._doKeyDown).
					unbind("keypress", this._doKeyPress).
					unbind("keyup", this._doKeyUp);
			} else if (nodeName === "div" || nodeName === "span") {
				$target.removeClass(this.markerClassName).empty();
			}
		},
	
		/* Enable the date picker to a jQuery selection.
		 * @param  target	element - the target input field or division or span
		 */
		_enableDatepicker: function(target) {
			var nodeName, inline,
				$target = $(target),
				inst = $.data(target, PROP_NAME);
	
			if (!$target.hasClass(this.markerClassName)) {
				return;
			}
	
			nodeName = target.nodeName.toLowerCase();
			if (nodeName === "input") {
				target.disabled = false;
				inst.trigger.filter("button").
					each(function() { this.disabled = false; }).end().
					filter("img").css({opacity: "1.0", cursor: ""});
			} else if (nodeName === "div" || nodeName === "span") {
				inline = $target.children("." + this._inlineClass);
				inline.children().removeClass("ui-state-disabled");
				inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
					prop("disabled", false);
			}
			this._disabledInputs = $.map(this._disabledInputs,
				function(value) { return (value === target ? null : value); }); // delete entry
		},
	
		/* Disable the date picker to a jQuery selection.
		 * @param  target	element - the target input field or division or span
		 */
		_disableDatepicker: function(target) {
			var nodeName, inline,
				$target = $(target),
				inst = $.data(target, PROP_NAME);
	
			if (!$target.hasClass(this.markerClassName)) {
				return;
			}
	
			nodeName = target.nodeName.toLowerCase();
			if (nodeName === "input") {
				target.disabled = true;
				inst.trigger.filter("button").
					each(function() { this.disabled = true; }).end().
					filter("img").css({opacity: "0.5", cursor: "default"});
			} else if (nodeName === "div" || nodeName === "span") {
				inline = $target.children("." + this._inlineClass);
				inline.children().addClass("ui-state-disabled");
				inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
					prop("disabled", true);
			}
			this._disabledInputs = $.map(this._disabledInputs,
				function(value) { return (value === target ? null : value); }); // delete entry
			this._disabledInputs[this._disabledInputs.length] = target;
		},
	
		/* Is the first field in a jQuery collection disabled as a datepicker?
		 * @param  target	element - the target input field or division or span
		 * @return boolean - true if disabled, false if enabled
		 */
		_isDisabledDatepicker: function(target) {
			if (!target) {
				return false;
			}
			for (var i = 0; i < this._disabledInputs.length; i++) {
				if (this._disabledInputs[i] === target) {
					return true;
				}
			}
			return false;
		},
	
		/* Retrieve the instance data for the target control.
		 * @param  target  element - the target input field or division or span
		 * @return  object - the associated instance data
		 * @throws  error if a jQuery problem getting data
		 */
		_getInst: function(target) {
			try {
				return $.data(target, PROP_NAME);
			}
			catch (err) {
				throw "Missing instance data for this datepicker";
			}
		},
	
		/* Update or retrieve the settings for a date picker attached to an input field or division.
		 * @param  target  element - the target input field or division or span
		 * @param  name	object - the new settings to update or
		 *				string - the name of the setting to change or retrieve,
		 *				when retrieving also "all" for all instance settings or
		 *				"defaults" for all global defaults
		 * @param  value   any - the new value for the setting
		 *				(omit if above is an object or to retrieve a value)
		 */
		_optionDatepicker: function(target, name, value) {
			var settings, date, minDate, maxDate,
				inst = this._getInst(target);
	
			if (arguments.length === 2 && typeof name === "string") {
				return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
					(inst ? (name === "all" ? $.extend({}, inst.settings) :
					this._get(inst, name)) : null));
			}
	
			settings = name || {};
			if (typeof name === "string") {
				settings = {};
				settings[name] = value;
			}
	
			if (inst) {
				if (this._curInst === inst) {
					this._hideDatepicker();
				}
	
				date = this._getDateDatepicker(target, true);
				minDate = this._getMinMaxDate(inst, "min");
				maxDate = this._getMinMaxDate(inst, "max");
				extendRemove(inst.settings, settings);
				// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
				if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
					inst.settings.minDate = this._formatDate(inst, minDate);
				}
				if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
					inst.settings.maxDate = this._formatDate(inst, maxDate);
				}
				if ( "disabled" in settings ) {
					if ( settings.disabled ) {
						this._disableDatepicker(target);
					} else {
						this._enableDatepicker(target);
					}
				}
				this._attachments($(target), inst);
				this._autoSize(inst);
				this._setDate(inst, date);
				this._updateAlternate(inst);
				this._updateDatepicker(inst);
			}
		},
	
		// change method deprecated
		_changeDatepicker: function(target, name, value) {
			this._optionDatepicker(target, name, value);
		},
	
		/* Redraw the date picker attached to an input field or division.
		 * @param  target  element - the target input field or division or span
		 */
		_refreshDatepicker: function(target) {
			var inst = this._getInst(target);
			if (inst) {
				this._updateDatepicker(inst);
			}
		},
	
		/* Set the dates for a jQuery selection.
		 * @param  target element - the target input field or division or span
		 * @param  date	Date - the new date
		 */
		_setDateDatepicker: function(target, date) {
			var inst = this._getInst(target);
			if (inst) {
				this._setDate(inst, date);
				this._updateDatepicker(inst);
				this._updateAlternate(inst);
			}
		},
	
		/* Get the date(s) for the first entry in a jQuery selection.
		 * @param  target element - the target input field or division or span
		 * @param  noDefault boolean - true if no default date is to be used
		 * @return Date - the current date
		 */
		_getDateDatepicker: function(target, noDefault) {
			var inst = this._getInst(target);
			if (inst && !inst.inline) {
				this._setDateFromField(inst, noDefault);
			}
			return (inst ? this._getDate(inst) : null);
		},
	
		/* Handle keystrokes. */
		_doKeyDown: function(event) {
			var onSelect, dateStr, sel,
				inst = $.datepicker._getInst(event.target),
				handled = true,
				isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
	
			inst._keyEvent = true;
			if ($.datepicker._datepickerShowing) {
				switch (event.keyCode) {
					case 9: $.datepicker._hideDatepicker();
							handled = false;
							break; // hide on tab out
					case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
										$.datepicker._currentClass + ")", inst.dpDiv);
							if (sel[0]) {
								$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
							}
	
							onSelect = $.datepicker._get(inst, "onSelect");
							if (onSelect) {
								dateStr = $.datepicker._formatDate(inst);
	
								// trigger custom callback
								onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
							} else {
								$.datepicker._hideDatepicker();
							}
	
							return false; // don't submit the form
					case 27: $.datepicker._hideDatepicker();
							break; // hide on escape
					case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
								-$.datepicker._get(inst, "stepBigMonths") :
								-$.datepicker._get(inst, "stepMonths")), "M");
							break; // previous month/year on page up/+ ctrl
					case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
								+$.datepicker._get(inst, "stepBigMonths") :
								+$.datepicker._get(inst, "stepMonths")), "M");
							break; // next month/year on page down/+ ctrl
					case 35: if (event.ctrlKey || event.metaKey) {
								$.datepicker._clearDate(event.target);
							}
							handled = event.ctrlKey || event.metaKey;
							break; // clear on ctrl or command +end
					case 36: if (event.ctrlKey || event.metaKey) {
								$.datepicker._gotoToday(event.target);
							}
							handled = event.ctrlKey || event.metaKey;
							break; // current on ctrl or command +home
					case 37: if (event.ctrlKey || event.metaKey) {
								$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
							}
							handled = event.ctrlKey || event.metaKey;
							// -1 day on ctrl or command +left
							if (event.originalEvent.altKey) {
								$.datepicker._adjustDate(event.target, (event.ctrlKey ?
									-$.datepicker._get(inst, "stepBigMonths") :
									-$.datepicker._get(inst, "stepMonths")), "M");
							}
							// next month/year on alt +left on Mac
							break;
					case 38: if (event.ctrlKey || event.metaKey) {
								$.datepicker._adjustDate(event.target, -7, "D");
							}
							handled = event.ctrlKey || event.metaKey;
							break; // -1 week on ctrl or command +up
					case 39: if (event.ctrlKey || event.metaKey) {
								$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
							}
							handled = event.ctrlKey || event.metaKey;
							// +1 day on ctrl or command +right
							if (event.originalEvent.altKey) {
								$.datepicker._adjustDate(event.target, (event.ctrlKey ?
									+$.datepicker._get(inst, "stepBigMonths") :
									+$.datepicker._get(inst, "stepMonths")), "M");
							}
							// next month/year on alt +right
							break;
					case 40: if (event.ctrlKey || event.metaKey) {
								$.datepicker._adjustDate(event.target, +7, "D");
							}
							handled = event.ctrlKey || event.metaKey;
							break; // +1 week on ctrl or command +down
					default: handled = false;
				}
			} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
				$.datepicker._showDatepicker(this);
			} else {
				handled = false;
			}
	
			if (handled) {
				event.preventDefault();
				event.stopPropagation();
			}
		},
	
		/* Filter entered characters - based on date format. */
		_doKeyPress: function(event) {
			var chars, chr,
				inst = $.datepicker._getInst(event.target);
	
			if ($.datepicker._get(inst, "constrainInput")) {
				chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
				chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
				return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
			}
		},
	
		/* Synchronise manual entry and field/alternate field. */
		_doKeyUp: function(event) {
			var date,
				inst = $.datepicker._getInst(event.target);
	
			if (inst.input.val() !== inst.lastVal) {
				try {
					date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
						(inst.input ? inst.input.val() : null),
						$.datepicker._getFormatConfig(inst));
	
					if (date) { // only if valid
						$.datepicker._setDateFromField(inst);
						$.datepicker._updateAlternate(inst);
						$.datepicker._updateDatepicker(inst);
					}
				}
				catch (err) {
				}
			}
			return true;
		},
	
		/* Pop-up the date picker for a given input field.
		 * If false returned from beforeShow event handler do not show.
		 * @param  input  element - the input field attached to the date picker or
		 *					event - if triggered by focus
		 */
		_showDatepicker: function(input) {
			input = input.target || input;
			if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
				input = $("input", input.parentNode)[0];
			}
	
			if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
				return;
			}
	
			var inst, beforeShow, beforeShowSettings, isFixed,
				offset, showAnim, duration;
	
			inst = $.datepicker._getInst(input);
			if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
				$.datepicker._curInst.dpDiv.stop(true, true);
				if ( inst && $.datepicker._datepickerShowing ) {
					$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
				}
			}
	
			beforeShow = $.datepicker._get(inst, "beforeShow");
			beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
			if(beforeShowSettings === false){
				return;
			}
			extendRemove(inst.settings, beforeShowSettings);
	
			inst.lastVal = null;
			$.datepicker._lastInput = input;
			$.datepicker._setDateFromField(inst);
	
			if ($.datepicker._inDialog) { // hide cursor
				input.value = "";
			}
			if (!$.datepicker._pos) { // position below input
				$.datepicker._pos = $.datepicker._findPos(input);
				$.datepicker._pos[1] += input.offsetHeight; // add the height
			}
	
			isFixed = false;
			$(input).parents().each(function() {
				isFixed |= $(this).css("position") === "fixed";
				return !isFixed;
			});
	
			offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
			$.datepicker._pos = null;
			//to avoid flashes on Firefox
			inst.dpDiv.empty();
			// determine sizing offscreen
			inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
			$.datepicker._updateDatepicker(inst);
			// fix width for dynamic number of date pickers
			// and adjust position before showing
			offset = $.datepicker._checkOffset(inst, offset, isFixed);
			inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
				"static" : (isFixed ? "fixed" : "absolute")), display: "none",
				left: offset.left + "px", top: offset.top + "px"});
	
			if (!inst.inline) {
				showAnim = $.datepicker._get(inst, "showAnim");
				duration = $.datepicker._get(inst, "duration");
				inst.dpDiv.zIndex($(input).zIndex()+1);
				$.datepicker._datepickerShowing = true;
	
				if ( $.effects && $.effects.effect[ showAnim ] ) {
					inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
				} else {
					inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
				}
	
				if ( $.datepicker._shouldFocusInput( inst ) ) {
					inst.input.focus();
				}
	
				$.datepicker._curInst = inst;
			}
		},
	
		/* Generate the date picker content. */
		_updateDatepicker: function(inst) {
			this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
			instActive = inst; // for delegate hover events
			inst.dpDiv.empty().append(this._generateHTML(inst));
			this._attachHandlers(inst);
			inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
	
			var origyearshtml,
				numMonths = this._getNumberOfMonths(inst),
				cols = numMonths[1],
				width = 17;
	
			inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
			if (cols > 1) {
				inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
			}
			inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
				"Class"]("ui-datepicker-multi");
			inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
				"Class"]("ui-datepicker-rtl");
	
			if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
				inst.input.focus();
			}
	
			// deffered render of the years select (to avoid flashes on Firefox)
			if( inst.yearshtml ){
				origyearshtml = inst.yearshtml;
				setTimeout(function(){
					//assure that inst.yearshtml didn't change.
					if( origyearshtml === inst.yearshtml && inst.yearshtml ){
						inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
					}
					origyearshtml = inst.yearshtml = null;
				}, 0);
			}
		},
	
		// #6694 - don't focus the input if it's already focused
		// this breaks the change event in IE
		// Support: IE and jQuery <1.9
		_shouldFocusInput: function( inst ) {
			return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
		},
	
		/* Check positioning to remain on screen. */
		_checkOffset: function(inst, offset, isFixed) {
			var dpWidth = inst.dpDiv.outerWidth(),
				dpHeight = inst.dpDiv.outerHeight(),
				inputWidth = inst.input ? inst.input.outerWidth() : 0,
				inputHeight = inst.input ? inst.input.outerHeight() : 0,
				viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
				viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
	
			offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
			offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
			offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
	
			// now check if datepicker is showing outside window viewport - move to a better place if so.
			offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
				Math.abs(offset.left + dpWidth - viewWidth) : 0);
			offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
				Math.abs(dpHeight + inputHeight) : 0);
	
			return offset;
		},
	
		/* Find an object's position on the screen. */
		_findPos: function(obj) {
			var position,
				inst = this._getInst(obj),
				isRTL = this._get(inst, "isRTL");
	
			while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
				obj = obj[isRTL ? "previousSibling" : "nextSibling"];
			}
	
			position = $(obj).offset();
			return [position.left, position.top];
		},
	
		/* Hide the date picker from view.
		 * @param  input  element - the input field attached to the date picker
		 */
		_hideDatepicker: function(input) {
			var showAnim, duration, postProcess, onClose,
				inst = this._curInst;
	
			if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
				return;
			}
	
			if (this._datepickerShowing) {
				showAnim = this._get(inst, "showAnim");
				duration = this._get(inst, "duration");
				postProcess = function() {
					$.datepicker._tidyDialog(inst);
				};
	
				// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
				if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
					inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
				} else {
					inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
						(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
				}
	
				if (!showAnim) {
					postProcess();
				}
				this._datepickerShowing = false;
	
				onClose = this._get(inst, "onClose");
				if (onClose) {
					onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
				}
	
				this._lastInput = null;
				if (this._inDialog) {
					this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
					if ($.blockUI) {
						$.unblockUI();
						$("body").append(this.dpDiv);
					}
				}
				this._inDialog = false;
			}
		},
	
		/* Tidy up after a dialog display. */
		_tidyDialog: function(inst) {
			inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
		},
	
		/* Close date picker if clicked elsewhere. */
		_checkExternalClick: function(event) {
			if (!$.datepicker._curInst) {
				return;
			}
	
			var $target = $(event.target),
				inst = $.datepicker._getInst($target[0]);
	
			if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
					$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
					!$target.hasClass($.datepicker.markerClassName) &&
					!$target.closest("." + $.datepicker._triggerClass).length &&
					$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
				( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
					$.datepicker._hideDatepicker();
			}
		},
	
		/* Adjust one of the date sub-fields. */
		_adjustDate: function(id, offset, period) {
			var target = $(id),
				inst = this._getInst(target[0]);
	
			if (this._isDisabledDatepicker(target[0])) {
				return;
			}
			this._adjustInstDate(inst, offset +
				(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
				period);
			this._updateDatepicker(inst);
		},
	
		/* Action for current link. */
		_gotoToday: function(id) {
			var date,
				target = $(id),
				inst = this._getInst(target[0]);
	
			if (this._get(inst, "gotoCurrent") && inst.currentDay) {
				inst.selectedDay = inst.currentDay;
				inst.drawMonth = inst.selectedMonth = inst.currentMonth;
				inst.drawYear = inst.selectedYear = inst.currentYear;
			} else {
				date = new Date();
				inst.selectedDay = date.getDate();
				inst.drawMonth = inst.selectedMonth = date.getMonth();
				inst.drawYear = inst.selectedYear = date.getFullYear();
			}
			this._notifyChange(inst);
			this._adjustDate(target);
		},
	
		/* Action for selecting a new month/year. */
		_selectMonthYear: function(id, select, period) {
			var target = $(id),
				inst = this._getInst(target[0]);
	
			inst["selected" + (period === "M" ? "Month" : "Year")] =
			inst["draw" + (period === "M" ? "Month" : "Year")] =
				parseInt(select.options[select.selectedIndex].value,10);
	
			this._notifyChange(inst);
			this._adjustDate(target);
		},
	
		/* Action for selecting a day. */
		_selectDay: function(id, month, year, td) {
			var inst,
				target = $(id);
	
			if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
				return;
			}
	
			inst = this._getInst(target[0]);
			inst.selectedDay = inst.currentDay = $("a", td).html();
			inst.selectedMonth = inst.currentMonth = month;
			inst.selectedYear = inst.currentYear = year;
			this._selectDate(id, this._formatDate(inst,
				inst.currentDay, inst.currentMonth, inst.currentYear));
		},
	
		/* Erase the input field and hide the date picker. */
		_clearDate: function(id) {
			var target = $(id);
			this._selectDate(target, "");
		},
	
		/* Update the input field with the selected date. */
		_selectDate: function(id, dateStr) {
			var onSelect,
				target = $(id),
				inst = this._getInst(target[0]);
	
			dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
			if (inst.input) {
				inst.input.val(dateStr);
			}
			this._updateAlternate(inst);
	
			onSelect = this._get(inst, "onSelect");
			if (onSelect) {
				onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
			} else if (inst.input) {
				inst.input.trigger("change"); // fire the change event
			}
	
			if (inst.inline){
				this._updateDatepicker(inst);
			} else {
				this._hideDatepicker();
				this._lastInput = inst.input[0];
				if (typeof(inst.input[0]) !== "object") {
					inst.input.focus(); // restore focus
				}
				this._lastInput = null;
			}
		},
	
		/* Update any alternate field to synchronise with the main field. */
		_updateAlternate: function(inst) {
			var altFormat, date, dateStr,
				altField = this._get(inst, "altField");
	
			if (altField) { // update alternate field too
				altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
				date = this._getDate(inst);
				dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
				$(altField).each(function() { $(this).val(dateStr); });
			}
		},
	
		/* Set as beforeShowDay function to prevent selection of weekends.
		 * @param  date  Date - the date to customise
		 * @return [boolean, string] - is this date selectable?, what is its CSS class?
		 */
		noWeekends: function(date) {
			var day = date.getDay();
			return [(day > 0 && day < 6), ""];
		},
	
		/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
		 * @param  date  Date - the date to get the week for
		 * @return  number - the number of the week within the year that contains this date
		 */
		iso8601Week: function(date) {
			var time,
				checkDate = new Date(date.getTime());
	
			// Find Thursday of this week starting on Monday
			checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
	
			time = checkDate.getTime();
			checkDate.setMonth(0); // Compare with Jan 1
			checkDate.setDate(1);
			return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
		},
	
		/* Parse a string value into a date object.
		 * See formatDate below for the possible formats.
		 *
		 * @param  format string - the expected format of the date
		 * @param  value string - the date in the above format
		 * @param  settings Object - attributes include:
		 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
		 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
		 *					dayNames		string[7] - names of the days from Sunday (optional)
		 *					monthNamesShort string[12] - abbreviated names of the months (optional)
		 *					monthNames		string[12] - names of the months (optional)
		 * @return  Date - the extracted date value or null if value is blank
		 */
		parseDate: function (format, value, settings) {
			if (format == null || value == null) {
				throw "Invalid arguments";
			}
	
			value = (typeof value === "object" ? value.toString() : value + "");
			if (value === "") {
				return null;
			}
	
			var iFormat, dim, extra,
				iValue = 0,
				shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
				shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
					new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
				dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
				dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
				monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
				monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
				year = -1,
				month = -1,
				day = -1,
				doy = -1,
				literal = false,
				date,
				// Check whether a format character is doubled
				lookAhead = function(match) {
					var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
					if (matches) {
						iFormat++;
					}
					return matches;
				},
				// Extract a number from the string value
				getNumber = function(match) {
					var isDoubled = lookAhead(match),
						size = (match === "@" ? 14 : (match === "!" ? 20 :
						(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
						digits = new RegExp("^\\d{1," + size + "}"),
						num = value.substring(iValue).match(digits);
					if (!num) {
						throw "Missing number at position " + iValue;
					}
					iValue += num[0].length;
					return parseInt(num[0], 10);
				},
				// Extract a name from the string value and convert to an index
				getName = function(match, shortNames, longNames) {
					var index = -1,
						names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
							return [ [k, v] ];
						}).sort(function (a, b) {
							return -(a[1].length - b[1].length);
						});
	
					$.each(names, function (i, pair) {
						var name = pair[1];
						if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
							index = pair[0];
							iValue += name.length;
							return false;
						}
					});
					if (index !== -1) {
						return index + 1;
					} else {
						throw "Unknown name at position " + iValue;
					}
				},
				// Confirm that a literal character matches the string value
				checkLiteral = function() {
					if (value.charAt(iValue) !== format.charAt(iFormat)) {
						throw "Unexpected literal at position " + iValue;
					}
					iValue++;
				};
	
			for (iFormat = 0; iFormat < format.length; iFormat++) {
				if (literal) {
					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
						literal = false;
					} else {
						checkLiteral();
					}
				} else {
					switch (format.charAt(iFormat)) {
						case "d":
							day = getNumber("d");
							break;
						case "D":
							getName("D", dayNamesShort, dayNames);
							break;
						case "o":
							doy = getNumber("o");
							break;
						case "m":
							month = getNumber("m");
							break;
						case "M":
							month = getName("M", monthNamesShort, monthNames);
							break;
						case "y":
							year = getNumber("y");
							break;
						case "@":
							date = new Date(getNumber("@"));
							year = date.getFullYear();
							month = date.getMonth() + 1;
							day = date.getDate();
							break;
						case "!":
							date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
							year = date.getFullYear();
							month = date.getMonth() + 1;
							day = date.getDate();
							break;
						case "'":
							if (lookAhead("'")){
								checkLiteral();
							} else {
								literal = true;
							}
							break;
						default:
							checkLiteral();
					}
				}
			}
	
			if (iValue < value.length){
				extra = value.substr(iValue);
				if (!/^\s+/.test(extra)) {
					throw "Extra/unparsed characters found in date: " + extra;
				}
			}
	
			if (year === -1) {
				year = new Date().getFullYear();
			} else if (year < 100) {
				year += new Date().getFullYear() - new Date().getFullYear() % 100 +
					(year <= shortYearCutoff ? 0 : -100);
			}
	
			if (doy > -1) {
				month = 1;
				day = doy;
				do {
					dim = this._getDaysInMonth(year, month - 1);
					if (day <= dim) {
						break;
					}
					month++;
					day -= dim;
				} while (true);
			}
	
			date = this._daylightSavingAdjust(new Date(year, month - 1, day));
			if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
				throw "Invalid date"; // E.g. 31/02/00
			}
			return date;
		},
	
		/* Standard date formats. */
		ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
		COOKIE: "D, dd M yy",
		ISO_8601: "yy-mm-dd",
		RFC_822: "D, d M y",
		RFC_850: "DD, dd-M-y",
		RFC_1036: "D, d M y",
		RFC_1123: "D, d M yy",
		RFC_2822: "D, d M yy",
		RSS: "D, d M y", // RFC 822
		TICKS: "!",
		TIMESTAMP: "@",
		W3C: "yy-mm-dd", // ISO 8601
	
		_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
			Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
	
		/* Format a date object into a string value.
		 * The format can be combinations of the following:
		 * d  - day of month (no leading zero)
		 * dd - day of month (two digit)
		 * o  - day of year (no leading zeros)
		 * oo - day of year (three digit)
		 * D  - day name short
		 * DD - day name long
		 * m  - month of year (no leading zero)
		 * mm - month of year (two digit)
		 * M  - month name short
		 * MM - month name long
		 * y  - year (two digit)
		 * yy - year (four digit)
		 * @ - Unix timestamp (ms since 01/01/1970)
		 * ! - Windows ticks (100ns since 01/01/0001)
		 * "..." - literal text
		 * '' - single quote
		 *
		 * @param  format string - the desired format of the date
		 * @param  date Date - the date value to format
		 * @param  settings Object - attributes include:
		 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
		 *					dayNames		string[7] - names of the days from Sunday (optional)
		 *					monthNamesShort string[12] - abbreviated names of the months (optional)
		 *					monthNames		string[12] - names of the months (optional)
		 * @return  string - the date in the above format
		 */
		formatDate: function (format, date, settings) {
			if (!date) {
				return "";
			}
	
			var iFormat,
				dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
				dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
				monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
				monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
				// Check whether a format character is doubled
				lookAhead = function(match) {
					var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
					if (matches) {
						iFormat++;
					}
					return matches;
				},
				// Format a number, with leading zero if necessary
				formatNumber = function(match, value, len) {
					var num = "" + value;
					if (lookAhead(match)) {
						while (num.length < len) {
							num = "0" + num;
						}
					}
					return num;
				},
				// Format a name, short or long as requested
				formatName = function(match, value, shortNames, longNames) {
					return (lookAhead(match) ? longNames[value] : shortNames[value]);
				},
				output = "",
				literal = false;
	
			if (date) {
				for (iFormat = 0; iFormat < format.length; iFormat++) {
					if (literal) {
						if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
							literal = false;
						} else {
							output += format.charAt(iFormat);
						}
					} else {
						switch (format.charAt(iFormat)) {
							case "d":
								output += formatNumber("d", date.getDate(), 2);
								break;
							case "D":
								output += formatName("D", date.getDay(), dayNamesShort, dayNames);
								break;
							case "o":
								output += formatNumber("o",
									Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
								break;
							case "m":
								output += formatNumber("m", date.getMonth() + 1, 2);
								break;
							case "M":
								output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
								break;
							case "y":
								output += (lookAhead("y") ? date.getFullYear() :
									(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
								break;
							case "@":
								output += date.getTime();
								break;
							case "!":
								output += date.getTime() * 10000 + this._ticksTo1970;
								break;
							case "'":
								if (lookAhead("'")) {
									output += "'";
								} else {
									literal = true;
								}
								break;
							default:
								output += format.charAt(iFormat);
						}
					}
				}
			}
			return output;
		},
	
		/* Extract all possible characters from the date format. */
		_possibleChars: function (format) {
			var iFormat,
				chars = "",
				literal = false,
				// Check whether a format character is doubled
				lookAhead = function(match) {
					var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
					if (matches) {
						iFormat++;
					}
					return matches;
				};
	
			for (iFormat = 0; iFormat < format.length; iFormat++) {
				if (literal) {
					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
						literal = false;
					} else {
						chars += format.charAt(iFormat);
					}
				} else {
					switch (format.charAt(iFormat)) {
						case "d": case "m": case "y": case "@":
							chars += "0123456789";
							break;
						case "D": case "M":
							return null; // Accept anything
						case "'":
							if (lookAhead("'")) {
								chars += "'";
							} else {
								literal = true;
							}
							break;
						default:
							chars += format.charAt(iFormat);
					}
				}
			}
			return chars;
		},
	
		/* Get a setting value, defaulting if necessary. */
		_get: function(inst, name) {
			return inst.settings[name] !== undefined ?
				inst.settings[name] : this._defaults[name];
		},
	
		/* Parse existing date and initialise date picker. */
		_setDateFromField: function(inst, noDefault) {
			if (inst.input.val() === inst.lastVal) {
				return;
			}
	
			var dateFormat = this._get(inst, "dateFormat"),
				dates = inst.lastVal = inst.input ? inst.input.val() : null,
				defaultDate = this._getDefaultDate(inst),
				date = defaultDate,
				settings = this._getFormatConfig(inst);
	
			try {
				date = this.parseDate(dateFormat, dates, settings) || defaultDate;
			} catch (event) {
				dates = (noDefault ? "" : dates);
			}
			inst.selectedDay = date.getDate();
			inst.drawMonth = inst.selectedMonth = date.getMonth();
			inst.drawYear = inst.selectedYear = date.getFullYear();
			inst.currentDay = (dates ? date.getDate() : 0);
			inst.currentMonth = (dates ? date.getMonth() : 0);
			inst.currentYear = (dates ? date.getFullYear() : 0);
			this._adjustInstDate(inst);
		},
	
		/* Retrieve the default date shown on opening. */
		_getDefaultDate: function(inst) {
			return this._restrictMinMax(inst,
				this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
		},
	
		/* A date may be specified as an exact value or a relative one. */
		_determineDate: function(inst, date, defaultDate) {
			var offsetNumeric = function(offset) {
					var date = new Date();
					date.setDate(date.getDate() + offset);
					return date;
				},
				offsetString = function(offset) {
					try {
						return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
							offset, $.datepicker._getFormatConfig(inst));
					}
					catch (e) {
						// Ignore
					}
	
					var date = (offset.toLowerCase().match(/^c/) ?
						$.datepicker._getDate(inst) : null) || new Date(),
						year = date.getFullYear(),
						month = date.getMonth(),
						day = date.getDate(),
						pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
						matches = pattern.exec(offset);
	
					while (matches) {
						switch (matches[2] || "d") {
							case "d" : case "D" :
								day += parseInt(matches[1],10); break;
							case "w" : case "W" :
								day += parseInt(matches[1],10) * 7; break;
							case "m" : case "M" :
								month += parseInt(matches[1],10);
								day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
								break;
							case "y": case "Y" :
								year += parseInt(matches[1],10);
								day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
								break;
						}
						matches = pattern.exec(offset);
					}
					return new Date(year, month, day);
				},
				newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
					(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
	
			newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
			if (newDate) {
				newDate.setHours(0);
				newDate.setMinutes(0);
				newDate.setSeconds(0);
				newDate.setMilliseconds(0);
			}
			return this._daylightSavingAdjust(newDate);
		},
	
		/* Handle switch to/from daylight saving.
		 * Hours may be non-zero on daylight saving cut-over:
		 * > 12 when midnight changeover, but then cannot generate
		 * midnight datetime, so jump to 1AM, otherwise reset.
		 * @param  date  (Date) the date to check
		 * @return  (Date) the corrected date
		 */
		_daylightSavingAdjust: function(date) {
			if (!date) {
				return null;
			}
			date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
			return date;
		},
	
		/* Set the date(s) directly. */
		_setDate: function(inst, date, noChange) {
			var clear = !date,
				origMonth = inst.selectedMonth,
				origYear = inst.selectedYear,
				newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
	
			inst.selectedDay = inst.currentDay = newDate.getDate();
			inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
			inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
			if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
				this._notifyChange(inst);
			}
			this._adjustInstDate(inst);
			if (inst.input) {
				inst.input.val(clear ? "" : this._formatDate(inst));
			}
		},
	
		/* Retrieve the date(s) directly. */
		_getDate: function(inst) {
			var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
				this._daylightSavingAdjust(new Date(
				inst.currentYear, inst.currentMonth, inst.currentDay)));
				return startDate;
		},
	
		/* Attach the onxxx handlers.  These are declared statically so
		 * they work with static code transformers like Caja.
		 */
		_attachHandlers: function(inst) {
			var stepMonths = this._get(inst, "stepMonths"),
				id = "#" + inst.id.replace( /\\\\/g, "\\" );
			inst.dpDiv.find("[data-handler]").map(function () {
				var handler = {
					prev: function () {
						$.datepicker._adjustDate(id, -stepMonths, "M");
					},
					next: function () {
						$.datepicker._adjustDate(id, +stepMonths, "M");
					},
					hide: function () {
						$.datepicker._hideDatepicker();
					},
					today: function () {
						$.datepicker._gotoToday(id);
					},
					selectDay: function () {
						$.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
						return false;
					},
					selectMonth: function () {
						$.datepicker._selectMonthYear(id, this, "M");
						return false;
					},
					selectYear: function () {
						$.datepicker._selectMonthYear(id, this, "Y");
						return false;
					}
				};
				$(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
			});
		},
	
		/* Generate the HTML for the current state of the date picker. */
		_generateHTML: function(inst) {
			var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
				controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
				monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
				selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
				cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
				printDate, dRow, tbody, daySettings, otherMonth, unselectable,
				tempDate = new Date(),
				today = this._daylightSavingAdjust(
					new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
				isRTL = this._get(inst, "isRTL"),
				showButtonPanel = this._get(inst, "showButtonPanel"),
				hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
				navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
				numMonths = this._getNumberOfMonths(inst),
				showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
				stepMonths = this._get(inst, "stepMonths"),
				isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
				currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
					new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
				minDate = this._getMinMaxDate(inst, "min"),
				maxDate = this._getMinMaxDate(inst, "max"),
				drawMonth = inst.drawMonth - showCurrentAtPos,
				drawYear = inst.drawYear;
	
			if (drawMonth < 0) {
				drawMonth += 12;
				drawYear--;
			}
			if (maxDate) {
				maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
					maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
				maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
				while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
					drawMonth--;
					if (drawMonth < 0) {
						drawMonth = 11;
						drawYear--;
					}
				}
			}
			inst.drawMonth = drawMonth;
			inst.drawYear = drawYear;
	
			prevText = this._get(inst, "prevText");
			prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
				this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
				this._getFormatConfig(inst)));
	
			prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
				"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
				" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
				(hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
	
			nextText = this._get(inst, "nextText");
			nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
				this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
				this._getFormatConfig(inst)));
	
			next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
				"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
				" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
				(hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
	
			currentText = this._get(inst, "currentText");
			gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
			currentText = (!navigationAsDateFormat ? currentText :
				this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
	
			controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
				this._get(inst, "closeText") + "</button>" : "");
	
			buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
				(this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
				">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
	
			firstDay = parseInt(this._get(inst, "firstDay"),10);
			firstDay = (isNaN(firstDay) ? 0 : firstDay);
	
			showWeek = this._get(inst, "showWeek");
			dayNames = this._get(inst, "dayNames");
			dayNamesMin = this._get(inst, "dayNamesMin");
			monthNames = this._get(inst, "monthNames");
			monthNamesShort = this._get(inst, "monthNamesShort");
			beforeShowDay = this._get(inst, "beforeShowDay");
			showOtherMonths = this._get(inst, "showOtherMonths");
			selectOtherMonths = this._get(inst, "selectOtherMonths");
			defaultDate = this._getDefaultDate(inst);
			html = "";
			dow;
			for (row = 0; row < numMonths[0]; row++) {
				group = "";
				this.maxRows = 4;
				for (col = 0; col < numMonths[1]; col++) {
					selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
					cornerClass = " ui-corner-all";
					calender = "";
					if (isMultiMonth) {
						calender += "<div class='ui-datepicker-group";
						if (numMonths[1] > 1) {
							switch (col) {
								case 0: calender += " ui-datepicker-group-first";
									cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
								case numMonths[1]-1: calender += " ui-datepicker-group-last";
									cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
								default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
							}
						}
						calender += "'>";
					}
					calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
						(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
						(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
						this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
						row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
						"</div><table class='ui-datepicker-calendar'><thead>" +
						"<tr>";
					thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
					for (dow = 0; dow < 7; dow++) { // days of the week
						day = (dow + firstDay) % 7;
						thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
							"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
					}
					calender += thead + "</tr></thead><tbody>";
					daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
					if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
						inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
					}
					leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
					curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
					numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
					this.maxRows = numRows;
					printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
					for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
						calender += "<tr>";
						tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
							this._get(inst, "calculateWeek")(printDate) + "</td>");
						for (dow = 0; dow < 7; dow++) { // create date picker days
							daySettings = (beforeShowDay ?
								beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
							otherMonth = (printDate.getMonth() !== drawMonth);
							unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
								(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
							tbody += "<td class='" +
								((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
								(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
								((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
								(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
								// or defaultDate is current printedDate and defaultDate is selectedDate
								" " + this._dayOverClass : "") + // highlight selected day
								(unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
								(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
								(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
								(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
								((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
								(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
								(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
								(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
								(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
								(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
								(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
								"' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
							printDate.setDate(printDate.getDate() + 1);
							printDate = this._daylightSavingAdjust(printDate);
						}
						calender += tbody + "</tr>";
					}
					drawMonth++;
					if (drawMonth > 11) {
						drawMonth = 0;
						drawYear++;
					}
					calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
								((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
					group += calender;
				}
				html += group;
			}
			html += buttonPanel;
			inst._keyEvent = false;
			return html;
		},
	
		/* Generate the month and year header. */
		_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
				secondary, monthNames, monthNamesShort) {
	
			var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
				changeMonth = this._get(inst, "changeMonth"),
				changeYear = this._get(inst, "changeYear"),
				showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
				html = "<div class='ui-datepicker-title'>",
				monthHtml = "";
	
			// month selection
			if (secondary || !changeMonth) {
				monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
			} else {
				inMinYear = (minDate && minDate.getFullYear() === drawYear);
				inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
				monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
				for ( month = 0; month < 12; month++) {
					if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
						monthHtml += "<option value='" + month + "'" +
							(month === drawMonth ? " selected='selected'" : "") +
							">" + monthNamesShort[month] + "</option>";
					}
				}
				monthHtml += "</select>";
			}
	
			if (!showMonthAfterYear) {
				html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
			}
	
			// year selection
			if ( !inst.yearshtml ) {
				inst.yearshtml = "";
				if (secondary || !changeYear) {
					html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
				} else {
					// determine range of years to display
					years = this._get(inst, "yearRange").split(":");
					thisYear = new Date().getFullYear();
					determineYear = function(value) {
						var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
							(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
							parseInt(value, 10)));
						return (isNaN(year) ? thisYear : year);
					};
					year = determineYear(years[0]);
					endYear = Math.max(year, determineYear(years[1] || ""));
					year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
					endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
					inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
					for (; year <= endYear; year++) {
						inst.yearshtml += "<option value='" + year + "'" +
							(year === drawYear ? " selected='selected'" : "") +
							">" + year + "</option>";
					}
					inst.yearshtml += "</select>";
	
					html += inst.yearshtml;
					inst.yearshtml = null;
				}
			}
	
			html += this._get(inst, "yearSuffix");
			if (showMonthAfterYear) {
				html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
			}
			html += "</div>"; // Close datepicker_header
			return html;
		},
	
		/* Adjust one of the date sub-fields. */
		_adjustInstDate: function(inst, offset, period) {
			var year = inst.drawYear + (period === "Y" ? offset : 0),
				month = inst.drawMonth + (period === "M" ? offset : 0),
				day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
				date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
	
			inst.selectedDay = date.getDate();
			inst.drawMonth = inst.selectedMonth = date.getMonth();
			inst.drawYear = inst.selectedYear = date.getFullYear();
			if (period === "M" || period === "Y") {
				this._notifyChange(inst);
			}
		},
	
		/* Ensure a date is within any min/max bounds. */
		_restrictMinMax: function(inst, date) {
			var minDate = this._getMinMaxDate(inst, "min"),
				maxDate = this._getMinMaxDate(inst, "max"),
				newDate = (minDate && date < minDate ? minDate : date);
			return (maxDate && newDate > maxDate ? maxDate : newDate);
		},
	
		/* Notify change of month/year. */
		_notifyChange: function(inst) {
			var onChange = this._get(inst, "onChangeMonthYear");
			if (onChange) {
				onChange.apply((inst.input ? inst.input[0] : null),
					[inst.selectedYear, inst.selectedMonth + 1, inst]);
			}
		},
	
		/* Determine the number of months to show. */
		_getNumberOfMonths: function(inst) {
			var numMonths = this._get(inst, "numberOfMonths");
			return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
		},
	
		/* Determine the current maximum date - ensure no time components are set. */
		_getMinMaxDate: function(inst, minMax) {
			return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
		},
	
		/* Find the number of days in a given month. */
		_getDaysInMonth: function(year, month) {
			return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
		},
	
		/* Find the day of the week of the first of a month. */
		_getFirstDayOfMonth: function(year, month) {
			return new Date(year, month, 1).getDay();
		},
	
		/* Determines if we should allow a "next/prev" month display change. */
		_canAdjustMonth: function(inst, offset, curYear, curMonth) {
			var numMonths = this._getNumberOfMonths(inst),
				date = this._daylightSavingAdjust(new Date(curYear,
				curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
	
			if (offset < 0) {
				date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
			}
			return this._isInRange(inst, date);
		},
	
		/* Is the given date in the accepted range? */
		_isInRange: function(inst, date) {
			var yearSplit, currentYear,
				minDate = this._getMinMaxDate(inst, "min"),
				maxDate = this._getMinMaxDate(inst, "max"),
				minYear = null,
				maxYear = null,
				years = this._get(inst, "yearRange");
				if (years){
					yearSplit = years.split(":");
					currentYear = new Date().getFullYear();
					minYear = parseInt(yearSplit[0], 10);
					maxYear = parseInt(yearSplit[1], 10);
					if ( yearSplit[0].match(/[+\-].*/) ) {
						minYear += currentYear;
					}
					if ( yearSplit[1].match(/[+\-].*/) ) {
						maxYear += currentYear;
					}
				}
	
			return ((!minDate || date.getTime() >= minDate.getTime()) &&
				(!maxDate || date.getTime() <= maxDate.getTime()) &&
				(!minYear || date.getFullYear() >= minYear) &&
				(!maxYear || date.getFullYear() <= maxYear));
		},
	
		/* Provide the configuration settings for formatting/parsing. */
		_getFormatConfig: function(inst) {
			var shortYearCutoff = this._get(inst, "shortYearCutoff");
			shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
				new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
			return {shortYearCutoff: shortYearCutoff,
				dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
				monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
		},
	
		/* Format the given date for display. */
		_formatDate: function(inst, day, month, year) {
			if (!day) {
				inst.currentDay = inst.selectedDay;
				inst.currentMonth = inst.selectedMonth;
				inst.currentYear = inst.selectedYear;
			}
			var date = (day ? (typeof day === "object" ? day :
				this._daylightSavingAdjust(new Date(year, month, day))) :
				this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
			return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
		}
	});
	
	/*
	 * Bind hover events for datepicker elements.
	 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
	 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
	 */
	function bindHover(dpDiv) {
		var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
		return dpDiv.delegate(selector, "mouseout", function() {
				$(this).removeClass("ui-state-hover");
				if (this.className.indexOf("ui-datepicker-prev") !== -1) {
					$(this).removeClass("ui-datepicker-prev-hover");
				}
				if (this.className.indexOf("ui-datepicker-next") !== -1) {
					$(this).removeClass("ui-datepicker-next-hover");
				}
			})
			.delegate(selector, "mouseover", function(){
				if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
					$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
					$(this).addClass("ui-state-hover");
					if (this.className.indexOf("ui-datepicker-prev") !== -1) {
						$(this).addClass("ui-datepicker-prev-hover");
					}
					if (this.className.indexOf("ui-datepicker-next") !== -1) {
						$(this).addClass("ui-datepicker-next-hover");
					}
				}
			});
	}
	
	/* jQuery extend now ignores nulls! */
	function extendRemove(target, props) {
		$.extend(target, props);
		for (var name in props) {
			if (props[name] == null) {
				target[name] = props[name];
			}
		}
		return target;
	}
	
	/* Invoke the datepicker functionality.
	   @param  options  string - a command, optionally followed by additional parameters or
						Object - settings for attaching new datepicker functionality
	   @return  jQuery object */
	$.fn.datepicker = function(options){
	
		/* Verify an empty collection wasn't passed - Fixes #6976 */
		if ( !this.length ) {
			return this;
		}
	
		/* Initialise the date picker. */
		if (!$.datepicker.initialized) {
			$(document).mousedown($.datepicker._checkExternalClick);
			$.datepicker.initialized = true;
		}
	
		/* Append datepicker main container to body if not exist. */
		if ($("#"+$.datepicker._mainDivId).length === 0) {
			$("body").append($.datepicker.dpDiv);
		}
	
		var otherArgs = Array.prototype.slice.call(arguments, 1);
		if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
			return $.datepicker["_" + options + "Datepicker"].
				apply($.datepicker, [this[0]].concat(otherArgs));
		}
		if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
			return $.datepicker["_" + options + "Datepicker"].
				apply($.datepicker, [this[0]].concat(otherArgs));
		}
		return this.each(function() {
			typeof options === "string" ?
				$.datepicker["_" + options + "Datepicker"].
					apply($.datepicker, [this].concat(otherArgs)) :
				$.datepicker._attachDatepicker(this, options);
		});
	};
	
	$.datepicker = new Datepicker(); // singleton instance
	$.datepicker.initialized = false;
	$.datepicker.uuid = new Date().getTime();
	$.datepicker.version = "1.10.3";
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	var sizeRelatedOptions = {
			buttons: true,
			height: true,
			maxHeight: true,
			maxWidth: true,
			minHeight: true,
			minWidth: true,
			width: true
		},
		resizableRelatedOptions = {
			maxHeight: true,
			maxWidth: true,
			minHeight: true,
			minWidth: true
		};
	
	$.widget( "ui.dialog", {
		version: "1.10.3",
		options: {
			appendTo: "body",
			autoOpen: true,
			buttons: [],
			closeOnEscape: true,
			closeText: "close",
			dialogClass: "",
			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
		},
	
		_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");
			this.options.title = this.options.title || this.originalTitle;
	
			this._createWrapper();
	
			this.element
				.show()
				.removeAttr("title")
				.addClass("ui-dialog-content ui-widget-content")
				.appendTo( this.uiDialog );
	
			this._createTitlebar();
			this._createButtonPane();
	
			if ( this.options.draggable && $.fn.draggable ) {
				this._makeDraggable();
			}
			if ( this.options.resizable && $.fn.resizable ) {
				this._makeResizable();
			}
	
			this._isOpen = false;
		},
	
		_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._destroyOverlay();
	
			this.element
				.removeUniqueId()
				.removeClass("ui-dialog-content ui-widget-content")
				.css( this.originalCss )
				// Without detaching first, the following becomes really slow
				.detach();
	
			this.uiDialog.stop( true, true ).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._destroyOverlay();
	
			if ( !this.opener.filter(":focusable").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
				$( this.document[0].activeElement ).blur();
			}
	
			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 = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
			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 = $( this.document[0].activeElement );
	
			this._size();
			this._position();
			this._createOverlay();
			this._moveToTop( null, true );
			this._show( this.uiDialog, this.options.show, function() {
				that._focusTabbable();
				that._trigger("focus");
			});
	
			this._trigger("open");
		},
	
		_focusTabbable: function() {
			// Set focus to the first match:
			// 1. First element inside the dialog matching [autofocus]
			// 2. Tabbable element inside the content element
			// 3. Tabbable element inside the buttonpane
			// 4. The close button
			// 5. The dialog itself
			var 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 ).focus();
		},
	
		_keepFocus: function( event ) {
			function checkFocus() {
				var activeElement = this.document[0].activeElement,
					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>")
				.addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
					this.options.dialogClass )
				.hide()
				.attr({
					// Setting tabIndex makes the div focusable
					tabIndex: -1,
					role: "dialog"
				})
				.appendTo( this._appendTo() );
	
			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 ) {
						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 ) {
						first.focus( 1 );
						event.preventDefault();
					} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
						last.focus( 1 );
						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>")
				.addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
				.prependTo( this.uiDialog );
			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.focus();
					}
				}
			});
	
			this.uiDialogTitlebarClose = $("<button></button>")
				.button({
					label: this.options.closeText,
					icons: {
						primary: "ui-icon-closethick"
					},
					text: false
				})
				.addClass("ui-dialog-titlebar-close")
				.appendTo( this.uiDialogTitlebar );
			this._on( this.uiDialogTitlebarClose, {
				click: function( event ) {
					event.preventDefault();
					this.close( event );
				}
			});
	
			uiDialogTitle = $("<span>")
				.uniqueId()
				.addClass("ui-dialog-title")
				.prependTo( this.uiDialogTitlebar );
			this._title( uiDialogTitle );
	
			this.uiDialog.attr({
				"aria-labelledby": uiDialogTitle.attr("id")
			});
		},
	
		_title: function( title ) {
			if ( !this.options.title ) {
				title.html("&#160;");
			}
			title.text( this.options.title );
		},
	
		_createButtonPane: function() {
			this.uiDialogButtonPane = $("<div>")
				.addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
	
			this.uiButtonSet = $("<div>")
				.addClass("ui-dialog-buttonset")
				.appendTo( this.uiDialogButtonPane );
	
			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.uiDialog.removeClass("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;
				props.click = function() {
					click.apply( that.element[0], arguments );
				};
				buttonOptions = {
					icons: props.icons,
					text: props.showText
				};
				delete props.icons;
				delete props.showText;
				$( "<button></button>", props )
					.button( buttonOptions )
					.appendTo( that.uiButtonSet );
			});
			this.uiDialog.addClass("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 ) {
					$( this ).addClass("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 ) {
					options.position = [
						ui.position.left - that.document.scrollLeft(),
						ui.position.top - that.document.scrollTop()
					];
					$( this ).removeClass("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 ) {
					$( this ).addClass("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 ) {
					options.height = $( this ).height();
					options.width = $( this ).width();
					$( this ).removeClass("ui-dialog-resizing");
					that._unblockFrames();
					that._trigger( "resizeStop", event, filteredUi( ui ) );
				}
			})
			.css( "position", position );
		},
	
		_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 sizeRelatedOptions ) {
					resize = true;
				}
				if ( key in 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 ) {
			/*jshint maxcomplexity:15*/
			var isDraggable, isResizable,
				uiDialog = this.uiDialog;
	
			if ( key === "dialogClass" ) {
				uiDialog
					.removeClass( this.options.dialogClass )
					.addClass( value );
			}
	
			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: "" + value
				});
			}
	
			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;
			}
	
			var that = this,
				widgetFullName = this.widgetFullName;
			if ( !$.ui.dialog.overlayInstances ) {
				// Prevent use of anchors and inputs.
				// We use a delay in case the overlay is created from an
				// event that we're going to be cancelling. (#2804)
				this._delay(function() {
					// Handle .dialog().dialog("close") (#4065)
					if ( $.ui.dialog.overlayInstances ) {
						this.document.bind( "focusin.dialog", function( event ) {
							if ( !that._allowInteraction( event ) ) {
								event.preventDefault();
								$(".ui-dialog:visible:last .ui-dialog-content")
									.data( widgetFullName )._focusTabbable();
							}
						});
					}
				});
			}
	
			this.overlay = $("<div>")
				.addClass("ui-widget-overlay ui-front")
				.appendTo( this._appendTo() );
			this._on( this.overlay, {
				mousedown: "_keepFocus"
			});
			$.ui.dialog.overlayInstances++;
		},
	
		_destroyOverlay: function() {
			if ( !this.options.modal ) {
				return;
			}
	
			if ( this.overlay ) {
				$.ui.dialog.overlayInstances--;
	
				if ( !$.ui.dialog.overlayInstances ) {
					this.document.unbind( "focusin.dialog" );
				}
				this.overlay.remove();
				this.overlay = null;
			}
		}
	});
	
	$.ui.dialog.overlayInstances = 0;
	
	// DEPRECATED
	if ( $.uiBackCompat !== false ) {
		// position option with array notation
		// just override with old implementation
		$.widget( "ui.dialog", $.ui.dialog, {
			_position: function() {
				var position = this.options.position,
					myAt = [],
					offset = [ 0, 0 ],
					isVisible;
	
				if ( position ) {
					if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
						myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
						if ( myAt.length === 1 ) {
							myAt[1] = myAt[0];
						}
	
						$.each( [ "left", "top" ], function( i, offsetPosition ) {
							if ( +myAt[ i ] === myAt[ i ] ) {
								offset[ i ] = myAt[ i ];
								myAt[ i ] = offsetPosition;
							}
						});
	
						position = {
							my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
								myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
							at: myAt.join(" ")
						};
					}
	
					position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
				} else {
					position = $.ui.dialog.prototype.options.position;
				}
	
				// need to show the dialog to get the actual offset in the position plugin
				isVisible = this.uiDialog.is(":visible");
				if ( !isVisible ) {
					this.uiDialog.show();
				}
				this.uiDialog.position( position );
				if ( !isVisible ) {
					this.uiDialog.hide();
				}
			}
		});
	}
	
	}( jQuery ) );
	
	(function( $, undefined ) {
	
	var rvertical = /up|down|vertical/,
		rpositivemotion = /up|left|vertical|horizontal/;
	
	$.effects.effect.blind = function( o, done ) {
		// Create element
		var el = $( this ),
			props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
			mode = $.effects.setMode( el, o.mode || "hide" ),
			direction = o.direction || "up",
			vertical = rvertical.test( direction ),
			ref = vertical ? "height" : "width",
			ref2 = vertical ? "top" : "left",
			motion = rpositivemotion.test( direction ),
			animation = {},
			show = mode === "show",
			wrapper, distance, margin;
	
		// if already wrapped, the wrapper's properties are my property. #6245
		if ( el.parent().is( ".ui-effects-wrapper" ) ) {
			$.effects.save( el.parent(), props );
		} else {
			$.effects.save( el, props );
		}
		el.show();
		wrapper = $.effects.createWrapper( el ).css({
			overflow: "hidden"
		});
	
		distance = wrapper[ ref ]();
		margin = parseFloat( wrapper.css( ref2 ) ) || 0;
	
		animation[ ref ] = show ? distance : 0;
		if ( !motion ) {
			el
				.css( vertical ? "bottom" : "right", 0 )
				.css( vertical ? "top" : "left", "auto" )
				.css({ position: "absolute" });
	
			animation[ ref2 ] = show ? margin : distance + margin;
		}
	
		// start at 0 if we are showing
		if ( show ) {
			wrapper.css( ref, 0 );
			if ( ! motion ) {
				wrapper.css( ref2, margin + distance );
			}
		}
	
		// Animate
		wrapper.animate( animation, {
			duration: o.duration,
			easing: o.easing,
			queue: false,
			complete: function() {
				if ( mode === "hide" ) {
					el.hide();
				}
				$.effects.restore( el, props );
				$.effects.removeWrapper( el );
				done();
			}
		});
	
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.effects.effect.bounce = function( o, done ) {
		var el = $( this ),
			props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
	
			// defaults:
			mode = $.effects.setMode( el, o.mode || "effect" ),
			hide = mode === "hide",
			show = mode === "show",
			direction = o.direction || "up",
			distance = o.distance,
			times = o.times || 5,
	
			// number of internal animations
			anims = times * 2 + ( show || hide ? 1 : 0 ),
			speed = o.duration / anims,
			easing = o.easing,
	
			// utility:
			ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
			motion = ( direction === "up" || direction === "left" ),
			i,
			upAnim,
			downAnim,
	
			// we will need to re-assemble the queue to stack our animations in place
			queue = el.queue(),
			queuelen = queue.length;
	
		// Avoid touching opacity to prevent clearType and PNG issues in IE
		if ( show || hide ) {
			props.push( "opacity" );
		}
	
		$.effects.save( el, props );
		el.show();
		$.effects.createWrapper( el ); // Create Wrapper
	
		// default distance for the BIGGEST bounce is the outer Distance / 3
		if ( !distance ) {
			distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
		}
	
		if ( show ) {
			downAnim = { opacity: 1 };
			downAnim[ ref ] = 0;
	
			// if we are showing, force opacity 0 and set the initial position
			// then do the "first" animation
			el.css( "opacity", 0 )
				.css( ref, motion ? -distance * 2 : distance * 2 )
				.animate( downAnim, speed, easing );
		}
	
		// start at the smallest distance if we are hiding
		if ( hide ) {
			distance = distance / Math.pow( 2, times - 1 );
		}
	
		downAnim = {};
		downAnim[ ref ] = 0;
		// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
		for ( i = 0; i < times; i++ ) {
			upAnim = {};
			upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
	
			el.animate( upAnim, speed, easing )
				.animate( downAnim, speed, easing );
	
			distance = hide ? distance * 2 : distance / 2;
		}
	
		// Last Bounce when Hiding
		if ( hide ) {
			upAnim = { opacity: 0 };
			upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
	
			el.animate( upAnim, speed, easing );
		}
	
		el.queue(function() {
			if ( hide ) {
				el.hide();
			}
			$.effects.restore( el, props );
			$.effects.removeWrapper( el );
			done();
		});
	
		// inject all the animations we just queued to be first in line (after "inprogress")
		if ( queuelen > 1) {
			queue.splice.apply( queue,
				[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
		}
		el.dequeue();
	
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.effects.effect.clip = function( o, done ) {
		// Create element
		var el = $( this ),
			props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
			mode = $.effects.setMode( el, o.mode || "hide" ),
			show = mode === "show",
			direction = o.direction || "vertical",
			vert = direction === "vertical",
			size = vert ? "height" : "width",
			position = vert ? "top" : "left",
			animation = {},
			wrapper, animate, distance;
	
		// Save & Show
		$.effects.save( el, props );
		el.show();
	
		// Create Wrapper
		wrapper = $.effects.createWrapper( el ).css({
			overflow: "hidden"
		});
		animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
		distance = animate[ size ]();
	
		// Shift
		if ( show ) {
			animate.css( size, 0 );
			animate.css( position, distance / 2 );
		}
	
		// Create Animation Object:
		animation[ size ] = show ? distance : 0;
		animation[ position ] = show ? 0 : distance / 2;
	
		// Animate
		animate.animate( animation, {
			queue: false,
			duration: o.duration,
			easing: o.easing,
			complete: function() {
				if ( !show ) {
					el.hide();
				}
				$.effects.restore( el, props );
				$.effects.removeWrapper( el );
				done();
			}
		});
	
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.effects.effect.drop = function( o, done ) {
	
		var el = $( this ),
			props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
			mode = $.effects.setMode( el, o.mode || "hide" ),
			show = mode === "show",
			direction = o.direction || "left",
			ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
			motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
			animation = {
				opacity: show ? 1 : 0
			},
			distance;
	
		// Adjust
		$.effects.save( el, props );
		el.show();
		$.effects.createWrapper( el );
	
		distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
	
		if ( show ) {
			el
				.css( "opacity", 0 )
				.css( ref, motion === "pos" ? -distance : distance );
		}
	
		// Animation
		animation[ ref ] = ( show ?
			( motion === "pos" ? "+=" : "-=" ) :
			( motion === "pos" ? "-=" : "+=" ) ) +
			distance;
	
		// Animate
		el.animate( animation, {
			queue: false,
			duration: o.duration,
			easing: o.easing,
			complete: function() {
				if ( mode === "hide" ) {
					el.hide();
				}
				$.effects.restore( el, props );
				$.effects.removeWrapper( el );
				done();
			}
		});
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.effects.effect.explode = function( o, done ) {
	
		var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
			cells = rows,
			el = $( this ),
			mode = $.effects.setMode( el, o.mode || "hide" ),
			show = mode === "show",
	
			// show and then visibility:hidden the element before calculating offset
			offset = el.show().css( "visibility", "hidden" ).offset(),
	
			// width and height of a piece
			width = Math.ceil( el.outerWidth() / cells ),
			height = Math.ceil( el.outerHeight() / rows ),
			pieces = [],
	
			// loop
			i, j, left, top, mx, my;
	
		// children animate complete:
		function childComplete() {
			pieces.push( this );
			if ( pieces.length === rows * cells ) {
				animComplete();
			}
		}
	
		// clone the element for each row and cell.
		for( i = 0; i < rows ; i++ ) { // ===>
			top = offset.top + i * height;
			my = i - ( rows - 1 ) / 2 ;
	
			for( j = 0; j < cells ; j++ ) { // |||
				left = offset.left + j * width;
				mx = j - ( cells - 1 ) / 2 ;
	
				// Create a clone of the now hidden main element that will be absolute positioned
				// within a wrapper div off the -left and -top equal to size of our pieces
				el
					.clone()
					.appendTo( "body" )
					.wrap( "<div></div>" )
					.css({
						position: "absolute",
						visibility: "visible",
						left: -j * width,
						top: -i * height
					})
	
				// select the wrapper - make it overflow: hidden and absolute positioned based on
				// where the original was located +left and +top equal to the size of pieces
					.parent()
					.addClass( "ui-effects-explode" )
					.css({
						position: "absolute",
						overflow: "hidden",
						width: width,
						height: height,
						left: left + ( show ? mx * width : 0 ),
						top: top + ( show ? my * height : 0 ),
						opacity: show ? 0 : 1
					}).animate({
						left: left + ( show ? 0 : mx * width ),
						top: top + ( show ? 0 : my * height ),
						opacity: show ? 1 : 0
					}, o.duration || 500, o.easing, childComplete );
			}
		}
	
		function animComplete() {
			el.css({
				visibility: "visible"
			});
			$( pieces ).remove();
			if ( !show ) {
				el.hide();
			}
			done();
		}
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.effects.effect.fade = function( o, done ) {
		var el = $( this ),
			mode = $.effects.setMode( el, o.mode || "toggle" );
	
		el.animate({
			opacity: mode
		}, {
			queue: false,
			duration: o.duration,
			easing: o.easing,
			complete: done
		});
	};
	
	})( jQuery );
	
	(function( $, undefined ) {
	
	$.effects.effect.fold = function( o, done ) {
	
		// Create element
		var el = $( this ),
			props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
			mode = $.effects.setMode( el, o.mode || "hide" ),
			show = mode === "show",
			hide = mode === "hide",
			size = o.size || 15,
			percent = /([0-9]+)%/.exec( size ),
			horizFirst = !!o.horizFirst,
			widthFirst = show !== horizFirst,
			ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
			duration = o.duration / 2,
			wrapper, distance,
			animation1 = {},
			animation2 = {};
	
		$.effects.save( el, props );
		el.show();
	
		// Create Wrapper
		wrapper = $.effects.createWrapper( el ).css({
			overflow: "hidden"
		});
		distance = widthFirst ?
			[ wrapper.width(), wrapper.height() ] :
			[ wrapper.height(), wrapper.width() ];
	
		if ( percent ) {
			size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
		}
		if ( show ) {
			wrapper.css( horizFirst ? {
				height: 0,
				width: size
			} : {
				height: size,
				width: 0
			});
		}
	
		// Animation
		animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
		animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
	
		// Animate
		wrapper
			.animate( animation1, duration, o.easing )
			.animate( animation2, duration, o.easing, function() {
				if ( hide ) {
					el.hide();
				}
				$.effects.restore( el, props );
				$.effects.removeWrapper( el );
				done();
			});
	
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.effects.effect.highlight = function( o, done ) {
		var elem = $( this ),
			props = [ "backgroundImage", "backgroundColor", "opacity" ],
			mode = $.effects.setMode( elem, o.mode || "show" ),
			animation = {
				backgroundColor: elem.css( "backgroundColor" )
			};
	
		if (mode === "hide") {
			animation.opacity = 0;
		}
	
		$.effects.save( elem, props );
	
		elem
			.show()
			.css({
				backgroundImage: "none",
				backgroundColor: o.color || "#ffff99"
			})
			.animate( animation, {
				queue: false,
				duration: o.duration,
				easing: o.easing,
				complete: function() {
					if ( mode === "hide" ) {
						elem.hide();
					}
					$.effects.restore( elem, props );
					done();
				}
			});
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.effects.effect.pulsate = function( o, done ) {
		var elem = $( this ),
			mode = $.effects.setMode( elem, o.mode || "show" ),
			show = mode === "show",
			hide = mode === "hide",
			showhide = ( show || mode === "hide" ),
	
			// showing or hiding leaves of the "last" animation
			anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
			duration = o.duration / anims,
			animateTo = 0,
			queue = elem.queue(),
			queuelen = queue.length,
			i;
	
		if ( show || !elem.is(":visible")) {
			elem.css( "opacity", 0 ).show();
			animateTo = 1;
		}
	
		// anims - 1 opacity "toggles"
		for ( i = 1; i < anims; i++ ) {
			elem.animate({
				opacity: animateTo
			}, duration, o.easing );
			animateTo = 1 - animateTo;
		}
	
		elem.animate({
			opacity: animateTo
		}, duration, o.easing);
	
		elem.queue(function() {
			if ( hide ) {
				elem.hide();
			}
			done();
		});
	
		// We just queued up "anims" animations, we need to put them next in the queue
		if ( queuelen > 1 ) {
			queue.splice.apply( queue,
				[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
		}
		elem.dequeue();
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.effects.effect.puff = function( o, done ) {
		var elem = $( this ),
			mode = $.effects.setMode( elem, o.mode || "hide" ),
			hide = mode === "hide",
			percent = parseInt( o.percent, 10 ) || 150,
			factor = percent / 100,
			original = {
				height: elem.height(),
				width: elem.width(),
				outerHeight: elem.outerHeight(),
				outerWidth: elem.outerWidth()
			};
	
		$.extend( o, {
			effect: "scale",
			queue: false,
			fade: true,
			mode: mode,
			complete: done,
			percent: hide ? percent : 100,
			from: hide ?
				original :
				{
					height: original.height * factor,
					width: original.width * factor,
					outerHeight: original.outerHeight * factor,
					outerWidth: original.outerWidth * factor
				}
		});
	
		elem.effect( o );
	};
	
	$.effects.effect.scale = function( o, done ) {
	
		// Create element
		var el = $( this ),
			options = $.extend( true, {}, o ),
			mode = $.effects.setMode( el, o.mode || "effect" ),
			percent = parseInt( o.percent, 10 ) ||
				( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
			direction = o.direction || "both",
			origin = o.origin,
			original = {
				height: el.height(),
				width: el.width(),
				outerHeight: el.outerHeight(),
				outerWidth: el.outerWidth()
			},
			factor = {
				y: direction !== "horizontal" ? (percent / 100) : 1,
				x: direction !== "vertical" ? (percent / 100) : 1
			};
	
		// We are going to pass this effect to the size effect:
		options.effect = "size";
		options.queue = false;
		options.complete = done;
	
		// Set default origin and restore for show/hide
		if ( mode !== "effect" ) {
			options.origin = origin || ["middle","center"];
			options.restore = true;
		}
	
		options.from = o.from || ( mode === "show" ? {
			height: 0,
			width: 0,
			outerHeight: 0,
			outerWidth: 0
		} : original );
		options.to = {
			height: original.height * factor.y,
			width: original.width * factor.x,
			outerHeight: original.outerHeight * factor.y,
			outerWidth: original.outerWidth * factor.x
		};
	
		// Fade option to support puff
		if ( options.fade ) {
			if ( mode === "show" ) {
				options.from.opacity = 0;
				options.to.opacity = 1;
			}
			if ( mode === "hide" ) {
				options.from.opacity = 1;
				options.to.opacity = 0;
			}
		}
	
		// Animate
		el.effect( options );
	
	};
	
	$.effects.effect.size = function( o, done ) {
	
		// Create element
		var original, baseline, factor,
			el = $( this ),
			props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
	
			// Always restore
			props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
	
			// Copy for children
			props2 = [ "width", "height", "overflow" ],
			cProps = [ "fontSize" ],
			vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
			hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
	
			// Set options
			mode = $.effects.setMode( el, o.mode || "effect" ),
			restore = o.restore || mode !== "effect",
			scale = o.scale || "both",
			origin = o.origin || [ "middle", "center" ],
			position = el.css( "position" ),
			props = restore ? props0 : props1,
			zero = {
				height: 0,
				width: 0,
				outerHeight: 0,
				outerWidth: 0
			};
	
		if ( mode === "show" ) {
			el.show();
		}
		original = {
			height: el.height(),
			width: el.width(),
			outerHeight: el.outerHeight(),
			outerWidth: el.outerWidth()
		};
	
		if ( o.mode === "toggle" && mode === "show" ) {
			el.from = o.to || zero;
			el.to = o.from || original;
		} else {
			el.from = o.from || ( mode === "show" ? zero : original );
			el.to = o.to || ( mode === "hide" ? zero : original );
		}
	
		// Set scaling factor
		factor = {
			from: {
				y: el.from.height / original.height,
				x: el.from.width / original.width
			},
			to: {
				y: el.to.height / original.height,
				x: el.to.width / original.width
			}
		};
	
		// Scale the css box
		if ( scale === "box" || scale === "both" ) {
	
			// Vertical props scaling
			if ( factor.from.y !== factor.to.y ) {
				props = props.concat( vProps );
				el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
				el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
			}
	
			// Horizontal props scaling
			if ( factor.from.x !== factor.to.x ) {
				props = props.concat( hProps );
				el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
				el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
			}
		}
	
		// Scale the content
		if ( scale === "content" || scale === "both" ) {
	
			// Vertical props scaling
			if ( factor.from.y !== factor.to.y ) {
				props = props.concat( cProps ).concat( props2 );
				el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
				el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
			}
		}
	
		$.effects.save( el, props );
		el.show();
		$.effects.createWrapper( el );
		el.css( "overflow", "hidden" ).css( el.from );
	
		// Adjust
		if (origin) { // Calculate baseline shifts
			baseline = $.effects.getBaseline( origin, original );
			el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
			el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
			el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
			el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
		}
		el.css( el.from ); // set top & left
	
		// Animate
		if ( scale === "content" || scale === "both" ) { // Scale the children
	
			// Add margins/font-size
			vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
			hProps = hProps.concat([ "marginLeft", "marginRight" ]);
			props2 = props0.concat(vProps).concat(hProps);
	
			el.find( "*[width]" ).each( function(){
				var child = $( this ),
					c_original = {
						height: child.height(),
						width: child.width(),
						outerHeight: child.outerHeight(),
						outerWidth: child.outerWidth()
					};
				if (restore) {
					$.effects.save(child, props2);
				}
	
				child.from = {
					height: c_original.height * factor.from.y,
					width: c_original.width * factor.from.x,
					outerHeight: c_original.outerHeight * factor.from.y,
					outerWidth: c_original.outerWidth * factor.from.x
				};
				child.to = {
					height: c_original.height * factor.to.y,
					width: c_original.width * factor.to.x,
					outerHeight: c_original.height * factor.to.y,
					outerWidth: c_original.width * factor.to.x
				};
	
				// Vertical props scaling
				if ( factor.from.y !== factor.to.y ) {
					child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
					child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
				}
	
				// Horizontal props scaling
				if ( factor.from.x !== factor.to.x ) {
					child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
					child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
				}
	
				// Animate children
				child.css( child.from );
				child.animate( child.to, o.duration, o.easing, function() {
	
					// Restore children
					if ( restore ) {
						$.effects.restore( child, props2 );
					}
				});
			});
		}
	
		// Animate
		el.animate( el.to, {
			queue: false,
			duration: o.duration,
			easing: o.easing,
			complete: function() {
				if ( el.to.opacity === 0 ) {
					el.css( "opacity", el.from.opacity );
				}
				if( mode === "hide" ) {
					el.hide();
				}
				$.effects.restore( el, props );
				if ( !restore ) {
	
					// we need to calculate our new positioning based on the scaling
					if ( position === "static" ) {
						el.css({
							position: "relative",
							top: el.to.top,
							left: el.to.left
						});
					} else {
						$.each([ "top", "left" ], function( idx, pos ) {
							el.css( pos, function( _, str ) {
								var val = parseInt( str, 10 ),
									toRef = idx ? el.to.left : el.to.top;
	
								// if original was "auto", recalculate the new value from wrapper
								if ( str === "auto" ) {
									return toRef + "px";
								}
	
								return val + toRef + "px";
							});
						});
					}
				}
	
				$.effects.removeWrapper( el );
				done();
			}
		});
	
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.effects.effect.shake = function( o, done ) {
	
		var el = $( this ),
			props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
			mode = $.effects.setMode( el, o.mode || "effect" ),
			direction = o.direction || "left",
			distance = o.distance || 20,
			times = o.times || 3,
			anims = times * 2 + 1,
			speed = Math.round(o.duration/anims),
			ref = (direction === "up" || direction === "down") ? "top" : "left",
			positiveMotion = (direction === "up" || direction === "left"),
			animation = {},
			animation1 = {},
			animation2 = {},
			i,
	
			// we will need to re-assemble the queue to stack our animations in place
			queue = el.queue(),
			queuelen = queue.length;
	
		$.effects.save( el, props );
		el.show();
		$.effects.createWrapper( el );
	
		// Animation
		animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
		animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
		animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
	
		// Animate
		el.animate( animation, speed, o.easing );
	
		// Shakes
		for ( i = 1; i < times; i++ ) {
			el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
		}
		el
			.animate( animation1, speed, o.easing )
			.animate( animation, speed / 2, o.easing )
			.queue(function() {
				if ( mode === "hide" ) {
					el.hide();
				}
				$.effects.restore( el, props );
				$.effects.removeWrapper( el );
				done();
			});
	
		// inject all the animations we just queued to be first in line (after "inprogress")
		if ( queuelen > 1) {
			queue.splice.apply( queue,
				[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
		}
		el.dequeue();
	
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.effects.effect.slide = function( o, done ) {
	
		// Create element
		var el = $( this ),
			props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
			mode = $.effects.setMode( el, o.mode || "show" ),
			show = mode === "show",
			direction = o.direction || "left",
			ref = (direction === "up" || direction === "down") ? "top" : "left",
			positiveMotion = (direction === "up" || direction === "left"),
			distance,
			animation = {};
	
		// Adjust
		$.effects.save( el, props );
		el.show();
		distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
	
		$.effects.createWrapper( el ).css({
			overflow: "hidden"
		});
	
		if ( show ) {
			el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
		}
	
		// Animation
		animation[ ref ] = ( show ?
			( positiveMotion ? "+=" : "-=") :
			( positiveMotion ? "-=" : "+=")) +
			distance;
	
		// Animate
		el.animate( animation, {
			queue: false,
			duration: o.duration,
			easing: o.easing,
			complete: function() {
				if ( mode === "hide" ) {
					el.hide();
				}
				$.effects.restore( el, props );
				$.effects.removeWrapper( el );
				done();
			}
		});
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.effects.effect.transfer = function( o, done ) {
		var elem = $( this ),
			target = $( o.to ),
			targetFixed = target.css( "position" ) === "fixed",
			body = $("body"),
			fixTop = targetFixed ? body.scrollTop() : 0,
			fixLeft = targetFixed ? body.scrollLeft() : 0,
			endPosition = target.offset(),
			animation = {
				top: endPosition.top - fixTop ,
				left: endPosition.left - fixLeft ,
				height: target.innerHeight(),
				width: target.innerWidth()
			},
			startPosition = elem.offset(),
			transfer = $( "<div class='ui-effects-transfer'></div>" )
				.appendTo( document.body )
				.addClass( o.className )
				.css({
					top: startPosition.top - fixTop ,
					left: startPosition.left - fixLeft ,
					height: elem.innerHeight(),
					width: elem.innerWidth(),
					position: targetFixed ? "fixed" : "absolute"
				})
				.animate( animation, o.duration, o.easing, function() {
					transfer.remove();
					done();
				});
	};
	
	})(jQuery);
	
	(function( $, undefined ) {
	
	$.widget( "ui.menu", {
		version: "1.10.3",
		defaultElement: "<ul>",
		delay: 300,
		options: {
			icons: {
				submenu: "ui-icon-carat-1-e"
			},
			menus: "ul",
			position: {
				my: "left top",
				at: "right top"
			},
			role: "menu",
	
			// callbacks
			blur: null,
			focus: null,
			select: null
		},
	
		_create: function() {
			this.activeMenu = this.element;
			// flag used to prevent firing of the click handler
			// as the event bubbles up through nested menus
			this.mouseHandled = false;
			this.element
				.uniqueId()
				.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
				.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
				.attr({
					role: this.options.role,
					tabIndex: 0
				})
				// need to catch all clicks on disabled menu
				// not possible through _on
				.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
					if ( this.options.disabled ) {
						event.preventDefault();
					}
				}, this ));
	
			if ( this.options.disabled ) {
				this.element
					.addClass( "ui-state-disabled" )
					.attr( "aria-disabled", "true" );
			}
	
			this._on({
				// Prevent focus from sticking to links inside menu after clicking
				// them (focus should always stay on UL during navigation).
				"mousedown .ui-menu-item > a": function( event ) {
					event.preventDefault();
				},
				"click .ui-state-disabled > a": function( event ) {
					event.preventDefault();
				},
				"click .ui-menu-item:has(a)": function( event ) {
					var target = $( event.target ).closest( ".ui-menu-item" );
					if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
						this.mouseHandled = true;
	
						this.select( event );
						// Open submenu on click
						if ( target.has( ".ui-menu" ).length ) {
							this.expand( event );
						} else if ( !this.element.is( ":focus" ) ) {
							// Redirect focus to the menu
							this.element.trigger( "focus", [ true ] );
	
							// If the active item is on the top level, let it stay active.
							// Otherwise, blur the active item since it is no longer visible.
							if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
								clearTimeout( this.timer );
							}
						}
					}
				},
				"mouseenter .ui-menu-item": function( event ) {
					var target = $( event.currentTarget );
					// Remove ui-state-active class from siblings of the newly focused menu item
					// to avoid a jump caused by adjacent elements both having a class with a border
					target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
					this.focus( event, target );
				},
				mouseleave: "collapseAll",
				"mouseleave .ui-menu": "collapseAll",
				focus: function( event, keepActiveItem ) {
					// If there's already an active item, keep it active
					// If not, activate the first item
					var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
	
					if ( !keepActiveItem ) {
						this.focus( event, item );
					}
				},
				blur: function( event ) {
					this._delay(function() {
						if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
							this.collapseAll( event );
						}
					});
				},
				keydown: "_keydown"
			});
	
			this.refresh();
	
			// Clicks outside of a menu collapse any open menus
			this._on( this.document, {
				click: function( event ) {
					if ( !$( event.target ).closest( ".ui-menu" ).length ) {
						this.collapseAll( event );
					}
	
					// Reset the mouseHandled flag
					this.mouseHandled = false;
				}
			});
		},
	
		_destroy: function() {
			// Destroy (sub)menus
			this.element
				.removeAttr( "aria-activedescendant" )
				.find( ".ui-menu" ).addBack()
					.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
					.removeAttr( "role" )
					.removeAttr( "tabIndex" )
					.removeAttr( "aria-labelledby" )
					.removeAttr( "aria-expanded" )
					.removeAttr( "aria-hidden" )
					.removeAttr( "aria-disabled" )
					.removeUniqueId()
					.show();
	
			// Destroy menu items
			this.element.find( ".ui-menu-item" )
				.removeClass( "ui-menu-item" )
				.removeAttr( "role" )
				.removeAttr( "aria-disabled" )
				.children( "a" )
					.removeUniqueId()
					.removeClass( "ui-corner-all ui-state-hover" )
					.removeAttr( "tabIndex" )
					.removeAttr( "role" )
					.removeAttr( "aria-haspopup" )
					.children().each( function() {
						var elem = $( this );
						if ( elem.data( "ui-menu-submenu-carat" ) ) {
							elem.remove();
						}
					});
	
			// Destroy menu dividers
			this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
		},
	
		_keydown: function( event ) {
			/*jshint maxcomplexity:20*/
			var match, prev, character, skip, regex,
				preventDefault = true;
	
			function escape( value ) {
				return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
			}
	
			switch ( event.keyCode ) {
			case $.ui.keyCode.PAGE_UP:
				this.previousPage( event );
				break;
			case $.ui.keyCode.PAGE_DOWN:
				this.nextPage( event );
				break;
			case $.ui.keyCode.HOME:
				this._move( "first", "first", event );
				break;
			case $.ui.keyCode.END:
				this._move( "last", "last", event );
				break;
			case $.ui.keyCode.UP:
				this.previous( event );
				break;
			case $.ui.keyCode.DOWN:
				this.next( event );
				break;
			case $.ui.keyCode.LEFT:
				this.collapse( event );
				break;
			case $.ui.keyCode.RIGHT:
				if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
					this.expand( event );
				}
				break;
			case $.ui.keyCode.ENTER:
			case $.ui.keyCode.SPACE:
				this._activate( event );
				break;
			case $.ui.keyCode.ESCAPE:
				this.collapse( event );
				break;
			default:
				preventDefault = false;
				prev = this.previousFilter || "";
				character = String.fromCharCode( event.keyCode );
				skip = false;
	
				clearTimeout( this.filterTimer );
	
				if ( character === prev ) {
					skip = true;
				} else {
					character = prev + character;
				}
	
				regex = new RegExp( "^" + escape( character ), "i" );
				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
					return regex.test( $( this ).children( "a" ).text() );
				});
				match = skip && match.index( this.active.next() ) !== -1 ?
					this.active.nextAll( ".ui-menu-item" ) :
					match;
	
				// If no matches on the current filter, reset to the last character pressed
				// to move down the menu to the first item that starts with that character
				if ( !match.length ) {
					character = String.fromCharCode( event.keyCode );
					regex = new RegExp( "^" + escape( character ), "i" );
					match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
						return regex.test( $( this ).children( "a" ).text() );
					});
				}
	
				if ( match.length ) {
					this.focus( event, match );
					if ( match.length > 1 ) {
						this.previousFilter = character;
						this.filterTimer = this._delay(function() {
							delete this.previousFilter;
						}, 1000 );
					} else {
						delete this.previousFilter;
					}
				} else {
					delete this.previousFilter;
				}
			}
	
			if ( preventDefault ) {
				event.preventDefault();
			}
		},
	
		_activate: function( event ) {
			if ( !this.active.is( ".ui-state-disabled" ) ) {
				if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
					this.expand( event );
				} else {
					this.select( event );
				}
			}
		},
	
		refresh: function() {
			var menus,
				icon = this.options.icons.submenu,
				submenus = this.element.find( this.options.menus );
	
			// Initialize nested menus
			submenus.filter( ":not(.ui-menu)" )
				.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
				.hide()
				.attr({
					role: this.options.role,
					"aria-hidden": "true",
					"aria-expanded": "false"
				})
				.each(function() {
					var menu = $( this ),
						item = menu.prev( "a" ),
						submenuCarat = $( "<span>" )
							.addClass( "ui-menu-icon ui-icon " + icon )
							.data( "ui-menu-submenu-carat", true );
	
					item
						.attr( "aria-haspopup", "true" )
						.prepend( submenuCarat );
					menu.attr( "aria-labelledby", item.attr( "id" ) );
				});
	
			menus = submenus.add( this.element );
	
			// Don't refresh list items that are already adapted
			menus.children( ":not(.ui-menu-item):has(a)" )
				.addClass( "ui-menu-item" )
				.attr( "role", "presentation" )
				.children( "a" )
					.uniqueId()
					.addClass( "ui-corner-all" )
					.attr({
						tabIndex: -1,
						role: this._itemRole()
					});
	
			// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
			menus.children( ":not(.ui-menu-item)" ).each(function() {
				var item = $( this );
				// hyphen, em dash, en dash
				if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
					item.addClass( "ui-widget-content ui-menu-divider" );
				}
			});
	
			// Add aria-disabled attribute to any disabled menu item
			menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
	
			// If the active item has been removed, blur the menu
			if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
				this.blur();
			}
		},
	
		_itemRole: function() {
			return {
				menu: "menuitem",
				listbox: "option"
			}[ this.options.role ];
		},
	
		_setOption: function( key, value ) {
			if ( key === "icons" ) {
				this.element.find( ".ui-menu-icon" )
					.removeClass( this.options.icons.submenu )
					.addClass( value.submenu );
			}
			this._super( key, value );
		},
	
		focus: function( event, item ) {
			var nested, focused;
			this.blur( event, event && event.type === "focus" );
	
			this._scrollIntoView( item );
	
			this.active = item.first();
			focused = this.active.children( "a" ).addClass( "ui-state-focus" );
			// Only update aria-activedescendant if there's a role
			// otherwise we assume focus is managed elsewhere
			if ( this.options.role ) {
				this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
			}
	
			// Highlight active parent menu item, if any
			this.active
				.parent()
				.closest( ".ui-menu-item" )
				.children( "a:first" )
				.addClass( "ui-state-active" );
	
			if ( event && event.type === "keydown" ) {
				this._close();
			} else {
				this.timer = this._delay(function() {
					this._close();
				}, this.delay );
			}
	
			nested = item.children( ".ui-menu" );
			if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
				this._startOpening(nested);
			}
			this.activeMenu = item.parent();
	
			this._trigger( "focus", event, { item: item } );
		},
	
		_scrollIntoView: function( item ) {
			var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
			if ( this._hasScroll() ) {
				borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
				paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
				offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
				scroll = this.activeMenu.scrollTop();
				elementHeight = this.activeMenu.height();
				itemHeight = item.height();
	
				if ( offset < 0 ) {
					this.activeMenu.scrollTop( scroll + offset );
				} else if ( offset + itemHeight > elementHeight ) {
					this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
				}
			}
		},
	
		blur: function( event, fromFocus ) {
			if ( !fromFocus ) {
				clearTimeout( this.timer );
			}
	
			if ( !this.active ) {
				return;
			}
	
			this.active.children( "a" ).removeClass( "ui-state-focus" );
			this.active = null;
	
			this._trigger( "blur", event, { item: this.active } );
		},
	
		_startOpening: function( submenu ) {
			clearTimeout( this.timer );
	
			// Don't open if already open fixes a Firefox bug that caused a .5 pixel
			// shift in the submenu position when mousing over the carat icon
			if ( submenu.attr( "aria-hidden" ) !== "true" ) {
				return;
			}
	
			this.timer = this._delay(function() {
				this._close();
				this._open( submenu );
			}, this.delay );
		},
	
		_open: function( submenu ) {
			var position = $.extend({
				of: this.active
			}, this.options.position );
	
			clearTimeout( this.timer );
			this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
				.hide()
				.attr( "aria-hidden", "true" );
	
			submenu
				.show()
				.removeAttr( "aria-hidden" )
				.attr( "aria-expanded", "true" )
				.position( position );
		},
	
		collapseAll: function( event, all ) {
			clearTimeout( this.timer );
			this.timer = this._delay(function() {
				// If we were passed an event, look for the submenu that contains the event
				var currentMenu = all ? this.element :
					$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
	
				// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
				if ( !currentMenu.length ) {
					currentMenu = this.element;
				}
	
				this._close( currentMenu );
	
				this.blur( event );
				this.activeMenu = currentMenu;
			}, this.delay );
		},
	
		// With no arguments, closes the currently active menu - if nothing is active
		// it closes all menus.  If passed an argument, it will search for menus BELOW
		_close: function( startMenu ) {
			if ( !startMenu ) {
				startMenu = this.active ? this.active.parent() : this.element;
			}
	
			startMenu
				.find( ".ui-menu" )
					.hide()
					.attr( "aria-hidden", "true" )
					.attr( "aria-expanded", "false" )
				.end()
				.find( "a.ui-state-active" )
					.removeClass( "ui-state-active" );
		},
	
		collapse: function( event ) {
			var newItem = this.active &&
				this.active.parent().closest( ".ui-menu-item", this.element );
			if ( newItem && newItem.length ) {
				this._close();
				this.focus( event, newItem );
			}
		},
	
		expand: function( event ) {
			var newItem = this.active &&
				this.active
					.children( ".ui-menu " )
					.children( ".ui-menu-item" )
					.first();
	
			if ( newItem && newItem.length ) {
				this._open( newItem.parent() );
	
				// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
				this._delay(function() {
					this.focus( event, newItem );
				});
			}
		},
	
		next: function( event ) {
			this._move( "next", "first", event );
		},
	
		previous: function( event ) {
			this._move( "prev", "last", event );
		},
	
		isFirstItem: function() {
			return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
		},
	
		isLastItem: function() {
			return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
		},
	
		_move: function( direction, filter, event ) {
			var next;
			if ( this.active ) {
				if ( direction === "first" || direction === "last" ) {
					next = this.active
						[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
						.eq( -1 );
				} else {
					next = this.active
						[ direction + "All" ]( ".ui-menu-item" )
						.eq( 0 );
				}
			}
			if ( !next || !next.length || !this.active ) {
				next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
			}
	
			this.focus( event, next );
		},
	
		nextPage: function( event ) {
			var item, base, height;
	
			if ( !this.active ) {
				this.next( event );
				return;
			}
			if ( this.isLastItem() ) {
				return;
			}
			if ( this._hasScroll() ) {
				base = this.active.offset().top;
				height = this.element.height();
				this.active.nextAll( ".ui-menu-item" ).each(function() {
					item = $( this );
					return item.offset().top - base - height < 0;
				});
	
				this.focus( event, item );
			} else {
				this.focus( event, this.activeMenu.children( ".ui-menu-item" )
					[ !this.active ? "first" : "last" ]() );
			}
		},
	
		previousPage: function( event ) {
			var item, base, height;
			if ( !this.active ) {
				this.next( event );
				return;
			}
			if ( this.isFirstItem() ) {
				return;
			}
			if ( this._hasScroll() ) {
				base = this.active.offset().top;
				height = this.element.height();
				this.active.prevAll( ".ui-menu-item" ).each(function() {
					item = $( this );
					return item.offset().top - base + height > 0;
				});
	
				this.focus( event, item );
			} else {
				this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
			}
		},
	
		_hasScroll: function() {
			return this.element.outerHeight() < this.element.prop( "scrollHeight" );
		},
	
		select: function( event ) {
			// TODO: It should never be possible to not have an active item at this
			// point, but the tests don't trigger mouseenter before click.
			this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
			var ui = { item: this.active };
			if ( !this.active.has( ".ui-menu" ).length ) {
				this.collapseAll( event, true );
			}
			this._trigger( "select", event, ui );
		}
	});
	
	}( jQuery ));
	
	(function( $, undefined ) {
	
	$.ui = $.ui || {};
	
	var cachedScrollbarWidth,
		max = Math.max,
		abs = Math.abs,
		round = Math.round,
		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;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.element.css( "overflow-x" ),
				overflowY = within.isWindow ? "" : 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] );
			return {
				element: withinElement,
				isWindow: isWindow,
				offset: withinElement.offset() || { left: 0, top: 0 },
				scrollLeft: withinElement.scrollLeft(),
				scrollTop: withinElement.scrollTop(),
				width: isWindow ? withinElement.width() : withinElement.outerWidth(),
				height: isWindow ? withinElement.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 ];
	
			// if the browser doesn't support fractions, then round for consistent results
			if ( !$.support.offsetFractions ) {
				position.left = round( position.left );
				position.top = round( position.top );
			}
	
			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 ( ( position.top + myOffset + atOffset + offset) > overTop && ( 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 ( ( position.top + myOffset + atOffset + offset) > overBottom && ( 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 );
			}
		}
	};
	
	// fraction support test
	(function () {
		var testElement, testElementParent, testElementStyle, offsetLeft, i,
			body = document.getElementsByTagName( "body" )[ 0 ],
			div = document.createElement( "div" );
	
		//Create a "fake body" for testing based on method used in jQuery.support
		testElement = document.createElement( body ? "div" : "body" );
		testElementStyle = {
			visibility: "hidden",
			width: 0,
			height: 0,
			border: 0,
			margin: 0,
			background: "none"
		};
		if ( body ) {
			$.extend( testElementStyle, {
				position: "absolute",
				left: "-1000px",
				top: "-1000px"
			});
		}
		for ( i in testElementStyle ) {
			testElement.style[ i ] = testElementStyle[ i ];
		}
		testElement.appendChild( div );
		testElementParent = body || document.documentElement;
		testElementParent.insertBefore( testElement, testElementParent.firstChild );
	
		div.style.cssText = "position: absolute; left: 10.7432222px;";
	
		offsetLeft = $( div ).offset().left;
		$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
	
		testElement.innerHTML = "";
		testElementParent.removeChild( testElement );
	})();
	
	}( jQuery ) );
	
	(function( $, undefined ) {
	
	$.widget( "ui.progressbar", {
		version: "1.10.3",
		options: {
			max: 100,
			value: 0,
	
			change: null,
			complete: null
		},
	
		min: 0,
	
		_create: function() {
			// Constrain initial value
			this.oldValue = this.options.value = this._constrainedValue();
	
			this.element
				.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
				.attr({
					// Only set static values, aria-valuenow and aria-valuemax are
					// set inside _refreshValue()
					role: "progressbar",
					"aria-valuemin": this.min
				});
	
			this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
				.appendTo( this.element );
	
			this._refreshValue();
		},
	
		_destroy: function() {
			this.element
				.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
				.removeAttr( "role" )
				.removeAttr( "aria-valuemin" )
				.removeAttr( "aria-valuemax" )
				.removeAttr( "aria-valuenow" );
	
			this.valueDiv.remove();
		},
	
		value: function( newValue ) {
			if ( newValue === undefined ) {
				return this.options.value;
			}
	
			this.options.value = this._constrainedValue( newValue );
			this._refreshValue();
		},
	
		_constrainedValue: function( newValue ) {
			if ( newValue === undefined ) {
				newValue = this.options.value;
			}
	
			this.indeterminate = newValue === false;
	
			// sanitize value
			if ( typeof newValue !== "number" ) {
				newValue = 0;
			}
	
			return this.indeterminate ? false :
				Math.min( this.options.max, Math.max( this.min, newValue ) );
		},
	
		_setOptions: function( options ) {
			// Ensure "value" option is set after other values (like max)
			var value = options.value;
			delete options.value;
	
			this._super( options );
	
			this.options.value = this._constrainedValue( value );
			this._refreshValue();
		},
	
		_setOption: function( key, value ) {
			if ( key === "max" ) {
				// Don't allow a max less than min
				value = Math.max( this.min, value );
			}
	
			this._super( key, value );
		},
	
		_percentage: function() {
			return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
		},
	
		_refreshValue: function() {
			var value = this.options.value,
				percentage = this._percentage();
	
			this.valueDiv
				.toggle( this.indeterminate || value > this.min )
				.toggleClass( "ui-corner-right", value === this.options.max )
				.width( percentage.toFixed(0) + "%" );
	
			this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
	
			if ( this.indeterminate ) {
				this.element.removeAttr( "aria-valuenow" );
				if ( !this.overlayDiv ) {
					this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
				}
			} else {
				this.element.attr({
					"aria-valuemax": this.options.max,
					"aria-valuenow": value
				});
				if ( this.overlayDiv ) {
					this.overlayDiv.remove();
					this.overlayDiv = null;
				}
			}
	
			if ( this.oldValue !== value ) {
				this.oldValue = value;
				this._trigger( "change" );
			}
			if ( value === this.options.max ) {
				this._trigger( "complete" );
			}
		}
	});
	
	})( jQuery );
	
	(function( $, undefined ) {
	
	// number of pages in a slider
	// (how many times can you page up/down to go through the whole range)
	var numPages = 5;
	
	$.widget( "ui.slider", $.ui.mouse, {
		version: "1.10.3",
		widgetEventPrefix: "slide",
	
		options: {
			animate: false,
			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
		},
	
		_create: function() {
			this._keySliding = false;
			this._mouseSliding = false;
			this._animateOff = true;
			this._handleIndex = null;
			this._detectOrientation();
			this._mouseInit();
	
			this.element
				.addClass( "ui-slider" +
					" ui-slider-" + this.orientation +
					" ui-widget" +
					" ui-widget-content" +
					" ui-corner-all");
	
			this._refresh();
			this._setOption( "disabled", this.options.disabled );
	
			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" ).addClass( "ui-state-default ui-corner-all" ),
				handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
				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.handle = this.handles.eq( 0 );
	
			this.handles.each(function( i ) {
				$( this ).data( "ui-slider-handle-index", i );
			});
		},
	
		_createRange: function() {
			var options = this.options,
				classes = "";
	
			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></div>" )
						.appendTo( this.element );
	
					classes = "ui-slider-range" +
					// note: this isn't the most fittingly semantic framework class for this element,
					// but worked best visually with a variety of themes
					" ui-widget-header ui-corner-all";
				} else {
					this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
						// Handle range switching from true to min/max
						.css({
							"left": "",
							"bottom": ""
						});
				}
	
				this.range.addClass( classes +
					( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
			} else {
				this.range = $([]);
			}
		},
	
		_setupEvents: function() {
			var elements = this.handles.add( this.range ).filter( "a" );
			this._off( elements );
			this._on( elements, this._handleEvents );
			this._hoverable( elements );
			this._focusable( elements );
		},
	
		_destroy: function() {
			this.handles.remove();
			this.range.remove();
	
			this.element
				.removeClass( "ui-slider" +
					" ui-slider-horizontal" +
					" ui-slider-vertical" +
					" ui-widget" +
					" ui-widget-content" +
					" ui-corner-all" );
	
			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;
	
			closestHandle
				.addClass( "ui-state-active" )
				.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.handles.removeClass( "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 );
		},
	
		_start: function( event, index ) {
			var uiHash = {
				handle: this.handles[ index ],
				value: this.value()
			};
			if ( this.options.values && this.options.values.length ) {
				uiHash.value = this.values( index );
				uiHash.values = this.values();
			}
			return this._trigger( "start", event, uiHash );
		},
	
		_slide: function( event, index, newVal ) {
			var otherVal,
				newValues,
				allowed;
	
			if ( this.options.values && this.options.values.length ) {
				otherVal = this.values( index ? 0 : 1 );
	
				if ( ( this.options.values.length === 2 && this.options.range === true ) &&
						( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
					) {
					newVal = otherVal;
				}
	
				if ( newVal !== this.values( index ) ) {
					newValues = this.values();
					newValues[ index ] = newVal;
					// A slide can be canceled by returning false from the slide callback
					allowed = this._trigger( "slide", event, {
						handle: this.handles[ index ],
						value: newVal,
						values: newValues
					} );
					otherVal = this.values( index ? 0 : 1 );
					if ( allowed !== false ) {
						this.values( index, newVal, true );
					}
				}
			} else {
				if ( newVal !== this.value() ) {
					// A slide can be canceled by returning false from the slide callback
					allowed = this._trigger( "slide", event, {
						handle: this.handles[ index ],
						value: newVal
					} );
					if ( allowed !== false ) {
						this.value( newVal );
					}
				}
			}
		},
	
		_stop: function( event, index ) {
			var uiHash = {
				handle: this.handles[ index ],
				value: this.value()
			};
			if ( this.options.values && this.options.values.length ) {
				uiHash.value = this.values( index );
				uiHash.values = this.values();
			}
	
			this._trigger( "stop", event, uiHash );
		},
	
		_change: function( event, index ) {
			if ( !this._keySliding && !this._mouseSliding ) {
				var uiHash = {
					handle: this.handles[ index ],
					value: this.value()
				};
				if ( this.options.values && this.options.values.length ) {
					uiHash.value = this.values( index );
					uiHash.values = this.values();
				}
	
				//store the last changed value index for reference when handles overlap
				this._lastChangedValue = index;
	
				this._trigger( "change", event, uiHash );
			}
		},
	
		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.options.values && this.options.values.length ) {
						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;
			}
	
			$.Widget.prototype._setOption.apply( this, arguments );
	
			switch ( key ) {
				case "orientation":
					this._detectOrientation();
					this.element
						.removeClass( "ui-slider-horizontal ui-slider-vertical" )
						.addClass( "ui-slider-" + this.orientation );
					this._refreshValue();
					break;
				case "value":
					this._animateOff = true;
					this._refreshValue();
					this._change( null, 0 );
					this._animateOff = false;
					break;
				case "values":
					this._animateOff = true;
					this._refreshValue();
					for ( i = 0; i < valsLength; i += 1 ) {
						this._change( null, i );
					}
					this._animateOff = false;
					break;
				case "min":
				case "max":
					this._animateOff = true;
					this._refreshValue();
					this._animateOff = false;
					break;
				case "range":
					this._animateOff = true;
					this._refresh();
					this._animateOff = false;
					break;
			}
		},
	
		//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.options.values && this.options.values.length ) {
				// .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) );
		},
	
		_valueMin: function() {
			return this.options.min;
		},
	
		_valueMax: function() {
			return this.options.max;
		},
	
		_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.options.values && this.options.values.length ) {
				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[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: 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[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
				}
			}
		},
	
		_handleEvents: {
			keydown: function( event ) {
				/*jshint maxcomplexity:25*/
				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;
							$( event.target ).addClass( "ui-state-active" );
							allowed = this._start( event, index );
							if ( allowed === false ) {
								return;
							}
						}
						break;
				}
	
				step = this.options.step;
				if ( this.options.values && this.options.values.length ) {
					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()) / numPages ) );
						break;
					case $.ui.keyCode.PAGE_DOWN:
						newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / 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 );
			},
			click: function( event ) {
				event.preventDefault();
			},
			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 );
					$( event.target ).removeClass( "ui-state-active" );
				}
			}
		}
	
	});
	
	}(jQuery));
	
	(function( $ ) {
	
	function modifier( fn ) {
		return function() {
			var previous = this.element.val();
			fn.apply( this, arguments );
			this._refresh();
			if ( previous !== this.element.val() ) {
				this._trigger( "change" );
			}
		};
	}
	
	$.widget( "ui.spinner", {
		version: "1.10.3",
		defaultElement: "<input>",
		widgetEventPrefix: "spin",
		options: {
			culture: null,
			icons: {
				down: "ui-icon-triangle-1-s",
				up: "ui-icon-triangle-1-n"
			},
			incremental: true,
			max: null,
			min: null,
			numberFormat: null,
			page: 10,
			step: 1,
	
			change: null,
			spin: null,
			start: null,
			stop: null
		},
	
		_create: function() {
			// handle string values that need to be parsed
			this._setOption( "max", this.options.max );
			this._setOption( "min", this.options.min );
			this._setOption( "step", this.options.step );
	
			// format the value, but don't constrain
			this._value( this.element.val(), true );
	
			this._draw();
			this._on( this._events );
			this._refresh();
	
			// turning off autocomplete prevents the browser from remembering the
			// value when navigating through history, so we re-enable autocomplete
			// if the page is unloaded before the widget is destroyed. #7790
			this._on( this.window, {
				beforeunload: function() {
					this.element.removeAttr( "autocomplete" );
				}
			});
		},
	
		_getCreateOptions: function() {
			var options = {},
				element = this.element;
	
			$.each( [ "min", "max", "step" ], function( i, option ) {
				var value = element.attr( option );
				if ( value !== undefined && value.length ) {
					options[ option ] = value;
				}
			});
	
			return options;
		},
	
		_events: {
			keydown: function( event ) {
				if ( this._start( event ) && this._keydown( event ) ) {
					event.preventDefault();
				}
			},
			keyup: "_stop",
			focus: function() {
				this.previous = this.element.val();
			},
			blur: function( event ) {
				if ( this.cancelBlur ) {
					delete this.cancelBlur;
					return;
				}
	
				this._stop();
				this._refresh();
				if ( this.previous !== this.element.val() ) {
					this._trigger( "change", event );
				}
			},
			mousewheel: function( event, delta ) {
				if ( !delta ) {
					return;
				}
				if ( !this.spinning && !this._start( event ) ) {
					return false;
				}
	
				this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
				clearTimeout( this.mousewheelTimer );
				this.mousewheelTimer = this._delay(function() {
					if ( this.spinning ) {
						this._stop( event );
					}
				}, 100 );
				event.preventDefault();
			},
			"mousedown .ui-spinner-button": function( event ) {
				var previous;
	
				// We never want the buttons to have focus; whenever the user is
				// interacting with the spinner, the focus should be on the input.
				// If the input is focused then this.previous is properly set from
				// when the input first received focus. If the input is not focused
				// then we need to set this.previous based on the value before spinning.
				previous = this.element[0] === this.document[0].activeElement ?
					this.previous : this.element.val();
				function checkFocus() {
					var isActive = this.element[0] === this.document[0].activeElement;
					if ( !isActive ) {
						this.element.focus();
						this.previous = previous;
						// support: IE
						// IE sets focus asynchronously, so we need to check if focus
						// moved off of the input because the user clicked on the button.
						this._delay(function() {
							this.previous = previous;
						});
					}
				}
	
				// ensure focus is on (or stays on) the text field
				event.preventDefault();
				checkFocus.call( this );
	
				// support: IE
				// IE doesn't prevent moving focus even with event.preventDefault()
				// so we set a flag to know when we should ignore the blur event
				// and check (again) if focus moved off of the input.
				this.cancelBlur = true;
				this._delay(function() {
					delete this.cancelBlur;
					checkFocus.call( this );
				});
	
				if ( this._start( event ) === false ) {
					return;
				}
	
				this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
			},
			"mouseup .ui-spinner-button": "_stop",
			"mouseenter .ui-spinner-button": function( event ) {
				// button will add ui-state-active if mouse was down while mouseleave and kept down
				if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
					return;
				}
	
				if ( this._start( event ) === false ) {
					return false;
				}
				this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
			},
			// TODO: do we really want to consider this a stop?
			// shouldn't we just stop the repeater and wait until mouseup before
			// we trigger the stop event?
			"mouseleave .ui-spinner-button": "_stop"
		},
	
		_draw: function() {
			var uiSpinner = this.uiSpinner = this.element
				.addClass( "ui-spinner-input" )
				.attr( "autocomplete", "off" )
				.wrap( this._uiSpinnerHtml() )
				.parent()
					// add buttons
					.append( this._buttonHtml() );
	
			this.element.attr( "role", "spinbutton" );
	
			// button bindings
			this.buttons = uiSpinner.find( ".ui-spinner-button" )
				.attr( "tabIndex", -1 )
				.button()
				.removeClass( "ui-corner-all" );
	
			// IE 6 doesn't understand height: 50% for the buttons
			// unless the wrapper has an explicit height
			if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
					uiSpinner.height() > 0 ) {
				uiSpinner.height( uiSpinner.height() );
			}
	
			// disable spinner if element was already disabled
			if ( this.options.disabled ) {
				this.disable();
			}
		},
	
		_keydown: function( event ) {
			var options = this.options,
				keyCode = $.ui.keyCode;
	
			switch ( event.keyCode ) {
			case keyCode.UP:
				this._repeat( null, 1, event );
				return true;
			case keyCode.DOWN:
				this._repeat( null, -1, event );
				return true;
			case keyCode.PAGE_UP:
				this._repeat( null, options.page, event );
				return true;
			case keyCode.PAGE_DOWN:
				this._repeat( null, -options.page, event );
				return true;
			}
	
			return false;
		},
	
		_uiSpinnerHtml: function() {
			return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
		},
	
		_buttonHtml: function() {
			return "" +
				"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
					"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
				"</a>" +
				"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
					"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
				"</a>";
		},
	
		_start: function( event ) {
			if ( !this.spinning && this._trigger( "start", event ) === false ) {
				return false;
			}
	
			if ( !this.counter ) {
				this.counter = 1;
			}
			this.spinning = true;
			return true;
		},
	
		_repeat: function( i, steps, event ) {
			i = i || 500;
	
			clearTimeout( this.timer );
			this.timer = this._delay(function() {
				this._repeat( 40, steps, event );
			}, i );
	
			this._spin( steps * this.options.step, event );
		},
	
		_spin: function( step, event ) {
			var value = this.value() || 0;
	
			if ( !this.counter ) {
				this.counter = 1;
			}
	
			value = this._adjustValue( value + step * this._increment( this.counter ) );
	
			if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
				this._value( value );
				this.counter++;
			}
		},
	
		_increment: function( i ) {
			var incremental = this.options.incremental;
	
			if ( incremental ) {
				return $.isFunction( incremental ) ?
					incremental( i ) :
					Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
			}
	
			return 1;
		},
	
		_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;
		},
	
		_adjustValue: function( value ) {
			var base, aboveMin,
				options = this.options;
	
			// make sure we're at a valid step
			// - find out where we are relative to the base (min or 0)
			base = options.min !== null ? options.min : 0;
			aboveMin = value - base;
			// - round to the nearest step
			aboveMin = Math.round(aboveMin / options.step) * options.step;
			// - rounding is based on 0, so adjust back to our base
			value = base + aboveMin;
	
			// fix precision from bad JS floating point math
			value = parseFloat( value.toFixed( this._precision() ) );
	
			// clamp the value
			if ( options.max !== null && value > options.max) {
				return options.max;
			}
			if ( options.min !== null && value < options.min ) {
				return options.min;
			}
	
			return value;
		},
	
		_stop: function( event ) {
			if ( !this.spinning ) {
				return;
			}
	
			clearTimeout( this.timer );
			clearTimeout( this.mousewheelTimer );
			this.counter = 0;
			this.spinning = false;
			this._trigger( "stop", event );
		},
	
		_setOption: function( key, value ) {
			if ( key === "culture" || key === "numberFormat" ) {
				var prevValue = this._parse( this.element.val() );
				this.options[ key ] = value;
				this.element.val( this._format( prevValue ) );
				return;
			}
	
			if ( key === "max" || key === "min" || key === "step" ) {
				if ( typeof value === "string" ) {
					value = this._parse( value );
				}
			}
			if ( key === "icons" ) {
				this.buttons.first().find( ".ui-icon" )
					.removeClass( this.options.icons.up )
					.addClass( value.up );
				this.buttons.last().find( ".ui-icon" )
					.removeClass( this.options.icons.down )
					.addClass( value.down );
			}
	
			this._super( key, value );
	
			if ( key === "disabled" ) {
				if ( value ) {
					this.element.prop( "disabled", true );
					this.buttons.button( "disable" );
				} else {
					this.element.prop( "disabled", false );
					this.buttons.button( "enable" );
				}
			}
		},
	
		_setOptions: modifier(function( options ) {
			this._super( options );
			this._value( this.element.val() );
		}),
	
		_parse: function( val ) {
			if ( typeof val === "string" && val !== "" ) {
				val = window.Globalize && this.options.numberFormat ?
					Globalize.parseFloat( val, 10, this.options.culture ) : +val;
			}
			return val === "" || isNaN( val ) ? null : val;
		},
	
		_format: function( value ) {
			if ( value === "" ) {
				return "";
			}
			return window.Globalize && this.options.numberFormat ?
				Globalize.format( value, this.options.numberFormat, this.options.culture ) :
				value;
		},
	
		_refresh: function() {
			this.element.attr({
				"aria-valuemin": this.options.min,
				"aria-valuemax": this.options.max,
				// TODO: what should we do with values that can't be parsed?
				"aria-valuenow": this._parse( this.element.val() )
			});
		},
	
		// update the value without triggering change
		_value: function( value, allowAny ) {
			var parsed;
			if ( value !== "" ) {
				parsed = this._parse( value );
				if ( parsed !== null ) {
					if ( !allowAny ) {
						parsed = this._adjustValue( parsed );
					}
					value = this._format( parsed );
				}
			}
			this.element.val( value );
			this._refresh();
		},
	
		_destroy: function() {
			this.element
				.removeClass( "ui-spinner-input" )
				.prop( "disabled", false )
				.removeAttr( "autocomplete" )
				.removeAttr( "role" )
				.removeAttr( "aria-valuemin" )
				.removeAttr( "aria-valuemax" )
				.removeAttr( "aria-valuenow" );
			this.uiSpinner.replaceWith( this.element );
		},
	
		stepUp: modifier(function( steps ) {
			this._stepUp( steps );
		}),
		_stepUp: function( steps ) {
			if ( this._start() ) {
				this._spin( (steps || 1) * this.options.step );
				this._stop();
			}
		},
	
		stepDown: modifier(function( steps ) {
			this._stepDown( steps );
		}),
		_stepDown: function( steps ) {
			if ( this._start() ) {
				this._spin( (steps || 1) * -this.options.step );
				this._stop();
			}
		},
	
		pageUp: modifier(function( pages ) {
			this._stepUp( (pages || 1) * this.options.page );
		}),
	
		pageDown: modifier(function( pages ) {
			this._stepDown( (pages || 1) * this.options.page );
		}),
	
		value: function( newVal ) {
			if ( !arguments.length ) {
				return this._parse( this.element.val() );
			}
			modifier( this._value ).call( this, newVal );
		},
	
		widget: function() {
			return this.uiSpinner;
		}
	});
	
	}( jQuery ) );
	
	(function( $, undefined ) {
	
	var tabId = 0,
		rhash = /#.*$/;
	
	function getNextTabId() {
		return ++tabId;
	}
	
	function isLocal( anchor ) {
		return anchor.hash.length > 1 &&
			decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
				decodeURIComponent( location.href.replace( rhash, "" ) );
	}
	
	$.widget( "ui.tabs", {
		version: "1.10.3",
		delay: 300,
		options: {
			active: null,
			collapsible: false,
			event: "click",
			heightStyle: "content",
			hide: null,
			show: null,
	
			// callbacks
			activate: null,
			beforeActivate: null,
			beforeLoad: null,
			load: null
		},
	
		_create: function() {
			var that = this,
				options = this.options;
	
			this.running = false;
	
			this.element
				.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
				.toggleClass( "ui-tabs-collapsible", options.collapsible )
				// Prevent users from focusing disabled tabs via click
				.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
					if ( $( this ).is( ".ui-state-disabled" ) ) {
						event.preventDefault();
					}
				})
				// support: IE <9
				// Preventing the default action in mousedown doesn't prevent IE
				// from focusing the element, so if the anchor gets focused, blur.
				// We don't have to worry about focusing the previously focused
				// element since clicking on a non-focusable element should focus
				// the body anyway.
				.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
					if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
						this.blur();
					}
				});
	
			this._processTabs();
			options.active = this._initialActive();
	
			// Take disabling tabs via class attribute from HTML
			// into account and update option properly.
			if ( $.isArray( options.disabled ) ) {
				options.disabled = $.unique( options.disabled.concat(
					$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
						return that.tabs.index( li );
					})
				) ).sort();
			}
	
			// check for length avoids error when initializing empty list
			if ( this.options.active !== false && this.anchors.length ) {
				this.active = this._findActive( options.active );
			} else {
				this.active = $();
			}
	
			this._refresh();
	
			if ( this.active.length ) {
				this.load( options.active );
			}
		},
	
		_initialActive: function() {
			var active = this.options.active,
				collapsible = this.options.collapsible,
				locationHash = location.hash.substring( 1 );
	
			if ( active === null ) {
				// check the fragment identifier in the URL
				if ( locationHash ) {
					this.tabs.each(function( i, tab ) {
						if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
							active = i;
							return false;
						}
					});
				}
	
				// check for a tab marked active via a class
				if ( active === null ) {
					active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
				}
	
				// no active tab, set to false
				if ( active === null || active === -1 ) {
					active = this.tabs.length ? 0 : false;
				}
			}
	
			// handle numbers: negative, out of range
			if ( active !== false ) {
				active = this.tabs.index( this.tabs.eq( active ) );
				if ( active === -1 ) {
					active = collapsible ? false : 0;
				}
			}
	
			// don't allow collapsible: false and active: false
			if ( !collapsible && active === false && this.anchors.length ) {
				active = 0;
			}
	
			return active;
		},
	
		_getCreateEventData: function() {
			return {
				tab: this.active,
				panel: !this.active.length ? $() : this._getPanelForTab( this.active )
			};
		},
	
		_tabKeydown: function( event ) {
			/*jshint maxcomplexity:15*/
			var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
				selectedIndex = this.tabs.index( focusedTab ),
				goingForward = true;
	
			if ( this._handlePageNav( event ) ) {
				return;
			}
	
			switch ( event.keyCode ) {
				case $.ui.keyCode.RIGHT:
				case $.ui.keyCode.DOWN:
					selectedIndex++;
					break;
				case $.ui.keyCode.UP:
				case $.ui.keyCode.LEFT:
					goingForward = false;
					selectedIndex--;
					break;
				case $.ui.keyCode.END:
					selectedIndex = this.anchors.length - 1;
					break;
				case $.ui.keyCode.HOME:
					selectedIndex = 0;
					break;
				case $.ui.keyCode.SPACE:
					// Activate only, no collapsing
					event.preventDefault();
					clearTimeout( this.activating );
					this._activate( selectedIndex );
					return;
				case $.ui.keyCode.ENTER:
					// Toggle (cancel delayed activation, allow collapsing)
					event.preventDefault();
					clearTimeout( this.activating );
					// Determine if we should collapse or activate
					this._activate( selectedIndex === this.options.active ? false : selectedIndex );
					return;
				default:
					return;
			}
	
			// Focus the appropriate tab, based on which key was pressed
			event.preventDefault();
			clearTimeout( this.activating );
			selectedIndex = this._focusNextTab( selectedIndex, goingForward );
	
			// Navigating with control key will prevent automatic activation
			if ( !event.ctrlKey ) {
				// Update aria-selected immediately so that AT think the tab is already selected.
				// Otherwise AT may confuse the user by stating that they need to activate the tab,
				// but the tab will already be activated by the time the announcement finishes.
				focusedTab.attr( "aria-selected", "false" );
				this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
	
				this.activating = this._delay(function() {
					this.option( "active", selectedIndex );
				}, this.delay );
			}
		},
	
		_panelKeydown: function( event ) {
			if ( this._handlePageNav( event ) ) {
				return;
			}
	
			// Ctrl+up moves focus to the current tab
			if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
				event.preventDefault();
				this.active.focus();
			}
		},
	
		// Alt+page up/down moves focus to the previous/next tab (and activates)
		_handlePageNav: function( event ) {
			if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
				this._activate( this._focusNextTab( this.options.active - 1, false ) );
				return true;
			}
			if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
				this._activate( this._focusNextTab( this.options.active + 1, true ) );
				return true;
			}
		},
	
		_findNextTab: function( index, goingForward ) {
			var lastTabIndex = this.tabs.length - 1;
	
			function constrain() {
				if ( index > lastTabIndex ) {
					index = 0;
				}
				if ( index < 0 ) {
					index = lastTabIndex;
				}
				return index;
			}
	
			while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
				index = goingForward ? index + 1 : index - 1;
			}
	
			return index;
		},
	
		_focusNextTab: function( index, goingForward ) {
			index = this._findNextTab( index, goingForward );
			this.tabs.eq( index ).focus();
			return index;
		},
	
		_setOption: function( key, value ) {
			if ( key === "active" ) {
				// _activate() will handle invalid values and update this.options
				this._activate( value );
				return;
			}
	
			if ( key === "disabled" ) {
				// don't use the widget factory's disabled handling
				this._setupDisabled( value );
				return;
			}
	
			this._super( key, value);
	
			if ( key === "collapsible" ) {
				this.element.toggleClass( "ui-tabs-collapsible", value );
				// Setting collapsible: false while collapsed; open first panel
				if ( !value && this.options.active === false ) {
					this._activate( 0 );
				}
			}
	
			if ( key === "event" ) {
				this._setupEvents( value );
			}
	
			if ( key === "heightStyle" ) {
				this._setupHeightStyle( value );
			}
		},
	
		_tabId: function( tab ) {
			return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
		},
	
		_sanitizeSelector: function( hash ) {
			return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
		},
	
		refresh: function() {
			var options = this.options,
				lis = this.tablist.children( ":has(a[href])" );
	
			// get disabled tabs from class attribute from HTML
			// this will get converted to a boolean if needed in _refresh()
			options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
				return lis.index( tab );
			});
	
			this._processTabs();
	
			// was collapsed or no tabs
			if ( options.active === false || !this.anchors.length ) {
				options.active = false;
				this.active = $();
			// was active, but active tab is gone
			} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
				// all remaining tabs are disabled
				if ( this.tabs.length === options.disabled.length ) {
					options.active = false;
					this.active = $();
				// activate previous tab
				} else {
					this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
				}
			// was active, active tab still exists
			} else {
				// make sure active index is correct
				options.active = this.tabs.index( this.active );
			}
	
			this._refresh();
		},
	
		_refresh: function() {
			this._setupDisabled( this.options.disabled );
			this._setupEvents( this.options.event );
			this._setupHeightStyle( this.options.heightStyle );
	
			this.tabs.not( this.active ).attr({
				"aria-selected": "false",
				tabIndex: -1
			});
			this.panels.not( this._getPanelForTab( this.active ) )
				.hide()
				.attr({
					"aria-expanded": "false",
					"aria-hidden": "true"
				});
	
			// Make sure one tab is in the tab order
			if ( !this.active.length ) {
				this.tabs.eq( 0 ).attr( "tabIndex", 0 );
			} else {
				this.active
					.addClass( "ui-tabs-active ui-state-active" )
					.attr({
						"aria-selected": "true",
						tabIndex: 0
					});
				this._getPanelForTab( this.active )
					.show()
					.attr({
						"aria-expanded": "true",
						"aria-hidden": "false"
					});
			}
		},
	
		_processTabs: function() {
			var that = this;
	
			this.tablist = this._getList()
				.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
				.attr( "role", "tablist" );
	
			this.tabs = this.tablist.find( "> li:has(a[href])" )
				.addClass( "ui-state-default ui-corner-top" )
				.attr({
					role: "tab",
					tabIndex: -1
				});
	
			this.anchors = this.tabs.map(function() {
					return $( "a", this )[ 0 ];
				})
				.addClass( "ui-tabs-anchor" )
				.attr({
					role: "presentation",
					tabIndex: -1
				});
	
			this.panels = $();
	
			this.anchors.each(function( i, anchor ) {
				var selector, panel, panelId,
					anchorId = $( anchor ).uniqueId().attr( "id" ),
					tab = $( anchor ).closest( "li" ),
					originalAriaControls = tab.attr( "aria-controls" );
	
				// inline tab
				if ( isLocal( anchor ) ) {
					selector = anchor.hash;
					panel = that.element.find( that._sanitizeSelector( selector ) );
				// remote tab
				} else {
					panelId = that._tabId( tab );
					selector = "#" + panelId;
					panel = that.element.find( selector );
					if ( !panel.length ) {
						panel = that._createPanel( panelId );
						panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
					}
					panel.attr( "aria-live", "polite" );
				}
	
				if ( panel.length) {
					that.panels = that.panels.add( panel );
				}
				if ( originalAriaControls ) {
					tab.data( "ui-tabs-aria-controls", originalAriaControls );
				}
				tab.attr({
					"aria-controls": selector.substring( 1 ),
					"aria-labelledby": anchorId
				});
				panel.attr( "aria-labelledby", anchorId );
			});
	
			this.panels
				.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
				.attr( "role", "tabpanel" );
		},
	
		// allow overriding how to find the list for rare usage scenarios (#7715)
		_getList: function() {
			return this.element.find( "ol,ul" ).eq( 0 );
		},
	
		_createPanel: function( id ) {
			return $( "<div>" )
				.attr( "id", id )
				.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
				.data( "ui-tabs-destroy", true );
		},
	
		_setupDisabled: function( disabled ) {
			if ( $.isArray( disabled ) ) {
				if ( !disabled.length ) {
					disabled = false;
				} else if ( disabled.length === this.anchors.length ) {
					disabled = true;
				}
			}
	
			// disable tabs
			for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
				if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
					$( li )
						.addClass( "ui-state-disabled" )
						.attr( "aria-disabled", "true" );
				} else {
					$( li )
						.removeClass( "ui-state-disabled" )
						.removeAttr( "aria-disabled" );
				}
			}
	
			this.options.disabled = disabled;
		},
	
		_setupEvents: function( event ) {
			var events = {
				click: function( event ) {
					event.preventDefault();
				}
			};
			if ( event ) {
				$.each( event.split(" "), function( index, eventName ) {
					events[ eventName ] = "_eventHandler";
				});
			}
	
			this._off( this.anchors.add( this.tabs ).add( this.panels ) );
			this._on( this.anchors, events );
			this._on( this.tabs, { keydown: "_tabKeydown" } );
			this._on( this.panels, { keydown: "_panelKeydown" } );
	
			this._focusable( this.tabs );
			this._hoverable( this.tabs );
		},
	
		_setupHeightStyle: function( heightStyle ) {
			var maxHeight,
				parent = this.element.parent();
	
			if ( heightStyle === "fill" ) {
				maxHeight = parent.height();
				maxHeight -= this.element.outerHeight() - this.element.height();
	
				this.element.siblings( ":visible" ).each(function() {
					var elem = $( this ),
						position = elem.css( "position" );
	
					if ( position === "absolute" || position === "fixed" ) {
						return;
					}
					maxHeight -= elem.outerHeight( true );
				});
	
				this.element.children().not( this.panels ).each(function() {
					maxHeight -= $( this ).outerHeight( true );
				});
	
				this.panels.each(function() {
					$( this ).height( Math.max( 0, maxHeight -
						$( this ).innerHeight() + $( this ).height() ) );
				})
				.css( "overflow", "auto" );
			} else if ( heightStyle === "auto" ) {
				maxHeight = 0;
				this.panels.each(function() {
					maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
				}).height( maxHeight );
			}
		},
	
		_eventHandler: function( event ) {
			var options = this.options,
				active = this.active,
				anchor = $( event.currentTarget ),
				tab = anchor.closest( "li" ),
				clickedIsActive = tab[ 0 ] === active[ 0 ],
				collapsing = clickedIsActive && options.collapsible,
				toShow = collapsing ? $() : this._getPanelForTab( tab ),
				toHide = !active.length ? $() : this._getPanelForTab( active ),
				eventData = {
					oldTab: active,
					oldPanel: toHide,
					newTab: collapsing ? $() : tab,
					newPanel: toShow
				};
	
			event.preventDefault();
	
			if ( tab.hasClass( "ui-state-disabled" ) ||
					// tab is already loading
					tab.hasClass( "ui-tabs-loading" ) ||
					// can't switch durning an animation
					this.running ||
					// click on active header, but not collapsible
					( clickedIsActive && !options.collapsible ) ||
					// allow canceling activation
					( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
				return;
			}
	
			options.active = collapsing ? false : this.tabs.index( tab );
	
			this.active = clickedIsActive ? $() : tab;
			if ( this.xhr ) {
				this.xhr.abort();
			}
	
			if ( !toHide.length && !toShow.length ) {
				$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
			}
	
			if ( toShow.length ) {
				this.load( this.tabs.index( tab ), event );
			}
			this._toggle( event, eventData );
		},
	
		// handles show/hide for selecting tabs
		_toggle: function( event, eventData ) {
			var that = this,
				toShow = eventData.newPanel,
				toHide = eventData.oldPanel;
	
			this.running = true;
	
			function complete() {
				that.running = false;
				that._trigger( "activate", event, eventData );
			}
	
			function show() {
				eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
	
				if ( toShow.length && that.options.show ) {
					that._show( toShow, that.options.show, complete );
				} else {
					toShow.show();
					complete();
				}
			}
	
			// start out by hiding, then showing, then completing
			if ( toHide.length && this.options.hide ) {
				this._hide( toHide, this.options.hide, function() {
					eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
					show();
				});
			} else {
				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
				toHide.hide();
				show();
			}
	
			toHide.attr({
				"aria-expanded": "false",
				"aria-hidden": "true"
			});
			eventData.oldTab.attr( "aria-selected", "false" );
			// If we're switching tabs, remove the old tab from the tab order.
			// If we're opening from collapsed state, remove the previous tab from the tab order.
			// If we're collapsing, then keep the collapsing tab in the tab order.
			if ( toShow.length && toHide.length ) {
				eventData.oldTab.attr( "tabIndex", -1 );
			} else if ( toShow.length ) {
				this.tabs.filter(function() {
					return $( this ).attr( "tabIndex" ) === 0;
				})
				.attr( "tabIndex", -1 );
			}
	
			toShow.attr({
				"aria-expanded": "true",
				"aria-hidden": "false"
			});
			eventData.newTab.attr({
				"aria-selected": "true",
				tabIndex: 0
			});
		},
	
		_activate: function( index ) {
			var anchor,
				active = this._findActive( index );
	
			// trying to activate the already active panel
			if ( active[ 0 ] === this.active[ 0 ] ) {
				return;
			}
	
			// trying to collapse, simulate a click on the current active header
			if ( !active.length ) {
				active = this.active;
			}
	
			anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
			this._eventHandler({
				target: anchor,
				currentTarget: anchor,
				preventDefault: $.noop
			});
		},
	
		_findActive: function( index ) {
			return index === false ? $() : this.tabs.eq( index );
		},
	
		_getIndex: function( index ) {
			// meta-function to give users option to provide a href string instead of a numerical index.
			if ( typeof index === "string" ) {
				index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
			}
	
			return index;
		},
	
		_destroy: function() {
			if ( this.xhr ) {
				this.xhr.abort();
			}
	
			this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
	
			this.tablist
				.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
				.removeAttr( "role" );
	
			this.anchors
				.removeClass( "ui-tabs-anchor" )
				.removeAttr( "role" )
				.removeAttr( "tabIndex" )
				.removeUniqueId();
	
			this.tabs.add( this.panels ).each(function() {
				if ( $.data( this, "ui-tabs-destroy" ) ) {
					$( this ).remove();
				} else {
					$( this )
						.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
							"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
						.removeAttr( "tabIndex" )
						.removeAttr( "aria-live" )
						.removeAttr( "aria-busy" )
						.removeAttr( "aria-selected" )
						.removeAttr( "aria-labelledby" )
						.removeAttr( "aria-hidden" )
						.removeAttr( "aria-expanded" )
						.removeAttr( "role" );
				}
			});
	
			this.tabs.each(function() {
				var li = $( this ),
					prev = li.data( "ui-tabs-aria-controls" );
				if ( prev ) {
					li
						.attr( "aria-controls", prev )
						.removeData( "ui-tabs-aria-controls" );
				} else {
					li.removeAttr( "aria-controls" );
				}
			});
	
			this.panels.show();
	
			if ( this.options.heightStyle !== "content" ) {
				this.panels.css( "height", "" );
			}
		},
	
		enable: function( index ) {
			var disabled = this.options.disabled;
			if ( disabled === false ) {
				return;
			}
	
			if ( index === undefined ) {
				disabled = false;
			} else {
				index = this._getIndex( index );
				if ( $.isArray( disabled ) ) {
					disabled = $.map( disabled, function( num ) {
						return num !== index ? num : null;
					});
				} else {
					disabled = $.map( this.tabs, function( li, num ) {
						return num !== index ? num : null;
					});
				}
			}
			this._setupDisabled( disabled );
		},
	
		disable: function( index ) {
			var disabled = this.options.disabled;
			if ( disabled === true ) {
				return;
			}
	
			if ( index === undefined ) {
				disabled = true;
			} else {
				index = this._getIndex( index );
				if ( $.inArray( index, disabled ) !== -1 ) {
					return;
				}
				if ( $.isArray( disabled ) ) {
					disabled = $.merge( [ index ], disabled ).sort();
				} else {
					disabled = [ index ];
				}
			}
			this._setupDisabled( disabled );
		},
	
		load: function( index, event ) {
			index = this._getIndex( index );
			var that = this,
				tab = this.tabs.eq( index ),
				anchor = tab.find( ".ui-tabs-anchor" ),
				panel = this._getPanelForTab( tab ),
				eventData = {
					tab: tab,
					panel: panel
				};
	
			// not remote
			if ( isLocal( anchor[ 0 ] ) ) {
				return;
			}
	
			this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
	
			// support: jQuery <1.8
			// jQuery <1.8 returns false if the request is canceled in beforeSend,
			// but as of 1.8, $.ajax() always returns a jqXHR object.
			if ( this.xhr && this.xhr.statusText !== "canceled" ) {
				tab.addClass( "ui-tabs-loading" );
				panel.attr( "aria-busy", "true" );
	
				this.xhr
					.success(function( response ) {
						// support: jQuery <1.8
						// http://bugs.jquery.com/ticket/11778
						setTimeout(function() {
							panel.html( response );
							that._trigger( "load", event, eventData );
						}, 1 );
					})
					.complete(function( jqXHR, status ) {
						// support: jQuery <1.8
						// http://bugs.jquery.com/ticket/11778
						setTimeout(function() {
							if ( status === "abort" ) {
								that.panels.stop( false, true );
							}
	
							tab.removeClass( "ui-tabs-loading" );
							panel.removeAttr( "aria-busy" );
	
							if ( jqXHR === that.xhr ) {
								delete that.xhr;
							}
						}, 1 );
					});
			}
		},
	
		_ajaxSettings: function( anchor, event, eventData ) {
			var that = this;
			return {
				url: anchor.attr( "href" ),
				beforeSend: function( jqXHR, settings ) {
					return that._trigger( "beforeLoad", event,
						$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
				}
			};
		},
	
		_getPanelForTab: function( tab ) {
			var id = $( tab ).attr( "aria-controls" );
			return this.element.find( this._sanitizeSelector( "#" + id ) );
		}
	});
	
	})( jQuery );
	
	(function( $ ) {
	
	var increments = 0;
	
	function addDescribedBy( elem, id ) {
		var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
		describedby.push( id );
		elem
			.data( "ui-tooltip-id", id )
			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
	}
	
	function removeDescribedBy( elem ) {
		var id = elem.data( "ui-tooltip-id" ),
			describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
			index = $.inArray( id, describedby );
		if ( index !== -1 ) {
			describedby.splice( index, 1 );
		}
	
		elem.removeData( "ui-tooltip-id" );
		describedby = $.trim( describedby.join( " " ) );
		if ( describedby ) {
			elem.attr( "aria-describedby", describedby );
		} else {
			elem.removeAttr( "aria-describedby" );
		}
	}
	
	$.widget( "ui.tooltip", {
		version: "1.10.3",
		options: {
			content: function() {
				// support: IE<9, Opera in jQuery <1.7
				// .text() can't accept undefined, so coerce to a string
				var title = $( this ).attr( "title" ) || "";
				// Escape title, since we're going from an attribute to raw HTML
				return $( "<a>" ).text( title ).html();
			},
			hide: true,
			// Disabled elements have inconsistent behavior across browsers (#8661)
			items: "[title]:not([disabled])",
			position: {
				my: "left top+15",
				at: "left bottom",
				collision: "flipfit flip"
			},
			show: true,
			tooltipClass: null,
			track: false,
	
			// callbacks
			close: null,
			open: null
		},
	
		_create: function() {
			this._on({
				mouseover: "open",
				focusin: "open"
			});
	
			// IDs of generated tooltips, needed for destroy
			this.tooltips = {};
			// IDs of parent tooltips where we removed the title attribute
			this.parents = {};
	
			if ( this.options.disabled ) {
				this._disable();
			}
		},
	
		_setOption: function( key, value ) {
			var that = this;
	
			if ( key === "disabled" ) {
				this[ value ? "_disable" : "_enable" ]();
				this.options[ key ] = value;
				// disable element style changes
				return;
			}
	
			this._super( key, value );
	
			if ( key === "content" ) {
				$.each( this.tooltips, function( id, element ) {
					that._updateContent( element );
				});
			}
		},
	
		_disable: function() {
			var that = this;
	
			// close open tooltips
			$.each( this.tooltips, function( id, element ) {
				var event = $.Event( "blur" );
				event.target = event.currentTarget = element[0];
				that.close( event, true );
			});
	
			// remove title attributes to prevent native tooltips
			this.element.find( this.options.items ).addBack().each(function() {
				var element = $( this );
				if ( element.is( "[title]" ) ) {
					element
						.data( "ui-tooltip-title", element.attr( "title" ) )
						.attr( "title", "" );
				}
			});
		},
	
		_enable: function() {
			// restore title attributes
			this.element.find( this.options.items ).addBack().each(function() {
				var element = $( this );
				if ( element.data( "ui-tooltip-title" ) ) {
					element.attr( "title", element.data( "ui-tooltip-title" ) );
				}
			});
		},
	
		open: function( event ) {
			var that = this,
				target = $( event ? event.target : this.element )
					// we need closest here due to mouseover bubbling,
					// but always pointing at the same event target
					.closest( this.options.items );
	
			// No element to show a tooltip for or the tooltip is already open
			if ( !target.length || target.data( "ui-tooltip-id" ) ) {
				return;
			}
	
			if ( target.attr( "title" ) ) {
				target.data( "ui-tooltip-title", target.attr( "title" ) );
			}
	
			target.data( "ui-tooltip-open", true );
	
			// kill parent tooltips, custom or native, for hover
			if ( event && event.type === "mouseover" ) {
				target.parents().each(function() {
					var parent = $( this ),
						blurEvent;
					if ( parent.data( "ui-tooltip-open" ) ) {
						blurEvent = $.Event( "blur" );
						blurEvent.target = blurEvent.currentTarget = this;
						that.close( blurEvent, true );
					}
					if ( parent.attr( "title" ) ) {
						parent.uniqueId();
						that.parents[ this.id ] = {
							element: this,
							title: parent.attr( "title" )
						};
						parent.attr( "title", "" );
					}
				});
			}
	
			this._updateContent( target, event );
		},
	
		_updateContent: function( target, event ) {
			var content,
				contentOption = this.options.content,
				that = this,
				eventType = event ? event.type : null;
	
			if ( typeof contentOption === "string" ) {
				return this._open( event, target, contentOption );
			}
	
			content = contentOption.call( target[0], function( response ) {
				// ignore async response if tooltip was closed already
				if ( !target.data( "ui-tooltip-open" ) ) {
					return;
				}
				// IE may instantly serve a cached response for ajax requests
				// delay this call to _open so the other call to _open runs first
				that._delay(function() {
					// jQuery creates a special event for focusin when it doesn't
					// exist natively. To improve performance, the native event
					// object is reused and the type is changed. Therefore, we can't
					// rely on the type being correct after the event finished
					// bubbling, so we set it back to the previous value. (#8740)
					if ( event ) {
						event.type = eventType;
					}
					this._open( event, target, response );
				});
			});
			if ( content ) {
				this._open( event, target, content );
			}
		},
	
		_open: function( event, target, content ) {
			var tooltip, events, delayedShow,
				positionOption = $.extend( {}, this.options.position );
	
			if ( !content ) {
				return;
			}
	
			// Content can be updated multiple times. If the tooltip already
			// exists, then just update the content and bail.
			tooltip = this._find( target );
			if ( tooltip.length ) {
				tooltip.find( ".ui-tooltip-content" ).html( content );
				return;
			}
	
			// if we have a title, clear it to prevent the native tooltip
			// we have to check first to avoid defining a title if none exists
			// (we don't want to cause an element to start matching [title])
			//
			// We use removeAttr only for key events, to allow IE to export the correct
			// accessible attributes. For mouse events, set to empty string to avoid
			// native tooltip showing up (happens only when removing inside mouseover).
			if ( target.is( "[title]" ) ) {
				if ( event && event.type === "mouseover" ) {
					target.attr( "title", "" );
				} else {
					target.removeAttr( "title" );
				}
			}
	
			tooltip = this._tooltip( target );
			addDescribedBy( target, tooltip.attr( "id" ) );
			tooltip.find( ".ui-tooltip-content" ).html( content );
	
			function position( event ) {
				positionOption.of = event;
				if ( tooltip.is( ":hidden" ) ) {
					return;
				}
				tooltip.position( positionOption );
			}
			if ( this.options.track && event && /^mouse/.test( event.type ) ) {
				this._on( this.document, {
					mousemove: position
				});
				// trigger once to override element-relative positioning
				position( event );
			} else {
				tooltip.position( $.extend({
					of: target
				}, this.options.position ) );
			}
	
			tooltip.hide();
	
			this._show( tooltip, this.options.show );
			// Handle tracking tooltips that are shown with a delay (#8644). As soon
			// as the tooltip is visible, position the tooltip using the most recent
			// event.
			if ( this.options.show && this.options.show.delay ) {
				delayedShow = this.delayedShow = setInterval(function() {
					if ( tooltip.is( ":visible" ) ) {
						position( positionOption.of );
						clearInterval( delayedShow );
					}
				}, $.fx.interval );
			}
	
			this._trigger( "open", event, { tooltip: tooltip } );
	
			events = {
				keyup: function( event ) {
					if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
						var fakeEvent = $.Event(event);
						fakeEvent.currentTarget = target[0];
						this.close( fakeEvent, true );
					}
				},
				remove: function() {
					this._removeTooltip( tooltip );
				}
			};
			if ( !event || event.type === "mouseover" ) {
				events.mouseleave = "close";
			}
			if ( !event || event.type === "focusin" ) {
				events.focusout = "close";
			}
			this._on( true, target, events );
		},
	
		close: function( event ) {
			var that = this,
				target = $( event ? event.currentTarget : this.element ),
				tooltip = this._find( target );
	
			// disabling closes the tooltip, so we need to track when we're closing
			// to avoid an infinite loop in case the tooltip becomes disabled on close
			if ( this.closing ) {
				return;
			}
	
			// Clear the interval for delayed tracking tooltips
			clearInterval( this.delayedShow );
	
			// only set title if we had one before (see comment in _open())
			if ( target.data( "ui-tooltip-title" ) ) {
				target.attr( "title", target.data( "ui-tooltip-title" ) );
			}
	
			removeDescribedBy( target );
	
			tooltip.stop( true );
			this._hide( tooltip, this.options.hide, function() {
				that._removeTooltip( $( this ) );
			});
	
			target.removeData( "ui-tooltip-open" );
			this._off( target, "mouseleave focusout keyup" );
			// Remove 'remove' binding only on delegated targets
			if ( target[0] !== this.element[0] ) {
				this._off( target, "remove" );
			}
			this._off( this.document, "mousemove" );
	
			if ( event && event.type === "mouseleave" ) {
				$.each( this.parents, function( id, parent ) {
					$( parent.element ).attr( "title", parent.title );
					delete that.parents[ id ];
				});
			}
	
			this.closing = true;
			this._trigger( "close", event, { tooltip: tooltip } );
			this.closing = false;
		},
	
		_tooltip: function( element ) {
			var id = "ui-tooltip-" + increments++,
				tooltip = $( "<div>" )
					.attr({
						id: id,
						role: "tooltip"
					})
					.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
						( this.options.tooltipClass || "" ) );
			$( "<div>" )
				.addClass( "ui-tooltip-content" )
				.appendTo( tooltip );
			tooltip.appendTo( this.document[0].body );
			this.tooltips[ id ] = element;
			return tooltip;
		},
	
		_find: function( target ) {
			var id = target.data( "ui-tooltip-id" );
			return id ? $( "#" + id ) : $();
		},
	
		_removeTooltip: function( tooltip ) {
			tooltip.remove();
			delete this.tooltips[ tooltip.attr( "id" ) ];
		},
	
		_destroy: function() {
			var that = this;
	
			// close open tooltips
			$.each( this.tooltips, function( id, element ) {
				// Delegate to close method to handle common cleanup
				var event = $.Event( "blur" );
				event.target = event.currentTarget = element[0];
				that.close( event, true );
	
				// Remove immediately; destroying an open tooltip doesn't use the
				// hide animation
				$( "#" + id ).remove();
	
				// Restore the title
				if ( element.data( "ui-tooltip-title" ) ) {
					element.attr( "title", element.data( "ui-tooltip-title" ) );
					element.removeData( "ui-tooltip-title" );
				}
			});
		}
	});
	
	}( jQuery ) );


/***/ },
/* 446 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var widget = __webpack_require__(436);
	var _ = __webpack_require__(429);
	
	var ImageModel = widget.DOMWidgetModel.extend({
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        _model_name: 'ImageModel',
	        _view_name: 'ImageView',
	        format: 'png',
	        width: '',
	        height: '',
	        _b64value: ''
	    })
	});
	
	var ImageView = widget.DOMWidgetView.extend({
	    initialize: function() {
	        /**
	         * Called when view is instantiated.
	         */
	        this.setElement(document.createElement('img'));
	        ImageView.__super__.initialize.apply(this, arguments);
	    },
	
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.className = 'jupyter-widgets widget-image';
	        this.update(); // Set defaults.
	    },
	
	    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 ImageView.__super__.update.apply(this);
	    }
	});
	
	module.exports = {
	    ImageView: ImageView,
	    ImageModel: ImageModel
	};


/***/ },
/* 447 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var widget = __webpack_require__(436);
	var _ = __webpack_require__(429);
	
	var ColorPickerModel = widget.DOMWidgetModel.extend({
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        value: 'black',
	        description: '',
	        concise: false,
	        _model_name: 'ColorPickerModel',
	        _view_name: 'ColorPickerView'
	    })
	});
	
	var ColorPickerView = widget.DOMWidgetView.extend({
	    render: function() {
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-hbox');
	        this.el.classList.add('widget-colorpicker');
	
	        this.label = document.createElement('div');
	        this.label.classList.add('widget-label');
	        this.el.appendChild(this.label);
	
	        this.color_container = document.createElement('div');
	        this.color_container.className = 'widget-hbox';
	        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);
	        this.listenTo(this.model, 'change:description', this._update_description, this);
	        this.listenTo(this.model, 'change:concise', this._update_concise, this);
	
	        this._update_concise();
	        this._update_value();
	        this._update_description();
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'change [type="color"]': '_picker_change',
	        'change [type="text"]': '_text_change'
	    },
	
	    _update_value: function() {
	        var value = this.model.get('value');
	        this.colorpicker.value = color2hex(value);
	        this.textbox.value = value;
	    },
	
	    _update_description: function() {
	        var description = this.model.get('description');
	        if (description.length === 0) {
	            this.label.style.display = 'none';
	            this.color_container.style['justify-content'] = 'auto';
	        } else {
	            this.typeset(this.label, description);
	            this.color_container.style['justify-content'] = 'flex-end';
	            this.label.style.display = '';
	        }
	    },
	
	    _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 = '';
	        }
	    },
	
	    _picker_change: function() {
	        this.model.set('value', this.colorpicker.value);
	        this.touch();
	    },
	
	    _text_change: function() {
	        var value = this._validate_color(
	            this.textbox.value,
	            this.model.get('value')
	        );
	        this.model.set('value', value);
	        this.touch();
	    },
	
	    _validate_color: function(color, fallback) {
	        return color.match(/#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$/) ||
	          named_colors[color.toLowerCase()] ? color: fallback;
	    }
	});
	
	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);
	    }
	}
	
	module.exports = {
	    ColorPickerModel: ColorPickerModel,
	    ColorPickerView: ColorPickerView
	};


/***/ },
/* 448 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var widget = __webpack_require__(436);
	var utils = __webpack_require__(428);
	var $ = __webpack_require__(425);
	var _ = __webpack_require__(429);
	
	
	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 = widget.DOMWidgetModel.extend({
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        _model_name: 'SelectionModel',
	        selected_label: '',
	        _options_labels: [],
	        disabled: false,
	        description: ''
	    })
	});
	
	var DropdownModel = SelectionModel.extend({
	    defaults: _.extend({}, SelectionModel.prototype.defaults, {
	        _model_name: 'DropdownModel',
	        _view_name: 'DropdownView',
	        button_style: ''
	    })
	});
	
	var DropdownView = widget.DOMWidgetView.extend({
	    initialize: function() {
	        this.onKeydown = this._handle_keydown.bind(this);
	        this.onDismiss = this._handle_dismiss.bind(this);
	        DropdownView.__super__.initialize.apply(this, arguments);
	    },
	
	    remove: function() {
	        document.body.removeChild(this.droplist);
	        return DropdownView.__super__.remove.call(this);
	    },
	
	    render: function() {
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-hbox');
	        this.el.classList.add('widget-dropdown');
	
	        this.label = document.createElement('div');
	        this.el.appendChild(this.label);
	        this.label.className = 'widget-label';
	        this.label.style.display = 'none';
	
	        this.buttongroup = document.createElement('div');
	        this.buttongroup.className = 'widget-item';
	        this.el.appendChild(this.buttongroup);
	
	        this.droplabel = document.createElement('button');
	        this.droplabel.className = 'widget-dropdown-toggle widget-button';
	        this.buttongroup.appendChild(this.droplabel);
	
	        this.dropbutton = document.createElement('button');
	        this.dropbutton.className = 'widget-dropdown-toggle widget-button';
	
	        this.caret = document.createElement('i');
	        this.caret.className = 'widget-caret';
	        this.dropbutton.appendChild(this.caret);
	        this.buttongroup.appendChild(this.dropbutton);
	
	        // Drop lists are appended to the document body and absolutely
	        // positioned so that they can appear outside the flow of whichever
	        // container they were instantiated in.
	        this.droplist = document.createElement('ul');
	        this.droplist.className = 'widget-dropdown-droplist';
	        document.body.appendChild(this.droplist);
	        this.droplist.addEventListener('click', this._handle_click.bind(this));
	
	        this.listenTo(this.model, 'change:button_style', this.update_button_style, this);
	        this.update_button_style();
	
	        // Set defaults.
	        this.update();
	    },
	
	    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.
	         */
	        var view = this;
	        var items = this.model.get('_options_labels');
	        var links = _.pluck(this.droplist.querySelectorAll('a'), 'textContent');
	        var disabled = this.model.get('disabled');
	        var stale = false;
	
	        for (var i = 0, len = items.length; i < len; ++i) {
	            if (links[i] !== items[i]) {
	                stale = true;
	                break;
	            }
	        }
	
	        if (stale && (options === undefined || options.updated_view !== this)) {
	            this.droplist.textContent = '';
	            _.each(items, function(item) {
	                var li = document.createElement('li');
	                var a = document.createElement('a');
	                li.className = 'widget-dropdown-item';
	                a.setAttribute('href', '#');
	                a.textContent = item;
	                li.appendChild(a);
	                view.droplist.appendChild(li);
	            });
	        }
	
	        this.droplabel.disabled = disabled;
	        this.dropbutton.disabled = disabled;
	
	        var value = this.model.get('value') || '';
	        if (value.trim().length === 0) {
	            this.droplabel.innerHTML = '&nbsp;';
	        } else {
	            this.droplabel.textContent = value;
	        }
	
	        var description = this.model.get('description');
	        if (description.length === 0) {
	            this.label.style.display = 'none';
	        } else {
	            this.typeset(this.label, description);
	            this.label.style.display = '';
	        }
	
	        return DropdownView.__super__.update.call(this);
	    },
	
	    update_button_style: function() {
	        var class_map = {
	            primary: ['mod-primary'],
	            success: ['mod-success'],
	            info: ['mod-info'],
	            warning: ['mod-warning'],
	            danger: ['mod-danger']
	        };
	        this.update_mapped_classes(class_map, 'button_style', this.droplabel);
	        this.update_mapped_classes(class_map, 'button_style', this.dropbutton);
	    },
	
	    update_attr: function(name, value) { // TODO: Deprecated in 5.0
	        /**
	         * Set a css attr of the widget view.
	         */
	        if (name.substring(0, 6) === 'border' ||
	            name === 'background' ||
	            name === 'color') {
	            this.droplabel.style[name] = value;
	            this.dropbutton.style[name] = value;
	            this.droplist.style[name] = value;
	        } else {
	            this.el.style[name] = value;
	        }
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'click button.widget-button': '_toggle',
	        'keydown button.widget-button': '_activate'
	    },
	
	    /**
	     * Handles when a value is clicked.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    _handle_click: function(event) {
	        event.stopPropagation();
	        event.preventDefault();
	
	        // Manually hide the droplist.
	        this._toggle();
	
	        var value = event.target.textContent;
	        this.model.set('value', value, { updated_view: this });
	        this.touch();
	    },
	
	    /**
	     * Handles browser events that cause a dismissal of the drop list.
	     */
	    _handle_dismiss: function(event) {
	        // Check if the event came from the drop list itself.
	        var node = event.target;
	        var dropdownEvent;
	        while (node !== document.documentElement) {
	            dropdownEvent = node === this.droplist ||
	                node === this.droplabel || // This is relevant for mousedowns.
	                node === this.dropbutton;  // This is relevant for mousedowns.
	            if (dropdownEvent) {
	                return;
	            }
	            node = node.parentNode;
	        }
	        // If some error condition has caused this listener to still be active
	        // despite the drop list being invisible, remove all global listeners.
	        if (!this.droplist.classList.contains('mod-active')) {
	            document.removeEventListener('keydown', this.onKeydown);
	            document.removeEventListener('mousedown', this.onDismiss);
	            window.removeEventListener('scroll', this.onDismiss);
	            return;
	        }
	        // Deselect active item.
	        var active = this.droplist.querySelector('.mod-active');
	        if (active) {
	            active.classList.remove('mod-active');
	        }
	        // Close the drop list.
	        this.droplist.classList.remove('mod-active');
	        // Remove global keydown listener.
	        document.removeEventListener('keydown', this.onKeydown);
	        // Remove global mousedown listener.
	        document.removeEventListener('mousedown', this.onDismiss);
	        // Remove global scroll listener.
	        window.removeEventListener('scroll', this.onDismiss);
	        return;
	    },
	
	    /**
	     * Handles keydown events for navigating the drop list.
	     */
	    _handle_keydown: function(event) {
	        if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
	            return;
	        }
	
	        // If some error condition has caused this listener to still be active
	        // despite the drop list being invisible, remove all global listeners.
	        if (!this.droplist.classList.contains('mod-active')) {
	            document.removeEventListener('keydown', this.onKeydown);
	            document.removeEventListener('mousedown', this.onDismiss);
	            window.removeEventListener('scroll', this.onDismiss);
	            return;
	        }
	
	        switch (event.keyCode) {
	        case 13:  // Enter key
	            event.preventDefault();
	            event.stopPropagation();
	            var active = this.droplist.querySelector('.mod-active');
	            if (active) {
	                var value = active.textContent;
	                this.model.set('value', value, { updated_view: this });
	                this.touch();
	            }
	            // Close the drop list.
	            this._toggle();
	            this.dropbutton.focus();
	            return;
	        case 27:  // Escape key
	            event.preventDefault();
	            event.stopPropagation();
	            // Close the drop list.
	            this._toggle();
	            this.dropbutton.focus();
	            return;
	        case 38:  // Up arrow key
	            event.preventDefault();
	            event.stopPropagation();
	            var active = this.droplist.querySelector('.mod-active');
	            var items = this.droplist.querySelectorAll('.widget-dropdown-item');
	            var index;
	            if (active) {
	                index = _.indexOf(items, active);
	                index = Math.max(0, index - 1);
	                active.classList.remove('mod-active');
	            } else {
	                // If there is no selection, up arrow selects the last item.
	                index = items.length - 1;
	            }
	            items[index].classList.add('mod-active');
	            scrollIfNeeded(this.droplist, items[index]);
	            return;
	        case 40:  // Down arrow key
	            event.preventDefault();
	            event.stopPropagation();
	            var active = this.droplist.querySelector('.mod-active');
	            var items = this.droplist.querySelectorAll('.widget-dropdown-item');
	            var index;
	            if (active) {
	                index = _.indexOf(items, active);
	                index = Math.min(items.length - 1, index + 1);
	                active.classList.remove('mod-active');
	            } else {
	                // If there is no selection, down arrow selects the first item.
	                index = 0;
	            }
	            items[index].classList.add('mod-active');
	            scrollIfNeeded(this.droplist, items[index]);
	            return;
	        }
	    },
	
	    /**
	     * Activate the drop list.
	     *
	     * If the drop button is focused and the user presses enter, up, or down,
	     * activate the drop list.
	     */
	    _activate: function(event) {
	        if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
	            return;
	        }
	
	        switch (event.keyCode) {
	        case 13:  // Enter key
	        case 38:  // Up arrow key
	        case 40:  // Down arrow key
	            event.preventDefault();
	            event.stopPropagation();
	            this._toggle();
	            return;
	        }
	    },
	
	    /**
	     * Toggle the dropdown list.
	     *
	     * If the dropdown list doesn't fit below the dropdown label, this will
	     * cause the dropdown to be dropped 'up'.
	     */
	    _toggle: function() {
	        this.droplabel.blur();
	        this.dropbutton.blur();
	
	        if (this.droplist.classList.contains('mod-active')) {
	            // Deselect active item.
	            var active = this.droplist.querySelector('.mod-active');
	            if (active) {
	                active.classList.remove('mod-active');
	            }
	            // Close the drop list.
	            this.droplist.classList.remove('mod-active');
	            // Remove global keydown listener.
	            document.removeEventListener('keydown', this.onKeydown);
	            // Remove global mousedown listener.
	            document.removeEventListener('mousedown', this.onDismiss);
	            // Remove global scroll listener.
	            window.removeEventListener('scroll', this.onDismiss);
	            return;
	        }
	
	        // Add a global keydown listener for drop list events.
	        document.addEventListener('keydown', this.onKeydown, true);
	        // Add a global mousedown listener to dismiss drop list.
	        document.addEventListener('mousedown', this.onDismiss, true);
	        // Add a global scroll listener to dismiss drop list.
	        window.addEventListener('scroll', this.onDismiss, true);
	
	        // Set the currently selected item of the drop list.
	        var value = this.model.get('value');
	        var selectedIndex = _.indexOf(this.model.get('_options_labels'), value);
	        if (selectedIndex > -1) {
	            var items = this.droplist.querySelectorAll('.widget-dropdown-item');
	            items[selectedIndex].classList.add('mod-active');
	        }
	
	        var buttongroupRect = this.buttongroup.getBoundingClientRect();
	        var availableHeightAbove = buttongroupRect.top;
	        var availableHeightBelow = window.innerHeight - buttongroupRect.bottom;
	        // Account for 1px border.
	        availableHeightAbove += 1;
	        availableHeightBelow -= 1;
	        var width = buttongroupRect.width;
	        var maxHeight = Math.floor(
	            Math.max(availableHeightAbove, availableHeightBelow)
	        );
	        var top = 0;
	        var left = buttongroupRect.left;
	
	        this.droplist.style.left = left + 'px';
	        this.droplist.style.maxHeight = maxHeight + 'px';
	        this.droplist.style.width = width + 'px';
	
	        // Make drop list visible to compute its dimensions.
	        this.droplist.classList.add('mod-active');
	
	        var droplistRect = this.droplist.getBoundingClientRect();
	
	        // If the drop list fits below, render below.
	        if (droplistRect.height <= availableHeightBelow) {
	            // Account for 1px border.
	            top = Math.ceil(buttongroupRect.bottom + 1);
	            this.droplist.style.top = top + 'px';
	        // If the drop list fits above, render above.
	        } else if (droplistRect.height <= availableHeightAbove) {
	            // Account for 1px border.
	            top = Math.floor(buttongroupRect.top - droplistRect.height + 1);
	            this.droplist.style.top = top + 'px';
	        // Otherwise, render in whichever has more space, above or below.
	        } else if (availableHeightBelow >= availableHeightAbove) {
	            // Account for 1px border.
	            top = Math.ceil(buttongroupRect.bottom + 1);
	            this.droplist.style.top = top + 'px';
	        } else {
	            // Account for 1px border.
	            top = Math.floor(buttongroupRect.top - droplistRect.height + 1);
	            this.droplist.style.top = top + 'px';
	        }
	
	        // If a selection is active, scroll to it if necessary.
	        if (selectedIndex > -1) {
	            scrollIfNeeded(this.droplist, items[selectedIndex]);
	        }
	    }
	});
	
	var RadioButtonsModel = SelectionModel.extend({
	    defaults: _.extend({}, SelectionModel.prototype.defaults, {
	        _model_name: 'RadioButtonsModel',
	        _view_name: 'RadioButtonsView',
	        tooltips: [],
	        icons: [],
	        button_style: ''
	    })
	});
	
	var RadioButtonsView = widget.DOMWidgetView.extend({
	    render : function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-hbox');
	        this.el.classList.add('widget-radio');
	
	        this.label = document.createElement('div');
	        this.label.className = 'widget-label';
	        this.label.style.display = 'none';
	        this.el.appendChild(this.label);
	
	        this.container = document.createElement('div');
	        this.el.appendChild(this.container);
	        this.container.classList.add('widget-radio-box');
	
	        this.update();
	    },
	
	    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.
	         */
	        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) {
	                var label = document.createElement('label');
	                label.textContent = item;
	                view.container.appendChild(label);
	
	                var radio = document.createElement('input');
	                radio.setAttribute('type', 'radio');
	                radio.value = item;
	                radio.setAttribute('data-value', encodeURIComponent(item));
	                label.appendChild(radio);
	            });
	        }
	        var description = this.model.get('description');
	        if (description.length === 0) {
	            this.label.style.display = 'none';
	        } else {
	            this.label.textContent = description;
	            this.typeset(this.label, description);
	            this.label.style.display = '';
	        }
	        _.each(items, function(item) {
	            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('selected_label') === item;
	              radio_el.disabled = view.model.get('disabled');
	            }
	        });
	        return RadioButtonsView.__super__.update.call(this);
	    },
	
	    update_attr: function(name, value) {
	        /**
	         * Set a css attr of the widget view.
	         */
	        if (name == 'padding' || name == 'margin') {
	            this.el.style[name] = value;
	        } else {
	            this.container.style[name] = value;
	        }
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'click input[type="radio"]': '_handle_click'
	    },
	
	    _handle_click: function (event) {
	        /**
	         * Handle when a value is clicked.
	         *
	         * Calling model.set will trigger all of the other views of the
	         * model to update.
	         */
	        var value = event.target.value;
	        this.model.set('selected_label', value, {updated_view: this});
	        this.touch();
	    }
	});
	
	var ToggleButtonsModel = SelectionModel.extend({
	    defaults: _.extend({}, SelectionModel.prototype.defaults, {
	        _model_name: 'ToggleButtonsModel',
	        _view_name: 'ToggleButtonsView'
	    })
	});
	
	var ToggleButtonsView = widget.DOMWidgetView.extend({
	    initialize: function() {
	        this._css_state = {};
	        ToggleButtonsView.__super__.initialize.apply(this, arguments);
	    },
	
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widgets-hbox');
	        this.el.classList.add('widget-toggle-buttons');
	
	        this.label = document.createElement('div');
	        this.el.appendChild(this.label);
	        this.label.className = 'widget-label';
	        this.label.style.display = 'none';
	
	        this.buttongroup = document.createElement('div');
	        this.el.appendChild(this.buttongroup);
	
	        this.listenTo(this.model, 'change:button_style', this.update_button_style, this);
	        this.update();
	    },
	
	    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.
	         */
	        var view = this;
	        var items = this.model.get('_options_labels');
	        var icons = this.model.get('icons') || [];
	        var previous_icons = this.model.previous('icons') || [];
	        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';
	                button.innerHTML = item_html;
	                button.setAttribute('data-value', encodeURIComponent(item));
	                button.setAttribute('value', item);
	                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) {
	            var item_query = '[data-value="' + encodeURIComponent(item) + '"]';
	            var button = view.buttongroup.querySelector(item_query);
	            if (view.model.get('value') === item) {
	                button.classList.add('mod-active');
	            } else {
	                button.classList.remove('mod-active');
	            }
	        });
	
	        var description = this.model.get('description');
	        if (description.length === 0) {
	            this.label.style.display = 'none';
	        } else {
	            this.label.textContent = '';
	            this.typeset(this.label, description);
	            this.label.style.display = '';
	        }
	        this.update_button_style();
	        return ToggleButtonsView.__super__.update.call(this);
	    },
	
	    update_attr: function(name, value) { // TODO: Deprecated in 5.0
	        /**
	         * Set a css attr of the widget view.
	         */
	        if (name == 'padding' || name == 'margin') {
	            this.el.style[name] = value;
	        } else {
	            this._css_state[name] = value;
	            this.update_style_traits();
	        }
	    },
	
	    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];
	                        }
	                    }
	                }
	            }
	        }
	    },
	
	    update_button_style: function() {
	        var class_map = {
	            primary: ['mod-primary'],
	            success: ['mod-success'],
	            info: ['mod-info'],
	            warning: ['mod-warning'],
	            danger: ['mod-danger']
	        };
	        var view = this;
	        var buttons = this.buttongroup.querySelectorAll('button');
	        _.each(buttons, function(button) {
	            view.update_mapped_classes(class_map, 'button_style', button);
	        });
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'click button': '_handle_click'
	    },
	
	    _handle_click: function (event) {
	        /**
	         * Handle when a value is clicked.
	         *
	         * Calling model.set will trigger all of the other views of the
	         * model to update.
	         */
	        var value = event.target.value;
	        this.model.set('value', value, { updated_view: this });
	        this.touch();
	    }
	});
	
	var SelectModel = SelectionModel.extend({
	    defaults: _.extend({}, SelectionModel.prototype.defaults, {
	        _model_name: 'SelectModel',
	        _view_name: 'SelectView'
	    })
	});
	
	var SelectView = widget.DOMWidgetView.extend({
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-hbox');
	        this.el.classList.add('widget-select');
	
	        this.label = document.createElement('div');
	        this.el.appendChild(this.label);
	        this.label.className = 'widget-label';
	        this.label.style.display = 'none';
	
	        this.listbox = document.createElement('select');
	        this.listbox.className = 'widget-listbox';
	        this.listbox.setAttribute('size', '6');
	        this.el.appendChild(this.listbox);
	
	        this.update();
	    },
	
	    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.
	         */
	        var view = this;
	        var items = this.model.get('_options_labels');
	        var options = _.pluck(this.listbox.options, 'value');
	        var stale = false;
	
	        for (var i = 0, len = items.length; i < len; ++i) {
	            if (options[i] !== items[i]) {
	                stale = true;
	                break;
	            }
	        }
	
	        if (stale && (options === undefined || options.updated_view !== this)) {
	            // Add items to the DOM.
	            this.listbox.textContent = '';
	
	            _.each(items, function(item, index) {
	                var item_query = 'option[data-value="' +
	                    encodeURIComponent(item) + '"]';
	                var item_exists = view.listbox
	                    .querySelectorAll(item_query).length !== 0;
	                var option;
	                if (!item_exists) {
	                    option = document.createElement('option');
	                    option.textContent = item.replace ?
	                        item.replace(/ /g, '\xa0') : item;
	                    option.setAttribute('data-value', encodeURIComponent(item));
	                    option.value = item;
	                    view.listbox.appendChild(option);
	                }
	            });
	
	            // Disable listbox if needed
	            this.listbox.disabled = this.model.get('disabled');
	
	            // Select the correct element
	            var value = view.model.get('selected_label');
	            view.listbox.selectedIndex = items.indexOf(value);
	
	            var description = this.model.get('description');
	            if (description.length === 0) {
	                this.label.style.display = 'none';
	            } else {
	                this.typeset(this.label, description);
	                this.label.style.display = '';
	            }
	        }
	        return SelectView.__super__.update.call(this);
	    },
	
	    update_attr: function(name, value) { // TODO: Deprecated in 5.0
	        /**
	         * Set a css attr of the widget view.
	         */
	        if (name == 'padding' || name == 'margin') {
	            this.el.style[name] = value;
	        } else {
	            this.listbox.style[name] = value;
	        }
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'change select': '_handle_change'
	    },
	
	    _handle_change: function() {
	        /**
	         * Handle when a new value is selected.
	         *
	         * Calling model.set will trigger all of the other views of the
	         * model to update.
	         */
	        var value = this.listbox.options[this.listbox.selectedIndex].value;
	        this.model.set('selected_label', value, {updated_view: this});
	        this.touch();
	    }
	});
	
	var SelectionSliderModel = SelectionModel.extend({
	    defaults: _.extend({}, SelectionModel.prototype.defaults, {
	        _model_name: 'SelectionSliderModel',
	        _view_name: 'SelectionSliderView',
	        orientation: 'horizontal',
	        readout: true,
	        continuous_update: true
	    })
	});
	
	var SelectionSliderView = widget.DOMWidgetView.extend({
	    render : function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.$el.addClass('jupyter-widgets widget-hbox widget-hslider');
	
	        this.label = document.createElement('div');
	        this.label.classList.add('widget-label');
	        this.label.style.display = 'none';
	        this.$el.append(this.label);
	
	        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.append(this.slider_container);
	
	        this.readout = document.createElement('div');
	        this.$el.append(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);
	        this.listenTo(this.model, 'change:description', function(sender, value) {
	            this.updateDescription();
	        }, this);
	
	        this.$slider.find('a').css('background', this.model.get('slider_color'));
	
	        // Set defaults.
	        this.update();
	        this.updateDescription();
	    },
	
	    update_attr: function(name, value) { // TODO: Deprecated in 5.0
	        /**
	         * Set a css attr of the widget view.
	         */
	        if (name == 'color') {
	            this.readout.style[name] = value;
	        } else if (name.substring(0, 4) == 'font') {
	            this.readout.style[name] = value;
	        } else if (name.substring(0, 6) == 'border') {
	            var slider_items = this.$slider[0].querySelectorAll('a');
	            if (slider_items.length) {
	              slider_items[0].style[name] = value;
	            }
	            this.slider_container.style[name] = value;
	        } else if (name == 'background') {
	            this.slider_container.style[name] = value;
	        } else {
	            this.el.style[name] = value;
	        }
	    },
	
	    updateDescription: function(options) {
	        var description = this.model.get('description');
	        if (description.length === 0) {
	            this.label.style.display = 'none';
	        } else {
	            this.typeset(this.label, description);
	            this.label.style.display = '';
	        }
	    },
	
	    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) {
	            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 value = this.model.get('value');
	            var index = labels.indexOf(value);
	            this.$slider.slider('option', 'value', index);
	            this.readout.textContent = value;
	
	            // Use the right CSS classes for vertical & horizontal sliders
	            if (orientation === 'vertical') {
	                this.$el
	                    .removeClass('widget-hslider')
	                    .addClass('widget-vslider');
	                this.$el
	                    .removeClass('widget-hbox')
	                    .addClass('widget-vbox');
	
	            } else {
	                this.$el
	                    .removeClass('widget-vslider')
	                    .addClass('widget-hslider');
	
	                this.$el
	                    .removeClass('widget-vbox')
	                    .addClass('widget-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 SelectionSliderView.__super__.update.call(this);
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'slide': 'handleSliderChange',
	        'slidestop': 'handleSliderChanged'
	    },
	
	    /**
	     * Called when the slider value is changing.
	     */
	    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.
	     */
	    handleSliderChanged: 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;
	        this.model.set('selected_label', selected_label, {updated_view: this});
	        this.touch();
	    },
	
	    _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);
	    }
	});
	
	var MultipleSelectionModel = SelectionModel.extend({
	    defaults: _.extend({}, SelectionModel.prototype.defaults, {
	        _model_name: 'MultipleSelectionModel',
	        selected_labels: []
	    })
	});
	
	var SelectMultipleModel = MultipleSelectionModel.extend({
	    defaults: _.extend({}, MultipleSelectionModel.prototype.defaults, {
	        _model_name: 'SelectMultipleModel',
	        _view_name: 'SelectMultipleView'
	    })
	});
	
	var SelectMultipleView = SelectView.extend({
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        SelectMultipleView.__super__.render.call(this);
	        this.el.classList.remove('widget-select');
	        this.el.classList.add('widget-select-multiple');
	        this.listbox.multiple = true;
	        this.update();
	    },
	
	    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.
	         */
	        SelectMultipleView.__super__.update.apply(this, arguments);
	        var selected = this.model.get('value') || [];
	        var values = _.map(selected, encodeURIComponent);
	        var options = this.listbox.options;
	        for (var i = 0, len = options.length; i < len; ++i) {
	            var value = options[i].getAttribute('data-value');
	            options[i].selected = _.contains(values, value);
	        }
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'change select': '_handle_change'
	    },
	
	    _handle_change: function() {
	        /**
	         * Handle when a new value is selected.
	         *
	         * Calling model.set will trigger all of the other views of the
	         * model to update.
	         */
	
	        // In order to preserve type information correctly, we need to map
	        // the selected indices to the options list.
	        var items = this.model.get('_options_labels');
	        var values = Array.prototype.map
	            .call(this.listbox.selectedOptions || [], function(option) {
	                return items[option.index];
	            });
	        this.model.set('value', values, {updated_view: this});
	        this.touch();
	    }
	});
	
	module.exports = {
	    SelectionModel: SelectionModel,
	    DropdownView: DropdownView,
	    DropdownModel: DropdownModel,
	    RadioButtonsView: RadioButtonsView,
	    RadioButtonsModel: RadioButtonsModel,
	    ToggleButtonsView: ToggleButtonsView,
	    ToggleButtonsModel: ToggleButtonsModel,
	    SelectView: SelectView,
	    SelectModel: SelectModel,
	    SelectionSliderView: SelectionSliderView,
	    SelectionSliderModel: SelectionSliderModel,
	    MultipleSelectionModel: MultipleSelectionModel,
	    SelectMultipleView: SelectMultipleView,
	    SelectMultipleModel: SelectMultipleModel
	};


/***/ },
/* 449 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var widget = __webpack_require__(436);
	var utils = __webpack_require__(428);
	var box = __webpack_require__(441);
	var _ = __webpack_require__(429);
	var TabBar = __webpack_require__(40).TabBar;
	var Title = __webpack_require__(20).Title;
	
	var SelectionContainerModel = box.BoxModel.extend({
	    defaults: _.extend({}, box.BoxModel.prototype.defaults, {
	        _model_name: 'SelectionContainerModel',
	        selected_index: 0,
	        _titles: {}
	    })
	});
	
	var AccordionModel = SelectionContainerModel.extend({
	    defaults: _.extend({}, SelectionContainerModel.prototype.defaults, {
	        _model_name: 'AccordionModel',
	        _view_name: 'AccordionView'
	    })
	});
	
	var AccordionView = widget.DOMWidgetView.extend({
	    initialize: function(){
	        AccordionView.__super__.initialize.apply(this, arguments);
	
	        this.containers = [];
	        this.model_containers = {};
	        this.children_views = new widget.ViewList(this.add_child_view, this.remove_child_view, this);
	        this.listenTo(this.model, 'change:children', function(model, value, options) {
	            this.children_views.update(value);
	        }, this);
	    },
	
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        var guid = 'panel-group' + utils.uuid();
	        this.el.id = guid;
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('panel-group');
	
	        this.listenTo(this.model, 'change:selected_index', function(model, value, options) {
	            this.update_selected_index(options);
	        }, this);
	        this.listenTo(this.model, 'change:_titles', function(model, value, options) {
	            this.update_titles(options);
	        }, this);
	        this.on('displayed', function() {
	            this.update_titles();
	        }, this);
	        this.children_views.update(this.model.get('children'));
	    },
	
	    /**
	     * Set tab titles
	     */
	    update_titles: function() {
	        var titles = this.model.get('_titles');
	        var that = this;
	        _.each(titles, function(title, page_index) {
	            var accordion = that.containers[page_index];
	            if (accordion !== undefined) {
	                accordion
	                    .children('.panel-heading')
	                    .find('.accordion-toggle')
	                    .text(title);
	            }
	        });
	    },
	
	    /**
	     * Only update the selection if the selection wasn't triggered
	     * by the front-end.  It must be triggered by the back-end.
	     */
	    update_selected_index: function(options) {
	        if (options === undefined || options.updated_view != this) {
	            var old_index = this.model.previous('selected_index');
	            var new_index = this.model.get('selected_index');
	            /* old_index can be out of bounds, this check avoids raising
	               a javascript error. */
	            this.collapseTab(old_index);
	            this.expandTab(new_index);
	        }
	    },
	
	    /**
	     * Collapses an accordion tab.
	     * @param  {number} index
	     */
	    collapseTab: function(index) {
	        var page = this.containers[index].children('.collapse');
	
	        if (page.hasClass('in')) {
	            page.removeClass('in');
	            page.collapse('hide');
	        }
	    },
	
	    /**
	     * Expands an accordion tab.
	     * @param  {number} index
	     */
	    expandTab: function(index) {
	        var page = this.containers[index].children('.collapse');
	
	        if (!page.hasClass('in')) {
	            page.addClass('in');
	            page.collapse('show');
	        }
	    },
	
	    remove_child_view: function(view) {
	        /**
	         * Called when a child is removed from children list.
	         * TODO: does this handle two different views of the same model as children?
	         */
	        var model = view.model;
	        var accordion_group = this.model_containers[model.id];
	        this.containers.splice(accordion_group.container_index, 1);
	        delete this.model_containers[model.id];
	        accordion_group.remove();
	    },
	
	    add_child_view: function(model) {
	        /**
	         * Called when a child is added to children list.
	         */
	        var index = this.containers.length;
	        var uuid = utils.uuid();
	        var accordion_group = document.createElement('div');
	        accordion_group.className = 'panel panel-default';
	        this.el.appendChild(accordion_group);
	
	        var accordion_heading = document.createElement('div');
	        accordion_heading.classList.add('panel-heading');
	        accordion_group.appendChild(accordion_heading);
	
	        var that = this;
	        var accordion_toggle = document.createElement('a');
	        accordion_toggle.classList.add('accordion-toggle');
	        accordion_toggle.setAttribute('data-toggle', 'collapse');
	        accordion_toggle.setAttribute('data-parent', '#' + this.el.id);
	        accordion_toggle.setAttribute('href', '#' + uuid);
	        accordion_toggle.onclick = function() {
	          that.model.set('selected_index', index, {updated_view: that});
	          that.touch();
	        };
	        accordion_toggle.textContent('Page ' + index);
	        accordion_heading.appendChild(accordion_toggle);
	
	        var accordion_body = document.createElement('div');
	        accordion_body.id = uuid;
	        accordion_body.className = 'panel-collapse collapse';
	        accordion_group.appendChild(accordion_body);
	
	        var accordion_inner = document.createElement('div');
	        accordion_inner.classList.add('panel-body');
	        accordion_body.appendChild(accordion_inner);
	
	        var container_index = this.containers.push(accordion_group) - 1;
	        accordion_group.container_index = container_index;
	        this.model_containers[model.id] = accordion_group;
	
	        var dummy = document.createElement('div');
	        accordion_inner.appendChild(dummy);
	        return this.create_child_view(model).then(function(view) {
	
	            dummy.parentNode.replaceChild(dummy, view.el);
	
	            that.update_selected_index();
	            that.update_titles();
	
	            // Trigger the displayed event of the child view.
	            that.displayed.then(function() {
	                view.trigger('displayed', that);
	            });
	            return view;
	        }).catch(utils.reject('Could not add child view to box', true));
	    },
	
	    remove: function() {
	        /**
	         * We remove this widget before removing the children as an optimization
	         * we want to remove the entire container from the DOM first before
	         * removing each individual child separately.
	         */
	        AccordionView.__super__.remove.apply(this, arguments);
	        this.children_views.remove();
	    }
	});
	
	var TabModel = SelectionContainerModel.extend({
	    defaults: _.extend({}, SelectionContainerModel.prototype.defaults, {
	        _model_name: 'TabModel',
	        _view_name: 'TabView'
	    })
	});
	
	var TabView = widget.DOMWidgetView.extend({
	    initialize: function() {
	        /**
	         * Public constructor.
	         */
	        TabView.__super__.initialize.apply(this, arguments);
	        this.childrenViews = new widget.ViewList(
	            this.addChildView,
	            this.removeChildView,
	            this
	        );
	        this.listenTo(this.model, 'change:children',
	            function(model, value) { this.childrenViews.update(value); },
	            this
	        );
	        this.listenTo(this.model, 'change:_titles',
	            function(model, value, options) { this.updateTitles(options); },
	            this
	        );
	    },
	
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        var parent = this;
	
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-tab');
	
	        this.tabBar = new TabBar();
	        this.tabBar.tabsMovable = false;
	        this.tabBar.addClass('widget-tab-bar');
	        this.tabBar.currentChanged.connect(this._onTabChanged, this);
	        this.tabBar.tabCloseRequested.connect(this._onTabCloseRequested, this);
	
	        this.tabContents = document.createElement('div');
	        this.tabContents.className = 'widget-tab-contents';
	
	        this.childrenViews.update(this.model.get('children'));
	
	        this.displayed.then(function() {
	            parent.tabBar.attach(parent.el);
	            parent.el.appendChild(parent.tabContents);
	        });
	    },
	
	    addChildView: function(model) {
	        /**
	         * Called when a child is added to children list.
	         */
	        var parent = this;
	
	        return this.create_child_view(model).then(function(child) {
	            var current = parent.el.querySelector('.mod-active');
	            if (current) {
	                current.classList.remove('mod-active');
	            }
	
	            child.el.classList.add('widget-tab-child');
	            child.el.classList.add('mod-active');
	
	            parent.tabContents.appendChild(child.el);
	            parent.tabBar.addItem({
	                title: new Title({ text: '', closable: true })
	            });
	            var tab = parent.tabBar.itemAt(parent.tabBar.itemCount() - 1);
	
	            parent.displayed.then(function() {
	                child.trigger('displayed', parent);
	                parent.update();
	            });
	
	            child.on('remove', function() { parent.tabBar.removeItem(tab); });
	
	            return child;
	        }).catch(utils.reject('Could not add child view to box', true));
	    },
	
	    removeChildView: function(child) { child.remove(); },
	
	    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.
	         */
	        this.updateTitles();
	        this.updateSelectedIndex(options);
	        return TabView.__super__.update.call(this);
	    },
	
	    /**
	     * Updates the tab page titles.
	     */
	    updateTitles: function() {
	        var titles = this.model.get('_titles') || {};
	        for (var i = this.tabBar.itemCount() - 1; i > -1; i--) {
	            this.tabBar.itemAt(i).title.text = titles[i] || (i + 1) + '';
	        }
	    },
	
	    /**
	     * Updates the selected index.
	     */
	    updateSelectedIndex: function(options) {
	        if (options === undefined || options.updated_view !== this) {
	            var index = this.model.get('selected_index');
	            if (typeof index === 'undefined') {
	                index = 0;
	            }
	            if (0 <= index && index < this.tabBar.itemCount()) {
	                this.selectPage(index);
	            }
	        }
	    },
	
	    /**
	     * Select a page.
	     */
	    selectPage: function(index) {
	        var actives = this.el.querySelectorAll('.mod-active');
	        if (actives.length) {
	            for (var i = 0, len = actives.length; i < len; i++) {
	                actives[i].classList.remove('mod-active');
	            }
	        }
	
	        var active = this.el.querySelectorAll('.widget-tab-child')[index];
	        if (active) {
	            active.classList.add('mod-active');
	        }
	    },
	
	    remove: function() {
	        /*
	         * The tab bar needs to be disposed before its node is removed by the
	         * super call, otherwise phosphor's Widget.detach will throw an error.
	         */
	        this.tabBar.dispose();
	        /**
	         * We remove this widget before removing the children as an optimization
	         * we want to remove the entire container from the DOM first before
	         * removing each individual child separately.
	         */
	        TabView.__super__.remove.apply(this, arguments);
	        this.childrenViews.remove();
	    },
	
	    _onTabChanged: function(sender, args) {
	        this.model.set('selected_index', args.index, { updated_view: this });
	        this.touch();
	    },
	
	    _onTabCloseRequested: function(sender, args) {
	        /*
	         * When a tab is removed, the titles dictionary must be reset for all
	         * indices that are larger than the index of the tab that was removed.
	         */
	        var len = this.model.get('children').length;
	        var titles = this.model.get('_titles') || {};
	        delete titles[args.index];
	        for (var i = args.index + 1; i < len; i++) {
	            titles[i - 1] = titles[i];
	            delete titles[i];
	        }
	
	        var children = _.filter(
	            this.model.get('children'),
	            function(child, index) { return index !== args.index; }
	        );
	
	        this.model.set(
	            { 'children': children, '_titles': titles },
	            { updated_view: this }
	        );
	        this.touch();
	    }
	});
	
	module.exports = {
	    SelectionContainerModel: SelectionContainerModel,
	    AccordionModel: AccordionModel,
	    AccordionView: AccordionView,
	    TabModel: TabModel,
	    TabView: TabView
	};


/***/ },
/* 450 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var widget = __webpack_require__(436);
	var _ = __webpack_require__(429);
	
	var StringModel = widget.DOMWidgetModel.extend({
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        value: '',
	        disabled: false,
	        description: '',
	        placeholder: '',
	        _model_name: 'StringModel'
	    })
	});
	
	var HTMLModel = StringModel.extend({
	    defaults: _.extend({}, StringModel.prototype.defaults, {
	        _view_name: 'HTMLView',
	        _model_name: 'HTMLModel'
	    })
	});
	
	var HTMLView = widget.DOMWidgetView.extend({
	    render : function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-html');
	        this.update(); // Set defaults.
	    },
	
	    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.
	         */
	        this.el.innerHTML = this.model.get('value');
	        return HTMLView.__super__.update.apply(this);
	    }
	});
	
	var LabelModel = StringModel.extend({
	    defaults: _.extend({}, StringModel.prototype.defaults, {
	        _view_name: 'LabelView',
	        _model_name: 'LabelModel'
	    })
	});
	
	var LabelView = widget.DOMWidgetView.extend({
	    render : function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-latex');
	        this.update(); // Set defaults.
	    },
	
	    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.
	         */
	        this.typeset(this.el, this.model.get('value'));
	        return LabelView.__super__.update.apply(this);
	    }
	});
	
	var TextareaModel = StringModel.extend({
	    defaults: _.extend({}, StringModel.prototype.defaults, {
	        _view_name: 'TextareaView',
	        _model_name: 'TextareaModel'
	    })
	});
	
	var TextareaView = widget.DOMWidgetView.extend({
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-hbox');
	        this.el.classList.add('widget-textarea');
	
	        this.label = document.createElement('div');
	        this.label.classList.add('widget-label');
	        this.label.style.display = 'none';
	        this.el.appendChild(this.label);
	
	        this.textbox = document.createElement('textarea');
	        this.textbox.setAttribute('rows', 5);
	        this.textbox.classList.add('form-control');
	        this.el.appendChild(this.textbox);
	
	        this.update(); // Set defaults.
	        var model = this;
	        this.listenTo(this.model, 'msg:custom', function() {
	          model._handle_textarea_msg()
	        });
	        this.listenTo(this.model, 'change:placeholder',
	            function(model, value, options) {
	                this.update_placeholder(value);
	            }, this);
	
	        this.update_placeholder();
	    },
	
	    _handle_textarea_msg: function (content) {
	        /**
	         * Handle when a custom msg is recieved from the back-end.
	         */
	        if (content.method == 'scroll_to_bottom') {
	            this.scroll_to_bottom();
	        }
	    },
	
	    update_placeholder: function(value) {
	        value = value || this.model.get('placeholder');
	        this.textbox.setAttribute('placeholder', value);
	    },
	
	    scroll_to_bottom: function () {
	        /**
	         * Scroll the text-area view to the bottom.
	         */
	        //this.$textbox.scrollTop(this.$textbox[0].scrollHeight); // DW TODO
	    },
	
	    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) {
	            this.textbox.value = this.model.get('value');
	
	            var disabled = this.model.get('disabled');
	            this.textbox.disabled = disabled;
	
	            var description = this.model.get('description');
	            if (description.length === 0) {
	                this.label.style.display = 'none';
	            } else {
	                this.typeset(this.label, description);
	                this.label.style.display = '';
	            }
	        }
	        return TextareaView.__super__.update.apply(this);
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'keyup textarea' : 'handleChanging',
	        'paste textarea' : 'handleChanging',
	        'cut textarea'   : 'handleChanging'
	    },
	
	    handleChanging: function(e) {
	        /**
	         * Handles and validates user input.
	         *
	         * Calling model.set will trigger all of the other views of the
	         * model to update.
	         */
	        this.model.set('value', e.target.value, {updated_view: this});
	        this.touch();
	    }
	});
	
	var TextModel = StringModel.extend({
	    defaults: _.extend({}, StringModel.prototype.defaults, {
	        _view_name: 'TextView',
	        _model_name: 'TextModel'
	    })
	});
	
	var TextView = widget.DOMWidgetView.extend({
	    render: function() {
	        /**
	         * Called when view is rendered.
	         */
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-hbox');
	        this.el.classList.add('widget-text');
	        this.label = document.createElement('div');
	        this.label.className = 'widget-label';
	        this.el.appendChild(this.label);
	        this.label.style.display = 'none';
	
	        this.textbox = document.createElement('input');
	        this.textbox.setAttribute('type', 'text');
	        this.textbox.className = 'form-control';
	        this.el.appendChild(this.textbox);
	
	        this.update(); // Set defaults.
	        this.listenTo(this.model, 'change:placeholder', function(model, value, options) {
	            this.update_placeholder(value);
	        }, this);
	
	        this.update_placeholder();
	    },
	
	    update_placeholder: function(value) {
	        if (!value) {
	            value = this.model.get('placeholder');
	        }
	        this.textbox.setAttribute('placeholder', value);
	    },
	
	    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;
	
	            var description = this.model.get('description');
	            if (description.length === 0) {
	                this.label.style.display = 'none';
	            } else {
	                this.typeset(this.label, description);
	                this.label.style.display = '';
	            }
	        }
	        return TextView.__super__.update.apply(this);
	    },
	
	    events: {
	        // Dictionary of events and their handlers.
	        'keyup input'    : 'handleChanging',
	        'paste input'    : 'handleChanging',
	        'cut input'      : 'handleChanging',
	        'keypress input' : 'handleKeypress',
	        'blur input'     : 'handleBlur',
	        'focusout input' : 'handleFocusOut'
	    },
	
	    handleChanging: function(e) {
	        /**
	         * Handles user input.
	         *
	         * Calling model.set will trigger all of the other views of the
	         * model to update.
	         */
	        this.model.set('value', e.target.value, {updated_view: this});
	        this.touch();
	    },
	
	    handleKeypress: function(e) {
	        /**
	         * Handles text submition
	         */
	        if (e.keyCode == 13) { // Return key
	            this.send({event: 'submit'});
	            e.stopPropagation();
	            e.preventDefault();
	            return false;
	        }
	    },
	
	    handleBlur: function(e) {
	        /**
	         * 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?
	         */
	        if (e.relatedTarget === null) {
	            e.stopPropagation();
	            e.preventDefault();
	            return false;
	        }
	    },
	
	    handleFocusOut: function(e) {
	        /**
	         * Prevent a blur from firing if the blur was not user intended.
	         * This is a workaround for the return-key focus loss bug.
	         */
	        if (e.relatedTarget === null) {
	            e.stopPropagation();
	            e.preventDefault();
	            return false;
	        }
	    }
	});
	
	module.exports = {
	    StringModel: StringModel,
	    HTMLView: HTMLView,
	    HTMLModel: HTMLModel,
	    LabelView: LabelView,
	    LabelModel: LabelModel,
	    TextareaView: TextareaView,
	    TextareaModel: TextareaModel,
	    TextView: TextView,
	    TextModel: TextModel
	};


/***/ },
/* 451 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	
	var widget = __webpack_require__(436);
	var utils= __webpack_require__(428);
	var _ = __webpack_require__(429);
	
	var ControllerButtonModel = widget.DOMWidgetModel.extend({
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        _model_name: 'ControllerButtonModel',
	        _view_name: 'ControllerButtonView',
	        value: 0.0,
	        pressed: false
	    })
	});
	
	var ControllerButtonView = widget.DOMWidgetView.extend({
	    /* Very simple view for a gamepad button. */
	
	    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 = 0;
	        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);
	    },
	
	    update: function() {
	        this.bar.style.height = 100 * this.model.get('value') + '%';
	    }
	});
	
	var ControllerAxisModel = widget.DOMWidgetModel.extend({
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        _model_name: 'ControllerAxisModel',
	        _view_name: 'ControllerAxisView',
	        value: 0.0
	    })
	});
	
	var ControllerAxisView = widget.DOMWidgetView.extend({
	    /* Very simple view for a gamepad axis. */
	    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();
	    },
	
	    update: function() {
	        this.bullet.style.top = 50 * (this.model.get('value') + 1) + '%';
	    }
	
	});
	
	var ControllerModel = widget.DOMWidgetModel.extend({
	    /* The Controller model. */
	    defaults: _.extend({}, widget.DOMWidgetModel.prototype.defaults, {
	        _model_name: 'ControllerModel',
	        _view_name: 'ControllerView',
	        index: 0,
	        name: '',
	        mapping: '',
	        connected: false,
	        timestamp: 0,
	        buttons: [],
	        axes: []
	    }),
	
	    initialize: function() {
	        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();
	            }
	        }
	    },
	
	    wait_loop: function() {
	        /* 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.
	         */
	        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));
	        }
	    },
	
	    setup: function(pad) {
	        /* 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,
	         * }
	         */
	        // 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_loop: function() {
	        /* Update axes and buttons values, until the gamepad is disconnected.
	         * When the gamepad is disconnected, this.reset_gamepad is called.
	         */
	        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();
	        }
	    },
	
	    reset_gamepad: function() {
	        /* Resets the gamepad attributes, and start the wait_loop.
	         */
	        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));
	    },
	
	    _create_button_model: function(index) {
	        /* Creates a gamepad button widget.
	         */
	        return this.widget_manager.new_widget({
	             model_name: 'ControllerButtonModel',
	             model_module: 'jupyter-js-widgets',
	             widget_class: 'Jupyter.ControllerButton',
	        }).then(function(model) {
	             model.set('description', index);
	             return model;
	        });
	    },
	
	    _create_axis_model: function(index) {
	        /* Creates a gamepad axis widget.
	         */
	        return this.widget_manager.new_widget({
	             model_name: 'ControllerAxisModel',
	             model_module: 'jupyter-js-widgets',
	             widget_class: 'Jupyter.ControllerAxis',
	        }).then(function(model) {
	             model.set('description', index);
	             return model;
	        });
	    }
	
	}, {
	    serializers: _.extend({
	        buttons: {deserialize: widget.unpack_models},
	        axes: {deserialize: widget.unpack_models}
	    }, widget.DOMWidgetModel.serializers)
	});
	
	var ControllerView = widget.DOMWidgetView.extend({
	    /* A simple view for a gamepad. */
	
	    initialize: function() {
	        ControllerView.__super__.initialize.apply(this, arguments);
	
	        this.button_views = new widget.ViewList(this.add_button, null, this);
	        this.listenTo(this.model, 'change:buttons', function(model, value) {
	            this.button_views.update(value);
	        }, this);
	
	        this.axis_views = new widget.ViewList(this.add_axis, null, this);
	        this.listenTo(this.model, 'change:axes', function(model, value) {
	            this.axis_views.update(value);
	        }, this);
	
	        this.listenTo(this.model, 'change:name', this.update_label, this);
	    },
	
	    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();
	    },
	
	    update_label: function() {
	        this.label.textContent = this.model.get('name') || this.model.readout;
	    },
	
	    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));
	    },
	
	    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));
	    },
	
	    remove: function() {
	        ControllerView.__super__.remove.apply(this, arguments);
	        this.button_views.remove();
	        this.axis_views.remove();
	    }
	
	});
	
	module.exports = {
	    ControllerButtonView: ControllerButtonView,
	    ControllerButtonModel: ControllerButtonModel,
	    ControllerAxisView: ControllerAxisView,
	    ControllerAxisModel: ControllerAxisModel,
	    ControllerModel: ControllerModel,
	    ControllerView: ControllerView
	};


/***/ },
/* 452 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(453);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../../css-loader/index.js!./jquery-ui.min.css", function() {
				var newContent = require("!!./../../../css-loader/index.js!./jquery-ui.min.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 453 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "/*! jQuery UI - v1.10.4 - 2014-01-17\n* http://jqueryui.com\n* Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css\n* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px\n* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */\n\n.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:\"\";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;min-height:0}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;width:100%;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;min-height:0;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url(" + __webpack_require__(454) + ");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff url(" + __webpack_require__(455) + ") 50% 50% repeat-x;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url(" + __webpack_require__(456) + ") 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url(" + __webpack_require__(457) + ") 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url(" + __webpack_require__(458) + ") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url(" + __webpack_require__(459) + ") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url(" + __webpack_require__(460) + ") 50% 50% repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url(" + __webpack_require__(461) + ") 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url(" + __webpack_require__(462) + ")}.ui-widget-header .ui-icon{background-image:url(" + __webpack_require__(462) + ")}.ui-state-default .ui-icon{background-image:url(" + __webpack_require__(463) + ")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(" + __webpack_require__(464) + ")}.ui-state-active .ui-icon{background-image:url(" + __webpack_require__(464) + ")}.ui-state-highlight .ui-icon{background-image:url(" + __webpack_require__(465) + ")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(" + __webpack_require__(466) + ")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa url(" + __webpack_require__(467) + ") 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url(" + __webpack_require__(467) + ") 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}", ""]);
	
	// exports


/***/ },
/* 454 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "2b912f7c0653008ca28ebacda49025e7.gif";

/***/ },
/* 455 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "526043fecdd7256ac10bad4f823106c2.png";

/***/ },
/* 456 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "90c599d828988b99f5f683dbcb7454fe.png";

/***/ },
/* 457 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "b80c321cdb09746d881e6b9227fa4491.png";

/***/ },
/* 458 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "9101d59cbaae907090ec73466b2ae2af.png";

/***/ },
/* 459 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "c21ec2fd0054b39327298bf6cb158de4.png";

/***/ },
/* 460 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "88bce39a36f4e4c6186745b8df0bc60e.png";

/***/ },
/* 461 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "04df298d4d61db8edc888752745188ae.png";

/***/ },
/* 462 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "f8d707feae7c0e86544b6ca24161c536.png";

/***/ },
/* 463 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "6a373d461dc6968f4731c7fb1290eb3f.png";

/***/ },
/* 464 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "afa9fddb92eb250e309d9148bb62f43f.png";

/***/ },
/* 465 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "585392137cf5132c9aeb8de9cf729be6.png";

/***/ },
/* 466 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "04a5ee7f2a6c642f5705f7df873a1f24.png";

/***/ },
/* 467 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "5db425e1bb5ba30e906a9e729d519e28.png";

/***/ },
/* 468 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(469);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../css-loader/index.js!./widgets.min.css", function() {
				var newContent = require("!!./../../css-loader/index.js!./widgets.min.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 469 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, ".widget-modal-backdrop{position:absolute;left:0;top:0;width:100%;height:100%;background:#000;z-index:999;opacity:.5;display:flex;align-items:center;justify-content:center;flex-direction:column}.widget-modal-backdrop.widget-modal-hidden{display:none}.widget-modal-backdrop.widget-modal-hide{animation:fadeout .25s}.widget-modal-backdrop.widget-modal-show{animation:fadein .25s}@keyframes fadein{from{opacity:0}to{opacity:.5}}@keyframes fadeout{from{opacity:.5}to{opacity:0}}.widget-modal-text{color:#fff;font-size:x-large;font-weight:700}.widget-modal-text div,.widget-modal-text i{display:inline}.widget-modal-text div{padding-left:1ex}.widget-modal-progress{width:300px}.jupyter-widgets{margin:2px}.jupyter-widgets.widget-container{margin:0}.widget-area{page-break-inside:avoid;-webkit-box-orient:horizontal;-webkit-box-align:stretch;-moz-box-orient:horizontal;-moz-box-align:stretch;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}.widget-area .widget-subarea{padding:.4em 0;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2;-webkit-box-orient:vertical;-webkit-box-align:stretch;-moz-box-orient:vertical;-moz-box-align:stretch;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch}.widget-area.connection-problems .prompt:after{content:\"\\F127\";font-family:FontAwesome;color:#d9534f;top:3px;padding:3px}.slide-track{border:1px solid #CCC;background:#FFF;border-radius:2px}.widget-hslider{width:300px}.widget-hslider .slider-container{padding-left:8px;padding-right:2px;overflow:visible;flex-grow:1;height:5px;max-height:5px;margin-top:15px;margin-bottom:12px;border:1px solid #CCC;background:#FFF;border-radius:2px;-webkit-box-orient:horizontal;-webkit-box-align:stretch;-moz-box-orient:horizontal;-moz-box-align:stretch;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}.widget-hslider .slider-container .ui-slider{-webkit-box-orient:horizontal;-webkit-box-align:stretch;-moz-box-orient:horizontal;-moz-box-align:stretch;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1;border:0;background:0 0}.widget-hslider .slider-container .ui-slider .ui-slider-handle{width:12px;height:28px;margin-top:-8px;border-radius:2px}.widget-hslider .slider-container .ui-slider .ui-slider-range{height:12px;margin-top:-4px}.widget-vslider{width:50px;height:250px}.widget-vslider .slider-container{padding-bottom:5px;overflow:visible;flex-grow:1;width:5px;max-width:5px;margin-left:auto;margin-right:auto;border:1px solid #CCC;background:#FFF;border-radius:2px;-webkit-box-orient:vertical;-webkit-box-align:stretch;-moz-box-orient:vertical;-moz-box-align:stretch;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch}.widget-vslider .slider-container .ui-slider{-webkit-box-orient:vertical;-webkit-box-align:stretch;-moz-box-orient:vertical;-moz-box-align:stretch;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1;border:0;background:0 0;margin-left:-4px;margin-top:5px}.widget-vslider .slider-container .ui-slider .ui-slider-handle{width:28px;height:12px;margin-left:-9px;border-radius:2px}.widget-vslider .slider-container .ui-slider .ui-slider-range{width:12px;margin-left:-1px}.widget-colorpicker{width:300px;display:flex}.widget-colorpicker.short{width:148px}.widget-colorpicker .widget-hbox,.widget-colorpicker input[type=text]{flex-grow:1}.widget-checkbox{width:148px;height:32px}.widget-button,.widget-toggle-button{background:#888;border:1px solid #111;color:#eee;cursor:pointer;display:inline-block;text-align:center;vertical-align:middle;white-space:nowrap;width:148px;height:32px;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.widget-button i.fa,.widget-toggle-button i.fa{padding-right:3px}.widget-button:hover,.widget-toggle-button:hover{outline:0!important}.widget-button:active,.widget-toggle-button:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.widget-button:empty:before,.widget-toggle-button:empty:before{content:\"\\A0\"}.widget-button.mod-primary,.widget-toggle-button.mod-primary{background-color:#337ab7;border-color:#245580;color:#eee}.widget-button.mod-success,.widget-toggle-button.mod-success{background-color:#5cb85c;border-color:#3e8f3e;color:#eee}.widget-button.mod-info,.widget-toggle-button.mod-info{background-color:#5bc0de;border-color:#28a4c9;color:#eee}.widget-button.mod-warning,.widget-toggle-button.mod-warning{background-color:#f0ad4e;border-color:#e38d13;color:#eee}.widget-button.mod-danger,.widget-toggle-button.mod-danger{background-color:#d9534f;border-color:#b92c28;color:#eee}.widget-button.mod-active,.widget-toggle-button.mod-active{border-color:#000;color:#000}.widget-toggle-buttons button{margin:2px;min-width:100px}.widget-tab{height:100%}.widget-tab .widget-tab-contents{height:100%}.widget-tab .widget-tab-contents .widget-tab-child{display:none;height:100%}.widget-tab .widget-tab-contents .widget-tab-child.mod-active{display:block}.widget-tab .widget-tab-bar.p-TabBar{min-height:28px;max-height:28px;color:#757575;background:#F5F5F5;font:12px Helvetica,Arial,sans-serif}.widget-tab .widget-tab-bar.p-TabBar>.p-TabBar-header{flex:0 0 1px;background:#BDBDBD}.widget-tab .widget-tab-bar.p-TabBar>.p-TabBar-footer{flex:0 0 3px;background:#FAFAFA;border-top:1px solid #BDBDBD;border-bottom:1px solid #E0E0E0}.widget-tab .widget-tab-bar .p-TabBar-content{min-width:0;max-height:22px}.widget-tab .widget-tab-bar .p-TabBar-tab{flex-basis:124px;min-height:23px;max-height:23px;min-width:35px;margin-left:-1px;padding:0 10px;background:#EEE;border:1px solid #BDBDBD;border-bottom:none;transform:translateY(-1px)}.widget-tab .widget-tab-bar .p-TabBar-tab:last-child{margin-right:-1px}.widget-tab .widget-tab-bar .p-TabBar-tab.p-mod-current{min-height:24px;max-height:24px;background:#FAFAFA;border-top:1px solid #F27624}.widget-tab .widget-tab-bar .p-TabBar-tab:hover:not(.p-mod-current){background:#FAFAFA}.widget-tab .widget-tab-bar .p-TabBar-tab.p-mod-closable>.p-TabBar-tabCloseIcon{margin-left:4px}.widget-tab .widget-tab-bar .p-TabBar-tab.p-mod-closable>.p-TabBar-tabCloseIcon:before{font-family:FontAwesome;content:'\\F00D'}.widget-tab .widget-tab-bar .p-TabBar-tabCloseIcon,.widget-tab .widget-tab-bar .p-TabBar-tabIcon,.widget-tab .widget-tab-bar .p-TabBar-tabText{line-height:22px}.widget-text{width:300px}.widget-textarea{width:300px}.widget-listbox{width:300px}.widget-select-multiple{width:300px}.widget-dropdown{display:block;height:32px;width:300px}.widget-dropdown.short{width:148px}.widget-dropdown .widget-button{width:auto}.widget-dropdown div.widget-item{display:flex;flex-grow:1;margin:0;padding:0}.widget-dropdown div.widget-item button{flex:1;outline:0}.widget-dropdown div.widget-item button:last-child{flex:0;flex-basis:2em;margin-left:-1px}.widget-dropdown div.widget-item button:last-child i.widget-caret{font-size:1em;font-style:normal;font-family:FontAwesome;line-height:1em;position:relative}.widget-dropdown div.widget-item button:last-child i.widget-caret:before{content:\"\\F0D7\"}ul.widget-dropdown-droplist{background:#eee;border-width:1px;border-style:solid;border-color:#ddd;box-sizing:border-box;list-style-type:none;position:absolute;margin:0;z-index:101;padding:0;height:auto;overflow:auto;display:none}ul.widget-dropdown-droplist a{color:inherit;text-decoration:none}ul.widget-dropdown-droplist li{display:block;padding:0 5px}ul.widget-dropdown-droplist li:hover{background:#ddd}ul.widget-dropdown-droplist li.mod-active{background:#999;color:#eee}ul.widget-dropdown-droplist.mod-active{display:block}.widget-hprogress{width:300px;height:32px}.widget-hprogress .progress{flex-grow:1;margin-top:auto;margin-bottom:auto}.widget-hprogress .progress-bar{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}.widget-vprogress{height:250px;width:50px}.widget-vprogress .progress{flex-grow:1;width:12px;margin-left:auto;margin-right:auto;margin-bottom:0}.widget-vprogress .progress-bar{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}.widget-combo-btn{min-width:123px}.widget_item .dropdown-menu li a{color:inherit}.widget-valid{font-size:1em;position:relative}.widget-valid i{margin-right:1.5em}.widget-valid i:before{font-family:FontAwesome;font-style:normal;font-size:1.5em;position:absolute;top:0}.widget-valid.mod-valid{color:green}.widget-valid.mod-valid i:before{content:\"\\F00C\"}.widget-valid.mod-invalid{color:red}.widget-valid.mod-invalid i:before{content:\"\\F00D\"}.widget-hbox{-webkit-box-orient:horizontal;-webkit-box-align:stretch;-moz-box-orient:horizontal;-moz-box-align:stretch;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}.widget-hbox input[type=checkbox]{margin-top:10px;margin-bottom:10px}.widget-hbox input[type=color]{height:32px;width:28px;padding:1px}.widget-hbox .widget-label{min-width:10ex;max-width:10ex;padding-right:8px;padding-top:5px;text-align:right;vertical-align:text-top;word-wrap:break-word}.widget-hbox .widget-readout{padding-left:4px;padding-top:5px;height:32px;text-align:center;vertical-align:text-top;min-width:7em;max-width:7em;margin-left:3px;overflow:hidden;white-space:nowrap}.widget-hbox .widget-readout.overflow{-webkit-box-shadow:0 0 0 1px rgba(77,0,0,.15);-moz-box-shadow:0 0 0 1px rgba(77,0,0,.15);box-shadow:0 0 0 1px rgba(77,0,0,.15)}.widget-vbox{-webkit-box-orient:vertical;-webkit-box-align:stretch;-moz-box-orient:vertical;-moz-box-align:stretch;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch}.widget-vbox input[type=color]{height:32px;padding:1px}.widget-vbox .widget-label{padding-bottom:5px;text-align:center;vertical-align:text-bottom}.widget-vbox .widget-readout{padding-top:5px;white-space:nowrap;text-align:center;vertical-align:text-top;margin-top:4px;overflow:hidden}.widget-vbox .widget-readout.overflow{-webkit-box-shadow:0 0 0 1px rgba(77,0,0,.15);-moz-box-shadow:0 0 0 1px rgba(77,0,0,.15);box-shadow:0 0 0 1px rgba(77,0,0,.15)}.widget-box{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start}.widget-radio-box{-webkit-box-orient:vertical;-webkit-box-align:stretch;-moz-box-orient:vertical;-moz-box-align:stretch;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding-top:4px}.widget-radio-box label{margin-top:2px;margin-bottom:2px;margin-left:22px}.widget-radio-box input{float:left;margin-right:5px}/*# sourceMappingURL=widgets.min.css.map */", ""]);
	
	// exports


/***/ },
/* 470 */
/***/ function(module, exports, __webpack_require__) {

	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2016, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	'use strict';
	var phosphor_commandpalette_1 = __webpack_require__(54);
	/**
	 * The default commmand palette extension.
	 */
	exports.commandPaletteExtension = {
	    id: 'phosphide.extensions.commandPalette',
	    activate: activateCommandPalette
	};
	/**
	 *
	 */
	function activateCommandPalette(app) {
	    var widget = new phosphor_commandpalette_1.CommandPalette();
	    widget.id = 'command-palette';
	    widget.title.text = 'Commands';
	    widget.model = app.palette.model;
	    app.commands.add([
	        { id: 'command-palette:toggle', handler: togglePalette },
	        { id: 'command-palette:activate', handler: activatePalette },
	        { id: 'command-palette:hide', handler: hidePalette }
	    ]);
	    app.shell.addToLeftArea(widget);
	    return Promise.resolve();
	    function activatePalette() {
	        app.shell.activateLeft(widget.id);
	        widget.inputNode.focus();
	        widget.inputNode.select();
	    }
	    function hidePalette() {
	        if (!widget.isHidden)
	            app.shell.collapseLeft();
	    }
	    function togglePalette() {
	        if (widget.isHidden) {
	            activatePalette();
	        }
	        else {
	            hidePalette();
	        }
	    }
	}


/***/ },
/* 471 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var phosphor_dragdrop_1 = __webpack_require__(31);
	/**
	 * The clipboard provider.
	 */
	exports.clipboardProvider = {
	    id: 'jupyter.services.clipboard',
	    provides: phosphor_dragdrop_1.MimeData,
	    resolve: function () {
	        return new phosphor_dragdrop_1.MimeData();
	    }
	};


/***/ },
/* 472 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var docmanager_1 = __webpack_require__(274);
	/**
	 * The default document registry provider.
	 */
	exports.docRegistryProvider = {
	    id: 'jupyter.services.document-registry',
	    provides: docmanager_1.DocumentRegistry,
	    resolve: function () {
	        var registry = new docmanager_1.DocumentRegistry();
	        registry.registerModelFactory(new docmanager_1.TextModelFactory());
	        registry.registerModelFactory(new docmanager_1.Base64ModelFactory());
	        return registry;
	    }
	};


/***/ },
/* 473 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	var index_1 = __webpack_require__(273);
	var renderers_1 = __webpack_require__(474);
	/**
	 * The default rendermime provider.
	 */
	exports.renderMimeProvider = {
	    id: 'jupyter.services.rendermime',
	    provides: index_1.RenderMime,
	    resolve: function () {
	        var transformers = [
	            new renderers_1.JavascriptRenderer(),
	            new renderers_1.MarkdownRenderer(),
	            new renderers_1.HTMLRenderer(),
	            new renderers_1.ImageRenderer(),
	            new renderers_1.SVGRenderer(),
	            new renderers_1.LatexRenderer(),
	            new renderers_1.TextRenderer()
	        ];
	        var renderers = {};
	        var order = [];
	        for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
	            var t = transformers_1[_i];
	            for (var _a = 0, _b = t.mimetypes; _a < _b.length; _a++) {
	                var m = _b[_a];
	                renderers[m] = t;
	                order.push(m);
	            }
	        }
	        return new index_1.RenderMime(renderers, order);
	    }
	};


/***/ },
/* 474 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || function (d, b) {
	    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	    function __() { this.constructor = d; }
	    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	};
	var marked = __webpack_require__(475);
	var ansi_up_1 = __webpack_require__(476);
	var phosphor_widget_1 = __webpack_require__(20);
	var latex_1 = __webpack_require__(477);
	/**
	 * A widget for displaying HTML and rendering math.
	 */
	var HTMLWidget = (function (_super) {
	    __extends(HTMLWidget, _super);
	    function HTMLWidget(html) {
	        _super.call(this);
	        try {
	            var range = document.createRange();
	            this.node.appendChild(range.createContextualFragment(html));
	        }
	        catch (error) {
	            console.warn('Environment does not support Range ' +
	                'createContextualFragment, falling back on innerHTML');
	            this.node.innerHTML = html;
	        }
	    }
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     *
	     * ####Notes
	     * If the node is visible, it is typeset.
	     */
	    HTMLWidget.prototype.onAfterAttach = function (msg) {
	        latex_1.typeset(this.node);
	    };
	    return HTMLWidget;
	}(phosphor_widget_1.Widget));
	exports.HTMLWidget = HTMLWidget;
	/**
	 * A widget for displaying text and rendering math.
	 */
	var LatexWidget = (function (_super) {
	    __extends(LatexWidget, _super);
	    function LatexWidget(text) {
	        _super.call(this);
	        text = text.replace(/<br>|\$\$|^\$|\$$|\\\(|\\\)|\\\[|\\\]/g, '');
	        this.node.innerHTML = text;
	    }
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     *
	     * ####Notes
	     * If the node is visible, it is typeset.
	     */
	    LatexWidget.prototype.onAfterAttach = function (msg) {
	        latex_1.typeset(this.node);
	    };
	    return LatexWidget;
	}(phosphor_widget_1.Widget));
	exports.LatexWidget = LatexWidget;
	/**
	 * A renderer for raw html.
	 */
	var HTMLRenderer = (function () {
	    function HTMLRenderer() {
	        this.mimetypes = ['text/html'];
	    }
	    HTMLRenderer.prototype.render = function (mimetype, data) {
	        return new HTMLWidget(data);
	    };
	    return HTMLRenderer;
	}());
	exports.HTMLRenderer = HTMLRenderer;
	/**
	 * A renderer for `<img>` data.
	 */
	var ImageRenderer = (function () {
	    function ImageRenderer() {
	        this.mimetypes = ['image/png', 'image/jpeg', 'image/gif'];
	    }
	    ImageRenderer.prototype.render = function (mimetype, data) {
	        var w = new phosphor_widget_1.Widget();
	        var img = document.createElement('img');
	        img.src = "data:" + mimetype + ";base64," + data;
	        w.node.appendChild(img);
	        return w;
	    };
	    return ImageRenderer;
	}());
	exports.ImageRenderer = ImageRenderer;
	/**
	 * A renderer for plain text and Jupyter console text data.
	 */
	var TextRenderer = (function () {
	    function TextRenderer() {
	        this.mimetypes = ['text/plain', 'application/vnd.jupyter.console-text'];
	    }
	    TextRenderer.prototype.render = function (mimetype, data) {
	        var w = new phosphor_widget_1.Widget();
	        var el = document.createElement('pre');
	        var esc = ansi_up_1.escape_for_html(data);
	        el.innerHTML = ansi_up_1.ansi_to_html(esc);
	        w.node.appendChild(el);
	        return w;
	    };
	    return TextRenderer;
	}());
	exports.TextRenderer = TextRenderer;
	/**
	 * A renderer for raw `<script>` data.
	 */
	var JavascriptRenderer = (function () {
	    function JavascriptRenderer() {
	        this.mimetypes = ['text/javascript', 'application/javascript'];
	    }
	    JavascriptRenderer.prototype.render = function (mimetype, data) {
	        var w = new phosphor_widget_1.Widget();
	        var s = document.createElement('script');
	        s.type = mimetype;
	        s.textContent = data;
	        w.node.appendChild(s);
	        return w;
	    };
	    return JavascriptRenderer;
	}());
	exports.JavascriptRenderer = JavascriptRenderer;
	/**
	 * A renderer for `<svg>` data.
	 */
	var SVGRenderer = (function () {
	    function SVGRenderer() {
	        this.mimetypes = ['image/svg+xml'];
	    }
	    SVGRenderer.prototype.render = function (mimetype, data) {
	        var w = new phosphor_widget_1.Widget();
	        w.node.innerHTML = data;
	        var svgElement = w.node.getElementsByTagName('svg')[0];
	        if (!svgElement) {
	            throw new Error('SVGRender: Error: Failed to create <svg> element');
	        }
	        return w;
	    };
	    return SVGRenderer;
	}());
	exports.SVGRenderer = SVGRenderer;
	/**
	 * A renderer for PDF data.
	 */
	var PDFRenderer = (function () {
	    function PDFRenderer() {
	        this.mimetypes = ['application/pdf'];
	    }
	    PDFRenderer.prototype.render = function (mimetype, data) {
	        var w = new phosphor_widget_1.Widget();
	        var a = document.createElement('a');
	        a.target = '_blank';
	        a.textContent = "View PDF";
	        a.href = 'data:application/pdf;base64,' + data;
	        w.node.appendChild(a);
	        return w;
	    };
	    return PDFRenderer;
	}());
	exports.PDFRenderer = PDFRenderer;
	/**
	 * A renderer for LateX data.
	 */
	var LatexRenderer = (function () {
	    function LatexRenderer() {
	        this.mimetypes = ['text/latex'];
	    }
	    LatexRenderer.prototype.render = function (mimetype, data) {
	        return new LatexWidget(data);
	    };
	    return LatexRenderer;
	}());
	exports.LatexRenderer = LatexRenderer;
	/**
	 * A renderer for Jupyter Markdown data.
	 */
	var MarkdownRenderer = (function () {
	    function MarkdownRenderer() {
	        this.mimetypes = ['text/markdown'];
	    }
	    MarkdownRenderer.prototype.render = function (mimetype, text) {
	        var data = latex_1.removeMath(text);
	        var html = marked(data['text']);
	        return new HTMLWidget(latex_1.replaceMath(html, data['math']));
	    };
	    return MarkdownRenderer;
	}());
	exports.MarkdownRenderer = MarkdownRenderer;


/***/ },
/* 475 */
/***/ function(module, exports, __webpack_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) {
	  return html.replace(/&([#\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; }())))

/***/ },
/* 476 */
/***/ function(module, exports, __webpack_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);


/***/ },
/* 477 */
/***/ function(module, exports) {

	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	// 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') ? '~' : '$'; });
	        };
	    }
	    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.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) {
	    text = text.replace(/@@(\d+)@@/g, function (match, n) { return math[n]; });
	    return text;
	}
	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 }
	        }
	    });
	    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;');
	    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;
	}
	;


/***/ }
/******/ ]);
//# sourceMappingURL=bundle.js.map