From bcc465d26b0f2c983e393998066d24398648030d Mon Sep 17 00:00:00 2001 From: Pomax Date: Fri, 31 Mar 2017 09:04:05 -0700 Subject: [PATCH] . --- article.js | 49722 +------------------------------------ en-GB/article.js | 49722 +------------------------------------ lib/vendor/bezier.js | 1 + lib/vendor/chroma.min.js | 33 + package.json | 7 +- 5 files changed, 91 insertions(+), 99394 deletions(-) create mode 100644 lib/vendor/bezier.js create mode 100644 lib/vendor/chroma.min.js diff --git a/article.js b/article.js index 710b40fc..0fad81db 100644 --- a/article.js +++ b/article.js @@ -1,6791 +1,5 @@ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else if(typeof exports === 'object') - exports["BezierArticle"] = factory(); - else - root["BezierArticle"] = factory(); -})(this, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; - -/******/ // 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] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; - -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - -/******/ // Flag the module as loaded -/******/ module.l = true; - -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } - - -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; - -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; - -/******/ // identity function for calling harmony imports with the correct context -/******/ __webpack_require__.i = function(value) { return value; }; - -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; - -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; - -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; - -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; - -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 337); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports) { - -// shim for using process in browser -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; - -process.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; }; - - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); -var Locale = __webpack_require__(68); -var locale = new Locale(); - -module.exports = function generateBase(page, handler) { - - // the basic class just has a title and basic content. - var componentClass = { - getDefaultProps: function getDefaultProps() { - return { - title: locale.getTitle(page) - }; - }, - - render: function render() { - return locale.getContent(page, this); - } - }; - - // if the content requires code bindings, ensure those exist: - if (handler) { - Object.keys(handler).forEach(function (key) { - componentClass[key] = handler[key]; - }); - } - - // then build the actual React class - return React.createClass(componentClass); -}; - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ - -var validateFormat = function validateFormat(format) {}; - -if (process.env.NODE_ENV !== 'production') { - validateFormat = function validateFormat(format) { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - }; -} - -function invariant(condition, format, a, b, c, d, e, f) { - validateFormat(format); - - if (!condition) { - var error; - if (format === undefined) { - error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error(format.replace(/%s/g, function () { - return args[argIndex++]; - })); - error.name = 'Invariant Violation'; - } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -} - -module.exports = invariant; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var emptyFunction = __webpack_require__(12); - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = emptyFunction; - -if (process.env.NODE_ENV !== 'production') { - (function () { - var printWarning = function printWarning(format) { - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - var argIndex = 0; - var message = 'Warning: ' + format.replace(/%s/g, function () { - return args[argIndex++]; - }); - if (typeof console !== 'undefined') { - console.error(message); - } - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch (x) {} - }; - - warning = function warning(condition, format) { - if (format === undefined) { - throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); - } - - if (format.indexOf('Failed Composite propType: ') === 0) { - return; // Ignore CompositeComponent proptype check. - } - - if (!condition) { - for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { - args[_key2 - 2] = arguments[_key2]; - } - - printWarning.apply(undefined, [format].concat(args)); - } - }; - })(); -} - -module.exports = warning; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - -/** - * WARNING: DO NOT manually require this module. - * This is a replacement for `invariant(...)` used by the error code system - * and will _only_ be required by the corresponding babel pass. - * It always throws. - */ - -function reactProdInvariant(code) { - var argCount = arguments.length - 1; - - var message = 'Minified React error #' + code + '; visit ' + 'http://facebook.github.io/react/docs/error-decoder.html?invariant=' + code; - - for (var argIdx = 0; argIdx < argCount; argIdx++) { - message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]); - } - - message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.'; - - var error = new Error(message); - error.name = 'Invariant Violation'; - error.framesToPop = 1; // we don't care about reactProdInvariant's own frame - - throw error; -} - -module.exports = reactProdInvariant; - -/***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = __webpack_require__(27); - - -/***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -/* eslint-disable no-unused-vars */ -var hasOwnProperty = Object.prototype.hasOwnProperty; -var propIsEnumerable = Object.prototype.propertyIsEnumerable; - -function toObject(val) { - if (val === null || val === undefined) { - throw new TypeError('Object.assign cannot be called with null or undefined'); - } - - return Object(val); -} - -function shouldUseNative() { - try { - if (!Object.assign) { - return false; - } - - // Detect buggy property enumeration order in older V8 versions. - - // https://bugs.chromium.org/p/v8/issues/detail?id=4118 - var test1 = new String('abc'); // eslint-disable-line - test1[5] = 'de'; - if (Object.getOwnPropertyNames(test1)[0] === '5') { - return false; - } - - // https://bugs.chromium.org/p/v8/issues/detail?id=3056 - var test2 = {}; - for (var i = 0; i < 10; i++) { - test2['_' + String.fromCharCode(i)] = i; - } - var order2 = Object.getOwnPropertyNames(test2).map(function (n) { - return test2[n]; - }); - if (order2.join('') !== '0123456789') { - return false; - } - - // https://bugs.chromium.org/p/v8/issues/detail?id=3056 - var test3 = {}; - 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { - test3[letter] = letter; - }); - if (Object.keys(Object.assign({}, test3)).join('') !== - 'abcdefghijklmnopqrst') { - return false; - } - - return true; - } catch (e) { - // We don't expect any of the above to throw, but better to be safe. - return false; - } -} - -module.exports = shouldUseNative() ? Object.assign : function (target, source) { - var from; - var to = toObject(target); - var symbols; - - for (var s = 1; s < arguments.length; s++) { - from = Object(arguments[s]); - - for (var key in from) { - if (hasOwnProperty.call(from, key)) { - to[key] = from[key]; - } - } - - if (Object.getOwnPropertySymbols) { - symbols = Object.getOwnPropertySymbols(from); - for (var i = 0; i < symbols.length; i++) { - if (propIsEnumerable.call(from, symbols[i])) { - to[symbols[i]] = from[symbols[i]]; - } - } - } - } - - return to; -}; - - -/***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var DOMProperty = __webpack_require__(18); -var ReactDOMComponentFlags = __webpack_require__(81); - -var invariant = __webpack_require__(2); - -var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; -var Flags = ReactDOMComponentFlags; - -var internalInstanceKey = '__reactInternalInstance$' + Math.random().toString(36).slice(2); - -/** - * Check if a given node should be cached. - */ -function shouldPrecacheNode(node, nodeID) { - return node.nodeType === 1 && node.getAttribute(ATTR_NAME) === String(nodeID) || node.nodeType === 8 && node.nodeValue === ' react-text: ' + nodeID + ' ' || node.nodeType === 8 && node.nodeValue === ' react-empty: ' + nodeID + ' '; -} - -/** - * Drill down (through composites and empty components) until we get a host or - * host text component. - * - * This is pretty polymorphic but unavoidable with the current structure we have - * for `_renderedChildren`. - */ -function getRenderedHostOrTextFromComponent(component) { - var rendered; - while (rendered = component._renderedComponent) { - component = rendered; - } - return component; -} - -/** - * Populate `_hostNode` on the rendered host/text component with the given - * DOM node. The passed `inst` can be a composite. - */ -function precacheNode(inst, node) { - var hostInst = getRenderedHostOrTextFromComponent(inst); - hostInst._hostNode = node; - node[internalInstanceKey] = hostInst; -} - -function uncacheNode(inst) { - var node = inst._hostNode; - if (node) { - delete node[internalInstanceKey]; - inst._hostNode = null; - } -} - -/** - * Populate `_hostNode` on each child of `inst`, assuming that the children - * match up with the DOM (element) children of `node`. - * - * We cache entire levels at once to avoid an n^2 problem where we access the - * children of a node sequentially and have to walk from the start to our target - * node every time. - * - * Since we update `_renderedChildren` and the actual DOM at (slightly) - * different times, we could race here and see a newer `_renderedChildren` than - * the DOM nodes we see. To avoid this, ReactMultiChild calls - * `prepareToManageChildren` before we change `_renderedChildren`, at which - * time the container's child nodes are always cached (until it unmounts). - */ -function precacheChildNodes(inst, node) { - if (inst._flags & Flags.hasCachedChildNodes) { - return; - } - var children = inst._renderedChildren; - var childNode = node.firstChild; - outer: for (var name in children) { - if (!children.hasOwnProperty(name)) { - continue; - } - var childInst = children[name]; - var childID = getRenderedHostOrTextFromComponent(childInst)._domID; - if (childID === 0) { - // We're currently unmounting this child in ReactMultiChild; skip it. - continue; - } - // We assume the child nodes are in the same order as the child instances. - for (; childNode !== null; childNode = childNode.nextSibling) { - if (shouldPrecacheNode(childNode, childID)) { - precacheNode(childInst, childNode); - continue outer; - } - } - // We reached the end of the DOM children without finding an ID match. - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Unable to find element with ID %s.', childID) : _prodInvariant('32', childID) : void 0; - } - inst._flags |= Flags.hasCachedChildNodes; -} - -/** - * Given a DOM node, return the closest ReactDOMComponent or - * ReactDOMTextComponent instance ancestor. - */ -function getClosestInstanceFromNode(node) { - if (node[internalInstanceKey]) { - return node[internalInstanceKey]; - } - - // Walk up the tree until we find an ancestor whose instance we have cached. - var parents = []; - while (!node[internalInstanceKey]) { - parents.push(node); - if (node.parentNode) { - node = node.parentNode; - } else { - // Top of the tree. This node must not be part of a React tree (or is - // unmounted, potentially). - return null; - } - } - - var closest; - var inst; - for (; node && (inst = node[internalInstanceKey]); node = parents.pop()) { - closest = inst; - if (parents.length) { - precacheChildNodes(inst, node); - } - } - - return closest; -} - -/** - * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent - * instance, or null if the node was not rendered by this React. - */ -function getInstanceFromNode(node) { - var inst = getClosestInstanceFromNode(node); - if (inst != null && inst._hostNode === node) { - return inst; - } else { - return null; - } -} - -/** - * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding - * DOM node. - */ -function getNodeFromInstance(inst) { - // Without this first invariant, passing a non-DOM-component triggers the next - // invariant for a missing parent, which is super confusing. - !(inst._hostNode !== undefined) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0; - - if (inst._hostNode) { - return inst._hostNode; - } - - // Walk up the tree until we find an ancestor whose DOM node we have cached. - var parents = []; - while (!inst._hostNode) { - parents.push(inst); - !inst._hostParent ? process.env.NODE_ENV !== 'production' ? invariant(false, 'React DOM tree root should always have a node reference.') : _prodInvariant('34') : void 0; - inst = inst._hostParent; - } - - // Now parents contains each ancestor that does *not* have a cached native - // node, and `inst` is the deepest ancestor that does. - for (; parents.length; inst = parents.pop()) { - precacheChildNodes(inst, inst._hostNode); - } - - return inst._hostNode; -} - -var ReactDOMComponentTree = { - getClosestInstanceFromNode: getClosestInstanceFromNode, - getInstanceFromNode: getInstanceFromNode, - getNodeFromInstance: getNodeFromInstance, - precacheChildNodes: precacheChildNodes, - precacheNode: precacheNode, - uncacheNode: uncacheNode -}; - -module.exports = ReactDOMComponentTree; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); - -/** - * Simple, lightweight module assisting with the detection and context of - * Worker. Helps avoid circular dependencies and allows code to reason about - * whether or not they are in a Worker, even if they never include the main - * `ReactWorker` dependency. - */ -var ExecutionEnvironment = { - - canUseDOM: canUseDOM, - - canUseWorkers: typeof Worker !== 'undefined', - - canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent), - - canUseViewport: canUseDOM && !!window.screen, - - isInWorker: !canUseDOM // For now, this is true - might change in the future. - -}; - -module.exports = ExecutionEnvironment; - -/***/ }), -/* 9 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(23); - -var ReactCurrentOwner = __webpack_require__(15); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -function isNative(fn) { - // Based on isNative() from Lodash - var funcToString = Function.prototype.toString; - var hasOwnProperty = Object.prototype.hasOwnProperty; - var reIsNative = RegExp('^' + funcToString - // Take an example native function source for comparison - .call(hasOwnProperty) - // Strip regex characters so we can use it for regex - .replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') - // Remove hasOwnProperty from the template to make it generic - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'); - try { - var source = funcToString.call(fn); - return reIsNative.test(source); - } catch (err) { - return false; - } -} - -var canUseCollections = -// Array.from -typeof Array.from === 'function' && -// Map -typeof Map === 'function' && isNative(Map) && -// Map.prototype.keys -Map.prototype != null && typeof Map.prototype.keys === 'function' && isNative(Map.prototype.keys) && -// Set -typeof Set === 'function' && isNative(Set) && -// Set.prototype.keys -Set.prototype != null && typeof Set.prototype.keys === 'function' && isNative(Set.prototype.keys); - -var setItem; -var getItem; -var removeItem; -var getItemIDs; -var addRoot; -var removeRoot; -var getRootIDs; - -if (canUseCollections) { - var itemMap = new Map(); - var rootIDSet = new Set(); - - setItem = function (id, item) { - itemMap.set(id, item); - }; - getItem = function (id) { - return itemMap.get(id); - }; - removeItem = function (id) { - itemMap['delete'](id); - }; - getItemIDs = function () { - return Array.from(itemMap.keys()); - }; - - addRoot = function (id) { - rootIDSet.add(id); - }; - removeRoot = function (id) { - rootIDSet['delete'](id); - }; - getRootIDs = function () { - return Array.from(rootIDSet.keys()); - }; -} else { - var itemByKey = {}; - var rootByKey = {}; - - // Use non-numeric keys to prevent V8 performance issues: - // https://github.com/facebook/react/pull/7232 - var getKeyFromID = function (id) { - return '.' + id; - }; - var getIDFromKey = function (key) { - return parseInt(key.substr(1), 10); - }; - - setItem = function (id, item) { - var key = getKeyFromID(id); - itemByKey[key] = item; - }; - getItem = function (id) { - var key = getKeyFromID(id); - return itemByKey[key]; - }; - removeItem = function (id) { - var key = getKeyFromID(id); - delete itemByKey[key]; - }; - getItemIDs = function () { - return Object.keys(itemByKey).map(getIDFromKey); - }; - - addRoot = function (id) { - var key = getKeyFromID(id); - rootByKey[key] = true; - }; - removeRoot = function (id) { - var key = getKeyFromID(id); - delete rootByKey[key]; - }; - getRootIDs = function () { - return Object.keys(rootByKey).map(getIDFromKey); - }; -} - -var unmountedIDs = []; - -function purgeDeep(id) { - var item = getItem(id); - if (item) { - var childIDs = item.childIDs; - - removeItem(id); - childIDs.forEach(purgeDeep); - } -} - -function describeComponentFrame(name, source, ownerName) { - return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : ''); -} - -function getDisplayName(element) { - if (element == null) { - return '#empty'; - } else if (typeof element === 'string' || typeof element === 'number') { - return '#text'; - } else if (typeof element.type === 'string') { - return element.type; - } else { - return element.type.displayName || element.type.name || 'Unknown'; - } -} - -function describeID(id) { - var name = ReactComponentTreeHook.getDisplayName(id); - var element = ReactComponentTreeHook.getElement(id); - var ownerID = ReactComponentTreeHook.getOwnerID(id); - var ownerName; - if (ownerID) { - ownerName = ReactComponentTreeHook.getDisplayName(ownerID); - } - process.env.NODE_ENV !== 'production' ? warning(element, 'ReactComponentTreeHook: Missing React element for debugID %s when ' + 'building stack', id) : void 0; - return describeComponentFrame(name, element && element._source, ownerName); -} - -var ReactComponentTreeHook = { - onSetChildren: function (id, nextChildIDs) { - var item = getItem(id); - !item ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Item must have been set') : _prodInvariant('144') : void 0; - item.childIDs = nextChildIDs; - - for (var i = 0; i < nextChildIDs.length; i++) { - var nextChildID = nextChildIDs[i]; - var nextChild = getItem(nextChildID); - !nextChild ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected hook events to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('140') : void 0; - !(nextChild.childIDs != null || typeof nextChild.element !== 'object' || nextChild.element == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onSetChildren() to fire for a container child before its parent includes it in onSetChildren().') : _prodInvariant('141') : void 0; - !nextChild.isMounted ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onMountComponent() to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('71') : void 0; - if (nextChild.parentID == null) { - nextChild.parentID = id; - // TODO: This shouldn't be necessary but mounting a new root during in - // componentWillMount currently causes not-yet-mounted components to - // be purged from our tree data so their parent id is missing. - } - !(nextChild.parentID === id) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onBeforeMountComponent() parent and onSetChildren() to be consistent (%s has parents %s and %s).', nextChildID, nextChild.parentID, id) : _prodInvariant('142', nextChildID, nextChild.parentID, id) : void 0; - } - }, - onBeforeMountComponent: function (id, element, parentID) { - var item = { - element: element, - parentID: parentID, - text: null, - childIDs: [], - isMounted: false, - updateCount: 0 - }; - setItem(id, item); - }, - onBeforeUpdateComponent: function (id, element) { - var item = getItem(id); - if (!item || !item.isMounted) { - // We may end up here as a result of setState() in componentWillUnmount(). - // In this case, ignore the element. - return; - } - item.element = element; - }, - onMountComponent: function (id) { - var item = getItem(id); - !item ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Item must have been set') : _prodInvariant('144') : void 0; - item.isMounted = true; - var isRoot = item.parentID === 0; - if (isRoot) { - addRoot(id); - } - }, - onUpdateComponent: function (id) { - var item = getItem(id); - if (!item || !item.isMounted) { - // We may end up here as a result of setState() in componentWillUnmount(). - // In this case, ignore the element. - return; - } - item.updateCount++; - }, - onUnmountComponent: function (id) { - var item = getItem(id); - if (item) { - // We need to check if it exists. - // `item` might not exist if it is inside an error boundary, and a sibling - // error boundary child threw while mounting. Then this instance never - // got a chance to mount, but it still gets an unmounting event during - // the error boundary cleanup. - item.isMounted = false; - var isRoot = item.parentID === 0; - if (isRoot) { - removeRoot(id); - } - } - unmountedIDs.push(id); - }, - purgeUnmountedComponents: function () { - if (ReactComponentTreeHook._preventPurging) { - // Should only be used for testing. - return; - } - - for (var i = 0; i < unmountedIDs.length; i++) { - var id = unmountedIDs[i]; - purgeDeep(id); - } - unmountedIDs.length = 0; - }, - isMounted: function (id) { - var item = getItem(id); - return item ? item.isMounted : false; - }, - getCurrentStackAddendum: function (topElement) { - var info = ''; - if (topElement) { - var name = getDisplayName(topElement); - var owner = topElement._owner; - info += describeComponentFrame(name, topElement._source, owner && owner.getName()); - } - - var currentOwner = ReactCurrentOwner.current; - var id = currentOwner && currentOwner._debugID; - - info += ReactComponentTreeHook.getStackAddendumByID(id); - return info; - }, - getStackAddendumByID: function (id) { - var info = ''; - while (id) { - info += describeID(id); - id = ReactComponentTreeHook.getParentID(id); - } - return info; - }, - getChildIDs: function (id) { - var item = getItem(id); - return item ? item.childIDs : []; - }, - getDisplayName: function (id) { - var element = ReactComponentTreeHook.getElement(id); - if (!element) { - return null; - } - return getDisplayName(element); - }, - getElement: function (id) { - var item = getItem(id); - return item ? item.element : null; - }, - getOwnerID: function (id) { - var element = ReactComponentTreeHook.getElement(id); - if (!element || !element._owner) { - return null; - } - return element._owner._debugID; - }, - getParentID: function (id) { - var item = getItem(id); - return item ? item.parentID : null; - }, - getSource: function (id) { - var item = getItem(id); - var element = item ? item.element : null; - var source = element != null ? element._source : null; - return source; - }, - getText: function (id) { - var element = ReactComponentTreeHook.getElement(id); - if (typeof element === 'string') { - return element; - } else if (typeof element === 'number') { - return '' + element; - } else { - return null; - } - }, - getUpdateCount: function (id) { - var item = getItem(id); - return item ? item.updateCount : 0; - }, - - - getRootIDs: getRootIDs, - getRegisteredIDs: getItemIDs -}; - -module.exports = ReactComponentTreeHook; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 10 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -// Trust the developer to only use ReactInstrumentation with a __DEV__ check - -var debugTool = null; - -if (process.env.NODE_ENV !== 'production') { - var ReactDebugTool = __webpack_require__(266); - debugTool = ReactDebugTool; -} - -module.exports = { debugTool: debugTool }; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - - - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = function() {}; - -if (process.env.NODE_ENV !== 'production') { - warning = function(condition, format, args) { - var len = arguments.length; - args = new Array(len > 2 ? len - 2 : 0); - for (var key = 2; key < len; key++) { - args[key - 2] = arguments[key]; - } - if (format === undefined) { - throw new Error( - '`warning(condition, format, ...args)` requires a warning ' + - 'message argument' - ); - } - - if (format.length < 10 || (/^[s\W]*$/).test(format)) { - throw new Error( - 'The warning format should be able to uniquely identify this ' + - 'warning. Please, use a more descriptive format than: ' + format - ); - } - - if (!condition) { - var argIndex = 0; - var message = 'Warning: ' + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - if (typeof console !== 'undefined') { - console.error(message); - } - try { - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch(x) {} - } - }; -} - -module.exports = warning; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - -function makeEmptyFunction(arg) { - return function () { - return arg; - }; -} - -/** - * This function accepts and discards inputs; it has no side effects. This is - * primarily useful idiomatically for overridable function endpoints which - * always need to be callable, since JS lacks a null-call idiom ala Cocoa. - */ -var emptyFunction = function emptyFunction() {}; - -emptyFunction.thatReturns = makeEmptyFunction; -emptyFunction.thatReturnsFalse = makeEmptyFunction(false); -emptyFunction.thatReturnsTrue = makeEmptyFunction(true); -emptyFunction.thatReturnsNull = makeEmptyFunction(null); -emptyFunction.thatReturnsThis = function () { - return this; -}; -emptyFunction.thatReturnsArgument = function (arg) { - return arg; -}; - -module.exports = emptyFunction; - -/***/ }), -/* 13 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - - - -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ - -var invariant = function(condition, format, a, b, c, d, e, f) { - if (process.env.NODE_ENV !== 'production') { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - } - - if (!condition) { - var error; - if (format === undefined) { - error = new Error( - 'Minified exception occurred; use the non-minified dev environment ' + - 'for the full error message and additional helpful warnings.' - ); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error( - format.replace(/%s/g, function() { return args[argIndex++]; }) - ); - error.name = 'Invariant Violation'; - } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -}; - -module.exports = invariant; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var CallbackQueue = __webpack_require__(79); -var PooledClass = __webpack_require__(20); -var ReactFeatureFlags = __webpack_require__(84); -var ReactReconciler = __webpack_require__(26); -var Transaction = __webpack_require__(38); - -var invariant = __webpack_require__(2); - -var dirtyComponents = []; -var updateBatchNumber = 0; -var asapCallbackQueue = CallbackQueue.getPooled(); -var asapEnqueued = false; - -var batchingStrategy = null; - -function ensureInjected() { - !(ReactUpdates.ReactReconcileTransaction && batchingStrategy) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must inject a reconcile transaction class and batching strategy') : _prodInvariant('123') : void 0; -} - -var NESTED_UPDATES = { - initialize: function () { - this.dirtyComponentsLength = dirtyComponents.length; - }, - close: function () { - if (this.dirtyComponentsLength !== dirtyComponents.length) { - // Additional updates were enqueued by componentDidUpdate handlers or - // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run - // these new updates so that if A's componentDidUpdate calls setState on - // B, B will update before the callback A's updater provided when calling - // setState. - dirtyComponents.splice(0, this.dirtyComponentsLength); - flushBatchedUpdates(); - } else { - dirtyComponents.length = 0; - } - } -}; - -var UPDATE_QUEUEING = { - initialize: function () { - this.callbackQueue.reset(); - }, - close: function () { - this.callbackQueue.notifyAll(); - } -}; - -var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING]; - -function ReactUpdatesFlushTransaction() { - this.reinitializeTransaction(); - this.dirtyComponentsLength = null; - this.callbackQueue = CallbackQueue.getPooled(); - this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled( - /* useCreateElement */true); -} - -_assign(ReactUpdatesFlushTransaction.prototype, Transaction, { - getTransactionWrappers: function () { - return TRANSACTION_WRAPPERS; - }, - - destructor: function () { - this.dirtyComponentsLength = null; - CallbackQueue.release(this.callbackQueue); - this.callbackQueue = null; - ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction); - this.reconcileTransaction = null; - }, - - perform: function (method, scope, a) { - // Essentially calls `this.reconcileTransaction.perform(method, scope, a)` - // with this transaction's wrappers around it. - return Transaction.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a); - } -}); - -PooledClass.addPoolingTo(ReactUpdatesFlushTransaction); - -function batchedUpdates(callback, a, b, c, d, e) { - ensureInjected(); - return batchingStrategy.batchedUpdates(callback, a, b, c, d, e); -} - -/** - * Array comparator for ReactComponents by mount ordering. - * - * @param {ReactComponent} c1 first component you're comparing - * @param {ReactComponent} c2 second component you're comparing - * @return {number} Return value usable by Array.prototype.sort(). - */ -function mountOrderComparator(c1, c2) { - return c1._mountOrder - c2._mountOrder; -} - -function runBatchedUpdates(transaction) { - var len = transaction.dirtyComponentsLength; - !(len === dirtyComponents.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected flush transaction\'s stored dirty-components length (%s) to match dirty-components array length (%s).', len, dirtyComponents.length) : _prodInvariant('124', len, dirtyComponents.length) : void 0; - - // Since reconciling a component higher in the owner hierarchy usually (not - // always -- see shouldComponentUpdate()) will reconcile children, reconcile - // them before their children by sorting the array. - dirtyComponents.sort(mountOrderComparator); - - // Any updates enqueued while reconciling must be performed after this entire - // batch. Otherwise, if dirtyComponents is [A, B] where A has children B and - // C, B could update twice in a single batch if C's render enqueues an update - // to B (since B would have already updated, we should skip it, and the only - // way we can know to do so is by checking the batch counter). - updateBatchNumber++; - - for (var i = 0; i < len; i++) { - // If a component is unmounted before pending changes apply, it will still - // be here, but we assume that it has cleared its _pendingCallbacks and - // that performUpdateIfNecessary is a noop. - var component = dirtyComponents[i]; - - // If performUpdateIfNecessary happens to enqueue any new updates, we - // shouldn't execute the callbacks until the next render happens, so - // stash the callbacks first - var callbacks = component._pendingCallbacks; - component._pendingCallbacks = null; - - var markerName; - if (ReactFeatureFlags.logTopLevelRenders) { - var namedComponent = component; - // Duck type TopLevelWrapper. This is probably always true. - if (component._currentElement.type.isReactTopLevelWrapper) { - namedComponent = component._renderedComponent; - } - markerName = 'React update: ' + namedComponent.getName(); - console.time(markerName); - } - - ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction, updateBatchNumber); - - if (markerName) { - console.timeEnd(markerName); - } - - if (callbacks) { - for (var j = 0; j < callbacks.length; j++) { - transaction.callbackQueue.enqueue(callbacks[j], component.getPublicInstance()); - } - } - } -} - -var flushBatchedUpdates = function () { - // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents - // array and perform any updates enqueued by mount-ready handlers (i.e., - // componentDidUpdate) but we need to check here too in order to catch - // updates enqueued by setState callbacks and asap calls. - while (dirtyComponents.length || asapEnqueued) { - if (dirtyComponents.length) { - var transaction = ReactUpdatesFlushTransaction.getPooled(); - transaction.perform(runBatchedUpdates, null, transaction); - ReactUpdatesFlushTransaction.release(transaction); - } - - if (asapEnqueued) { - asapEnqueued = false; - var queue = asapCallbackQueue; - asapCallbackQueue = CallbackQueue.getPooled(); - queue.notifyAll(); - CallbackQueue.release(queue); - } - } -}; - -/** - * Mark a component as needing a rerender, adding an optional callback to a - * list of functions which will be executed once the rerender occurs. - */ -function enqueueUpdate(component) { - ensureInjected(); - - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. (This is called by each top-level update - // function, like setState, forceUpdate, etc.; creation and - // destruction of top-level components is guarded in ReactMount.) - - if (!batchingStrategy.isBatchingUpdates) { - batchingStrategy.batchedUpdates(enqueueUpdate, component); - return; - } - - dirtyComponents.push(component); - if (component._updateBatchNumber == null) { - component._updateBatchNumber = updateBatchNumber + 1; - } -} - -/** - * Enqueue a callback to be run at the end of the current batching cycle. Throws - * if no updates are currently being performed. - */ -function asap(callback, context) { - !batchingStrategy.isBatchingUpdates ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context whereupdates are not being batched.') : _prodInvariant('125') : void 0; - asapCallbackQueue.enqueue(callback, context); - asapEnqueued = true; -} - -var ReactUpdatesInjection = { - injectReconcileTransaction: function (ReconcileTransaction) { - !ReconcileTransaction ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a reconcile transaction class') : _prodInvariant('126') : void 0; - ReactUpdates.ReactReconcileTransaction = ReconcileTransaction; - }, - - injectBatchingStrategy: function (_batchingStrategy) { - !_batchingStrategy ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batching strategy') : _prodInvariant('127') : void 0; - !(typeof _batchingStrategy.batchedUpdates === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batchedUpdates() function') : _prodInvariant('128') : void 0; - !(typeof _batchingStrategy.isBatchingUpdates === 'boolean') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : _prodInvariant('129') : void 0; - batchingStrategy = _batchingStrategy; - } -}; - -var ReactUpdates = { - /** - * React references `ReactReconcileTransaction` using this property in order - * to allow dependency injection. - * - * @internal - */ - ReactReconcileTransaction: null, - - batchedUpdates: batchedUpdates, - enqueueUpdate: enqueueUpdate, - flushBatchedUpdates: flushBatchedUpdates, - injection: ReactUpdatesInjection, - asap: asap -}; - -module.exports = ReactUpdates; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 15 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/** - * Keeps track of the current owner. - * - * The current owner is the component who should own any components that are - * currently being constructed. - */ -var ReactCurrentOwner = { - - /** - * @internal - * @type {ReactComponent} - */ - current: null - -}; - -module.exports = ReactCurrentOwner; - -/***/ }), -/* 16 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -var React = __webpack_require__(5); -var noop = __webpack_require__(107); - -module.exports = function (Component) { - var options = Component.keyHandlingOptions, - propName = options.propName || "", - values = options.values || {}, - controller = options.controller || noop, - getDefaultProps = Component.getDefaultProps, - ref = "wrappedComponent"; - - return React.createClass({ - values: values, - - getDefaultProps: getDefaultProps, - - onKeyDown: function onKeyDown(event, api) { - var v = this.values[event.keyCode]; - if (v) { - event.preventDefault(); - if (typeof v === "function") { - v(api); - } else { - api[propName] += v; - controller(api); - } - } - }, - - getComponent: function getComponent() { - var wrappedComponent = this.refs[ref]; - if (wrappedComponent.getComponent) { - return wrappedComponent.getComponent(); - } - return wrappedComponent; - }, - - render: function render() { - return React.createElement(Component, _extends({}, this.props, { onKeyDown: this.onKeyDown, ref: ref })); - } - }); -}; - -/***/ }), -/* 17 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var PooledClass = __webpack_require__(20); - -var emptyFunction = __webpack_require__(12); -var warning = __webpack_require__(3); - -var didWarnForAddedNewProperty = false; -var isProxySupported = typeof Proxy === 'function'; - -var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances']; - -/** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var EventInterface = { - type: null, - target: null, - // currentTarget is set when dispatching; no use in copying it here - currentTarget: emptyFunction.thatReturnsNull, - eventPhase: null, - bubbles: null, - cancelable: null, - timeStamp: function (event) { - return event.timeStamp || Date.now(); - }, - defaultPrevented: null, - isTrusted: null -}; - -/** - * Synthetic events are dispatched by event plugins, typically in response to a - * top-level event delegation handler. - * - * These systems should generally use pooling to reduce the frequency of garbage - * collection. The system should check `isPersistent` to determine whether the - * event should be released into the pool after being dispatched. Users that - * need a persisted event should invoke `persist`. - * - * Synthetic events (and subclasses) implement the DOM Level 3 Events API by - * normalizing browser quirks. Subclasses do not necessarily have to implement a - * DOM interface; custom application-specific events can also subclass this. - * - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {*} targetInst Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @param {DOMEventTarget} nativeEventTarget Target node. - */ -function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) { - if (process.env.NODE_ENV !== 'production') { - // these have a getter/setter for warnings - delete this.nativeEvent; - delete this.preventDefault; - delete this.stopPropagation; - } - - this.dispatchConfig = dispatchConfig; - this._targetInst = targetInst; - this.nativeEvent = nativeEvent; - - var Interface = this.constructor.Interface; - for (var propName in Interface) { - if (!Interface.hasOwnProperty(propName)) { - continue; - } - if (process.env.NODE_ENV !== 'production') { - delete this[propName]; // this has a getter/setter for warnings - } - var normalize = Interface[propName]; - if (normalize) { - this[propName] = normalize(nativeEvent); - } else { - if (propName === 'target') { - this.target = nativeEventTarget; - } else { - this[propName] = nativeEvent[propName]; - } - } - } - - var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false; - if (defaultPrevented) { - this.isDefaultPrevented = emptyFunction.thatReturnsTrue; - } else { - this.isDefaultPrevented = emptyFunction.thatReturnsFalse; - } - this.isPropagationStopped = emptyFunction.thatReturnsFalse; - return this; -} - -_assign(SyntheticEvent.prototype, { - - preventDefault: function () { - this.defaultPrevented = true; - var event = this.nativeEvent; - if (!event) { - return; - } - - if (event.preventDefault) { - event.preventDefault(); - } else if (typeof event.returnValue !== 'unknown') { - // eslint-disable-line valid-typeof - event.returnValue = false; - } - this.isDefaultPrevented = emptyFunction.thatReturnsTrue; - }, - - stopPropagation: function () { - var event = this.nativeEvent; - if (!event) { - return; - } - - if (event.stopPropagation) { - event.stopPropagation(); - } else if (typeof event.cancelBubble !== 'unknown') { - // eslint-disable-line valid-typeof - // The ChangeEventPlugin registers a "propertychange" event for - // IE. This event does not support bubbling or cancelling, and - // any references to cancelBubble throw "Member not found". A - // typeof check of "unknown" circumvents this issue (and is also - // IE specific). - event.cancelBubble = true; - } - - this.isPropagationStopped = emptyFunction.thatReturnsTrue; - }, - - /** - * We release all dispatched `SyntheticEvent`s after each event loop, adding - * them back into the pool. This allows a way to hold onto a reference that - * won't be added back into the pool. - */ - persist: function () { - this.isPersistent = emptyFunction.thatReturnsTrue; - }, - - /** - * Checks if this event should be released back into the pool. - * - * @return {boolean} True if this should not be released, false otherwise. - */ - isPersistent: emptyFunction.thatReturnsFalse, - - /** - * `PooledClass` looks for `destructor` on each instance it releases. - */ - destructor: function () { - var Interface = this.constructor.Interface; - for (var propName in Interface) { - if (process.env.NODE_ENV !== 'production') { - Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName])); - } else { - this[propName] = null; - } - } - for (var i = 0; i < shouldBeReleasedProperties.length; i++) { - this[shouldBeReleasedProperties[i]] = null; - } - if (process.env.NODE_ENV !== 'production') { - Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null)); - Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction)); - Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction)); - } - } - -}); - -SyntheticEvent.Interface = EventInterface; - -if (process.env.NODE_ENV !== 'production') { - if (isProxySupported) { - /*eslint-disable no-func-assign */ - SyntheticEvent = new Proxy(SyntheticEvent, { - construct: function (target, args) { - return this.apply(target, Object.create(target.prototype), args); - }, - apply: function (constructor, that, args) { - return new Proxy(constructor.apply(that, args), { - set: function (target, prop, value) { - if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) { - process.env.NODE_ENV !== 'production' ? warning(didWarnForAddedNewProperty || target.isPersistent(), 'This synthetic event is reused for performance reasons. If you\'re ' + 'seeing this, you\'re adding a new property in the synthetic event object. ' + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.') : void 0; - didWarnForAddedNewProperty = true; - } - target[prop] = value; - return true; - } - }); - } - }); - /*eslint-enable no-func-assign */ - } -} -/** - * Helper to reduce boilerplate when creating subclasses. - * - * @param {function} Class - * @param {?object} Interface - */ -SyntheticEvent.augmentClass = function (Class, Interface) { - var Super = this; - - var E = function () {}; - E.prototype = Super.prototype; - var prototype = new E(); - - _assign(prototype, Class.prototype); - Class.prototype = prototype; - Class.prototype.constructor = Class; - - Class.Interface = _assign({}, Super.Interface, Interface); - Class.augmentClass = Super.augmentClass; - - PooledClass.addPoolingTo(Class, PooledClass.fourArgumentPooler); -}; - -PooledClass.addPoolingTo(SyntheticEvent, PooledClass.fourArgumentPooler); - -module.exports = SyntheticEvent; - -/** - * Helper to nullify syntheticEvent instance properties when destructing - * - * @param {object} SyntheticEvent - * @param {String} propName - * @return {object} defineProperty object - */ -function getPooledWarningPropertyDefinition(propName, getVal) { - var isFunction = typeof getVal === 'function'; - return { - configurable: true, - set: set, - get: get - }; - - function set(val) { - var action = isFunction ? 'setting the method' : 'setting the property'; - warn(action, 'This is effectively a no-op'); - return val; - } - - function get() { - var action = isFunction ? 'accessing the method' : 'accessing the property'; - var result = isFunction ? 'This is a no-op function' : 'This is set to null'; - warn(action, result); - return getVal; - } - - function warn(action, result) { - var warningCondition = false; - process.env.NODE_ENV !== 'production' ? warning(warningCondition, 'This synthetic event is reused for performance reasons. If you\'re seeing this, ' + 'you\'re %s `%s` on a released/nullified synthetic event. %s. ' + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0; - } -} -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -function checkMask(value, bitmask) { - return (value & bitmask) === bitmask; -} - -var DOMPropertyInjection = { - /** - * Mapping from normalized, camelcased property names to a configuration that - * specifies how the associated DOM property should be accessed or rendered. - */ - MUST_USE_PROPERTY: 0x1, - HAS_BOOLEAN_VALUE: 0x4, - HAS_NUMERIC_VALUE: 0x8, - HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8, - HAS_OVERLOADED_BOOLEAN_VALUE: 0x20, - - /** - * Inject some specialized knowledge about the DOM. This takes a config object - * with the following properties: - * - * isCustomAttribute: function that given an attribute name will return true - * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* - * attributes where it's impossible to enumerate all of the possible - * attribute names, - * - * Properties: object mapping DOM property name to one of the - * DOMPropertyInjection constants or null. If your attribute isn't in here, - * it won't get written to the DOM. - * - * DOMAttributeNames: object mapping React attribute name to the DOM - * attribute name. Attribute names not specified use the **lowercase** - * normalized name. - * - * DOMAttributeNamespaces: object mapping React attribute name to the DOM - * attribute namespace URL. (Attribute names not specified use no namespace.) - * - * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. - * Property names not specified use the normalized name. - * - * DOMMutationMethods: Properties that require special mutation methods. If - * `value` is undefined, the mutation method should unset the property. - * - * @param {object} domPropertyConfig the config as described above. - */ - injectDOMPropertyConfig: function (domPropertyConfig) { - var Injection = DOMPropertyInjection; - var Properties = domPropertyConfig.Properties || {}; - var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {}; - var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; - var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; - var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; - - if (domPropertyConfig.isCustomAttribute) { - DOMProperty._isCustomAttributeFunctions.push(domPropertyConfig.isCustomAttribute); - } - - for (var propName in Properties) { - !!DOMProperty.properties.hasOwnProperty(propName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property \'%s\' which has already been injected. You may be accidentally injecting the same DOM property config twice, or you may be injecting two configs that have conflicting property names.', propName) : _prodInvariant('48', propName) : void 0; - - var lowerCased = propName.toLowerCase(); - var propConfig = Properties[propName]; - - var propertyInfo = { - attributeName: lowerCased, - attributeNamespace: null, - propertyName: propName, - mutationMethod: null, - - mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY), - hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE), - hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE), - hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE), - hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE) - }; - !(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or numeric value, but not a combination: %s', propName) : _prodInvariant('50', propName) : void 0; - - if (process.env.NODE_ENV !== 'production') { - DOMProperty.getPossibleStandardName[lowerCased] = propName; - } - - if (DOMAttributeNames.hasOwnProperty(propName)) { - var attributeName = DOMAttributeNames[propName]; - propertyInfo.attributeName = attributeName; - if (process.env.NODE_ENV !== 'production') { - DOMProperty.getPossibleStandardName[attributeName] = propName; - } - } - - if (DOMAttributeNamespaces.hasOwnProperty(propName)) { - propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName]; - } - - if (DOMPropertyNames.hasOwnProperty(propName)) { - propertyInfo.propertyName = DOMPropertyNames[propName]; - } - - if (DOMMutationMethods.hasOwnProperty(propName)) { - propertyInfo.mutationMethod = DOMMutationMethods[propName]; - } - - DOMProperty.properties[propName] = propertyInfo; - } - } -}; - -/* eslint-disable max-len */ -var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD'; -/* eslint-enable max-len */ - -/** - * DOMProperty exports lookup objects that can be used like functions: - * - * > DOMProperty.isValid['id'] - * true - * > DOMProperty.isValid['foobar'] - * undefined - * - * Although this may be confusing, it performs better in general. - * - * @see http://jsperf.com/key-exists - * @see http://jsperf.com/key-missing - */ -var DOMProperty = { - - ID_ATTRIBUTE_NAME: 'data-reactid', - ROOT_ATTRIBUTE_NAME: 'data-reactroot', - - ATTRIBUTE_NAME_START_CHAR: ATTRIBUTE_NAME_START_CHAR, - ATTRIBUTE_NAME_CHAR: ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040', - - /** - * Map from property "standard name" to an object with info about how to set - * the property in the DOM. Each object contains: - * - * attributeName: - * Used when rendering markup or with `*Attribute()`. - * attributeNamespace - * propertyName: - * Used on DOM node instances. (This includes properties that mutate due to - * external factors.) - * mutationMethod: - * If non-null, used instead of the property or `setAttribute()` after - * initial render. - * mustUseProperty: - * Whether the property must be accessed and mutated as an object property. - * hasBooleanValue: - * Whether the property should be removed when set to a falsey value. - * hasNumericValue: - * Whether the property must be numeric or parse as a numeric and should be - * removed when set to a falsey value. - * hasPositiveNumericValue: - * Whether the property must be positive numeric or parse as a positive - * numeric and should be removed when set to a falsey value. - * hasOverloadedBooleanValue: - * Whether the property can be used as a flag as well as with a value. - * Removed when strictly equal to false; present without a value when - * strictly equal to true; present with a value otherwise. - */ - properties: {}, - - /** - * Mapping from lowercase property names to the properly cased version, used - * to warn in the case of missing properties. Available only in __DEV__. - * - * autofocus is predefined, because adding it to the property whitelist - * causes unintended side effects. - * - * @type {Object} - */ - getPossibleStandardName: process.env.NODE_ENV !== 'production' ? { autofocus: 'autoFocus' } : null, - - /** - * All of the isCustomAttribute() functions that have been injected. - */ - _isCustomAttributeFunctions: [], - - /** - * Checks whether a property name is a custom attribute. - * @method - */ - isCustomAttribute: function (attributeName) { - for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { - var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; - if (isCustomAttributeFn(attributeName)) { - return true; - } - } - return false; - }, - - injection: DOMPropertyInjection -}; - -module.exports = DOMProperty; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 19 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -exports.isReactChildren = isReactChildren; -exports.createRouteFromReactElement = createRouteFromReactElement; -exports.createRoutesFromReactChildren = createRoutesFromReactChildren; -exports.createRoutes = createRoutes; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -function isValidChild(object) { - return object == null || _react2['default'].isValidElement(object); -} - -function isReactChildren(object) { - return isValidChild(object) || Array.isArray(object) && object.every(isValidChild); -} - -function checkPropTypes(componentName, propTypes, props) { - componentName = componentName || 'UnknownComponent'; - - for (var propName in propTypes) { - if (propTypes.hasOwnProperty(propName)) { - var error = propTypes[propName](props, propName, componentName); - - /* istanbul ignore if: error logging */ - if (error instanceof Error) process.env.NODE_ENV !== 'production' ? _warning2['default'](false, error.message) : undefined; - } - } -} - -function createRoute(defaultProps, props) { - return _extends({}, defaultProps, props); -} - -function createRouteFromReactElement(element) { - var type = element.type; - var route = createRoute(type.defaultProps, element.props); - - if (type.propTypes) checkPropTypes(type.displayName || type.name, type.propTypes, route); - - if (route.children) { - var childRoutes = createRoutesFromReactChildren(route.children, route); - - if (childRoutes.length) route.childRoutes = childRoutes; - - delete route.children; - } - - return route; -} - -/** - * Creates and returns a routes object from the given ReactChildren. JSX - * provides a convenient way to visualize how routes in the hierarchy are - * nested. - * - * import { Route, createRoutesFromReactChildren } from 'react-router' - * - * const routes = createRoutesFromReactChildren( - * - * - * - * - * ) - * - * Note: This method is automatically used when you provide children - * to a component. - */ - -function createRoutesFromReactChildren(children, parentRoute) { - var routes = []; - - _react2['default'].Children.forEach(children, function (element) { - if (_react2['default'].isValidElement(element)) { - // Component classes may have a static create* method. - if (element.type.createRouteFromReactElement) { - var route = element.type.createRouteFromReactElement(element, parentRoute); - - if (route) routes.push(route); - } else { - routes.push(createRouteFromReactElement(element)); - } - } - }); - - return routes; -} - -/** - * Creates and returns an array of routes from the given object which - * may be a JSX route, a plain object route, or an array of either. - */ - -function createRoutes(routes) { - if (isReactChildren(routes)) { - routes = createRoutesFromReactChildren(routes); - } else if (routes && !Array.isArray(routes)) { - routes = [routes]; - } - - return routes; -} -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -/** - * Static poolers. Several custom versions for each potential number of - * arguments. A completely generic pooler is easy to implement, but would - * require accessing the `arguments` object. In each of these, `this` refers to - * the Class itself, not an instance. If any others are needed, simply add them - * here, or in their own files. - */ -var oneArgumentPooler = function (copyFieldsFrom) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, copyFieldsFrom); - return instance; - } else { - return new Klass(copyFieldsFrom); - } -}; - -var twoArgumentPooler = function (a1, a2) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2); - return instance; - } else { - return new Klass(a1, a2); - } -}; - -var threeArgumentPooler = function (a1, a2, a3) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3); - return instance; - } else { - return new Klass(a1, a2, a3); - } -}; - -var fourArgumentPooler = function (a1, a2, a3, a4) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3, a4); - return instance; - } else { - return new Klass(a1, a2, a3, a4); - } -}; - -var standardReleaser = function (instance) { - var Klass = this; - !(instance instanceof Klass) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : _prodInvariant('25') : void 0; - instance.destructor(); - if (Klass.instancePool.length < Klass.poolSize) { - Klass.instancePool.push(instance); - } -}; - -var DEFAULT_POOL_SIZE = 10; -var DEFAULT_POOLER = oneArgumentPooler; - -/** - * Augments `CopyConstructor` to be a poolable class, augmenting only the class - * itself (statically) not adding any prototypical fields. Any CopyConstructor - * you give this may have a `poolSize` property, and will look for a - * prototypical `destructor` on instances. - * - * @param {Function} CopyConstructor Constructor that can be used to reset. - * @param {Function} pooler Customizable pooler. - */ -var addPoolingTo = function (CopyConstructor, pooler) { - // Casting as any so that flow ignores the actual implementation and trusts - // it to match the type we declared - var NewKlass = CopyConstructor; - NewKlass.instancePool = []; - NewKlass.getPooled = pooler || DEFAULT_POOLER; - if (!NewKlass.poolSize) { - NewKlass.poolSize = DEFAULT_POOL_SIZE; - } - NewKlass.release = standardReleaser; - return NewKlass; -}; - -var PooledClass = { - addPoolingTo: addPoolingTo, - oneArgumentPooler: oneArgumentPooler, - twoArgumentPooler: twoArgumentPooler, - threeArgumentPooler: threeArgumentPooler, - fourArgumentPooler: fourArgumentPooler -}; - -module.exports = PooledClass; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 21 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.falsy = falsy; - -var _react = __webpack_require__(5); - -var func = _react.PropTypes.func; -var object = _react.PropTypes.object; -var arrayOf = _react.PropTypes.arrayOf; -var oneOfType = _react.PropTypes.oneOfType; -var element = _react.PropTypes.element; -var shape = _react.PropTypes.shape; -var string = _react.PropTypes.string; - -function falsy(props, propName, componentName) { - if (props[propName]) return new Error('<' + componentName + '> should not have a "' + propName + '" prop'); -} - -var history = shape({ - listen: func.isRequired, - pushState: func.isRequired, - replaceState: func.isRequired, - go: func.isRequired -}); - -exports.history = history; -var location = shape({ - pathname: string.isRequired, - search: string.isRequired, - state: object, - action: string.isRequired, - key: string -}); - -exports.location = location; -var component = oneOfType([func, string]); -exports.component = component; -var components = oneOfType([component, object]); -exports.components = components; -var route = oneOfType([object, element]); -exports.route = route; -var routes = oneOfType([route, arrayOf(route)]); - -exports.routes = routes; -exports['default'] = { - falsy: falsy, - history: history, - location: location, - component: component, - components: components, - route: route -}; - -/***/ }), -/* 22 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var ReactCurrentOwner = __webpack_require__(15); - -var warning = __webpack_require__(3); -var canDefineProperty = __webpack_require__(66); -var hasOwnProperty = Object.prototype.hasOwnProperty; - -var REACT_ELEMENT_TYPE = __webpack_require__(103); - -var RESERVED_PROPS = { - key: true, - ref: true, - __self: true, - __source: true -}; - -var specialPropKeyWarningShown, specialPropRefWarningShown; - -function hasValidRef(config) { - if (process.env.NODE_ENV !== 'production') { - if (hasOwnProperty.call(config, 'ref')) { - var getter = Object.getOwnPropertyDescriptor(config, 'ref').get; - if (getter && getter.isReactWarning) { - return false; - } - } - } - return config.ref !== undefined; -} - -function hasValidKey(config) { - if (process.env.NODE_ENV !== 'production') { - if (hasOwnProperty.call(config, 'key')) { - var getter = Object.getOwnPropertyDescriptor(config, 'key').get; - if (getter && getter.isReactWarning) { - return false; - } - } - } - return config.key !== undefined; -} - -function defineKeyPropWarningGetter(props, displayName) { - var warnAboutAccessingKey = function () { - if (!specialPropKeyWarningShown) { - specialPropKeyWarningShown = true; - process.env.NODE_ENV !== 'production' ? warning(false, '%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName) : void 0; - } - }; - warnAboutAccessingKey.isReactWarning = true; - Object.defineProperty(props, 'key', { - get: warnAboutAccessingKey, - configurable: true - }); -} - -function defineRefPropWarningGetter(props, displayName) { - var warnAboutAccessingRef = function () { - if (!specialPropRefWarningShown) { - specialPropRefWarningShown = true; - process.env.NODE_ENV !== 'production' ? warning(false, '%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName) : void 0; - } - }; - warnAboutAccessingRef.isReactWarning = true; - Object.defineProperty(props, 'ref', { - get: warnAboutAccessingRef, - configurable: true - }); -} - -/** - * Factory method to create a new React element. This no longer adheres to - * the class pattern, so do not use new to call it. Also, no instanceof check - * will work. Instead test $$typeof field against Symbol.for('react.element') to check - * if something is a React Element. - * - * @param {*} type - * @param {*} key - * @param {string|object} ref - * @param {*} self A *temporary* helper to detect places where `this` is - * different from the `owner` when React.createElement is called, so that we - * can warn. We want to get rid of owner and replace string `ref`s with arrow - * functions, and as long as `this` and owner are the same, there will be no - * change in behavior. - * @param {*} source An annotation object (added by a transpiler or otherwise) - * indicating filename, line number, and/or other information. - * @param {*} owner - * @param {*} props - * @internal - */ -var ReactElement = function (type, key, ref, self, source, owner, props) { - var element = { - // This tag allow us to uniquely identify this as a React Element - $$typeof: REACT_ELEMENT_TYPE, - - // Built-in properties that belong on the element - type: type, - key: key, - ref: ref, - props: props, - - // Record the component responsible for creating this element. - _owner: owner - }; - - if (process.env.NODE_ENV !== 'production') { - // The validation flag is currently mutative. We put it on - // an external backing store so that we can freeze the whole object. - // This can be replaced with a WeakMap once they are implemented in - // commonly used development environments. - element._store = {}; - - // To make comparing ReactElements easier for testing purposes, we make - // the validation flag non-enumerable (where possible, which should - // include every environment we run tests in), so the test framework - // ignores it. - if (canDefineProperty) { - Object.defineProperty(element._store, 'validated', { - configurable: false, - enumerable: false, - writable: true, - value: false - }); - // self and source are DEV only properties. - Object.defineProperty(element, '_self', { - configurable: false, - enumerable: false, - writable: false, - value: self - }); - // Two elements created in two different places should be considered - // equal for testing purposes and therefore we hide it from enumeration. - Object.defineProperty(element, '_source', { - configurable: false, - enumerable: false, - writable: false, - value: source - }); - } else { - element._store.validated = false; - element._self = self; - element._source = source; - } - if (Object.freeze) { - Object.freeze(element.props); - Object.freeze(element); - } - } - - return element; -}; - -/** - * Create and return a new ReactElement of the given type. - * See https://facebook.github.io/react/docs/top-level-api.html#react.createelement - */ -ReactElement.createElement = function (type, config, children) { - var propName; - - // Reserved names are extracted - var props = {}; - - var key = null; - var ref = null; - var self = null; - var source = null; - - if (config != null) { - if (hasValidRef(config)) { - ref = config.ref; - } - if (hasValidKey(config)) { - key = '' + config.key; - } - - self = config.__self === undefined ? null : config.__self; - source = config.__source === undefined ? null : config.__source; - // Remaining properties are added to a new props object - for (propName in config) { - if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { - props[propName] = config[propName]; - } - } - } - - // Children can be more than one argument, and those are transferred onto - // the newly allocated props object. - var childrenLength = arguments.length - 2; - if (childrenLength === 1) { - props.children = children; - } else if (childrenLength > 1) { - var childArray = Array(childrenLength); - for (var i = 0; i < childrenLength; i++) { - childArray[i] = arguments[i + 2]; - } - if (process.env.NODE_ENV !== 'production') { - if (Object.freeze) { - Object.freeze(childArray); - } - } - props.children = childArray; - } - - // Resolve default props - if (type && type.defaultProps) { - var defaultProps = type.defaultProps; - for (propName in defaultProps) { - if (props[propName] === undefined) { - props[propName] = defaultProps[propName]; - } - } - } - if (process.env.NODE_ENV !== 'production') { - if (key || ref) { - if (typeof props.$$typeof === 'undefined' || props.$$typeof !== REACT_ELEMENT_TYPE) { - var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type; - if (key) { - defineKeyPropWarningGetter(props, displayName); - } - if (ref) { - defineRefPropWarningGetter(props, displayName); - } - } - } - } - return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props); -}; - -/** - * Return a function that produces ReactElements of a given type. - * See https://facebook.github.io/react/docs/top-level-api.html#react.createfactory - */ -ReactElement.createFactory = function (type) { - var factory = ReactElement.createElement.bind(null, type); - // Expose the type on the factory and the prototype so that it can be - // easily accessed on elements. E.g. `.type === Foo`. - // This should not be named `constructor` since this may not be the function - // that created the element, and it may not even be a constructor. - // Legacy hook TODO: Warn if this is accessed - factory.type = type; - return factory; -}; - -ReactElement.cloneAndReplaceKey = function (oldElement, newKey) { - var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props); - - return newElement; -}; - -/** - * Clone and return a new ReactElement using element as the starting point. - * See https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement - */ -ReactElement.cloneElement = function (element, config, children) { - var propName; - - // Original props are copied - var props = _assign({}, element.props); - - // Reserved names are extracted - var key = element.key; - var ref = element.ref; - // Self is preserved since the owner is preserved. - var self = element._self; - // Source is preserved since cloneElement is unlikely to be targeted by a - // transpiler, and the original source is probably a better indicator of the - // true owner. - var source = element._source; - - // Owner will be preserved, unless ref is overridden - var owner = element._owner; - - if (config != null) { - if (hasValidRef(config)) { - // Silently steal the ref from the parent. - ref = config.ref; - owner = ReactCurrentOwner.current; - } - if (hasValidKey(config)) { - key = '' + config.key; - } - - // Remaining properties override existing props - var defaultProps; - if (element.type && element.type.defaultProps) { - defaultProps = element.type.defaultProps; - } - for (propName in config) { - if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { - if (config[propName] === undefined && defaultProps !== undefined) { - // Resolve default props - props[propName] = defaultProps[propName]; - } else { - props[propName] = config[propName]; - } - } - } - } - - // Children can be more than one argument, and those are transferred onto - // the newly allocated props object. - var childrenLength = arguments.length - 2; - if (childrenLength === 1) { - props.children = children; - } else if (childrenLength > 1) { - var childArray = Array(childrenLength); - for (var i = 0; i < childrenLength; i++) { - childArray[i] = arguments[i + 2]; - } - props.children = childArray; - } - - return ReactElement(element.type, key, ref, self, source, owner, props); -}; - -/** - * Verifies the object is a ReactElement. - * See https://facebook.github.io/react/docs/top-level-api.html#react.isvalidelement - * @param {?object} object - * @return {boolean} True if `object` is a valid component. - * @final - */ -ReactElement.isValidElement = function (object) { - return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; -}; - -module.exports = ReactElement; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 23 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - -/** - * WARNING: DO NOT manually require this module. - * This is a replacement for `invariant(...)` used by the error code system - * and will _only_ be required by the corresponding babel pass. - * It always throws. - */ - -function reactProdInvariant(code) { - var argCount = arguments.length - 1; - - var message = 'Minified React error #' + code + '; visit ' + 'http://facebook.github.io/react/docs/error-decoder.html?invariant=' + code; - - for (var argIdx = 0; argIdx < argCount; argIdx++) { - message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]); - } - - message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.'; - - var error = new Error(message); - error.name = 'Invariant Violation'; - error.framesToPop = 1; // we don't care about reactProdInvariant's own frame - - throw error; -} - -module.exports = reactProdInvariant; - -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _extractPath = __webpack_require__(77); - -var _extractPath2 = _interopRequireDefault(_extractPath); - -function parsePath(path) { - var pathname = _extractPath2['default'](path); - var search = ''; - var hash = ''; - - process.env.NODE_ENV !== 'production' ? _warning2['default'](path === pathname, 'A path must be pathname + search + hash only, not a fully qualified URL like "%s"', path) : undefined; - - var hashIndex = pathname.indexOf('#'); - if (hashIndex !== -1) { - hash = pathname.substring(hashIndex); - pathname = pathname.substring(0, hashIndex); - } - - var searchIndex = pathname.indexOf('?'); - if (searchIndex !== -1) { - search = pathname.substring(searchIndex); - pathname = pathname.substring(0, searchIndex); - } - - if (pathname === '') pathname = '/'; - - return { - pathname: pathname, - search: search, - hash: hash - }; -} - -exports['default'] = parsePath; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 25 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMNamespaces = __webpack_require__(47); -var setInnerHTML = __webpack_require__(40); - -var createMicrosoftUnsafeLocalFunction = __webpack_require__(54); -var setTextContent = __webpack_require__(97); - -var ELEMENT_NODE_TYPE = 1; -var DOCUMENT_FRAGMENT_NODE_TYPE = 11; - -/** - * In IE (8-11) and Edge, appending nodes with no children is dramatically - * faster than appending a full subtree, so we essentially queue up the - * .appendChild calls here and apply them so each node is added to its parent - * before any children are added. - * - * In other browsers, doing so is slower or neutral compared to the other order - * (in Firefox, twice as slow) so we only do this inversion in IE. - * - * See https://github.com/spicyj/innerhtml-vs-createelement-vs-clonenode. - */ -var enableLazy = typeof document !== 'undefined' && typeof document.documentMode === 'number' || typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string' && /\bEdge\/\d/.test(navigator.userAgent); - -function insertTreeChildren(tree) { - if (!enableLazy) { - return; - } - var node = tree.node; - var children = tree.children; - if (children.length) { - for (var i = 0; i < children.length; i++) { - insertTreeBefore(node, children[i], null); - } - } else if (tree.html != null) { - setInnerHTML(node, tree.html); - } else if (tree.text != null) { - setTextContent(node, tree.text); - } -} - -var insertTreeBefore = createMicrosoftUnsafeLocalFunction(function (parentNode, tree, referenceNode) { - // DocumentFragments aren't actually part of the DOM after insertion so - // appending children won't update the DOM. We need to ensure the fragment - // is properly populated first, breaking out of our lazy approach for just - // this level. Also, some plugins (like Flash Player) will read - // nodes immediately upon insertion into the DOM, so - // must also be populated prior to insertion into the DOM. - if (tree.node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE || tree.node.nodeType === ELEMENT_NODE_TYPE && tree.node.nodeName.toLowerCase() === 'object' && (tree.node.namespaceURI == null || tree.node.namespaceURI === DOMNamespaces.html)) { - insertTreeChildren(tree); - parentNode.insertBefore(tree.node, referenceNode); - } else { - parentNode.insertBefore(tree.node, referenceNode); - insertTreeChildren(tree); - } -}); - -function replaceChildWithTree(oldNode, newTree) { - oldNode.parentNode.replaceChild(newTree.node, oldNode); - insertTreeChildren(newTree); -} - -function queueChild(parentTree, childTree) { - if (enableLazy) { - parentTree.children.push(childTree); - } else { - parentTree.node.appendChild(childTree.node); - } -} - -function queueHTML(tree, html) { - if (enableLazy) { - tree.html = html; - } else { - setInnerHTML(tree.node, html); - } -} - -function queueText(tree, text) { - if (enableLazy) { - tree.text = text; - } else { - setTextContent(tree.node, text); - } -} - -function toString() { - return this.node.nodeName; -} - -function DOMLazyTree(node) { - return { - node: node, - children: [], - html: null, - text: null, - toString: toString - }; -} - -DOMLazyTree.insertTreeBefore = insertTreeBefore; -DOMLazyTree.replaceChildWithTree = replaceChildWithTree; -DOMLazyTree.queueChild = queueChild; -DOMLazyTree.queueHTML = queueHTML; -DOMLazyTree.queueText = queueText; - -module.exports = DOMLazyTree; - -/***/ }), -/* 26 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactRef = __webpack_require__(280); -var ReactInstrumentation = __webpack_require__(10); - -var warning = __webpack_require__(3); - -/** - * Helper to call ReactRef.attachRefs with this composite component, split out - * to avoid allocations in the transaction mount-ready queue. - */ -function attachRefs() { - ReactRef.attachRefs(this, this._currentElement); -} - -var ReactReconciler = { - - /** - * Initializes the component, renders markup, and registers event listeners. - * - * @param {ReactComponent} internalInstance - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {?object} the containing host component instance - * @param {?object} info about the host container - * @return {?string} Rendered markup to be inserted into the DOM. - * @final - * @internal - */ - mountComponent: function (internalInstance, transaction, hostParent, hostContainerInfo, context, parentDebugID // 0 in production and for roots - ) { - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onBeforeMountComponent(internalInstance._debugID, internalInstance._currentElement, parentDebugID); - } - } - var markup = internalInstance.mountComponent(transaction, hostParent, hostContainerInfo, context, parentDebugID); - if (internalInstance._currentElement && internalInstance._currentElement.ref != null) { - transaction.getReactMountReady().enqueue(attachRefs, internalInstance); - } - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onMountComponent(internalInstance._debugID); - } - } - return markup; - }, - - /** - * Returns a value that can be passed to - * ReactComponentEnvironment.replaceNodeWithMarkup. - */ - getHostNode: function (internalInstance) { - return internalInstance.getHostNode(); - }, - - /** - * Releases any resources allocated by `mountComponent`. - * - * @final - * @internal - */ - unmountComponent: function (internalInstance, safely) { - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onBeforeUnmountComponent(internalInstance._debugID); - } - } - ReactRef.detachRefs(internalInstance, internalInstance._currentElement); - internalInstance.unmountComponent(safely); - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onUnmountComponent(internalInstance._debugID); - } - } - }, - - /** - * Update a component using a new element. - * - * @param {ReactComponent} internalInstance - * @param {ReactElement} nextElement - * @param {ReactReconcileTransaction} transaction - * @param {object} context - * @internal - */ - receiveComponent: function (internalInstance, nextElement, transaction, context) { - var prevElement = internalInstance._currentElement; - - if (nextElement === prevElement && context === internalInstance._context) { - // Since elements are immutable after the owner is rendered, - // we can do a cheap identity compare here to determine if this is a - // superfluous reconcile. It's possible for state to be mutable but such - // change should trigger an update of the owner which would recreate - // the element. We explicitly check for the existence of an owner since - // it's possible for an element created outside a composite to be - // deeply mutated and reused. - - // TODO: Bailing out early is just a perf optimization right? - // TODO: Removing the return statement should affect correctness? - return; - } - - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, nextElement); - } - } - - var refsChanged = ReactRef.shouldUpdateRefs(prevElement, nextElement); - - if (refsChanged) { - ReactRef.detachRefs(internalInstance, prevElement); - } - - internalInstance.receiveComponent(nextElement, transaction, context); - - if (refsChanged && internalInstance._currentElement && internalInstance._currentElement.ref != null) { - transaction.getReactMountReady().enqueue(attachRefs, internalInstance); - } - - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID); - } - } - }, - - /** - * Flush any dirty changes in a component. - * - * @param {ReactComponent} internalInstance - * @param {ReactReconcileTransaction} transaction - * @internal - */ - performUpdateIfNecessary: function (internalInstance, transaction, updateBatchNumber) { - if (internalInstance._updateBatchNumber !== updateBatchNumber) { - // The component's enqueued batch number should always be the current - // batch or the following one. - process.env.NODE_ENV !== 'production' ? warning(internalInstance._updateBatchNumber == null || internalInstance._updateBatchNumber === updateBatchNumber + 1, 'performUpdateIfNecessary: Unexpected batch number (current %s, ' + 'pending %s)', updateBatchNumber, internalInstance._updateBatchNumber) : void 0; - return; - } - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, internalInstance._currentElement); - } - } - internalInstance.performUpdateIfNecessary(transaction); - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID); - } - } - } - -}; - -module.exports = ReactReconciler; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 27 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var ReactChildren = __webpack_require__(326); -var ReactComponent = __webpack_require__(63); -var ReactPureComponent = __webpack_require__(330); -var ReactClass = __webpack_require__(327); -var ReactDOMFactories = __webpack_require__(328); -var ReactElement = __webpack_require__(22); -var ReactPropTypes = __webpack_require__(329); -var ReactVersion = __webpack_require__(331); - -var onlyChild = __webpack_require__(333); -var warning = __webpack_require__(3); - -var createElement = ReactElement.createElement; -var createFactory = ReactElement.createFactory; -var cloneElement = ReactElement.cloneElement; - -if (process.env.NODE_ENV !== 'production') { - var ReactElementValidator = __webpack_require__(104); - createElement = ReactElementValidator.createElement; - createFactory = ReactElementValidator.createFactory; - cloneElement = ReactElementValidator.cloneElement; -} - -var __spread = _assign; - -if (process.env.NODE_ENV !== 'production') { - var warned = false; - __spread = function () { - process.env.NODE_ENV !== 'production' ? warning(warned, 'React.__spread is deprecated and should not be used. Use ' + 'Object.assign directly or another helper function with similar ' + 'semantics. You may be seeing this warning due to your compiler. ' + 'See https://fb.me/react-spread-deprecation for more details.') : void 0; - warned = true; - return _assign.apply(null, arguments); - }; -} - -var React = { - - // Modern - - Children: { - map: ReactChildren.map, - forEach: ReactChildren.forEach, - count: ReactChildren.count, - toArray: ReactChildren.toArray, - only: onlyChild - }, - - Component: ReactComponent, - PureComponent: ReactPureComponent, - - createElement: createElement, - cloneElement: cloneElement, - isValidElement: ReactElement.isValidElement, - - // Classic - - PropTypes: ReactPropTypes, - createClass: ReactClass.createClass, - createFactory: createFactory, - createMixin: function (mixin) { - // Currently a noop. Will be used to validate and trace mixins. - return mixin; - }, - - // This looks DOM specific but these are actually isomorphic helpers - // since they are just generating DOM strings. - DOM: ReactDOMFactories, - - version: ReactVersion, - - // Deprecated hook for JSX spread, don't use this for anything. - __spread: __spread -}; - -module.exports = React; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var emptyObject = {}; - -if (process.env.NODE_ENV !== 'production') { - Object.freeze(emptyObject); -} - -module.exports = emptyObject; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 29 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Indicates that navigation was caused by a call to history.push. - */ - - -exports.__esModule = true; -var PUSH = 'PUSH'; - -exports.PUSH = PUSH; -/** - * Indicates that navigation was caused by a call to history.replace. - */ -var REPLACE = 'REPLACE'; - -exports.REPLACE = REPLACE; -/** - * Indicates that navigation was caused by some other action such - * as using a browser's back/forward buttons and/or manually manipulating - * the URL in a browser's location bar. This is the default. - * - * See https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate - * for more information. - */ -var POP = 'POP'; - -exports.POP = POP; -exports['default'] = { - PUSH: PUSH, - REPLACE: REPLACE, - POP: POP -}; - -/***/ }), -/* 30 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var EventPluginRegistry = __webpack_require__(35); -var EventPluginUtils = __webpack_require__(48); -var ReactErrorUtils = __webpack_require__(52); - -var accumulateInto = __webpack_require__(91); -var forEachAccumulated = __webpack_require__(92); -var invariant = __webpack_require__(2); - -/** - * Internal store for event listeners - */ -var listenerBank = {}; - -/** - * Internal queue of events that have accumulated their dispatches and are - * waiting to have their dispatches executed. - */ -var eventQueue = null; - -/** - * Dispatches an event and releases it back into the pool, unless persistent. - * - * @param {?object} event Synthetic event to be dispatched. - * @param {boolean} simulated If the event is simulated (changes exn behavior) - * @private - */ -var executeDispatchesAndRelease = function (event, simulated) { - if (event) { - EventPluginUtils.executeDispatchesInOrder(event, simulated); - - if (!event.isPersistent()) { - event.constructor.release(event); - } - } -}; -var executeDispatchesAndReleaseSimulated = function (e) { - return executeDispatchesAndRelease(e, true); -}; -var executeDispatchesAndReleaseTopLevel = function (e) { - return executeDispatchesAndRelease(e, false); -}; - -var getDictionaryKey = function (inst) { - // Prevents V8 performance issue: - // https://github.com/facebook/react/pull/7232 - return '.' + inst._rootNodeID; -}; - -function isInteractive(tag) { - return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; -} - -function shouldPreventMouseEvent(name, type, props) { - switch (name) { - case 'onClick': - case 'onClickCapture': - case 'onDoubleClick': - case 'onDoubleClickCapture': - case 'onMouseDown': - case 'onMouseDownCapture': - case 'onMouseMove': - case 'onMouseMoveCapture': - case 'onMouseUp': - case 'onMouseUpCapture': - return !!(props.disabled && isInteractive(type)); - default: - return false; - } -} - -/** - * This is a unified interface for event plugins to be installed and configured. - * - * Event plugins can implement the following properties: - * - * `extractEvents` {function(string, DOMEventTarget, string, object): *} - * Required. When a top-level event is fired, this method is expected to - * extract synthetic events that will in turn be queued and dispatched. - * - * `eventTypes` {object} - * Optional, plugins that fire events must publish a mapping of registration - * names that are used to register listeners. Values of this mapping must - * be objects that contain `registrationName` or `phasedRegistrationNames`. - * - * `executeDispatch` {function(object, function, string)} - * Optional, allows plugins to override how an event gets dispatched. By - * default, the listener is simply invoked. - * - * Each plugin that is injected into `EventsPluginHub` is immediately operable. - * - * @public - */ -var EventPluginHub = { - - /** - * Methods for injecting dependencies. - */ - injection: { - - /** - * @param {array} InjectedEventPluginOrder - * @public - */ - injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder, - - /** - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - */ - injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName - - }, - - /** - * Stores `listener` at `listenerBank[registrationName][key]`. Is idempotent. - * - * @param {object} inst The instance, which is the source of events. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {function} listener The callback to store. - */ - putListener: function (inst, registrationName, listener) { - !(typeof listener === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener) : _prodInvariant('94', registrationName, typeof listener) : void 0; - - var key = getDictionaryKey(inst); - var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {}); - bankForRegistrationName[key] = listener; - - var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; - if (PluginModule && PluginModule.didPutListener) { - PluginModule.didPutListener(inst, registrationName, listener); - } - }, - - /** - * @param {object} inst The instance, which is the source of events. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @return {?function} The stored callback. - */ - getListener: function (inst, registrationName) { - // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not - // live here; needs to be moved to a better place soon - var bankForRegistrationName = listenerBank[registrationName]; - if (shouldPreventMouseEvent(registrationName, inst._currentElement.type, inst._currentElement.props)) { - return null; - } - var key = getDictionaryKey(inst); - return bankForRegistrationName && bankForRegistrationName[key]; - }, - - /** - * Deletes a listener from the registration bank. - * - * @param {object} inst The instance, which is the source of events. - * @param {string} registrationName Name of listener (e.g. `onClick`). - */ - deleteListener: function (inst, registrationName) { - var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; - if (PluginModule && PluginModule.willDeleteListener) { - PluginModule.willDeleteListener(inst, registrationName); - } - - var bankForRegistrationName = listenerBank[registrationName]; - // TODO: This should never be null -- when is it? - if (bankForRegistrationName) { - var key = getDictionaryKey(inst); - delete bankForRegistrationName[key]; - } - }, - - /** - * Deletes all listeners for the DOM element with the supplied ID. - * - * @param {object} inst The instance, which is the source of events. - */ - deleteAllListeners: function (inst) { - var key = getDictionaryKey(inst); - for (var registrationName in listenerBank) { - if (!listenerBank.hasOwnProperty(registrationName)) { - continue; - } - - if (!listenerBank[registrationName][key]) { - continue; - } - - var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; - if (PluginModule && PluginModule.willDeleteListener) { - PluginModule.willDeleteListener(inst, registrationName); - } - - delete listenerBank[registrationName][key]; - } - }, - - /** - * Allows registered plugins an opportunity to extract events from top-level - * native browser events. - * - * @return {*} An accumulation of synthetic events. - * @internal - */ - extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var events; - var plugins = EventPluginRegistry.plugins; - for (var i = 0; i < plugins.length; i++) { - // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; - if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); - if (extractedEvents) { - events = accumulateInto(events, extractedEvents); - } - } - } - return events; - }, - - /** - * Enqueues a synthetic event that should be dispatched when - * `processEventQueue` is invoked. - * - * @param {*} events An accumulation of synthetic events. - * @internal - */ - enqueueEvents: function (events) { - if (events) { - eventQueue = accumulateInto(eventQueue, events); - } - }, - - /** - * Dispatches all synthetic events on the event queue. - * - * @internal - */ - processEventQueue: function (simulated) { - // Set `eventQueue` to null before processing it so that we can tell if more - // events get enqueued while processing. - var processingEventQueue = eventQueue; - eventQueue = null; - if (simulated) { - forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated); - } else { - forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); - } - !!eventQueue ? process.env.NODE_ENV !== 'production' ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : _prodInvariant('95') : void 0; - // This would be a good time to rethrow if any of the event handlers threw. - ReactErrorUtils.rethrowCaughtError(); - }, - - /** - * These are needed for tests only. Do not use! - */ - __purge: function () { - listenerBank = {}; - }, - - __getListenerBank: function () { - return listenerBank; - } - -}; - -module.exports = EventPluginHub; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 31 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var EventPluginHub = __webpack_require__(30); -var EventPluginUtils = __webpack_require__(48); - -var accumulateInto = __webpack_require__(91); -var forEachAccumulated = __webpack_require__(92); -var warning = __webpack_require__(3); - -var getListener = EventPluginHub.getListener; - -/** - * Some event types have a notion of different registration names for different - * "phases" of propagation. This finds listeners by a given phase. - */ -function listenerAtPhase(inst, event, propagationPhase) { - var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase]; - return getListener(inst, registrationName); -} - -/** - * Tags a `SyntheticEvent` with dispatched listeners. Creating this function - * here, allows us to not have to bind or create functions for each event. - * Mutating the event's members allows us to not have to create a wrapping - * "dispatch" object that pairs the event with the listener. - */ -function accumulateDirectionalDispatches(inst, phase, event) { - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(inst, 'Dispatching inst must not be null') : void 0; - } - var listener = listenerAtPhase(inst, event, phase); - if (listener) { - event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); - } -} - -/** - * Collect dispatches (must be entirely collected before dispatching - see unit - * tests). Lazily allocate the array to conserve memory. We must loop through - * each event and perform the traversal for each one. We cannot perform a - * single traversal for the entire collection of events because each event may - * have a different target. - */ -function accumulateTwoPhaseDispatchesSingle(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - EventPluginUtils.traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); - } -} - -/** - * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. - */ -function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - var targetInst = event._targetInst; - var parentInst = targetInst ? EventPluginUtils.getParentInstance(targetInst) : null; - EventPluginUtils.traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); - } -} - -/** - * Accumulates without regard to direction, does not look for phased - * registration names. Same as `accumulateDirectDispatchesSingle` but without - * requiring that the `dispatchMarker` be the same as the dispatched ID. - */ -function accumulateDispatches(inst, ignoredDirection, event) { - if (event && event.dispatchConfig.registrationName) { - var registrationName = event.dispatchConfig.registrationName; - var listener = getListener(inst, registrationName); - if (listener) { - event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); - } - } -} - -/** - * Accumulates dispatches on an `SyntheticEvent`, but only for the - * `dispatchMarker`. - * @param {SyntheticEvent} event - */ -function accumulateDirectDispatchesSingle(event) { - if (event && event.dispatchConfig.registrationName) { - accumulateDispatches(event._targetInst, null, event); - } -} - -function accumulateTwoPhaseDispatches(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); -} - -function accumulateTwoPhaseDispatchesSkipTarget(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); -} - -function accumulateEnterLeaveDispatches(leave, enter, from, to) { - EventPluginUtils.traverseEnterLeave(from, to, accumulateDispatches, leave, enter); -} - -function accumulateDirectDispatches(events) { - forEachAccumulated(events, accumulateDirectDispatchesSingle); -} - -/** - * A small set of propagation patterns, each of which will accept a small amount - * of information, and generate a set of "dispatch ready event objects" - which - * are sets of events that have already been annotated with a set of dispatched - * listener functions/ids. The API is designed this way to discourage these - * propagation strategies from actually executing the dispatches, since we - * always want to collect the entire set of dispatches before executing event a - * single one. - * - * @constructor EventPropagators - */ -var EventPropagators = { - accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches, - accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget, - accumulateDirectDispatches: accumulateDirectDispatches, - accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches -}; - -module.exports = EventPropagators; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 32 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * `ReactInstanceMap` maintains a mapping from a public facing stateful - * instance (key) and the internal representation (value). This allows public - * methods to accept the user facing instance as an argument and map them back - * to internal methods. - */ - -// TODO: Replace this with ES6: var ReactInstanceMap = new Map(); - -var ReactInstanceMap = { - - /** - * This API should be called `delete` but we'd have to make sure to always - * transform these to strings for IE support. When this transform is fully - * supported we can rename it. - */ - remove: function (key) { - key._reactInternalInstance = undefined; - }, - - get: function (key) { - return key._reactInternalInstance; - }, - - has: function (key) { - return key._reactInternalInstance !== undefined; - }, - - set: function (key, value) { - key._reactInternalInstance = value; - } - -}; - -module.exports = ReactInstanceMap; - -/***/ }), -/* 33 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticEvent = __webpack_require__(17); - -var getEventTarget = __webpack_require__(57); - -/** - * @interface UIEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var UIEventInterface = { - view: function (event) { - if (event.view) { - return event.view; - } - - var target = getEventTarget(event); - if (target.window === target) { - // target is a window object - return target; - } - - var doc = target.ownerDocument; - // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. - if (doc) { - return doc.defaultView || doc.parentWindow; - } else { - return window; - } - }, - detail: function (event) { - return event.detail || 0; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticEvent} - */ -function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface); - -module.exports = SyntheticUIEvent; - -/***/ }), -/* 34 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; -exports.compilePattern = compilePattern; -exports.matchPattern = matchPattern; -exports.getParamNames = getParamNames; -exports.getParams = getParams; -exports.formatPattern = formatPattern; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); -} - -function escapeSource(string) { - return escapeRegExp(string).replace(/\/+/g, '/+'); -} - -function _compilePattern(pattern) { - var regexpSource = ''; - var paramNames = []; - var tokens = []; - - var match = undefined, - lastIndex = 0, - matcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|\*\*|\*|\(|\)/g; - while (match = matcher.exec(pattern)) { - if (match.index !== lastIndex) { - tokens.push(pattern.slice(lastIndex, match.index)); - regexpSource += escapeSource(pattern.slice(lastIndex, match.index)); - } - - if (match[1]) { - regexpSource += '([^/?#]+)'; - paramNames.push(match[1]); - } else if (match[0] === '**') { - regexpSource += '([\\s\\S]*)'; - paramNames.push('splat'); - } else if (match[0] === '*') { - regexpSource += '([\\s\\S]*?)'; - paramNames.push('splat'); - } else if (match[0] === '(') { - regexpSource += '(?:'; - } else if (match[0] === ')') { - regexpSource += ')?'; - } - - tokens.push(match[0]); - - lastIndex = matcher.lastIndex; - } - - if (lastIndex !== pattern.length) { - tokens.push(pattern.slice(lastIndex, pattern.length)); - regexpSource += escapeSource(pattern.slice(lastIndex, pattern.length)); - } - - return { - pattern: pattern, - regexpSource: regexpSource, - paramNames: paramNames, - tokens: tokens - }; -} - -var CompiledPatternsCache = {}; - -function compilePattern(pattern) { - if (!(pattern in CompiledPatternsCache)) CompiledPatternsCache[pattern] = _compilePattern(pattern); - - return CompiledPatternsCache[pattern]; -} - -/** - * Attempts to match a pattern on the given pathname. Patterns may use - * the following special characters: - * - * - :paramName Matches a URL segment up to the next /, ?, or #. The - * captured string is considered a "param" - * - () Wraps a segment of the URL that is optional - * - * Consumes (non-greedy) all characters up to the next - * character in the pattern, or to the end of the URL if - * there is none - * - ** Consumes (greedy) all characters up to the next character - * in the pattern, or to the end of the URL if there is none - * - * The return value is an object with the following properties: - * - * - remainingPathname - * - paramNames - * - paramValues - */ - -function matchPattern(pattern, pathname) { - // Make leading slashes consistent between pattern and pathname. - if (pattern.charAt(0) !== '/') { - pattern = '/' + pattern; - } - if (pathname.charAt(0) !== '/') { - pathname = '/' + pathname; - } - - var _compilePattern2 = compilePattern(pattern); - - var regexpSource = _compilePattern2.regexpSource; - var paramNames = _compilePattern2.paramNames; - var tokens = _compilePattern2.tokens; - - regexpSource += '/*'; // Capture path separators - - // Special-case patterns like '*' for catch-all routes. - var captureRemaining = tokens[tokens.length - 1] !== '*'; - - if (captureRemaining) { - // This will match newlines in the remaining path. - regexpSource += '([\\s\\S]*?)'; - } - - var match = pathname.match(new RegExp('^' + regexpSource + '$', 'i')); - - var remainingPathname = undefined, - paramValues = undefined; - if (match != null) { - if (captureRemaining) { - remainingPathname = match.pop(); - var matchedPath = match[0].substr(0, match[0].length - remainingPathname.length); - - // If we didn't match the entire pathname, then make sure that the match - // we did get ends at a path separator (potentially the one we added - // above at the beginning of the path, if the actual match was empty). - if (remainingPathname && matchedPath.charAt(matchedPath.length - 1) !== '/') { - return { - remainingPathname: null, - paramNames: paramNames, - paramValues: null - }; - } - } else { - // If this matched at all, then the match was the entire pathname. - remainingPathname = ''; - } - - paramValues = match.slice(1).map(function (v) { - return v != null ? decodeURIComponent(v) : v; - }); - } else { - remainingPathname = paramValues = null; - } - - return { - remainingPathname: remainingPathname, - paramNames: paramNames, - paramValues: paramValues - }; -} - -function getParamNames(pattern) { - return compilePattern(pattern).paramNames; -} - -function getParams(pattern, pathname) { - var _matchPattern = matchPattern(pattern, pathname); - - var paramNames = _matchPattern.paramNames; - var paramValues = _matchPattern.paramValues; - - if (paramValues != null) { - return paramNames.reduce(function (memo, paramName, index) { - memo[paramName] = paramValues[index]; - return memo; - }, {}); - } - - return null; -} - -/** - * Returns a version of the given pattern with params interpolated. Throws - * if there is a dynamic segment of the pattern for which there is no param. - */ - -function formatPattern(pattern, params) { - params = params || {}; - - var _compilePattern3 = compilePattern(pattern); - - var tokens = _compilePattern3.tokens; - - var parenCount = 0, - pathname = '', - splatIndex = 0; - - var token = undefined, - paramName = undefined, - paramValue = undefined; - for (var i = 0, len = tokens.length; i < len; ++i) { - token = tokens[i]; - - if (token === '*' || token === '**') { - paramValue = Array.isArray(params.splat) ? params.splat[splatIndex++] : params.splat; - - !(paramValue != null || parenCount > 0) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Missing splat #%s for path "%s"', splatIndex, pattern) : _invariant2['default'](false) : undefined; - - if (paramValue != null) pathname += encodeURI(paramValue); - } else if (token === '(') { - parenCount += 1; - } else if (token === ')') { - parenCount -= 1; - } else if (token.charAt(0) === ':') { - paramName = token.substring(1); - paramValue = params[paramName]; - - !(paramValue != null || parenCount > 0) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Missing "%s" parameter for path "%s"', paramName, pattern) : _invariant2['default'](false) : undefined; - - if (paramValue != null) pathname += encodeURIComponent(paramValue); - } else { - pathname += token; - } - } - - return pathname.replace(/\/+/g, '/'); -} -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 35 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -/** - * Injectable ordering of event plugins. - */ -var eventPluginOrder = null; - -/** - * Injectable mapping from names to event plugin modules. - */ -var namesToPlugins = {}; - -/** - * Recomputes the plugin list using the injected plugins and plugin ordering. - * - * @private - */ -function recomputePluginOrdering() { - if (!eventPluginOrder) { - // Wait until an `eventPluginOrder` is injected. - return; - } - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName]; - var pluginIndex = eventPluginOrder.indexOf(pluginName); - !(pluginIndex > -1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : _prodInvariant('96', pluginName) : void 0; - if (EventPluginRegistry.plugins[pluginIndex]) { - continue; - } - !pluginModule.extractEvents ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : _prodInvariant('97', pluginName) : void 0; - EventPluginRegistry.plugins[pluginIndex] = pluginModule; - var publishedEvents = pluginModule.eventTypes; - for (var eventName in publishedEvents) { - !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : _prodInvariant('98', eventName, pluginName) : void 0; - } - } -} - -/** - * Publishes an event so that it can be dispatched by the supplied plugin. - * - * @param {object} dispatchConfig Dispatch configuration for the event. - * @param {object} PluginModule Plugin publishing the event. - * @return {boolean} True if the event was successfully published. - * @private - */ -function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { - !!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : _prodInvariant('99', eventName) : void 0; - EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; - - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (var phaseName in phasedRegistrationNames) { - if (phasedRegistrationNames.hasOwnProperty(phaseName)) { - var phasedRegistrationName = phasedRegistrationNames[phaseName]; - publishRegistrationName(phasedRegistrationName, pluginModule, eventName); - } - } - return true; - } else if (dispatchConfig.registrationName) { - publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName); - return true; - } - return false; -} - -/** - * Publishes a registration name that is used to identify dispatched events and - * can be used with `EventPluginHub.putListener` to register listeners. - * - * @param {string} registrationName Registration name to add. - * @param {object} PluginModule Plugin publishing the event. - * @private - */ -function publishRegistrationName(registrationName, pluginModule, eventName) { - !!EventPluginRegistry.registrationNameModules[registrationName] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : _prodInvariant('100', registrationName) : void 0; - EventPluginRegistry.registrationNameModules[registrationName] = pluginModule; - EventPluginRegistry.registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies; - - if (process.env.NODE_ENV !== 'production') { - var lowerCasedName = registrationName.toLowerCase(); - EventPluginRegistry.possibleRegistrationNames[lowerCasedName] = registrationName; - - if (registrationName === 'onDoubleClick') { - EventPluginRegistry.possibleRegistrationNames.ondblclick = registrationName; - } - } -} - -/** - * Registers plugins so that they can extract and dispatch events. - * - * @see {EventPluginHub} - */ -var EventPluginRegistry = { - - /** - * Ordered list of injected plugins. - */ - plugins: [], - - /** - * Mapping from event name to dispatch config - */ - eventNameDispatchConfigs: {}, - - /** - * Mapping from registration name to plugin module - */ - registrationNameModules: {}, - - /** - * Mapping from registration name to event name - */ - registrationNameDependencies: {}, - - /** - * Mapping from lowercase registration names to the properly cased version, - * used to warn in the case of missing event handlers. Available - * only in __DEV__. - * @type {Object} - */ - possibleRegistrationNames: process.env.NODE_ENV !== 'production' ? {} : null, - // Trust the developer to only use possibleRegistrationNames in __DEV__ - - /** - * Injects an ordering of plugins (by plugin name). This allows the ordering - * to be decoupled from injection of the actual plugins so that ordering is - * always deterministic regardless of packaging, on-the-fly injection, etc. - * - * @param {array} InjectedEventPluginOrder - * @internal - * @see {EventPluginHub.injection.injectEventPluginOrder} - */ - injectEventPluginOrder: function (injectedEventPluginOrder) { - !!eventPluginOrder ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : _prodInvariant('101') : void 0; - // Clone the ordering so it cannot be dynamically mutated. - eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); - recomputePluginOrdering(); - }, - - /** - * Injects plugins to be used by `EventPluginHub`. The plugin names must be - * in the ordering injected by `injectEventPluginOrder`. - * - * Plugins can be injected as part of page initialization or on-the-fly. - * - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - * @internal - * @see {EventPluginHub.injection.injectEventPluginsByName} - */ - injectEventPluginsByName: function (injectedNamesToPlugins) { - var isOrderingDirty = false; - for (var pluginName in injectedNamesToPlugins) { - if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { - continue; - } - var pluginModule = injectedNamesToPlugins[pluginName]; - if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) { - !!namesToPlugins[pluginName] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : _prodInvariant('102', pluginName) : void 0; - namesToPlugins[pluginName] = pluginModule; - isOrderingDirty = true; - } - } - if (isOrderingDirty) { - recomputePluginOrdering(); - } - }, - - /** - * Looks up the plugin for the supplied event. - * - * @param {object} event A synthetic event. - * @return {?object} The plugin that created the supplied event. - * @internal - */ - getPluginModuleForEvent: function (event) { - var dispatchConfig = event.dispatchConfig; - if (dispatchConfig.registrationName) { - return EventPluginRegistry.registrationNameModules[dispatchConfig.registrationName] || null; - } - if (dispatchConfig.phasedRegistrationNames !== undefined) { - // pulling phasedRegistrationNames out of dispatchConfig helps Flow see - // that it is not undefined. - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - - for (var phase in phasedRegistrationNames) { - if (!phasedRegistrationNames.hasOwnProperty(phase)) { - continue; - } - var pluginModule = EventPluginRegistry.registrationNameModules[phasedRegistrationNames[phase]]; - if (pluginModule) { - return pluginModule; - } - } - } - return null; - }, - - /** - * Exposed for unit testing. - * @private - */ - _resetEventPlugins: function () { - eventPluginOrder = null; - for (var pluginName in namesToPlugins) { - if (namesToPlugins.hasOwnProperty(pluginName)) { - delete namesToPlugins[pluginName]; - } - } - EventPluginRegistry.plugins.length = 0; - - var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs; - for (var eventName in eventNameDispatchConfigs) { - if (eventNameDispatchConfigs.hasOwnProperty(eventName)) { - delete eventNameDispatchConfigs[eventName]; - } - } - - var registrationNameModules = EventPluginRegistry.registrationNameModules; - for (var registrationName in registrationNameModules) { - if (registrationNameModules.hasOwnProperty(registrationName)) { - delete registrationNameModules[registrationName]; - } - } - - if (process.env.NODE_ENV !== 'production') { - var possibleRegistrationNames = EventPluginRegistry.possibleRegistrationNames; - for (var lowerCasedName in possibleRegistrationNames) { - if (possibleRegistrationNames.hasOwnProperty(lowerCasedName)) { - delete possibleRegistrationNames[lowerCasedName]; - } - } - } - } - -}; - -module.exports = EventPluginRegistry; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 36 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var EventPluginRegistry = __webpack_require__(35); -var ReactEventEmitterMixin = __webpack_require__(270); -var ViewportMetrics = __webpack_require__(90); - -var getVendorPrefixedEventName = __webpack_require__(306); -var isEventSupported = __webpack_require__(58); - -/** - * Summary of `ReactBrowserEventEmitter` event handling: - * - * - Top-level delegation is used to trap most native browser events. This - * may only occur in the main thread and is the responsibility of - * ReactEventListener, which is injected and can therefore support pluggable - * event sources. This is the only work that occurs in the main thread. - * - * - We normalize and de-duplicate events to account for browser quirks. This - * may be done in the worker thread. - * - * - Forward these native events (with the associated top-level type used to - * trap it) to `EventPluginHub`, which in turn will ask plugins if they want - * to extract any synthetic events. - * - * - The `EventPluginHub` will then process each event by annotating them with - * "dispatches", a sequence of listeners and IDs that care about that event. - * - * - The `EventPluginHub` then dispatches the events. - * - * Overview of React and the event system: - * - * +------------+ . - * | DOM | . - * +------------+ . - * | . - * v . - * +------------+ . - * | ReactEvent | . - * | Listener | . - * +------------+ . +-----------+ - * | . +--------+|SimpleEvent| - * | . | |Plugin | - * +-----|------+ . v +-----------+ - * | | | . +--------------+ +------------+ - * | +-----------.--->|EventPluginHub| | Event | - * | | . | | +-----------+ | Propagators| - * | ReactEvent | . | | |TapEvent | |------------| - * | Emitter | . | |<---+|Plugin | |other plugin| - * | | . | | +-----------+ | utilities | - * | +-----------.--->| | +------------+ - * | | | . +--------------+ - * +-----|------+ . ^ +-----------+ - * | . | |Enter/Leave| - * + . +-------+|Plugin | - * +-------------+ . +-----------+ - * | application | . - * |-------------| . - * | | . - * | | . - * +-------------+ . - * . - * React Core . General Purpose Event Plugin System - */ - -var hasEventPageXY; -var alreadyListeningTo = {}; -var isMonitoringScrollValue = false; -var reactTopListenersCounter = 0; - -// For events like 'submit' which don't consistently bubble (which we trap at a -// lower node than `document`), binding at `document` would cause duplicate -// events so we don't include them here -var topEventMapping = { - topAbort: 'abort', - topAnimationEnd: getVendorPrefixedEventName('animationend') || 'animationend', - topAnimationIteration: getVendorPrefixedEventName('animationiteration') || 'animationiteration', - topAnimationStart: getVendorPrefixedEventName('animationstart') || 'animationstart', - topBlur: 'blur', - topCanPlay: 'canplay', - topCanPlayThrough: 'canplaythrough', - topChange: 'change', - topClick: 'click', - topCompositionEnd: 'compositionend', - topCompositionStart: 'compositionstart', - topCompositionUpdate: 'compositionupdate', - topContextMenu: 'contextmenu', - topCopy: 'copy', - topCut: 'cut', - topDoubleClick: 'dblclick', - topDrag: 'drag', - topDragEnd: 'dragend', - topDragEnter: 'dragenter', - topDragExit: 'dragexit', - topDragLeave: 'dragleave', - topDragOver: 'dragover', - topDragStart: 'dragstart', - topDrop: 'drop', - topDurationChange: 'durationchange', - topEmptied: 'emptied', - topEncrypted: 'encrypted', - topEnded: 'ended', - topError: 'error', - topFocus: 'focus', - topInput: 'input', - topKeyDown: 'keydown', - topKeyPress: 'keypress', - topKeyUp: 'keyup', - topLoadedData: 'loadeddata', - topLoadedMetadata: 'loadedmetadata', - topLoadStart: 'loadstart', - topMouseDown: 'mousedown', - topMouseMove: 'mousemove', - topMouseOut: 'mouseout', - topMouseOver: 'mouseover', - topMouseUp: 'mouseup', - topPaste: 'paste', - topPause: 'pause', - topPlay: 'play', - topPlaying: 'playing', - topProgress: 'progress', - topRateChange: 'ratechange', - topScroll: 'scroll', - topSeeked: 'seeked', - topSeeking: 'seeking', - topSelectionChange: 'selectionchange', - topStalled: 'stalled', - topSuspend: 'suspend', - topTextInput: 'textInput', - topTimeUpdate: 'timeupdate', - topTouchCancel: 'touchcancel', - topTouchEnd: 'touchend', - topTouchMove: 'touchmove', - topTouchStart: 'touchstart', - topTransitionEnd: getVendorPrefixedEventName('transitionend') || 'transitionend', - topVolumeChange: 'volumechange', - topWaiting: 'waiting', - topWheel: 'wheel' -}; - -/** - * To ensure no conflicts with other potential React instances on the page - */ -var topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2); - -function getListeningForDocument(mountAt) { - // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` - // directly. - if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { - mountAt[topListenersIDKey] = reactTopListenersCounter++; - alreadyListeningTo[mountAt[topListenersIDKey]] = {}; - } - return alreadyListeningTo[mountAt[topListenersIDKey]]; -} - -/** - * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For - * example: - * - * EventPluginHub.putListener('myID', 'onClick', myFunction); - * - * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'. - * - * @internal - */ -var ReactBrowserEventEmitter = _assign({}, ReactEventEmitterMixin, { - - /** - * Injectable event backend - */ - ReactEventListener: null, - - injection: { - /** - * @param {object} ReactEventListener - */ - injectReactEventListener: function (ReactEventListener) { - ReactEventListener.setHandleTopLevel(ReactBrowserEventEmitter.handleTopLevel); - ReactBrowserEventEmitter.ReactEventListener = ReactEventListener; - } - }, - - /** - * Sets whether or not any created callbacks should be enabled. - * - * @param {boolean} enabled True if callbacks should be enabled. - */ - setEnabled: function (enabled) { - if (ReactBrowserEventEmitter.ReactEventListener) { - ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled); - } - }, - - /** - * @return {boolean} True if callbacks are enabled. - */ - isEnabled: function () { - return !!(ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled()); - }, - - /** - * We listen for bubbled touch events on the document object. - * - * Firefox v8.01 (and possibly others) exhibited strange behavior when - * mounting `onmousemove` events at some node that was not the document - * element. The symptoms were that if your mouse is not moving over something - * contained within that mount point (for example on the background) the - * top-level listeners for `onmousemove` won't be called. However, if you - * register the `mousemove` on the document object, then it will of course - * catch all `mousemove`s. This along with iOS quirks, justifies restricting - * top-level listeners to the document object only, at least for these - * movement types of events and possibly all events. - * - * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html - * - * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but - * they bubble to document. - * - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {object} contentDocumentHandle Document which owns the container - */ - listenTo: function (registrationName, contentDocumentHandle) { - var mountAt = contentDocumentHandle; - var isListening = getListeningForDocument(mountAt); - var dependencies = EventPluginRegistry.registrationNameDependencies[registrationName]; - - for (var i = 0; i < dependencies.length; i++) { - var dependency = dependencies[i]; - if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { - if (dependency === 'topWheel') { - if (isEventSupported('wheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'wheel', mountAt); - } else if (isEventSupported('mousewheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'mousewheel', mountAt); - } else { - // Firefox needs to capture a different mouse scroll event. - // @see http://www.quirksmode.org/dom/events/tests/scroll.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'DOMMouseScroll', mountAt); - } - } else if (dependency === 'topScroll') { - - if (isEventSupported('scroll', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topScroll', 'scroll', mountAt); - } else { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topScroll', 'scroll', ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE); - } - } else if (dependency === 'topFocus' || dependency === 'topBlur') { - - if (isEventSupported('focus', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topFocus', 'focus', mountAt); - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topBlur', 'blur', mountAt); - } else if (isEventSupported('focusin')) { - // IE has `focusin` and `focusout` events which bubble. - // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topFocus', 'focusin', mountAt); - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topBlur', 'focusout', mountAt); - } - - // to make sure blur and focus event listeners are only attached once - isListening.topBlur = true; - isListening.topFocus = true; - } else if (topEventMapping.hasOwnProperty(dependency)) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(dependency, topEventMapping[dependency], mountAt); - } - - isListening[dependency] = true; - } - } - }, - - trapBubbledEvent: function (topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelType, handlerBaseName, handle); - }, - - trapCapturedEvent: function (topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelType, handlerBaseName, handle); - }, - - /** - * Protect against document.createEvent() returning null - * Some popup blocker extensions appear to do this: - * https://github.com/facebook/react/issues/6887 - */ - supportsEventPageXY: function () { - if (!document.createEvent) { - return false; - } - var ev = document.createEvent('MouseEvent'); - return ev != null && 'pageX' in ev; - }, - - /** - * Listens to window scroll and resize events. We cache scroll values so that - * application code can access them without triggering reflows. - * - * ViewportMetrics is only used by SyntheticMouse/TouchEvent and only when - * pageX/pageY isn't supported (legacy browsers). - * - * NOTE: Scroll events do not bubble. - * - * @see http://www.quirksmode.org/dom/events/scroll.html - */ - ensureScrollValueMonitoring: function () { - if (hasEventPageXY === undefined) { - hasEventPageXY = ReactBrowserEventEmitter.supportsEventPageXY(); - } - if (!hasEventPageXY && !isMonitoringScrollValue) { - var refresh = ViewportMetrics.refreshScrollValues; - ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh); - isMonitoringScrollValue = true; - } - } - -}); - -module.exports = ReactBrowserEventEmitter; - -/***/ }), -/* 37 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticUIEvent = __webpack_require__(33); -var ViewportMetrics = __webpack_require__(90); - -var getEventModifierState = __webpack_require__(56); - -/** - * @interface MouseEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var MouseEventInterface = { - screenX: null, - screenY: null, - clientX: null, - clientY: null, - ctrlKey: null, - shiftKey: null, - altKey: null, - metaKey: null, - getModifierState: getEventModifierState, - button: function (event) { - // Webkit, Firefox, IE9+ - // which: 1 2 3 - // button: 0 1 2 (standard) - var button = event.button; - if ('which' in event) { - return button; - } - // IE<9 - // which: undefined - // button: 0 0 0 - // button: 1 4 2 (onmouseup) - return button === 2 ? 2 : button === 4 ? 1 : 0; - }, - buttons: null, - relatedTarget: function (event) { - return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement); - }, - // "Proprietary" Interface. - pageX: function (event) { - return 'pageX' in event ? event.pageX : event.clientX + ViewportMetrics.currentScrollLeft; - }, - pageY: function (event) { - return 'pageY' in event ? event.pageY : event.clientY + ViewportMetrics.currentScrollTop; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface); - -module.exports = SyntheticMouseEvent; - -/***/ }), -/* 38 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -var OBSERVED_ERROR = {}; - -/** - * `Transaction` creates a black box that is able to wrap any method such that - * certain invariants are maintained before and after the method is invoked - * (Even if an exception is thrown while invoking the wrapped method). Whoever - * instantiates a transaction can provide enforcers of the invariants at - * creation time. The `Transaction` class itself will supply one additional - * automatic invariant for you - the invariant that any transaction instance - * should not be run while it is already being run. You would typically create a - * single instance of a `Transaction` for reuse multiple times, that potentially - * is used to wrap several different methods. Wrappers are extremely simple - - * they only require implementing two methods. - * - *
- *                       wrappers (injected at creation time)
- *                                      +        +
- *                                      |        |
- *                    +-----------------|--------|--------------+
- *                    |                 v        |              |
- *                    |      +---------------+   |              |
- *                    |   +--|    wrapper1   |---|----+         |
- *                    |   |  +---------------+   v    |         |
- *                    |   |          +-------------+  |         |
- *                    |   |     +----|   wrapper2  |--------+   |
- *                    |   |     |    +-------------+  |     |   |
- *                    |   |     |                     |     |   |
- *                    |   v     v                     v     v   | wrapper
- *                    | +---+ +---+   +---------+   +---+ +---+ | invariants
- * perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained
- * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
- *                    | |   | |   |   |         |   |   | |   | |
- *                    | |   | |   |   |         |   |   | |   | |
- *                    | |   | |   |   |         |   |   | |   | |
- *                    | +---+ +---+   +---------+   +---+ +---+ |
- *                    |  initialize                    close    |
- *                    +-----------------------------------------+
- * 
- * - * Use cases: - * - Preserving the input selection ranges before/after reconciliation. - * Restoring selection even in the event of an unexpected error. - * - Deactivating events while rearranging the DOM, preventing blurs/focuses, - * while guaranteeing that afterwards, the event system is reactivated. - * - Flushing a queue of collected DOM mutations to the main UI thread after a - * reconciliation takes place in a worker thread. - * - Invoking any collected `componentDidUpdate` callbacks after rendering new - * content. - * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue - * to preserve the `scrollTop` (an automatic scroll aware DOM). - * - (Future use case): Layout calculations before and after DOM updates. - * - * Transactional plugin API: - * - A module that has an `initialize` method that returns any precomputation. - * - and a `close` method that accepts the precomputation. `close` is invoked - * when the wrapped process is completed, or has failed. - * - * @param {Array} transactionWrapper Wrapper modules - * that implement `initialize` and `close`. - * @return {Transaction} Single transaction for reuse in thread. - * - * @class Transaction - */ -var TransactionImpl = { - /** - * Sets up this instance so that it is prepared for collecting metrics. Does - * so such that this setup method may be used on an instance that is already - * initialized, in a way that does not consume additional memory upon reuse. - * That can be useful if you decide to make your subclass of this mixin a - * "PooledClass". - */ - reinitializeTransaction: function () { - this.transactionWrappers = this.getTransactionWrappers(); - if (this.wrapperInitData) { - this.wrapperInitData.length = 0; - } else { - this.wrapperInitData = []; - } - this._isInTransaction = false; - }, - - _isInTransaction: false, - - /** - * @abstract - * @return {Array} Array of transaction wrappers. - */ - getTransactionWrappers: null, - - isInTransaction: function () { - return !!this._isInTransaction; - }, - - /** - * Executes the function within a safety window. Use this for the top level - * methods that result in large amounts of computation/mutations that would - * need to be safety checked. The optional arguments helps prevent the need - * to bind in many cases. - * - * @param {function} method Member of scope to call. - * @param {Object} scope Scope to invoke from. - * @param {Object?=} a Argument to pass to the method. - * @param {Object?=} b Argument to pass to the method. - * @param {Object?=} c Argument to pass to the method. - * @param {Object?=} d Argument to pass to the method. - * @param {Object?=} e Argument to pass to the method. - * @param {Object?=} f Argument to pass to the method. - * - * @return {*} Return value from `method`. - */ - perform: function (method, scope, a, b, c, d, e, f) { - !!this.isInTransaction() ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Transaction.perform(...): Cannot initialize a transaction when there is already an outstanding transaction.') : _prodInvariant('27') : void 0; - var errorThrown; - var ret; - try { - this._isInTransaction = true; - // Catching errors makes debugging more difficult, so we start with - // errorThrown set to true before setting it to false after calling - // close -- if it's still set to true in the finally block, it means - // one of these calls threw. - errorThrown = true; - this.initializeAll(0); - ret = method.call(scope, a, b, c, d, e, f); - errorThrown = false; - } finally { - try { - if (errorThrown) { - // If `method` throws, prefer to show that stack trace over any thrown - // by invoking `closeAll`. - try { - this.closeAll(0); - } catch (err) {} - } else { - // Since `method` didn't throw, we don't want to silence the exception - // here. - this.closeAll(0); - } - } finally { - this._isInTransaction = false; - } - } - return ret; - }, - - initializeAll: function (startIndex) { - var transactionWrappers = this.transactionWrappers; - for (var i = startIndex; i < transactionWrappers.length; i++) { - var wrapper = transactionWrappers[i]; - try { - // Catching errors makes debugging more difficult, so we start with the - // OBSERVED_ERROR state before overwriting it with the real return value - // of initialize -- if it's still set to OBSERVED_ERROR in the finally - // block, it means wrapper.initialize threw. - this.wrapperInitData[i] = OBSERVED_ERROR; - this.wrapperInitData[i] = wrapper.initialize ? wrapper.initialize.call(this) : null; - } finally { - if (this.wrapperInitData[i] === OBSERVED_ERROR) { - // The initializer for wrapper i threw an error; initialize the - // remaining wrappers but silence any exceptions from them to ensure - // that the first error is the one to bubble up. - try { - this.initializeAll(i + 1); - } catch (err) {} - } - } - } - }, - - /** - * Invokes each of `this.transactionWrappers.close[i]` functions, passing into - * them the respective return values of `this.transactionWrappers.init[i]` - * (`close`rs that correspond to initializers that failed will not be - * invoked). - */ - closeAll: function (startIndex) { - !this.isInTransaction() ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Transaction.closeAll(): Cannot close transaction when none are open.') : _prodInvariant('28') : void 0; - var transactionWrappers = this.transactionWrappers; - for (var i = startIndex; i < transactionWrappers.length; i++) { - var wrapper = transactionWrappers[i]; - var initData = this.wrapperInitData[i]; - var errorThrown; - try { - // Catching errors makes debugging more difficult, so we start with - // errorThrown set to true before setting it to false after calling - // close -- if it's still set to true in the finally block, it means - // wrapper.close threw. - errorThrown = true; - if (initData !== OBSERVED_ERROR && wrapper.close) { - wrapper.close.call(this, initData); - } - errorThrown = false; - } finally { - if (errorThrown) { - // The closer for wrapper i threw an error; close the remaining - // wrappers but silence any exceptions from them to ensure that the - // first error is the one to bubble up. - try { - this.closeAll(i + 1); - } catch (e) {} - } - } - } - this.wrapperInitData.length = 0; - } -}; - -module.exports = TransactionImpl; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 39 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * Based on the escape-html library, which is used under the MIT License below: - * - * Copyright (c) 2012-2013 TJ Holowaychuk - * Copyright (c) 2015 Andreas Lubbe - * Copyright (c) 2015 Tiancheng "Timothy" Gu - * - * 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. - * - */ - - - -// code copied and modified from escape-html -/** - * Module variables. - * @private - */ - -var matchHtmlRegExp = /["'&<>]/; - -/** - * Escape special characters in the given string of html. - * - * @param {string} string The string to escape for inserting into HTML - * @return {string} - * @public - */ - -function escapeHtml(string) { - var str = '' + string; - var match = matchHtmlRegExp.exec(str); - - if (!match) { - return str; - } - - var escape; - var html = ''; - var index = 0; - var lastIndex = 0; - - for (index = match.index; index < str.length; index++) { - switch (str.charCodeAt(index)) { - case 34: - // " - escape = '"'; - break; - case 38: - // & - escape = '&'; - break; - case 39: - // ' - escape = '''; // modified from escape-html; used to be ''' - break; - case 60: - // < - escape = '<'; - break; - case 62: - // > - escape = '>'; - break; - default: - continue; - } - - if (lastIndex !== index) { - html += str.substring(lastIndex, index); - } - - lastIndex = index + 1; - html += escape; - } - - return lastIndex !== index ? html + str.substring(lastIndex, index) : html; -} -// end code copied and modified from escape-html - - -/** - * Escapes text to prevent scripting attacks. - * - * @param {*} text Text value to escape. - * @return {string} An escaped string. - */ -function escapeTextContentForBrowser(text) { - if (typeof text === 'boolean' || typeof text === 'number') { - // this shortcircuit helps perf for types that we know will never have - // special characters, especially given that this function is used often - // for numeric dom ids. - return '' + text; - } - return escapeHtml(text); -} - -module.exports = escapeTextContentForBrowser; - -/***/ }), -/* 40 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ExecutionEnvironment = __webpack_require__(8); -var DOMNamespaces = __webpack_require__(47); - -var WHITESPACE_TEST = /^[ \r\n\t\f]/; -var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/; - -var createMicrosoftUnsafeLocalFunction = __webpack_require__(54); - -// SVG temp container for IE lacking innerHTML -var reusableSVGContainer; - -/** - * Set the innerHTML property of a node, ensuring that whitespace is preserved - * even in IE8. - * - * @param {DOMElement} node - * @param {string} html - * @internal - */ -var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) { - // IE does not have innerHTML for SVG nodes, so instead we inject the - // new markup in a temp node and then move the child nodes across into - // the target node - if (node.namespaceURI === DOMNamespaces.svg && !('innerHTML' in node)) { - reusableSVGContainer = reusableSVGContainer || document.createElement('div'); - reusableSVGContainer.innerHTML = '' + html + ''; - var svgNode = reusableSVGContainer.firstChild; - while (svgNode.firstChild) { - node.appendChild(svgNode.firstChild); - } - } else { - node.innerHTML = html; - } -}); - -if (ExecutionEnvironment.canUseDOM) { - // IE8: When updating a just created node with innerHTML only leading - // whitespace is removed. When updating an existing node with innerHTML - // whitespace in root TextNodes is also collapsed. - // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html - - // Feature detection; only IE8 is known to behave improperly like this. - var testElement = document.createElement('div'); - testElement.innerHTML = ' '; - if (testElement.innerHTML === '') { - setInnerHTML = function (node, html) { - // Magic theory: IE8 supposedly differentiates between added and updated - // nodes when processing innerHTML, innerHTML on updated nodes suffers - // from worse whitespace behavior. Re-adding a node like this triggers - // the initial and more favorable whitespace behavior. - // TODO: What to do on a detached node? - if (node.parentNode) { - node.parentNode.replaceChild(node, node); - } - - // We also implement a workaround for non-visible tags disappearing into - // thin air on IE8, this only happens if there is no visible text - // in-front of the non-visible tags. Piggyback on the whitespace fix - // and simply check if any non-visible tags appear in the source. - if (WHITESPACE_TEST.test(html) || html[0] === '<' && NONVISIBLE_TEST.test(html)) { - // Recover leading whitespace by temporarily prepending any character. - // \uFEFF has the potential advantage of being zero-width/invisible. - // UglifyJS drops U+FEFF chars when parsing, so use String.fromCharCode - // in hopes that this is preserved even if "\uFEFF" is transformed to - // the actual Unicode character (by Babel, for example). - // https://github.com/mishoo/UglifyJS2/blob/v2.4.20/lib/parse.js#L216 - node.innerHTML = String.fromCharCode(0xFEFF) + html; - - // deleteData leaves an empty `TextNode` which offsets the index of all - // children. Definitely want to avoid this. - var textNode = node.firstChild; - if (textNode.data.length === 1) { - node.removeChild(textNode); - } else { - textNode.deleteData(0, 1); - } - } else { - node.innerHTML = html; - } - }; - } - testElement = null; -} - -module.exports = setInnerHTML; - -/***/ }), -/* 41 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * This is an ordered list of all sections used in the Bezier primer. - * - * The ordering you see here reflects the ordering in which sections - * are present on the Primer page: do not change them unless there is - * a REALLY good reason to =) - * - */ -module.exports = { - preface: __webpack_require__(192), - - // the basic topic(s) introduction(s) - introduction: __webpack_require__(179), - whatis: __webpack_require__(206), - explanation: __webpack_require__(165), - control: __webpack_require__(158), - extended: __webpack_require__(167), - - // basic operations - matrix: __webpack_require__(180), - decasteljau: __webpack_require__(162), - flattening: __webpack_require__(171), - splitting: __webpack_require__(200), - matrixsplit: __webpack_require__(181), - reordering: __webpack_require__(196), - - // information that can be obtained through analysis - derivatives: __webpack_require__(163), - pointvectors: __webpack_require__(189), - components: __webpack_require__(156), - extremities: __webpack_require__(169), - boundingbox: __webpack_require__(135), - aligning: __webpack_require__(127), - tightbounds: __webpack_require__(202), - inflections: __webpack_require__(175), - canonical: __webpack_require__(145), - - // accurate arc length is hard, yo - arclength: __webpack_require__(131), - arclengthapprox: __webpack_require__(133), - tracing: __webpack_require__(204), - - // curve intersections - intersections: __webpack_require__(177), - curveintersection: __webpack_require__(160), - - // curve manipulation - abc: __webpack_require__(125), - moulding: __webpack_require__(183), - pointcurves: __webpack_require__(187), - - // A quick foray into Catmull-Rom splines - catmullconv: __webpack_require__(146), - catmullmoulding: __webpack_require__(148), - - // "things made of more than on curve" - polybezier: __webpack_require__(191), - shapes: __webpack_require__(198), - - // curve offsetting - projections: __webpack_require__(194), - offsetting: __webpack_require__(185), - graduatedoffset: __webpack_require__(173), - - // circle and arc approximation - circles: __webpack_require__(150), - circles_cubic: __webpack_require__(152), - arcapproximation: __webpack_require__(129), - - // A quick foray in to B-Spline land - bsplines: __webpack_require__(139), - - // comments come last for obvious reasons - comments: __webpack_require__(154) -}; - -/***/ }), -/* 42 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - * - */ - -/*eslint-disable no-self-compare */ - - - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -/** - * inlined Object.is polyfill to avoid requiring consumers ship their own - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is - */ -function is(x, y) { - // SameValue algorithm - if (x === y) { - // Steps 1-5, 7-10 - // Steps 6.b-6.e: +0 != -0 - // Added the nonzero y check to make Flow happy, but it is redundant - return x !== 0 || y !== 0 || 1 / x === 1 / y; - } else { - // Step 6.a: NaN == NaN - return x !== x && y !== y; - } -} - -/** - * Performs equality by iterating through keys on an object and returning false - * when any key has values which are not strictly equal between the arguments. - * Returns true when the values of all keys are strictly equal. - */ -function shallowEqual(objA, objB) { - if (is(objA, objB)) { - return true; - } - - if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { - return false; - } - - var keysA = Object.keys(objA); - var keysB = Object.keys(objB); - - if (keysA.length !== keysB.length) { - return false; - } - - // Test for A's keys different from B. - for (var i = 0; i < keysA.length; i++) { - if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { - return false; - } - } - - return true; -} - -module.exports = shallowEqual; - -/***/ }), -/* 43 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); -exports.canUseDOM = canUseDOM; - -/***/ }), -/* 44 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -//import warning from 'warning' - - - -exports.__esModule = true; -function deprecate(fn) { - return fn; - //return function () { - // warning(false, '[history] ' + message) - // return fn.apply(this, arguments) - //} -} - -exports["default"] = deprecate; -module.exports = exports["default"]; - -/***/ }), -/* 45 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -function runTransitionHook(hook, location, callback) { - var result = hook(location, callback); - - if (hook.length < 2) { - // Assume the hook runs synchronously and automatically - // call the callback with the return value. - callback(result); - } else { - process.env.NODE_ENV !== 'production' ? _warning2['default'](result === undefined, 'You should not "return" in a transition hook with a callback argument; call the callback instead') : undefined; - } -} - -exports['default'] = runTransitionHook; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 46 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMLazyTree = __webpack_require__(25); -var Danger = __webpack_require__(243); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactInstrumentation = __webpack_require__(10); - -var createMicrosoftUnsafeLocalFunction = __webpack_require__(54); -var setInnerHTML = __webpack_require__(40); -var setTextContent = __webpack_require__(97); - -function getNodeAfter(parentNode, node) { - // Special case for text components, which return [open, close] comments - // from getHostNode. - if (Array.isArray(node)) { - node = node[1]; - } - return node ? node.nextSibling : parentNode.firstChild; -} - -/** - * Inserts `childNode` as a child of `parentNode` at the `index`. - * - * @param {DOMElement} parentNode Parent node in which to insert. - * @param {DOMElement} childNode Child node to insert. - * @param {number} index Index at which to insert the child. - * @internal - */ -var insertChildAt = createMicrosoftUnsafeLocalFunction(function (parentNode, childNode, referenceNode) { - // We rely exclusively on `insertBefore(node, null)` instead of also using - // `appendChild(node)`. (Using `undefined` is not allowed by all browsers so - // we are careful to use `null`.) - parentNode.insertBefore(childNode, referenceNode); -}); - -function insertLazyTreeChildAt(parentNode, childTree, referenceNode) { - DOMLazyTree.insertTreeBefore(parentNode, childTree, referenceNode); -} - -function moveChild(parentNode, childNode, referenceNode) { - if (Array.isArray(childNode)) { - moveDelimitedText(parentNode, childNode[0], childNode[1], referenceNode); - } else { - insertChildAt(parentNode, childNode, referenceNode); - } -} - -function removeChild(parentNode, childNode) { - if (Array.isArray(childNode)) { - var closingComment = childNode[1]; - childNode = childNode[0]; - removeDelimitedText(parentNode, childNode, closingComment); - parentNode.removeChild(closingComment); - } - parentNode.removeChild(childNode); -} - -function moveDelimitedText(parentNode, openingComment, closingComment, referenceNode) { - var node = openingComment; - while (true) { - var nextNode = node.nextSibling; - insertChildAt(parentNode, node, referenceNode); - if (node === closingComment) { - break; - } - node = nextNode; - } -} - -function removeDelimitedText(parentNode, startNode, closingComment) { - while (true) { - var node = startNode.nextSibling; - if (node === closingComment) { - // The closing comment is removed by ReactMultiChild. - break; - } else { - parentNode.removeChild(node); - } - } -} - -function replaceDelimitedText(openingComment, closingComment, stringText) { - var parentNode = openingComment.parentNode; - var nodeAfterComment = openingComment.nextSibling; - if (nodeAfterComment === closingComment) { - // There are no text nodes between the opening and closing comments; insert - // a new one if stringText isn't empty. - if (stringText) { - insertChildAt(parentNode, document.createTextNode(stringText), nodeAfterComment); - } - } else { - if (stringText) { - // Set the text content of the first node after the opening comment, and - // remove all following nodes up until the closing comment. - setTextContent(nodeAfterComment, stringText); - removeDelimitedText(parentNode, nodeAfterComment, closingComment); - } else { - removeDelimitedText(parentNode, openingComment, closingComment); - } - } - - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: ReactDOMComponentTree.getInstanceFromNode(openingComment)._debugID, - type: 'replace text', - payload: stringText - }); - } -} - -var dangerouslyReplaceNodeWithMarkup = Danger.dangerouslyReplaceNodeWithMarkup; -if (process.env.NODE_ENV !== 'production') { - dangerouslyReplaceNodeWithMarkup = function (oldChild, markup, prevInstance) { - Danger.dangerouslyReplaceNodeWithMarkup(oldChild, markup); - if (prevInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: prevInstance._debugID, - type: 'replace with', - payload: markup.toString() - }); - } else { - var nextInstance = ReactDOMComponentTree.getInstanceFromNode(markup.node); - if (nextInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: nextInstance._debugID, - type: 'mount', - payload: markup.toString() - }); - } - } - }; -} - -/** - * Operations for updating with DOM children. - */ -var DOMChildrenOperations = { - - dangerouslyReplaceNodeWithMarkup: dangerouslyReplaceNodeWithMarkup, - - replaceDelimitedText: replaceDelimitedText, - - /** - * Updates a component's children by processing a series of updates. The - * update configurations are each expected to have a `parentNode` property. - * - * @param {array} updates List of update configurations. - * @internal - */ - processUpdates: function (parentNode, updates) { - if (process.env.NODE_ENV !== 'production') { - var parentNodeDebugID = ReactDOMComponentTree.getInstanceFromNode(parentNode)._debugID; - } - - for (var k = 0; k < updates.length; k++) { - var update = updates[k]; - switch (update.type) { - case 'INSERT_MARKUP': - insertLazyTreeChildAt(parentNode, update.content, getNodeAfter(parentNode, update.afterNode)); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: parentNodeDebugID, - type: 'insert child', - payload: { toIndex: update.toIndex, content: update.content.toString() } - }); - } - break; - case 'MOVE_EXISTING': - moveChild(parentNode, update.fromNode, getNodeAfter(parentNode, update.afterNode)); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: parentNodeDebugID, - type: 'move child', - payload: { fromIndex: update.fromIndex, toIndex: update.toIndex } - }); - } - break; - case 'SET_MARKUP': - setInnerHTML(parentNode, update.content); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: parentNodeDebugID, - type: 'replace children', - payload: update.content.toString() - }); - } - break; - case 'TEXT_CONTENT': - setTextContent(parentNode, update.content); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: parentNodeDebugID, - type: 'replace text', - payload: update.content.toString() - }); - } - break; - case 'REMOVE_NODE': - removeChild(parentNode, update.fromNode); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: parentNodeDebugID, - type: 'remove child', - payload: { fromIndex: update.fromIndex } - }); - } - break; - } - } - } - -}; - -module.exports = DOMChildrenOperations; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 47 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMNamespaces = { - html: 'http://www.w3.org/1999/xhtml', - mathml: 'http://www.w3.org/1998/Math/MathML', - svg: 'http://www.w3.org/2000/svg' -}; - -module.exports = DOMNamespaces; - -/***/ }), -/* 48 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var ReactErrorUtils = __webpack_require__(52); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -/** - * Injected dependencies: - */ - -/** - * - `ComponentTree`: [required] Module that can convert between React instances - * and actual node references. - */ -var ComponentTree; -var TreeTraversal; -var injection = { - injectComponentTree: function (Injected) { - ComponentTree = Injected; - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(Injected && Injected.getNodeFromInstance && Injected.getInstanceFromNode, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0; - } - }, - injectTreeTraversal: function (Injected) { - TreeTraversal = Injected; - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(Injected && Injected.isAncestor && Injected.getLowestCommonAncestor, 'EventPluginUtils.injection.injectTreeTraversal(...): Injected ' + 'module is missing isAncestor or getLowestCommonAncestor.') : void 0; - } - } -}; - -function isEndish(topLevelType) { - return topLevelType === 'topMouseUp' || topLevelType === 'topTouchEnd' || topLevelType === 'topTouchCancel'; -} - -function isMoveish(topLevelType) { - return topLevelType === 'topMouseMove' || topLevelType === 'topTouchMove'; -} -function isStartish(topLevelType) { - return topLevelType === 'topMouseDown' || topLevelType === 'topTouchStart'; -} - -var validateEventDispatches; -if (process.env.NODE_ENV !== 'production') { - validateEventDispatches = function (event) { - var dispatchListeners = event._dispatchListeners; - var dispatchInstances = event._dispatchInstances; - - var listenersIsArr = Array.isArray(dispatchListeners); - var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; - - var instancesIsArr = Array.isArray(dispatchInstances); - var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0; - - process.env.NODE_ENV !== 'production' ? warning(instancesIsArr === listenersIsArr && instancesLen === listenersLen, 'EventPluginUtils: Invalid `event`.') : void 0; - }; -} - -/** - * Dispatch the event to the listener. - * @param {SyntheticEvent} event SyntheticEvent to handle - * @param {boolean} simulated If the event is simulated (changes exn behavior) - * @param {function} listener Application-level callback - * @param {*} inst Internal component instance - */ -function executeDispatch(event, simulated, listener, inst) { - var type = event.type || 'unknown-event'; - event.currentTarget = EventPluginUtils.getNodeFromInstance(inst); - if (simulated) { - ReactErrorUtils.invokeGuardedCallbackWithCatch(type, listener, event); - } else { - ReactErrorUtils.invokeGuardedCallback(type, listener, event); - } - event.currentTarget = null; -} - -/** - * Standard/simple iteration through an event's collected dispatches. - */ -function executeDispatchesInOrder(event, simulated) { - var dispatchListeners = event._dispatchListeners; - var dispatchInstances = event._dispatchInstances; - if (process.env.NODE_ENV !== 'production') { - validateEventDispatches(event); - } - if (Array.isArray(dispatchListeners)) { - for (var i = 0; i < dispatchListeners.length; i++) { - if (event.isPropagationStopped()) { - break; - } - // Listeners and Instances are two parallel arrays that are always in sync. - executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]); - } - } else if (dispatchListeners) { - executeDispatch(event, simulated, dispatchListeners, dispatchInstances); - } - event._dispatchListeners = null; - event._dispatchInstances = null; -} - -/** - * Standard/simple iteration through an event's collected dispatches, but stops - * at the first dispatch execution returning true, and returns that id. - * - * @return {?string} id of the first dispatch execution who's listener returns - * true, or null if no listener returned true. - */ -function executeDispatchesInOrderStopAtTrueImpl(event) { - var dispatchListeners = event._dispatchListeners; - var dispatchInstances = event._dispatchInstances; - if (process.env.NODE_ENV !== 'production') { - validateEventDispatches(event); - } - if (Array.isArray(dispatchListeners)) { - for (var i = 0; i < dispatchListeners.length; i++) { - if (event.isPropagationStopped()) { - break; - } - // Listeners and Instances are two parallel arrays that are always in sync. - if (dispatchListeners[i](event, dispatchInstances[i])) { - return dispatchInstances[i]; - } - } - } else if (dispatchListeners) { - if (dispatchListeners(event, dispatchInstances)) { - return dispatchInstances; - } - } - return null; -} - -/** - * @see executeDispatchesInOrderStopAtTrueImpl - */ -function executeDispatchesInOrderStopAtTrue(event) { - var ret = executeDispatchesInOrderStopAtTrueImpl(event); - event._dispatchInstances = null; - event._dispatchListeners = null; - return ret; -} - -/** - * Execution of a "direct" dispatch - there must be at most one dispatch - * accumulated on the event or it is considered an error. It doesn't really make - * sense for an event with multiple dispatches (bubbled) to keep track of the - * return values at each dispatch execution, but it does tend to make sense when - * dealing with "direct" dispatches. - * - * @return {*} The return value of executing the single dispatch. - */ -function executeDirectDispatch(event) { - if (process.env.NODE_ENV !== 'production') { - validateEventDispatches(event); - } - var dispatchListener = event._dispatchListeners; - var dispatchInstance = event._dispatchInstances; - !!Array.isArray(dispatchListener) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : _prodInvariant('103') : void 0; - event.currentTarget = dispatchListener ? EventPluginUtils.getNodeFromInstance(dispatchInstance) : null; - var res = dispatchListener ? dispatchListener(event) : null; - event.currentTarget = null; - event._dispatchListeners = null; - event._dispatchInstances = null; - return res; -} - -/** - * @param {SyntheticEvent} event - * @return {boolean} True iff number of dispatches accumulated is greater than 0. - */ -function hasDispatches(event) { - return !!event._dispatchListeners; -} - -/** - * General utilities that are useful in creating custom Event Plugins. - */ -var EventPluginUtils = { - isEndish: isEndish, - isMoveish: isMoveish, - isStartish: isStartish, - - executeDirectDispatch: executeDirectDispatch, - executeDispatchesInOrder: executeDispatchesInOrder, - executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, - hasDispatches: hasDispatches, - - getInstanceFromNode: function (node) { - return ComponentTree.getInstanceFromNode(node); - }, - getNodeFromInstance: function (node) { - return ComponentTree.getNodeFromInstance(node); - }, - isAncestor: function (a, b) { - return TreeTraversal.isAncestor(a, b); - }, - getLowestCommonAncestor: function (a, b) { - return TreeTraversal.getLowestCommonAncestor(a, b); - }, - getParentInstance: function (inst) { - return TreeTraversal.getParentInstance(inst); - }, - traverseTwoPhase: function (target, fn, arg) { - return TreeTraversal.traverseTwoPhase(target, fn, arg); - }, - traverseEnterLeave: function (from, to, fn, argFrom, argTo) { - return TreeTraversal.traverseEnterLeave(from, to, fn, argFrom, argTo); - }, - - injection: injection -}; - -module.exports = EventPluginUtils; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 49 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/** - * Escape and wrap key so it is safe to use as a reactid - * - * @param {string} key to be escaped. - * @return {string} the escaped key. - */ - -function escape(key) { - var escapeRegex = /[=:]/g; - var escaperLookup = { - '=': '=0', - ':': '=2' - }; - var escapedString = ('' + key).replace(escapeRegex, function (match) { - return escaperLookup[match]; - }); - - return '$' + escapedString; -} - -/** - * Unescape and unwrap key for human-readable display - * - * @param {string} key to unescape. - * @return {string} the unescaped key. - */ -function unescape(key) { - var unescapeRegex = /(=0|=2)/g; - var unescaperLookup = { - '=0': '=', - '=2': ':' - }; - var keySubstring = key[0] === '.' && key[1] === '$' ? key.substring(2) : key.substring(1); - - return ('' + keySubstring).replace(unescapeRegex, function (match) { - return unescaperLookup[match]; - }); -} - -var KeyEscapeUtils = { - escape: escape, - unescape: unescape -}; - -module.exports = KeyEscapeUtils; - -/***/ }), -/* 50 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var React = __webpack_require__(27); -var ReactPropTypesSecret = __webpack_require__(89); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -var hasReadOnlyValue = { - 'button': true, - 'checkbox': true, - 'image': true, - 'hidden': true, - 'radio': true, - 'reset': true, - 'submit': true -}; - -function _assertSingleLink(inputProps) { - !(inputProps.checkedLink == null || inputProps.valueLink == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a valueLink. If you want to use checkedLink, you probably don\'t want to use valueLink and vice versa.') : _prodInvariant('87') : void 0; -} -function _assertValueLink(inputProps) { - _assertSingleLink(inputProps); - !(inputProps.value == null && inputProps.onChange == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a valueLink and a value or onChange event. If you want to use value or onChange, you probably don\'t want to use valueLink.') : _prodInvariant('88') : void 0; -} - -function _assertCheckedLink(inputProps) { - _assertSingleLink(inputProps); - !(inputProps.checked == null && inputProps.onChange == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a checked property or onChange event. If you want to use checked or onChange, you probably don\'t want to use checkedLink') : _prodInvariant('89') : void 0; -} - -var propTypes = { - value: function (props, propName, componentName) { - if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) { - return null; - } - return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); - }, - checked: function (props, propName, componentName) { - if (!props[propName] || props.onChange || props.readOnly || props.disabled) { - return null; - } - return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); - }, - onChange: React.PropTypes.func -}; - -var loggedTypeFailures = {}; -function getDeclarationErrorAddendum(owner) { - if (owner) { - var name = owner.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -/** - * Provide a linked `value` attribute for controlled forms. You should not use - * this outside of the ReactDOM controlled form components. - */ -var LinkedValueUtils = { - checkPropTypes: function (tagName, props, owner) { - for (var propName in propTypes) { - if (propTypes.hasOwnProperty(propName)) { - var error = propTypes[propName](props, propName, tagName, 'prop', null, ReactPropTypesSecret); - } - if (error instanceof Error && !(error.message in loggedTypeFailures)) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error.message] = true; - - var addendum = getDeclarationErrorAddendum(owner); - process.env.NODE_ENV !== 'production' ? warning(false, 'Failed form propType: %s%s', error.message, addendum) : void 0; - } - } - }, - - /** - * @param {object} inputProps Props for form component - * @return {*} current value of the input either from value prop or link. - */ - getValue: function (inputProps) { - if (inputProps.valueLink) { - _assertValueLink(inputProps); - return inputProps.valueLink.value; - } - return inputProps.value; - }, - - /** - * @param {object} inputProps Props for form component - * @return {*} current checked status of the input either from checked prop - * or link. - */ - getChecked: function (inputProps) { - if (inputProps.checkedLink) { - _assertCheckedLink(inputProps); - return inputProps.checkedLink.value; - } - return inputProps.checked; - }, - - /** - * @param {object} inputProps Props for form component - * @param {SyntheticEvent} event change event to handle - */ - executeOnChange: function (inputProps, event) { - if (inputProps.valueLink) { - _assertValueLink(inputProps); - return inputProps.valueLink.requestChange(event.target.value); - } else if (inputProps.checkedLink) { - _assertCheckedLink(inputProps); - return inputProps.checkedLink.requestChange(event.target.checked); - } else if (inputProps.onChange) { - return inputProps.onChange.call(undefined, event); - } - } -}; - -module.exports = LinkedValueUtils; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 51 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -var injected = false; - -var ReactComponentEnvironment = { - - /** - * Optionally injectable hook for swapping out mount images in the middle of - * the tree. - */ - replaceNodeWithMarkup: null, - - /** - * Optionally injectable hook for processing a queue of child updates. Will - * later move into MultiChildComponents. - */ - processChildrenUpdates: null, - - injection: { - injectEnvironment: function (environment) { - !!injected ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactCompositeComponent: injectEnvironment() can only be called once.') : _prodInvariant('104') : void 0; - ReactComponentEnvironment.replaceNodeWithMarkup = environment.replaceNodeWithMarkup; - ReactComponentEnvironment.processChildrenUpdates = environment.processChildrenUpdates; - injected = true; - } - } - -}; - -module.exports = ReactComponentEnvironment; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 52 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var caughtError = null; - -/** - * Call a function while guarding against errors that happens within it. - * - * @param {String} name of the guard to use for logging or debugging - * @param {Function} func The function to invoke - * @param {*} a First argument - * @param {*} b Second argument - */ -function invokeGuardedCallback(name, func, a) { - try { - func(a); - } catch (x) { - if (caughtError === null) { - caughtError = x; - } - } -} - -var ReactErrorUtils = { - invokeGuardedCallback: invokeGuardedCallback, - - /** - * Invoked by ReactTestUtils.Simulate so that any errors thrown by the event - * handler are sure to be rethrown by rethrowCaughtError. - */ - invokeGuardedCallbackWithCatch: invokeGuardedCallback, - - /** - * During execution of guarded functions we will capture the first error which - * we will rethrow to be handled by the top level error handler. - */ - rethrowCaughtError: function () { - if (caughtError) { - var error = caughtError; - caughtError = null; - throw error; - } - } -}; - -if (process.env.NODE_ENV !== 'production') { - /** - * To help development we can get better devtools integration by simulating a - * real browser event. - */ - if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') { - var fakeNode = document.createElement('react'); - ReactErrorUtils.invokeGuardedCallback = function (name, func, a) { - var boundFunc = func.bind(null, a); - var evtType = 'react-' + name; - fakeNode.addEventListener(evtType, boundFunc, false); - var evt = document.createEvent('Event'); - // $FlowFixMe https://github.com/facebook/flow/issues/2336 - evt.initEvent(evtType, false, false); - fakeNode.dispatchEvent(evt); - fakeNode.removeEventListener(evtType, boundFunc, false); - }; - } -} - -module.exports = ReactErrorUtils; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 53 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var ReactCurrentOwner = __webpack_require__(15); -var ReactInstanceMap = __webpack_require__(32); -var ReactInstrumentation = __webpack_require__(10); -var ReactUpdates = __webpack_require__(14); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -function enqueueUpdate(internalInstance) { - ReactUpdates.enqueueUpdate(internalInstance); -} - -function formatUnexpectedArgument(arg) { - var type = typeof arg; - if (type !== 'object') { - return type; - } - var displayName = arg.constructor && arg.constructor.name || type; - var keys = Object.keys(arg); - if (keys.length > 0 && keys.length < 20) { - return displayName + ' (keys: ' + keys.join(', ') + ')'; - } - return displayName; -} - -function getInternalInstanceReadyForUpdate(publicInstance, callerName) { - var internalInstance = ReactInstanceMap.get(publicInstance); - if (!internalInstance) { - if (process.env.NODE_ENV !== 'production') { - var ctor = publicInstance.constructor; - // Only warn when we have a callerName. Otherwise we should be silent. - // We're probably calling from enqueueCallback. We don't want to warn - // there because we already warned for the corresponding lifecycle method. - process.env.NODE_ENV !== 'production' ? warning(!callerName, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, ctor && (ctor.displayName || ctor.name) || 'ReactClass') : void 0; - } - return null; - } - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, '%s(...): Cannot update during an existing state transition (such as ' + 'within `render` or another component\'s constructor). Render methods ' + 'should be a pure function of props and state; constructor ' + 'side-effects are an anti-pattern, but can be moved to ' + '`componentWillMount`.', callerName) : void 0; - } - - return internalInstance; -} - -/** - * ReactUpdateQueue allows for state updates to be scheduled into a later - * reconciliation step. - */ -var ReactUpdateQueue = { - - /** - * Checks whether or not this composite component is mounted. - * @param {ReactClass} publicInstance The instance we want to test. - * @return {boolean} True if mounted, false otherwise. - * @protected - * @final - */ - isMounted: function (publicInstance) { - if (process.env.NODE_ENV !== 'production') { - var owner = ReactCurrentOwner.current; - if (owner !== null) { - process.env.NODE_ENV !== 'production' ? warning(owner._warnedAboutRefsInRender, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : void 0; - owner._warnedAboutRefsInRender = true; - } - } - var internalInstance = ReactInstanceMap.get(publicInstance); - if (internalInstance) { - // During componentWillMount and render this will still be null but after - // that will always render to something. At least for now. So we can use - // this hack. - return !!internalInstance._renderedComponent; - } else { - return false; - } - }, - - /** - * Enqueue a callback that will be executed after all the pending updates - * have processed. - * - * @param {ReactClass} publicInstance The instance to use as `this` context. - * @param {?function} callback Called after state is updated. - * @param {string} callerName Name of the calling function in the public API. - * @internal - */ - enqueueCallback: function (publicInstance, callback, callerName) { - ReactUpdateQueue.validateCallback(callback, callerName); - var internalInstance = getInternalInstanceReadyForUpdate(publicInstance); - - // Previously we would throw an error if we didn't have an internal - // instance. Since we want to make it a no-op instead, we mirror the same - // behavior we have in other enqueue* methods. - // We also need to ignore callbacks in componentWillMount. See - // enqueueUpdates. - if (!internalInstance) { - return null; - } - - if (internalInstance._pendingCallbacks) { - internalInstance._pendingCallbacks.push(callback); - } else { - internalInstance._pendingCallbacks = [callback]; - } - // TODO: The callback here is ignored when setState is called from - // componentWillMount. Either fix it or disallow doing so completely in - // favor of getInitialState. Alternatively, we can disallow - // componentWillMount during server-side rendering. - enqueueUpdate(internalInstance); - }, - - enqueueCallbackInternal: function (internalInstance, callback) { - if (internalInstance._pendingCallbacks) { - internalInstance._pendingCallbacks.push(callback); - } else { - internalInstance._pendingCallbacks = [callback]; - } - enqueueUpdate(internalInstance); - }, - - /** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldComponentUpdate`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @internal - */ - enqueueForceUpdate: function (publicInstance) { - var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'forceUpdate'); - - if (!internalInstance) { - return; - } - - internalInstance._pendingForceUpdate = true; - - enqueueUpdate(internalInstance); - }, - - /** - * Replaces all of the state. Always use this or `setState` to mutate state. - * You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} completeState Next state. - * @internal - */ - enqueueReplaceState: function (publicInstance, completeState) { - var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'replaceState'); - - if (!internalInstance) { - return; - } - - internalInstance._pendingStateQueue = [completeState]; - internalInstance._pendingReplaceState = true; - - enqueueUpdate(internalInstance); - }, - - /** - * Sets a subset of the state. This only exists because _pendingState is - * internal. This provides a merging strategy that is not available to deep - * properties which is confusing. TODO: Expose pendingState or don't use it - * during the merge. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} partialState Next partial state to be merged with state. - * @internal - */ - enqueueSetState: function (publicInstance, partialState) { - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onSetState(); - process.env.NODE_ENV !== 'production' ? warning(partialState != null, 'setState(...): You passed an undefined or null state object; ' + 'instead, use forceUpdate().') : void 0; - } - - var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState'); - - if (!internalInstance) { - return; - } - - var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []); - queue.push(partialState); - - enqueueUpdate(internalInstance); - }, - - enqueueElementInternal: function (internalInstance, nextElement, nextContext) { - internalInstance._pendingElement = nextElement; - // TODO: introduce _pendingContext instead of setting it directly. - internalInstance._context = nextContext; - enqueueUpdate(internalInstance); - }, - - validateCallback: function (callback, callerName) { - !(!callback || typeof callback === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s(...): Expected the last optional `callback` argument to be a function. Instead received: %s.', callerName, formatUnexpectedArgument(callback)) : _prodInvariant('122', callerName, formatUnexpectedArgument(callback)) : void 0; - } - -}; - -module.exports = ReactUpdateQueue; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 54 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -/* globals MSApp */ - - - -/** - * Create a function which has 'unsafe' privileges (required by windows8 apps) - */ - -var createMicrosoftUnsafeLocalFunction = function (func) { - if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { - return function (arg0, arg1, arg2, arg3) { - MSApp.execUnsafeLocalFunction(function () { - return func(arg0, arg1, arg2, arg3); - }); - }; - } else { - return func; - } -}; - -module.exports = createMicrosoftUnsafeLocalFunction; - -/***/ }), -/* 55 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * `charCode` represents the actual "character code" and is safe to use with - * `String.fromCharCode`. As such, only keys that correspond to printable - * characters produce a valid `charCode`, the only exception to this is Enter. - * The Tab-key is considered non-printable and does not have a `charCode`, - * presumably because it does not produce a tab-character in browsers. - * - * @param {object} nativeEvent Native browser event. - * @return {number} Normalized `charCode` property. - */ - -function getEventCharCode(nativeEvent) { - var charCode; - var keyCode = nativeEvent.keyCode; - - if ('charCode' in nativeEvent) { - charCode = nativeEvent.charCode; - - // FF does not set `charCode` for the Enter-key, check against `keyCode`. - if (charCode === 0 && keyCode === 13) { - charCode = 13; - } - } else { - // IE8 does not implement `charCode`, but `keyCode` has the correct value. - charCode = keyCode; - } - - // Some non-printable keys are reported in `charCode`/`keyCode`, discard them. - // Must not discard the (non-)printable Enter-key. - if (charCode >= 32 || charCode === 13) { - return charCode; - } - - return 0; -} - -module.exports = getEventCharCode; - -/***/ }), -/* 56 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * Translation from modifier key to the associated property in the event. - * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers - */ - -var modifierKeyToProp = { - 'Alt': 'altKey', - 'Control': 'ctrlKey', - 'Meta': 'metaKey', - 'Shift': 'shiftKey' -}; - -// IE8 does not implement getModifierState so we simply map it to the only -// modifier keys exposed by the event itself, does not support Lock-keys. -// Currently, all major browsers except Chrome seems to support Lock-keys. -function modifierStateGetter(keyArg) { - var syntheticEvent = this; - var nativeEvent = syntheticEvent.nativeEvent; - if (nativeEvent.getModifierState) { - return nativeEvent.getModifierState(keyArg); - } - var keyProp = modifierKeyToProp[keyArg]; - return keyProp ? !!nativeEvent[keyProp] : false; -} - -function getEventModifierState(nativeEvent) { - return modifierStateGetter; -} - -module.exports = getEventModifierState; - -/***/ }), -/* 57 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * Gets the target node from a native browser event by accounting for - * inconsistencies in browser DOM APIs. - * - * @param {object} nativeEvent Native browser event. - * @return {DOMEventTarget} Target node. - */ - -function getEventTarget(nativeEvent) { - var target = nativeEvent.target || nativeEvent.srcElement || window; - - // Normalize SVG element events #4963 - if (target.correspondingUseElement) { - target = target.correspondingUseElement; - } - - // Safari may fire events on text nodes (Node.TEXT_NODE is 3). - // @see http://www.quirksmode.org/js/events_properties.html - return target.nodeType === 3 ? target.parentNode : target; -} - -module.exports = getEventTarget; - -/***/ }), -/* 58 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ExecutionEnvironment = __webpack_require__(8); - -var useHasFeature; -if (ExecutionEnvironment.canUseDOM) { - useHasFeature = document.implementation && document.implementation.hasFeature && - // always returns true in newer browsers as per the standard. - // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature - document.implementation.hasFeature('', '') !== true; -} - -/** +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.BezierArticle=t():e.BezierArticle=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=325)}([function(e,t,n){"use strict";var r=n(4),i=n(63),a=new i;e.exports=function(e,t){var n={getDefaultProps:function(){return{title:a.getTitle(e)}},render:function(){return a.getContent(e,this)}};return t&&Object.keys(t).forEach(function(e){n[e]=t[e]}),r.createClass(n)}},function(e,t,n){"use strict";function r(e,t,n,r,a,o,s,l){if(i(t),!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,a,o,s,l],h=0;c=new Error(t.replace(/%s/g,function(){return u[h++]})),c.name="Invariant Violation"}throw c.framesToPop=1,c}}var i=function(e){};e.exports=r},function(e,t,n){"use strict";var r=n(9),i=r;e.exports=i},function(e,t,n){"use strict";function r(e){for(var t=arguments.length-1,n="Minified React error #"+e+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant="+e,r=0;r should not have a "'+t+'" prop')}t.__esModule=!0,t.falsy=r;var i=n(4),a=i.PropTypes.func,o=i.PropTypes.object,s=i.PropTypes.arrayOf,l=i.PropTypes.oneOfType,c=i.PropTypes.element,u=i.PropTypes.shape,h=i.PropTypes.string,d=u({listen:a.isRequired,pushState:a.isRequired,replaceState:a.isRequired,go:a.isRequired});t.history=d;var f=u({pathname:h.isRequired,search:h.isRequired,state:o,action:h.isRequired,key:h});t.location=f;var p=l([a,h]);t.component=p;var m=l([p,o]);t.components=m;var g=l([o,c]);t.route=g;var v=l([g,s(g)]);t.routes=v,t.default={falsy:r,history:d,location:f,component:p,components:m,route:g}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){var t=s.default(e),n="",r="",i=t.indexOf("#");i!==-1&&(r=t.substring(i),t=t.substring(0,i));var a=t.indexOf("?");return a!==-1&&(n=t.substring(a),t=t.substring(0,a)),""===t&&(t="/"),{pathname:t,search:n,hash:r}}t.__esModule=!0;var a=n(8),o=(r(a),n(72)),s=r(o);t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e){if(g){var t=e.node,n=e.children;if(n.length)for(var r=0;r1){for(var g=Array(m),v=0;v1){for(var y=Array(w),b=0;b0?void 0:f.default(!1),null!=u&&(a+=encodeURI(u))):"("===l?i+=1:")"===l?i-=1:":"===l.charAt(0)?(c=l.substring(1),u=t[c],null!=u||i>0?void 0:f.default(!1),null!=u&&(a+=encodeURIComponent(u))):a+=l;return a.replace(/\/+/g,"/")}t.__esModule=!0,t.compilePattern=s,t.matchPattern=l,t.getParamNames=c,t.getParams=u,t.formatPattern=h;var d=n(10),f=r(d),p={}},function(e,t,n){"use strict";function r(e){return Object.prototype.hasOwnProperty.call(e,m)||(e[m]=f++,h[e[m]]={}),h[e[m]]}var i,a=n(5),o=n(45),s=n(261),l=n(85),c=n(294),u=n(56),h={},d=!1,f=0,p={topAbort:"abort",topAnimationEnd:c("animationend")||"animationend",topAnimationIteration:c("animationiteration")||"animationiteration",topAnimationStart:c("animationstart")||"animationstart",topBlur:"blur",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topChange:"change",topClick:"click",topCompositionEnd:"compositionend",topCompositionStart:"compositionstart",topCompositionUpdate:"compositionupdate",topContextMenu:"contextmenu",topCopy:"copy",topCut:"cut",topDoubleClick:"dblclick",topDrag:"drag",topDragEnd:"dragend",topDragEnter:"dragenter",topDragExit:"dragexit",topDragLeave:"dragleave",topDragOver:"dragover",topDragStart:"dragstart",topDrop:"drop",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topFocus:"focus",topInput:"input",topKeyDown:"keydown",topKeyPress:"keypress",topKeyUp:"keyup",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topMouseDown:"mousedown",topMouseMove:"mousemove",topMouseOut:"mouseout",topMouseOver:"mouseover",topMouseUp:"mouseup",topPaste:"paste",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topScroll:"scroll",topSeeked:"seeked",topSeeking:"seeking",topSelectionChange:"selectionchange",topStalled:"stalled",topSuspend:"suspend",topTextInput:"textInput",topTimeUpdate:"timeupdate",topTouchCancel:"touchcancel",topTouchEnd:"touchend",topTouchMove:"touchmove",topTouchStart:"touchstart",topTransitionEnd:c("transitionend")||"transitionend",topVolumeChange:"volumechange",topWaiting:"waiting",topWheel:"wheel"},m="_reactListenersID"+String(Math.random()).slice(2),g=a({},s,{ReactEventListener:null,injection:{injectReactEventListener:function(e){e.setHandleTopLevel(g.handleTopLevel),g.ReactEventListener=e}},setEnabled:function(e){g.ReactEventListener&&g.ReactEventListener.setEnabled(e)},isEnabled:function(){return!(!g.ReactEventListener||!g.ReactEventListener.isEnabled())},listenTo:function(e,t){for(var n=t,i=r(n),a=o.registrationNameDependencies[e],s=0;s]/;e.exports=i},function(e,t,n){"use strict";var r,i=n(7),a=n(44),o=/^[ \r\n\t\f]/,s=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,l=n(52),c=l(function(e,t){if(e.namespaceURI!==a.svg||"innerHTML"in e)e.innerHTML=t;else{r=r||document.createElement("div"),r.innerHTML=""+t+"";for(var n=r.firstChild;n.firstChild;)e.appendChild(n.firstChild)}});if(i.canUseDOM){var u=document.createElement("div");u.innerHTML=" ",""===u.innerHTML&&(c=function(e,t){if(e.parentNode&&e.parentNode.replaceChild(e,e),o.test(t)||"<"===t[0]&&s.test(t)){e.innerHTML=String.fromCharCode(65279)+t;var n=e.firstChild;1===n.data.length?e.removeChild(n):n.deleteData(0,1)}else e.innerHTML=t}),u=null}e.exports=c},function(e,t,n){"use strict";e.exports={preface:n(189),introduction:n(176),whatis:n(203),explanation:n(162),control:n(155),extended:n(164), +matrix:n(177),decasteljau:n(159),flattening:n(168),splitting:n(197),matrixsplit:n(178),reordering:n(193),derivatives:n(160),pointvectors:n(186),components:n(153),extremities:n(166),boundingbox:n(132),aligning:n(124),tightbounds:n(199),inflections:n(172),canonical:n(142),arclength:n(128),arclengthapprox:n(130),tracing:n(201),intersections:n(174),curveintersection:n(157),abc:n(122),moulding:n(180),pointcurves:n(184),catmullconv:n(143),catmullmoulding:n(145),polybezier:n(188),shapes:n(195),projections:n(191),offsetting:n(182),graduatedoffset:n(170),circles:n(147),circles_cubic:n(149),arcapproximation:n(126),bsplines:n(136),comments:n(151)}},function(e,t,n){"use strict";function r(e,t){return e===t?0!==e||0!==t||1/e===1/t:e!==e&&t!==t}function i(e,t){if(r(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),i=Object.keys(t);if(n.length!==i.length)return!1;for(var o=0;o-1?void 0:o("96",e),!c.plugins[n]){t.extractEvents?void 0:o("97",e),c.plugins[n]=t;var r=t.eventTypes;for(var a in r)i(r[a],t,a)?void 0:o("98",a,e)}}}function i(e,t,n){c.eventNameDispatchConfigs.hasOwnProperty(n)?o("99",n):void 0,c.eventNameDispatchConfigs[n]=e;var r=e.phasedRegistrationNames;if(r){for(var i in r)if(r.hasOwnProperty(i)){var s=r[i];a(s,t,n)}return!0}return!!e.registrationName&&(a(e.registrationName,t,n),!0)}function a(e,t,n){c.registrationNameModules[e]?o("100",e):void 0,c.registrationNameModules[e]=t,c.registrationNameDependencies[e]=t.eventTypes[n].dependencies}var o=n(3),s=(n(1),null),l={},c={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},possibleRegistrationNames:null,injectEventPluginOrder:function(e){s?o("101"):void 0,s=Array.prototype.slice.call(e),r()},injectEventPluginsByName:function(e){var t=!1;for(var n in e)if(e.hasOwnProperty(n)){var i=e[n];l.hasOwnProperty(n)&&l[n]===i||(l[n]?o("102",n):void 0,l[n]=i,t=!0)}t&&r()},getPluginModuleForEvent:function(e){var t=e.dispatchConfig;if(t.registrationName)return c.registrationNameModules[t.registrationName]||null;if(void 0!==t.phasedRegistrationNames){var n=t.phasedRegistrationNames;for(var r in n)if(n.hasOwnProperty(r)){var i=c.registrationNameModules[n[r]];if(i)return i}}return null},_resetEventPlugins:function(){s=null;for(var e in l)l.hasOwnProperty(e)&&delete l[e];c.plugins.length=0;var t=c.eventNameDispatchConfigs;for(var n in t)t.hasOwnProperty(n)&&delete t[n];var r=c.registrationNameModules;for(var i in r)r.hasOwnProperty(i)&&delete r[i]}};e.exports=c},function(e,t,n){"use strict";function r(e){return"topMouseUp"===e||"topTouchEnd"===e||"topTouchCancel"===e}function i(e){return"topMouseMove"===e||"topTouchMove"===e}function a(e){return"topMouseDown"===e||"topTouchStart"===e}function o(e,t,n,r){var i=e.type||"unknown-event";e.currentTarget=v.getNodeFromInstance(r),t?m.invokeGuardedCallbackWithCatch(i,n,e):m.invokeGuardedCallback(i,n,e),e.currentTarget=null}function s(e,t){var n=e._dispatchListeners,r=e._dispatchInstances;if(Array.isArray(n))for(var i=0;i0&&r.length<20?n+" (keys: "+r.join(", ")+")":n}function a(e,t){var n=s.get(e);if(!n){return null}return n}var o=n(3),s=(n(15),n(30)),l=(n(11),n(12)),c=(n(1),n(2),{isMounted:function(e){var t=s.get(e);return!!t&&!!t._renderedComponent},enqueueCallback:function(e,t,n){c.validateCallback(t,n);var i=a(e);return i?(i._pendingCallbacks?i._pendingCallbacks.push(t):i._pendingCallbacks=[t],void r(i)):null},enqueueCallbackInternal:function(e,t){e._pendingCallbacks?e._pendingCallbacks.push(t):e._pendingCallbacks=[t],r(e)},enqueueForceUpdate:function(e){var t=a(e,"forceUpdate");t&&(t._pendingForceUpdate=!0,r(t))},enqueueReplaceState:function(e,t){var n=a(e,"replaceState");n&&(n._pendingStateQueue=[t],n._pendingReplaceState=!0,r(n))},enqueueSetState:function(e,t){var n=a(e,"setState");if(n){var i=n._pendingStateQueue||(n._pendingStateQueue=[]);i.push(t),r(n)}},enqueueElementInternal:function(e,t,n){e._pendingElement=t,e._context=n,r(e)},validateCallback:function(e,t){e&&"function"!=typeof e?o("122",t,i(e)):void 0}});e.exports=c},function(e,t,n){"use strict";var r=function(e){return"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(t,n,r,i){MSApp.execUnsafeLocalFunction(function(){return e(t,n,r,i)})}:e};e.exports=r},function(e,t,n){"use strict";function r(e){var t,n=e.keyCode;return"charCode"in e?(t=e.charCode,0===t&&13===n&&(t=13)):t=n,t>=32||13===t?t:0}e.exports=r},function(e,t,n){"use strict";function r(e){var t=this,n=t.nativeEvent;if(n.getModifierState)return n.getModifierState(e);var r=a[e];return!!r&&!!n[r]}function i(e){return r}var a={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};e.exports=i},function(e,t,n){"use strict";function r(e){var t=e.target||e.srcElement||window;return t.correspondingUseElement&&(t=t.correspondingUseElement),3===t.nodeType?t.parentNode:t}e.exports=r},function(e,t,n){"use strict";/** * Checks if an event is supported in the current execution environment. * * NOTE: This will not work correctly for non-generic events such as `change`, @@ -6799,25822 +13,24 @@ if (ExecutionEnvironment.canUseDOM) { * @internal * @license Modernizr 3.0.0pre (Custom Build) | MIT */ -function isEventSupported(eventNameSuffix, capture) { - if (!ExecutionEnvironment.canUseDOM || capture && !('addEventListener' in document)) { - return false; - } - - var eventName = 'on' + eventNameSuffix; - var isSupported = eventName in document; - - if (!isSupported) { - var element = document.createElement('div'); - element.setAttribute(eventName, 'return;'); - isSupported = typeof element[eventName] === 'function'; - } - - if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { - // This is the only way to test support for the `wheel` event in IE9+. - isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); - } - - return isSupported; -} - -module.exports = isEventSupported; - -/***/ }), -/* 59 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * Given a `prevElement` and `nextElement`, determines if the existing - * instance should be updated as opposed to being destroyed or replaced by a new - * instance. Both arguments are elements. This ensures that this logic can - * operate on stateless trees without any backing instance. - * - * @param {?object} prevElement - * @param {?object} nextElement - * @return {boolean} True if the existing instance should be updated. - * @protected - */ - -function shouldUpdateReactComponent(prevElement, nextElement) { - var prevEmpty = prevElement === null || prevElement === false; - var nextEmpty = nextElement === null || nextElement === false; - if (prevEmpty || nextEmpty) { - return prevEmpty === nextEmpty; - } - - var prevType = typeof prevElement; - var nextType = typeof nextElement; - if (prevType === 'string' || prevType === 'number') { - return nextType === 'string' || nextType === 'number'; - } else { - return nextType === 'object' && prevElement.type === nextElement.type && prevElement.key === nextElement.key; - } -} - -module.exports = shouldUpdateReactComponent; - -/***/ }), -/* 60 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var emptyFunction = __webpack_require__(12); -var warning = __webpack_require__(3); - -var validateDOMNesting = emptyFunction; - -if (process.env.NODE_ENV !== 'production') { - // This validation code was written based on the HTML5 parsing spec: - // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope - // - // Note: this does not catch all invalid nesting, nor does it try to (as it's - // not clear what practical benefit doing so provides); instead, we warn only - // for cases where the parser will give a parse tree differing from what React - // intended. For example,
is invalid but we don't warn - // because it still parses correctly; we do warn for other cases like nested - //

tags where the beginning of the second element implicitly closes the - // first, causing a confusing mess. - - // https://html.spec.whatwg.org/multipage/syntax.html#special - var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp']; - - // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope - var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', - - // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point - // TODO: Distinguish by namespace here -- for , including it here - // errs on the side of fewer warnings - 'foreignObject', 'desc', 'title']; - - // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope - var buttonScopeTags = inScopeTags.concat(['button']); - - // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags - var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt']; - - var emptyAncestorInfo = { - current: null, - - formTag: null, - aTagInScope: null, - buttonTagInScope: null, - nobrTagInScope: null, - pTagInButtonScope: null, - - listItemTagAutoclosing: null, - dlItemTagAutoclosing: null - }; - - var updatedAncestorInfo = function (oldInfo, tag, instance) { - var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo); - var info = { tag: tag, instance: instance }; - - if (inScopeTags.indexOf(tag) !== -1) { - ancestorInfo.aTagInScope = null; - ancestorInfo.buttonTagInScope = null; - ancestorInfo.nobrTagInScope = null; - } - if (buttonScopeTags.indexOf(tag) !== -1) { - ancestorInfo.pTagInButtonScope = null; - } - - // See rules for 'li', 'dd', 'dt' start tags in - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody - if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') { - ancestorInfo.listItemTagAutoclosing = null; - ancestorInfo.dlItemTagAutoclosing = null; - } - - ancestorInfo.current = info; - - if (tag === 'form') { - ancestorInfo.formTag = info; - } - if (tag === 'a') { - ancestorInfo.aTagInScope = info; - } - if (tag === 'button') { - ancestorInfo.buttonTagInScope = info; - } - if (tag === 'nobr') { - ancestorInfo.nobrTagInScope = info; - } - if (tag === 'p') { - ancestorInfo.pTagInButtonScope = info; - } - if (tag === 'li') { - ancestorInfo.listItemTagAutoclosing = info; - } - if (tag === 'dd' || tag === 'dt') { - ancestorInfo.dlItemTagAutoclosing = info; - } - - return ancestorInfo; - }; - - /** - * Returns whether - */ - var isTagValidWithParent = function (tag, parentTag) { - // First, let's check if we're in an unusual parsing mode... - switch (parentTag) { - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect - case 'select': - return tag === 'option' || tag === 'optgroup' || tag === '#text'; - case 'optgroup': - return tag === 'option' || tag === '#text'; - // Strictly speaking, seeing an <option> doesn't mean we're in a <select> - // but - case 'option': - return tag === '#text'; - - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption - // No special behavior since these rules fall back to "in body" mode for - // all except special table nodes which cause bad parsing behavior anyway. - - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr - case 'tr': - return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template'; - - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody - case 'tbody': - case 'thead': - case 'tfoot': - return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template'; - - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup - case 'colgroup': - return tag === 'col' || tag === 'template'; - - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable - case 'table': - return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template'; - - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead - case 'head': - return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template'; - - // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element - case 'html': - return tag === 'head' || tag === 'body'; - case '#document': - return tag === 'html'; - } - - // Probably in the "in body" parsing mode, so we outlaw only tag combos - // where the parsing rules cause implicit opens or closes to be added. - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody - switch (tag) { - case 'h1': - case 'h2': - case 'h3': - case 'h4': - case 'h5': - case 'h6': - return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6'; - - case 'rp': - case 'rt': - return impliedEndTags.indexOf(parentTag) === -1; - - case 'body': - case 'caption': - case 'col': - case 'colgroup': - case 'frame': - case 'head': - case 'html': - case 'tbody': - case 'td': - case 'tfoot': - case 'th': - case 'thead': - case 'tr': - // These tags are only valid with a few parents that have special child - // parsing rules -- if we're down here, then none of those matched and - // so we allow it only if we don't know what the parent is, as all other - // cases are invalid. - return parentTag == null; - } - - return true; - }; - - /** - * Returns whether - */ - var findInvalidAncestorForTag = function (tag, ancestorInfo) { - switch (tag) { - case 'address': - case 'article': - case 'aside': - case 'blockquote': - case 'center': - case 'details': - case 'dialog': - case 'dir': - case 'div': - case 'dl': - case 'fieldset': - case 'figcaption': - case 'figure': - case 'footer': - case 'header': - case 'hgroup': - case 'main': - case 'menu': - case 'nav': - case 'ol': - case 'p': - case 'section': - case 'summary': - case 'ul': - - case 'pre': - case 'listing': - - case 'table': - - case 'hr': - - case 'xmp': - - case 'h1': - case 'h2': - case 'h3': - case 'h4': - case 'h5': - case 'h6': - return ancestorInfo.pTagInButtonScope; - - case 'form': - return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope; - - case 'li': - return ancestorInfo.listItemTagAutoclosing; - - case 'dd': - case 'dt': - return ancestorInfo.dlItemTagAutoclosing; - - case 'button': - return ancestorInfo.buttonTagInScope; - - case 'a': - // Spec says something about storing a list of markers, but it sounds - // equivalent to this check. - return ancestorInfo.aTagInScope; - - case 'nobr': - return ancestorInfo.nobrTagInScope; - } - - return null; - }; - - /** - * Given a ReactCompositeComponent instance, return a list of its recursive - * owners, starting at the root and ending with the instance itself. - */ - var findOwnerStack = function (instance) { - if (!instance) { - return []; - } - - var stack = []; - do { - stack.push(instance); - } while (instance = instance._currentElement._owner); - stack.reverse(); - return stack; - }; - - var didWarn = {}; - - validateDOMNesting = function (childTag, childText, childInstance, ancestorInfo) { - ancestorInfo = ancestorInfo || emptyAncestorInfo; - var parentInfo = ancestorInfo.current; - var parentTag = parentInfo && parentInfo.tag; - - if (childText != null) { - process.env.NODE_ENV !== 'production' ? warning(childTag == null, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0; - childTag = '#text'; - } - - var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo; - var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo); - var problematic = invalidParent || invalidAncestor; - - if (problematic) { - var ancestorTag = problematic.tag; - var ancestorInstance = problematic.instance; - - var childOwner = childInstance && childInstance._currentElement._owner; - var ancestorOwner = ancestorInstance && ancestorInstance._currentElement._owner; - - var childOwners = findOwnerStack(childOwner); - var ancestorOwners = findOwnerStack(ancestorOwner); - - var minStackLen = Math.min(childOwners.length, ancestorOwners.length); - var i; - - var deepestCommon = -1; - for (i = 0; i < minStackLen; i++) { - if (childOwners[i] === ancestorOwners[i]) { - deepestCommon = i; - } else { - break; - } - } - - var UNKNOWN = '(unknown)'; - var childOwnerNames = childOwners.slice(deepestCommon + 1).map(function (inst) { - return inst.getName() || UNKNOWN; - }); - var ancestorOwnerNames = ancestorOwners.slice(deepestCommon + 1).map(function (inst) { - return inst.getName() || UNKNOWN; - }); - var ownerInfo = [].concat( - // If the parent and child instances have a common owner ancestor, start - // with that -- otherwise we just start with the parent's owners. - deepestCommon !== -1 ? childOwners[deepestCommon].getName() || UNKNOWN : [], ancestorOwnerNames, ancestorTag, - // If we're warning about an invalid (non-parent) ancestry, add '...' - invalidAncestor ? ['...'] : [], childOwnerNames, childTag).join(' > '); - - var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + ownerInfo; - if (didWarn[warnKey]) { - return; - } - didWarn[warnKey] = true; - - var tagDisplayName = childTag; - var whitespaceInfo = ''; - if (childTag === '#text') { - if (/\S/.test(childText)) { - tagDisplayName = 'Text nodes'; - } else { - tagDisplayName = 'Whitespace text nodes'; - whitespaceInfo = ' Make sure you don\'t have any extra whitespace between tags on ' + 'each line of your source code.'; - } - } else { - tagDisplayName = '<' + childTag + '>'; - } - - if (invalidParent) { - var info = ''; - if (ancestorTag === 'table' && childTag === 'tr') { - info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.'; - } - process.env.NODE_ENV !== 'production' ? warning(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s ' + 'See %s.%s', tagDisplayName, ancestorTag, whitespaceInfo, ownerInfo, info) : void 0; - } else { - process.env.NODE_ENV !== 'production' ? warning(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>. See %s.', tagDisplayName, ancestorTag, ownerInfo) : void 0; - } - } - }; - - validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo; - - // For testing - validateDOMNesting.isTagValidInContext = function (tag, ancestorInfo) { - ancestorInfo = ancestorInfo || emptyAncestorInfo; - var parentInfo = ancestorInfo.current; - var parentTag = parentInfo && parentInfo.tag; - return isTagValidWithParent(tag, parentTag) && !findInvalidAncestorForTag(tag, ancestorInfo); - }; -} - -module.exports = validateDOMNesting; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 61 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.loopAsync = loopAsync; -exports.mapAsync = mapAsync; - -function loopAsync(turns, work, callback) { - var currentTurn = 0, - isDone = false; - - function done() { - isDone = true; - callback.apply(this, arguments); - } - - function next() { - if (isDone) return; - - if (currentTurn < turns) { - work.call(this, currentTurn++, next, done); - } else { - done.apply(this, arguments); - } - } - - next(); -} - -function mapAsync(array, work, callback) { - var length = array.length; - var values = []; - - if (length === 0) return callback(null, values); - - var isDone = false, - doneCount = 0; - - function done(index, error, value) { - if (isDone) return; - - if (error) { - isDone = true; - callback(error); - } else { - values[index] = value; - - isDone = ++doneCount === length; - - if (isDone) callback(null, values); - } - } - - array.forEach(function (item, index) { - work(item, index, function (error, value) { - done(index, error, value); - }); - }); -} - -/***/ }), -/* 62 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _historyLibActions = __webpack_require__(29); - -var _historyLibUseQueries = __webpack_require__(235); - -var _historyLibUseQueries2 = _interopRequireDefault(_historyLibUseQueries); - -var _computeChangedRoutes2 = __webpack_require__(318); - -var _computeChangedRoutes3 = _interopRequireDefault(_computeChangedRoutes2); - -var _TransitionUtils = __webpack_require__(317); - -var _isActive2 = __webpack_require__(321); - -var _isActive3 = _interopRequireDefault(_isActive2); - -var _getComponents = __webpack_require__(319); - -var _getComponents2 = _interopRequireDefault(_getComponents); - -var _matchRoutes = __webpack_require__(323); - -var _matchRoutes2 = _interopRequireDefault(_matchRoutes); - -function hasAnyProperties(object) { - for (var p in object) { - if (object.hasOwnProperty(p)) return true; - }return false; -} - -/** - * Returns a new createHistory function that may be used to create - * history objects that know about routing. - * - * Enhances history objects with the following methods: - * - * - listen((error, nextState) => {}) - * - listenBeforeLeavingRoute(route, (nextLocation) => {}) - * - match(location, (error, redirectLocation, nextState) => {}) - * - isActive(pathname, query, indexOnly=false) - */ -function useRoutes(createHistory) { - return function () { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - var routes = options.routes; - - var historyOptions = _objectWithoutProperties(options, ['routes']); - - var history = _historyLibUseQueries2['default'](createHistory)(historyOptions); - var state = {}; - - function isActive(pathname, query) { - var indexOnly = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; - - return _isActive3['default'](pathname, query, indexOnly, state.location, state.routes, state.params); - } - - function createLocationFromRedirectInfo(_ref) { - var pathname = _ref.pathname; - var query = _ref.query; - var state = _ref.state; - - return history.createLocation(history.createPath(pathname, query), state, _historyLibActions.REPLACE); - } - - var partialNextState = undefined; - - function match(location, callback) { - if (partialNextState && partialNextState.location === location) { - // Continue from where we left off. - finishMatch(partialNextState, callback); - } else { - _matchRoutes2['default'](routes, location, function (error, nextState) { - if (error) { - callback(error); - } else if (nextState) { - finishMatch(_extends({}, nextState, { location: location }), callback); - } else { - callback(); - } - }); - } - } - - function finishMatch(nextState, callback) { - var _computeChangedRoutes = _computeChangedRoutes3['default'](state, nextState); - - var leaveRoutes = _computeChangedRoutes.leaveRoutes; - var enterRoutes = _computeChangedRoutes.enterRoutes; - - _TransitionUtils.runLeaveHooks(leaveRoutes); - - _TransitionUtils.runEnterHooks(enterRoutes, nextState, function (error, redirectInfo) { - if (error) { - callback(error); - } else if (redirectInfo) { - callback(null, createLocationFromRedirectInfo(redirectInfo)); - } else { - // TODO: Fetch components after state is updated. - _getComponents2['default'](nextState, function (error, components) { - if (error) { - callback(error); - } else { - // TODO: Make match a pure function and have some other API - // for "match and update state". - callback(null, null, state = _extends({}, nextState, { components: components })); - } - }); - } - }); - } - - var RouteGuid = 1; - - function getRouteID(route) { - return route.__id__ || (route.__id__ = RouteGuid++); - } - - var RouteHooks = {}; - - function getRouteHooksForRoutes(routes) { - return routes.reduce(function (hooks, route) { - hooks.push.apply(hooks, RouteHooks[getRouteID(route)]); - return hooks; - }, []); - } - - function transitionHook(location, callback) { - _matchRoutes2['default'](routes, location, function (error, nextState) { - if (nextState == null) { - // TODO: We didn't actually match anything, but hang - // onto error/nextState so we don't have to matchRoutes - // again in the listen callback. - callback(); - return; - } - - // Cache some state here so we don't have to - // matchRoutes() again in the listen callback. - partialNextState = _extends({}, nextState, { location: location }); - - var hooks = getRouteHooksForRoutes(_computeChangedRoutes3['default'](state, partialNextState).leaveRoutes); - - var result = undefined; - for (var i = 0, len = hooks.length; result == null && i < len; ++i) { - // Passing the location arg here indicates to - // the user that this is a transition hook. - result = hooks[i](location); - } - - callback(result); - }); - } - - function beforeUnloadHook() { - // Synchronously check to see if any route hooks want - // to prevent the current window/tab from closing. - if (state.routes) { - var hooks = getRouteHooksForRoutes(state.routes); - - var message = undefined; - for (var i = 0, len = hooks.length; typeof message !== 'string' && i < len; ++i) { - // Passing no args indicates to the user that this is a - // beforeunload hook. We don't know the next location. - message = hooks[i](); - } - - return message; - } - } - - var unlistenBefore = undefined, - unlistenBeforeUnload = undefined; - - /** - * Registers the given hook function to run before leaving the given route. - * - * During a normal transition, the hook function receives the next location - * as its only argument and must return either a) a prompt message to show - * the user, to make sure they want to leave the page or b) false, to prevent - * the transition. - * - * During the beforeunload event (in browsers) the hook receives no arguments. - * In this case it must return a prompt message to prevent the transition. - * - * Returns a function that may be used to unbind the listener. - */ - function listenBeforeLeavingRoute(route, hook) { - // TODO: Warn if they register for a route that isn't currently - // active. They're probably doing something wrong, like re-creating - // route objects on every location change. - var routeID = getRouteID(route); - var hooks = RouteHooks[routeID]; - - if (hooks == null) { - var thereWereNoRouteHooks = !hasAnyProperties(RouteHooks); - - hooks = RouteHooks[routeID] = [hook]; - - if (thereWereNoRouteHooks) { - // setup transition & beforeunload hooks - unlistenBefore = history.listenBefore(transitionHook); - - if (history.listenBeforeUnload) unlistenBeforeUnload = history.listenBeforeUnload(beforeUnloadHook); - } - } else if (hooks.indexOf(hook) === -1) { - hooks.push(hook); - } - - return function () { - var hooks = RouteHooks[routeID]; - - if (hooks != null) { - var newHooks = hooks.filter(function (item) { - return item !== hook; - }); - - if (newHooks.length === 0) { - delete RouteHooks[routeID]; - - if (!hasAnyProperties(RouteHooks)) { - // teardown transition & beforeunload hooks - if (unlistenBefore) { - unlistenBefore(); - unlistenBefore = null; - } - - if (unlistenBeforeUnload) { - unlistenBeforeUnload(); - unlistenBeforeUnload = null; - } - } - } else { - RouteHooks[routeID] = newHooks; - } - } - }; - } - - /** - * This is the API for stateful environments. As the location - * changes, we update state and call the listener. We can also - * gracefully handle errors and redirects. - */ - function listen(listener) { - // TODO: Only use a single history listener. Otherwise we'll - // end up with multiple concurrent calls to match. - return history.listen(function (location) { - if (state.location === location) { - listener(null, state); - } else { - match(location, function (error, redirectLocation, nextState) { - if (error) { - listener(error); - } else if (redirectLocation) { - history.transitionTo(redirectLocation); - } else if (nextState) { - listener(null, nextState); - } else { - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'Location "%s" did not match any routes', location.pathname + location.search + location.hash) : undefined; - } - }); - } - }); - } - - return _extends({}, history, { - isActive: isActive, - match: match, - listenBeforeLeavingRoute: listenBeforeLeavingRoute, - listen: listen - }); - }; -} - -exports['default'] = useRoutes; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 63 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(23); - -var ReactNoopUpdateQueue = __webpack_require__(64); - -var canDefineProperty = __webpack_require__(66); -var emptyObject = __webpack_require__(28); -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -/** - * Base class helpers for the updating state of a component. - */ -function ReactComponent(props, context, updater) { - this.props = props; - this.context = context; - this.refs = emptyObject; - // We initialize the default updater but the real one gets injected by the - // renderer. - this.updater = updater || ReactNoopUpdateQueue; -} - -ReactComponent.prototype.isReactComponent = {}; - -/** - * Sets a subset of the state. Always use this to mutate - * state. You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * There is no guarantee that calls to `setState` will run synchronously, - * as they may eventually be batched together. You can provide an optional - * callback that will be executed when the call to setState is actually - * completed. - * - * When a function is provided to setState, it will be called at some point in - * the future (not synchronously). It will be called with the up to date - * component arguments (state, props, context). These values can be different - * from this.* because your function may be called after receiveProps but before - * shouldComponentUpdate, and this new state, props, and context will not yet be - * assigned to this. - * - * @param {object|function} partialState Next partial state or function to - * produce next partial state to be merged with current state. - * @param {?function} callback Called after state is updated. - * @final - * @protected - */ -ReactComponent.prototype.setState = function (partialState, callback) { - !(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'setState(...): takes an object of state variables to update or a function which returns an object of state variables.') : _prodInvariant('85') : void 0; - this.updater.enqueueSetState(this, partialState); - if (callback) { - this.updater.enqueueCallback(this, callback, 'setState'); - } -}; - -/** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldComponentUpdate`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {?function} callback Called after update is complete. - * @final - * @protected - */ -ReactComponent.prototype.forceUpdate = function (callback) { - this.updater.enqueueForceUpdate(this); - if (callback) { - this.updater.enqueueCallback(this, callback, 'forceUpdate'); - } -}; - -/** - * Deprecated APIs. These APIs used to exist on classic React classes but since - * we would like to deprecate them, we're not going to move them over to this - * modern base class. Instead, we define a getter that warns if it's accessed. - */ -if (process.env.NODE_ENV !== 'production') { - var deprecatedAPIs = { - isMounted: ['isMounted', 'Instead, make sure to clean up subscriptions and pending requests in ' + 'componentWillUnmount to prevent memory leaks.'], - replaceState: ['replaceState', 'Refactor your code to use setState instead (see ' + 'https://github.com/facebook/react/issues/3236).'] - }; - var defineDeprecationWarning = function (methodName, info) { - if (canDefineProperty) { - Object.defineProperty(ReactComponent.prototype, methodName, { - get: function () { - process.env.NODE_ENV !== 'production' ? warning(false, '%s(...) is deprecated in plain JavaScript React classes. %s', info[0], info[1]) : void 0; - return undefined; - } - }); - } - }; - for (var fnName in deprecatedAPIs) { - if (deprecatedAPIs.hasOwnProperty(fnName)) { - defineDeprecationWarning(fnName, deprecatedAPIs[fnName]); - } - } -} - -module.exports = ReactComponent; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 64 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var warning = __webpack_require__(3); - -function warnNoop(publicInstance, callerName) { - if (process.env.NODE_ENV !== 'production') { - var constructor = publicInstance.constructor; - process.env.NODE_ENV !== 'production' ? warning(false, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, constructor && (constructor.displayName || constructor.name) || 'ReactClass') : void 0; - } -} - -/** - * This is the abstract API for an update queue. - */ -var ReactNoopUpdateQueue = { - - /** - * Checks whether or not this composite component is mounted. - * @param {ReactClass} publicInstance The instance we want to test. - * @return {boolean} True if mounted, false otherwise. - * @protected - * @final - */ - isMounted: function (publicInstance) { - return false; - }, - - /** - * Enqueue a callback that will be executed after all the pending updates - * have processed. - * - * @param {ReactClass} publicInstance The instance to use as `this` context. - * @param {?function} callback Called after state is updated. - * @internal - */ - enqueueCallback: function (publicInstance, callback) {}, - - /** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldComponentUpdate`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @internal - */ - enqueueForceUpdate: function (publicInstance) { - warnNoop(publicInstance, 'forceUpdate'); - }, - - /** - * Replaces all of the state. Always use this or `setState` to mutate state. - * You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} completeState Next state. - * @internal - */ - enqueueReplaceState: function (publicInstance, completeState) { - warnNoop(publicInstance, 'replaceState'); - }, - - /** - * Sets a subset of the state. This only exists because _pendingState is - * internal. This provides a merging strategy that is not available to deep - * properties which is confusing. TODO: Expose pendingState or don't use it - * during the merge. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} partialState Next partial state to be merged with state. - * @internal - */ - enqueueSetState: function (publicInstance, partialState) { - warnNoop(publicInstance, 'setState'); - } -}; - -module.exports = ReactNoopUpdateQueue; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 65 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactPropTypeLocationNames = {}; - -if (process.env.NODE_ENV !== 'production') { - ReactPropTypeLocationNames = { - prop: 'prop', - context: 'context', - childContext: 'child context' - }; -} - -module.exports = ReactPropTypeLocationNames; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 66 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var canDefineProperty = false; -if (process.env.NODE_ENV !== 'production') { - try { - // $FlowFixMe https://github.com/facebook/flow/issues/285 - Object.defineProperty({}, 'x', { get: function () {} }); - canDefineProperty = true; - } catch (x) { - // IE will fail on defineProperty - } -} - -module.exports = canDefineProperty; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 67 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/* global Symbol */ - -var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; -var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. - -/** - * Returns the iterator method function contained on the iterable object. - * - * Be sure to invoke the function with the iterable as context: - * - * var iteratorFn = getIteratorFn(myIterable); - * if (iteratorFn) { - * var iterator = iteratorFn.call(myIterable); - * ... - * } - * - * @param {?object} maybeIterable - * @return {?function} - */ -function getIteratorFn(maybeIterable) { - var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); - if (typeof iteratorFn === 'function') { - return iteratorFn; - } -} - -module.exports = getIteratorFn; - -/***/ }), -/* 68 */ -/***/ (function(module, exports, __webpack_require__) { - -var data = __webpack_require__(207); - -var Locale = function() { - this.data = {}; - this.data = data; -}; - -Locale.prototype = { - getSectionLocale: function(key) { - return this.data[key].locale; - }, - - getContent: function(key, handler) { - return this.data[key].getContent(handler); - }, - - getTitle: function(key) { - return this.data[key].title; - } -}; - -module.exports = Locale; - - -/***/ }), -/* 69 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var SectionHeader = React.createClass({ - displayName: "SectionHeader", - - statics: { - locale: '' - }, - - render: function render() { - var locale = SectionHeader.locale; - if (typeof window !== "undefined" && window.location.toString().indexOf(locale) === -1) { - locale = ''; - } - var fragmentid = (locale ? './' + locale + '/' : '.') + "#" + this.props.name; - return React.createElement( - "h2", - { id: this.props.name, "data-num": this.props.number }, - React.createElement( - "a", - { href: fragmentid }, - this.props.title - ) - ); - }, - componentDidMount: function componentDidMount() { - if (typeof window !== "undefined" && window.location) { - var h = window.location.hash; - if (h) { - window.location = window.location.hash; - } - } - } -}); - -module.exports = SectionHeader; - -/***/ }), -/* 70 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - A javascript Bezier curve library by Pomax. - - Based on http://pomax.github.io/bezierinfo - - This code is MIT licensed. -**/ -(function() { - "use strict"; - - // math-inlining. - var abs = Math.abs, - min = Math.min, - max = Math.max, - acos = Math.acos, - sqrt = Math.sqrt, - pi = Math.PI, - // a zero coordinate, which is surprisingly useful - ZERO = {x:0,y:0,z:0}; - - // quite needed - var utils = __webpack_require__(71); - - // not quite needed, but eventually this'll be useful... - var PolyBezier = __webpack_require__(209); - - /** - * Bezier curve constructor. The constructor argument can be one of three things: - * - * 1. array/4 of {x:..., y:..., z:...}, z optional - * 2. numerical array/8 ordered x1,y1,x2,y2,x3,y3,x4,y4 - * 3. numerical array/12 ordered x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4 - * - */ - var Bezier = function(coords) { - var args = (coords && coords.forEach) ? coords : [].slice.call(arguments); - var coordlen = false; - if(typeof args[0] === "object") { - coordlen = args.length; - var newargs = []; - args.forEach(function(point) { - ['x','y','z'].forEach(function(d) { - if(typeof point[d] !== "undefined") { - newargs.push(point[d]); - } - }); - }); - args = newargs; - } - var higher = false; - var len = args.length; - if (coordlen) { - if(coordlen>4) { - if (arguments.length !== 1) { - throw new Error("Only new Bezier(point[]) is accepted for 4th and higher order curves"); - } - higher = true; - } - } else { - if(len!==6 && len!==8 && len!==9 && len!==12) { - if (arguments.length !== 1) { - throw new Error("Only new Bezier(point[]) is accepted for 4th and higher order curves"); - } - } - } - var _3d = (!higher && (len === 9 || len === 12)) || (coords && coords[0] && typeof coords[0].z !== "undefined"); - this._3d = _3d; - var points = []; - for(var idx=0, step=(_3d ? 3 : 2); idx<len; idx+=step) { - var point = { - x: args[idx], - y: args[idx+1] - }; - if(_3d) { point.z = args[idx+2] }; - points.push(point); - } - this.order = points.length - 1; - this.points = points; - var dims = ['x','y']; - if(_3d) dims.push('z'); - this.dims = dims; - this.dimlen = dims.length; - - (function(curve) { - var order = curve.order; - var points = curve.points; - var a = utils.align(points, {p1:points[0], p2:points[order]}); - for(var i=0; i<a.length; i++) { - if(abs(a[i].y) > 0.0001) { - curve._linear = false; - return; - } - } - curve._linear = true; - }(this)); - - this._t1 = 0; - this._t2 = 1; - this.update(); - }; - - Bezier.fromSVG = function(svgString) { - var list = svgString.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/g).map(parseFloat); - var relative = /[cq]/.test(svgString); - if(!relative) return new Bezier(list); - list = list.map(function(v,i) { - return i < 2 ? v : v + list[i % 2]; - }); - return new Bezier(list); - }; - - function getABC(n,S,B,E,t) { - if(typeof t === "undefined") { t = 0.5; } - var u = utils.projectionratio(t,n), - um = 1-u, - C = { - x: u*S.x + um*E.x, - y: u*S.y + um*E.y - }, - s = utils.abcratio(t,n), - A = { - x: B.x + (B.x-C.x)/s, - y: B.y + (B.y-C.y)/s - }; - return { A:A, B:B, C:C }; - } - - Bezier.quadraticFromPoints = function(p1,p2,p3, t) { - if(typeof t === "undefined") { t = 0.5; } - // shortcuts, although they're really dumb - if(t===0) { return new Bezier(p2,p2,p3); } - if(t===1) { return new Bezier(p1,p2,p2); } - // real fitting. - var abc = getABC(2,p1,p2,p3,t); - return new Bezier(p1, abc.A, p3); - }; - - Bezier.cubicFromPoints = function(S,B,E, t,d1) { - if(typeof t === "undefined") { t = 0.5; } - var abc = getABC(3,S,B,E,t); - if(typeof d1 === "undefined") { d1 = utils.dist(B,abc.C); } - var d2 = d1 * (1-t)/t; - - var selen = utils.dist(S,E), - lx = (E.x-S.x)/selen, - ly = (E.y-S.y)/selen, - bx1 = d1 * lx, - by1 = d1 * ly, - bx2 = d2 * lx, - by2 = d2 * ly; - // derivation of new hull coordinates - var e1 = { x: B.x - bx1, y: B.y - by1 }, - e2 = { x: B.x + bx2, y: B.y + by2 }, - A = abc.A, - v1 = { x: A.x + (e1.x-A.x)/(1-t), y: A.y + (e1.y-A.y)/(1-t) }, - v2 = { x: A.x + (e2.x-A.x)/(t), y: A.y + (e2.y-A.y)/(t) }, - nc1 = { x: S.x + (v1.x-S.x)/(t), y: S.y + (v1.y-S.y)/(t) }, - nc2 = { x: E.x + (v2.x-E.x)/(1-t), y: E.y + (v2.y-E.y)/(1-t) }; - // ...done - return new Bezier(S,nc1,nc2,E); - }; - - var getUtils = function() { - return utils; - }; - - Bezier.getUtils = getUtils; - - Bezier.prototype = { - getUtils: getUtils, - valueOf: function() { - return this.toString(); - }, - toString: function() { - return utils.pointsToString(this.points); - }, - toSVG: function(relative) { - if(this._3d) return false; - var p = this.points, - x = p[0].x, - y = p[0].y, - s = ["M", x, y, (this.order===2 ? "Q":"C")]; - for(var i=1, last=p.length; i<last; i++) { - s.push(p[i].x); - s.push(p[i].y); - } - return s.join(" "); - }, - update: function() { - // one-time compute derivative coordinates - this.dpoints = []; - for(var p=this.points, d=p.length, c=d-1; d>1; d--, c--) { - var list = []; - for(var j=0, dpt; j<c; j++) { - dpt = { - x: c * (p[j+1].x - p[j].x), - y: c * (p[j+1].y - p[j].y) - }; - if(this._3d) { - dpt.z = c * (p[j+1].z - p[j].z); - } - list.push(dpt); - } - this.dpoints.push(list); - p = list; - }; - this.computedirection(); - }, - computedirection: function() { - var points = this.points; - var angle = utils.angle(points[0], points[this.order], points[1]); - this.clockwise = angle > 0; - }, - length: function() { - return utils.length(this.derivative.bind(this)); - }, - _lut: [], - getLUT: function(steps) { - steps = steps || 100; - if (this._lut.length === steps) { return this._lut; } - this._lut = []; - for(var t=0; t<=steps; t++) { - this._lut.push(this.compute(t/steps)); - } - return this._lut; - }, - on: function(point, error) { - error = error || 5; - var lut = this.getLUT(), hits = [], c, t=0; - for(var i=0; i<lut.length; i++) { - c = lut[i]; - if (utils.dist(c,point) < error) { - hits.push(c) - t += i / lut.length; - } - } - if(!hits.length) return false; - return t /= hits.length; - }, - project: function(point) { - // step 1: coarse check - var LUT = this.getLUT(), l = LUT.length-1, - closest = utils.closest(LUT, point), - mdist = closest.mdist, - mpos = closest.mpos; - if (mpos===0 || mpos===l) { - var t = mpos/l, pt = this.compute(t); - pt.t = t; - pt.d = mdist; - return pt; - } - - // step 2: fine check - var ft, t, p, d, - t1 = (mpos-1)/l, - t2 = (mpos+1)/l, - step = 0.1/l; - mdist += 1; - for(t=t1,ft=t; t<t2+step; t+=step) { - p = this.compute(t); - d = utils.dist(point, p); - if (d<mdist) { - mdist = d; - ft = t; - } - } - p = this.compute(ft); - p.t = ft; - p.d = mdist; - return p; - }, - get: function(t) { - return this.compute(t); - }, - point: function(idx) { - return this.points[idx]; - }, - compute: function(t) { - // shortcuts - if(t===0) { return this.points[0]; } - if(t===1) { return this.points[this.order]; } - - var p = this.points; - var mt = 1-t; - - // linear? - if(this.order===1) { - ret = { - x: mt*p[0].x + t*p[1].x, - y: mt*p[0].y + t*p[1].y - }; - if (this._3d) { ret.z = mt*p[0].z + t*p[1].z; } - return ret; - } - - // quadratic/cubic curve? - if(this.order<4) { - var mt2 = mt*mt, - t2 = t*t, - a,b,c,d = 0; - if(this.order===2) { - p = [p[0], p[1], p[2], ZERO]; - a = mt2; - b = mt*t*2; - c = t2; - } - else if(this.order===3) { - a = mt2*mt; - b = mt2*t*3; - c = mt*t2*3; - d = t*t2; - } - var ret = { - x: a*p[0].x + b*p[1].x + c*p[2].x + d*p[3].x, - y: a*p[0].y + b*p[1].y + c*p[2].y + d*p[3].y - }; - if(this._3d) { - ret.z = a*p[0].z + b*p[1].z + c*p[2].z + d*p[3].z; - } - return ret; - } - - // higher order curves: use de Casteljau's computation - var dCpts = JSON.parse(JSON.stringify(this.points)); - while(dCpts.length > 1) { - for (var i=0; i<dCpts.length-1; i++) { - dCpts[i] = { - x: dCpts[i].x + (dCpts[i+1].x - dCpts[i].x) * t, - y: dCpts[i].y + (dCpts[i+1].y - dCpts[i].y) * t - }; - if (typeof dCpts[i].z !== "undefined") { - dCpts[i] = dCpts[i].z + (dCpts[i+1].z - dCpts[i].z) * t - } - } - dCpts.splice(dCpts.length-1, 1); - } - return dCpts[0]; - }, - raise: function() { - var p = this.points, np = [p[0]], i, k=p.length, pi, pim; - for (var i=1; i<k; i++) { - pi = p[i]; - pim = p[i-1]; - np[i] = { - x: (k-i)/k * pi.x + i/k * pim.x, - y: (k-i)/k * pi.y + i/k * pim.y - }; - } - np[k] = p[k-1]; - return new Bezier(np); - }, - derivative: function(t) { - var mt = 1-t, - a,b,c=0, - p = this.dpoints[0]; - if(this.order===2) { p = [p[0], p[1], ZERO]; a = mt; b = t; } - if(this.order===3) { a = mt*mt; b = mt*t*2; c = t*t; } - var ret = { - x: a*p[0].x + b*p[1].x + c*p[2].x, - y: a*p[0].y + b*p[1].y + c*p[2].y - }; - if(this._3d) { - ret.z = a*p[0].z + b*p[1].z + c*p[2].z; - } - return ret; - }, - inflections: function() { - return utils.inflections(this.points); - }, - normal: function(t) { - return this._3d ? this.__normal3(t) : this.__normal2(t); - }, - __normal2: function(t) { - var d = this.derivative(t); - var q = sqrt(d.x*d.x + d.y*d.y) - return { x: -d.y/q, y: d.x/q }; - }, - __normal3: function(t) { - // see http://stackoverflow.com/questions/25453159 - var r1 = this.derivative(t), - r2 = this.derivative(t+0.01), - q1 = sqrt(r1.x*r1.x + r1.y*r1.y + r1.z*r1.z), - q2 = sqrt(r2.x*r2.x + r2.y*r2.y + r2.z*r2.z); - r1.x /= q1; r1.y /= q1; r1.z /= q1; - r2.x /= q2; r2.y /= q2; r2.z /= q2; - // cross product - var c = { - x: r2.y*r1.z - r2.z*r1.y, - y: r2.z*r1.x - r2.x*r1.z, - z: r2.x*r1.y - r2.y*r1.x - }; - var m = sqrt(c.x*c.x + c.y*c.y + c.z*c.z); - c.x /= m; c.y /= m; c.z /= m; - // rotation matrix - var R = [ c.x*c.x, c.x*c.y-c.z, c.x*c.z+c.y, - c.x*c.y+c.z, c.y*c.y, c.y*c.z-c.x, - c.x*c.z-c.y, c.y*c.z+c.x, c.z*c.z ]; - // normal vector: - var n = { - x: R[0] * r1.x + R[1] * r1.y + R[2] * r1.z, - y: R[3] * r1.x + R[4] * r1.y + R[5] * r1.z, - z: R[6] * r1.x + R[7] * r1.y + R[8] * r1.z - }; - return n; - }, - hull: function(t) { - var p = this.points, - _p = [], - pt, - q = [], - idx = 0, - i=0, - l=0; - q[idx++] = p[0]; - q[idx++] = p[1]; - q[idx++] = p[2]; - if(this.order === 3) { q[idx++] = p[3]; } - // we lerp between all points at each iteration, until we have 1 point left. - while(p.length>1) { - _p = []; - for(i=0, l=p.length-1; i<l; i++) { - pt = utils.lerp(t,p[i],p[i+1]); - q[idx++] = pt; - _p.push(pt); - } - p = _p; - } - return q; - }, - split: function(t1, t2) { - // shortcuts - if(t1===0 && !!t2) { return this.split(t2).left; } - if(t2===1) { return this.split(t1).right; } - - // no shortcut: use "de Casteljau" iteration. - var q = this.hull(t1); - var result = { - left: this.order === 2 ? new Bezier([q[0],q[3],q[5]]) : new Bezier([q[0],q[4],q[7],q[9]]), - right: this.order === 2 ? new Bezier([q[5],q[4],q[2]]) : new Bezier([q[9],q[8],q[6],q[3]]), - span: q - }; - - // make sure we bind _t1/_t2 information! - result.left._t1 = utils.map(0, 0,1, this._t1,this._t2); - result.left._t2 = utils.map(t1, 0,1, this._t1,this._t2); - result.right._t1 = utils.map(t1, 0,1, this._t1,this._t2); - result.right._t2 = utils.map(1, 0,1, this._t1,this._t2); - - // if we have no t2, we're done - if(!t2) { return result; } - - // if we have a t2, split again: - t2 = utils.map(t2,t1,1,0,1); - var subsplit = result.right.split(t2); - return subsplit.left; - }, - extrema: function() { - var dims = this.dims, - result={}, - roots=[], - p, mfn; - dims.forEach(function(dim) { - mfn = function(v) { return v[dim]; }; - p = this.dpoints[0].map(mfn); - result[dim] = utils.droots(p); - if(this.order === 3) { - p = this.dpoints[1].map(mfn); - result[dim] = result[dim].concat(utils.droots(p)); - } - result[dim] = result[dim].filter(function(t) { return (t>=0 && t<=1); }); - roots = roots.concat(result[dim].sort()); - }.bind(this)); - roots = roots.sort().filter(function(v,idx) { return (roots.indexOf(v) === idx); }); - result.values = roots; - return result; - }, - bbox: function() { - var extrema = this.extrema(), result = {}; - this.dims.forEach(function(d) { - result[d] = utils.getminmax(this, d, extrema[d]); - }.bind(this)); - return result; - }, - overlaps: function(curve) { - var lbbox = this.bbox(), - tbbox = curve.bbox(); - return utils.bboxoverlap(lbbox,tbbox); - }, - offset: function(t, d) { - if(typeof d !== "undefined") { - var c = this.get(t); - var n = this.normal(t); - var ret = { - c: c, - n: n, - x: c.x + n.x * d, - y: c.y + n.y * d - }; - if(this._3d) { - ret.z = c.z + n.z * d; - }; - return ret; - } - if(this._linear) { - var nv = this.normal(0); - var coords = this.points.map(function(p) { - var ret = { - x: p.x + t * nv.x, - y: p.y + t * nv.y - }; - if(p.z && n.z) { ret.z = p.z + t * nv.z; } - return ret; - }); - return [new Bezier(coords)]; - } - var reduced = this.reduce(); - return reduced.map(function(s) { - return s.scale(t); - }); - }, - simple: function() { - if(this.order===3) { - var a1 = utils.angle(this.points[0], this.points[3], this.points[1]); - var a2 = utils.angle(this.points[0], this.points[3], this.points[2]); - if(a1>0 && a2<0 || a1<0 && a2>0) return false; - } - var n1 = this.normal(0); - var n2 = this.normal(1); - var s = n1.x*n2.x + n1.y*n2.y; - if(this._3d) { s += n1.z*n2.z; } - var angle = abs(acos(s)); - return angle < pi/3; - }, - reduce: function() { - var i, t1=0, t2=0, step=0.01, segment, pass1=[], pass2=[]; - // first pass: split on extrema - var extrema = this.extrema().values; - if(extrema.indexOf(0)===-1) { extrema = [0].concat(extrema); } - if(extrema.indexOf(1)===-1) { extrema.push(1); } - - for(t1=extrema[0], i=1; i<extrema.length; i++) { - t2 = extrema[i]; - segment = this.split(t1,t2); - segment._t1 = t1; - segment._t2 = t2; - pass1.push(segment); - t1 = t2; - } - - // second pass: further reduce these segments to simple segments - pass1.forEach(function(p1) { - t1=0; - t2=0; - while(t2 <= 1) { - for(t2=t1+step; t2<=1+step; t2+=step) { - segment = p1.split(t1,t2); - if(!segment.simple()) { - t2 -= step; - if(abs(t1-t2)<step) { - // we can never form a reduction - return []; - } - segment = p1.split(t1,t2); - segment._t1 = utils.map(t1,0,1,p1._t1,p1._t2); - segment._t2 = utils.map(t2,0,1,p1._t1,p1._t2); - pass2.push(segment); - t1 = t2; - break; - } - } - } - if(t1<1) { - segment = p1.split(t1,1); - segment._t1 = utils.map(t1,0,1,p1._t1,p1._t2); - segment._t2 = p1._t2; - pass2.push(segment); - } - }); - return pass2; - }, - scale: function(d) { - var order = this.order; - var distanceFn = false - if(typeof d === "function") { distanceFn = d; } - if(distanceFn && order === 2) { return this.raise().scale(distanceFn); } - - // TODO: add special handling for degenerate (=linear) curves. - var clockwise = this.clockwise; - var r1 = distanceFn ? distanceFn(0) : d; - var r2 = distanceFn ? distanceFn(1) : d; - var v = [ this.offset(0,10), this.offset(1,10) ]; - var o = utils.lli4(v[0], v[0].c, v[1], v[1].c); - if(!o) { throw new Error("cannot scale this curve. Try reducing it first."); } - // move all points by distance 'd' wrt the origin 'o' - var points=this.points, np=[]; - - // move end points by fixed distance along normal. - [0,1].forEach(function(t) { - var p = np[t*order] = utils.copy(points[t*order]); - p.x += (t?r2:r1) * v[t].n.x; - p.y += (t?r2:r1) * v[t].n.y; - }.bind(this)); - - if (!distanceFn) { - // move control points to lie on the intersection of the offset - // derivative vector, and the origin-through-control vector - [0,1].forEach(function(t) { - if(this.order===2 && !!t) return; - var p = np[t*order]; - var d = this.derivative(t); - var p2 = { x: p.x + d.x, y: p.y + d.y }; - np[t+1] = utils.lli4(p, p2, o, points[t+1]); - }.bind(this)); - return new Bezier(np); - } - - // move control points by "however much necessary to - // ensure the correct tangent to endpoint". - [0,1].forEach(function(t) { - if(this.order===2 && !!t) return; - var p = points[t+1]; - var ov = { - x: p.x - o.x, - y: p.y - o.y - }; - var rc = distanceFn ? distanceFn((t+1)/order) : d; - if(distanceFn && !clockwise) rc = -rc; - var m = sqrt(ov.x*ov.x + ov.y*ov.y); - ov.x /= m; - ov.y /= m; - np[t+1] = { - x: p.x + rc*ov.x, - y: p.y + rc*ov.y - } - }.bind(this)); - return new Bezier(np); - }, - outline: function(d1, d2, d3, d4) { - d2 = (typeof d2 === "undefined") ? d1 : d2; - var reduced = this.reduce(), - len = reduced.length, - fcurves = [], - bcurves = [], - p, - alen = 0, - tlen = this.length(); - - var graduated = (typeof d3 !== "undefined" && typeof d4 !== "undefined"); - - function linearDistanceFunction(s,e, tlen,alen,slen) { - return function (v) { - var f1 = alen/tlen, f2 = (alen+slen)/tlen, d = e-s; - return utils.map(v, 0,1, s+f1*d, s+f2*d); - }; - }; - - // form curve oulines - reduced.forEach(function(segment) { - slen = segment.length(); - if (graduated) { - fcurves.push(segment.scale( linearDistanceFunction( d1, d3, tlen,alen,slen) )); - bcurves.push(segment.scale( linearDistanceFunction(-d2,-d4, tlen,alen,slen) )); - } else { - fcurves.push(segment.scale( d1)); - bcurves.push(segment.scale(-d2)); - } - alen += slen; - }); - - // reverse the "return" outline - bcurves = bcurves.map(function(s) { - p = s.points; - if(p[3]) { s.points = [p[3],p[2],p[1],p[0]]; } - else { s.points = [p[2],p[1],p[0]]; } - return s; - }).reverse(); - - // form the endcaps as lines - var fs = fcurves[0].points[0], - fe = fcurves[len-1].points[fcurves[len-1].points.length-1], - bs = bcurves[len-1].points[bcurves[len-1].points.length-1], - be = bcurves[0].points[0], - ls = utils.makeline(bs,fs), - le = utils.makeline(fe,be), - segments = [ls].concat(fcurves).concat([le]).concat(bcurves), - slen = segments.length; - - return new PolyBezier(segments); - }, - outlineshapes: function(d1, d2, curveIntersectionThreshold) { - d2 = d2 || d1; - var outline = this.outline(d1,d2).curves; - var shapes = []; - for(var i=1, len=outline.length; i < len/2; i++) { - var shape = utils.makeshape(outline[i], outline[len-i], curveIntersectionThreshold); - shape.startcap.virtual = (i > 1); - shape.endcap.virtual = (i < len/2-1); - shapes.push(shape); - } - return shapes; - }, - intersects: function(curve, curveIntersectionThreshold) { - if(!curve) return this.selfintersects(curveIntersectionThreshold); - if(curve.p1 && curve.p2) { - return this.lineIntersects(curve); - } - if(curve instanceof Bezier) { curve = curve.reduce(); } - return this.curveintersects(this.reduce(), curve, curveIntersectionThreshold); - }, - lineIntersects: function(line) { - var mx = min(line.p1.x, line.p2.x), - my = min(line.p1.y, line.p2.y), - MX = max(line.p1.x, line.p2.x), - MY = max(line.p1.y, line.p2.y), - self=this; - return utils.roots(this.points, line).filter(function(t) { - var p = self.get(t); - return utils.between(p.x, mx, MX) && utils.between(p.y, my, MY); - }); - }, - selfintersects: function(curveIntersectionThreshold) { - var reduced = this.reduce(); - // "simple" curves cannot intersect with their direct - // neighbour, so for each segment X we check whether - // it intersects [0:x-2][x+2:last]. - var i,len=reduced.length-2,results=[],result,left,right; - for(i=0; i<len; i++) { - left = reduced.slice(i,i+1); - right = reduced.slice(i+2); - result = this.curveintersects(left, right, curveIntersectionThreshold); - results = results.concat( result ); - } - return results; - }, - curveintersects: function(c1, c2, curveIntersectionThreshold) { - var pairs = []; - // step 1: pair off any overlapping segments - c1.forEach(function(l) { - c2.forEach(function(r) { - if(l.overlaps(r)) { - pairs.push({ left: l, right: r }); - } - }); - }); - // step 2: for each pairing, run through the convergence algorithm. - var intersections = []; - pairs.forEach(function(pair) { - var result = utils.pairiteration(pair.left, pair.right, curveIntersectionThreshold); - if(result.length > 0) { - intersections = intersections.concat(result); - } - }); - return intersections; - }, - arcs: function(errorThreshold) { - errorThreshold = errorThreshold || 0.5; - var circles = []; - return this._iterate(errorThreshold, circles); - }, - _error: function(pc, np1, s, e) { - var q = (e - s) / 4, - c1 = this.get(s + q), - c2 = this.get(e - q), - ref = utils.dist(pc, np1), - d1 = utils.dist(pc, c1), - d2 = utils.dist(pc, c2); - return abs(d1-ref) + abs(d2-ref); - }, - _iterate: function(errorThreshold, circles) { - var s = 0, e = 1, safety; - // we do a binary search to find the "good `t` closest to no-longer-good" - do { - safety=0; - - // step 1: start with the maximum possible arc - e = 1; - - // points: - var np1 = this.get(s), np2, np3, arc, prev_arc; - - // booleans: - var curr_good = false, prev_good = false, done; - - // numbers: - var m = e, prev_e = 1, step = 0; - - // step 2: find the best possible arc - do { - prev_good = curr_good; - prev_arc = arc; - m = (s + e)/2; - step++; - - np2 = this.get(m); - np3 = this.get(e); - - arc = utils.getccenter(np1, np2, np3); - - //also save the t values - arc.interval = { - start: s, - end: e - }; - - var error = this._error(arc, np1, s, e); - curr_good = (error <= errorThreshold); - - done = prev_good && !curr_good; - if(!done) prev_e = e; - - // this arc is fine: we can move 'e' up to see if we can find a wider arc - if(curr_good) { - // if e is already at max, then we're done for this arc. - if (e >= 1) { - prev_e = 1; - prev_arc = arc; - break; - } - // if not, move it up by half the iteration distance - e = e + (e-s)/2; - } - - // this is a bad arc: we need to move 'e' down to find a good arc - else { - e = m; - } - } - while(!done && safety++<100); - - if(safety>=100) { - console.error("arc abstraction somehow failed..."); - break; - } - - // console.log("[F] arc found", s, prev_e, prev_arc.x, prev_arc.y, prev_arc.s, prev_arc.e); - - prev_arc = (prev_arc ? prev_arc : arc); - circles.push(prev_arc); - s = prev_e; - } - while(e < 1); - return circles; - } - }; - - module.exports = Bezier; - -}()); - - -/***/ }), -/* 71 */ -/***/ (function(module, exports, __webpack_require__) { - -(function() { - "use strict"; - - // math-inlining. - var abs = Math.abs, - cos = Math.cos, - sin = Math.sin, - acos = Math.acos, - atan2 = Math.atan2, - sqrt = Math.sqrt, - pow = Math.pow, - // cube root function yielding real roots - crt = function(v) { return (v<0) ? -pow(-v,1/3) : pow(v,1/3); }, - // trig constants - pi = Math.PI, - tau = 2*pi, - quart = pi/2, - // float precision significant decimal - epsilon = 0.000001; - - // Bezier utility functions - var utils = { - // Legendre-Gauss abscissae with n=24 (x_i values, defined at i=n as the roots of the nth order Legendre polynomial Pn(x)) - Tvalues: [ - -0.0640568928626056260850430826247450385909, - 0.0640568928626056260850430826247450385909, - -0.1911188674736163091586398207570696318404, - 0.1911188674736163091586398207570696318404, - -0.3150426796961633743867932913198102407864, - 0.3150426796961633743867932913198102407864, - -0.4337935076260451384870842319133497124524, - 0.4337935076260451384870842319133497124524, - -0.5454214713888395356583756172183723700107, - 0.5454214713888395356583756172183723700107, - -0.6480936519369755692524957869107476266696, - 0.6480936519369755692524957869107476266696, - -0.7401241915785543642438281030999784255232, - 0.7401241915785543642438281030999784255232, - -0.8200019859739029219539498726697452080761, - 0.8200019859739029219539498726697452080761, - -0.8864155270044010342131543419821967550873, - 0.8864155270044010342131543419821967550873, - -0.9382745520027327585236490017087214496548, - 0.9382745520027327585236490017087214496548, - -0.9747285559713094981983919930081690617411, - 0.9747285559713094981983919930081690617411, - -0.9951872199970213601799974097007368118745, - 0.9951872199970213601799974097007368118745 - ], - - // Legendre-Gauss weights with n=24 (w_i values, defined by a function linked to in the Bezier primer article) - Cvalues: [ - 0.1279381953467521569740561652246953718517, - 0.1279381953467521569740561652246953718517, - 0.1258374563468282961213753825111836887264, - 0.1258374563468282961213753825111836887264, - 0.1216704729278033912044631534762624256070, - 0.1216704729278033912044631534762624256070, - 0.1155056680537256013533444839067835598622, - 0.1155056680537256013533444839067835598622, - 0.1074442701159656347825773424466062227946, - 0.1074442701159656347825773424466062227946, - 0.0976186521041138882698806644642471544279, - 0.0976186521041138882698806644642471544279, - 0.0861901615319532759171852029837426671850, - 0.0861901615319532759171852029837426671850, - 0.0733464814110803057340336152531165181193, - 0.0733464814110803057340336152531165181193, - 0.0592985849154367807463677585001085845412, - 0.0592985849154367807463677585001085845412, - 0.0442774388174198061686027482113382288593, - 0.0442774388174198061686027482113382288593, - 0.0285313886289336631813078159518782864491, - 0.0285313886289336631813078159518782864491, - 0.0123412297999871995468056670700372915759, - 0.0123412297999871995468056670700372915759 - ], - - arcfn: function(t, derivativeFn) { - var d = derivativeFn(t); - var l = d.x*d.x + d.y*d.y; - if(typeof d.z !== "undefined") { - l += d.z*d.z; - } - return sqrt(l); - }, - - between: function(v, m, M) { - return (m <= v && v <= M) || utils.approximately(v, m) || utils.approximately(v, M); - }, - - approximately: function(a,b,precision) { - return abs(a-b) <= (precision || epsilon); - }, - - length: function(derivativeFn) { - var z=0.5,sum=0,len=utils.Tvalues.length,i,t; - for(i=0; i<len; i++) { - t = z * utils.Tvalues[i] + z; - sum += utils.Cvalues[i] * utils.arcfn(t,derivativeFn); - } - return z * sum; - }, - - map: function(v, ds,de, ts,te) { - var d1 = de-ds, d2 = te-ts, v2 = v-ds, r = v2/d1; - return ts + d2*r; - }, - - lerp: function(r, v1, v2) { - var ret = { - x: v1.x + r*(v2.x-v1.x), - y: v1.y + r*(v2.y-v1.y) - }; - if(!!v1.z && !!v2.z) { - ret.z = v1.z + r*(v2.z-v1.z); - } - return ret; - }, - - pointToString: function(p) { - var s = p.x+"/"+p.y; - if(typeof p.z !== "undefined") { - s += "/"+p.z; - } - return s; - }, - - pointsToString: function(points) { - return "[" + points.map(utils.pointToString).join(", ") + "]"; - }, - - copy: function(obj) { - return JSON.parse(JSON.stringify(obj)); - }, - - angle: function(o,v1,v2) { - var dx1 = v1.x - o.x, - dy1 = v1.y - o.y, - dx2 = v2.x - o.x, - dy2 = v2.y - o.y, - cross = dx1*dy2 - dy1*dx2, - m1 = sqrt(dx1*dx1+dy1*dy1), - m2 = sqrt(dx2*dx2+dy2*dy2), - dot; - dx1/=m1; dy1/=m1; dx2/=m2; dy2/=m2; - dot = dx1*dx2 + dy1*dy2; - return atan2(cross, dot); - }, - - // round as string, to avoid rounding errors - round: function(v, d) { - var s = '' + v; - var pos = s.indexOf("."); - return parseFloat(s.substring(0,pos+1+d)); - }, - - dist: function(p1, p2) { - var dx = p1.x - p2.x, - dy = p1.y - p2.y; - return sqrt(dx*dx+dy*dy); - }, - - closest: function(LUT, point) { - var mdist = pow(2,63), mpos, d; - LUT.forEach(function(p, idx) { - d = utils.dist(point, p); - if (d<mdist) { - mdist = d; - mpos = idx; - } - }); - return { mdist:mdist, mpos:mpos }; - }, - - abcratio: function(t, n) { - // see ratio(t) note on http://pomax.github.io/bezierinfo/#abc - if (n!==2 && n!==3) { - return false; - } - if (typeof t === "undefined") { - t = 0.5; - } else if (t===0 || t===1) { - return t; - } - var bottom = pow(t,n) + pow(1-t,n), top = bottom - 1; - return abs(top/bottom); - }, - - projectionratio: function(t, n) { - // see u(t) note on http://pomax.github.io/bezierinfo/#abc - if (n!==2 && n!==3) { - return false; - } - if (typeof t === "undefined") { - t = 0.5; - } else if (t===0 || t===1) { - return t; - } - var top = pow(1-t, n), bottom = pow(t,n) + top; - return top/bottom; - }, - - lli8: function(x1,y1,x2,y2,x3,y3,x4,y4) { - var nx=(x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4), - ny=(x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4), - d=(x1-x2)*(y3-y4)-(y1-y2)*(x3-x4); - if(d==0) { return false; } - return { x: nx/d, y: ny/d }; - }, - - lli4: function(p1,p2,p3,p4) { - var x1 = p1.x, y1 = p1.y, - x2 = p2.x, y2 = p2.y, - x3 = p3.x, y3 = p3.y, - x4 = p4.x, y4 = p4.y; - return utils.lli8(x1,y1,x2,y2,x3,y3,x4,y4); - }, - - lli: function(v1, v2) { - return utils.lli4(v1,v1.c,v2,v2.c); - }, - - makeline: function(p1,p2) { - var Bezier = __webpack_require__(70); - var x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y, dx = (x2-x1)/3, dy = (y2-y1)/3; - return new Bezier(x1, y1, x1+dx, y1+dy, x1+2*dx, y1+2*dy, x2, y2); - }, - - findbbox: function(sections) { - var mx=99999999,my=mx,MX=-mx,MY=MX; - sections.forEach(function(s) { - var bbox = s.bbox(); - if(mx > bbox.x.min) mx = bbox.x.min; - if(my > bbox.y.min) my = bbox.y.min; - if(MX < bbox.x.max) MX = bbox.x.max; - if(MY < bbox.y.max) MY = bbox.y.max; - }); - return { - x: { min: mx, mid:(mx+MX)/2, max: MX, size:MX-mx }, - y: { min: my, mid:(my+MY)/2, max: MY, size:MY-my } - } - }, - - shapeintersections: function(s1, bbox1, s2, bbox2, curveIntersectionThreshold) { - if(!utils.bboxoverlap(bbox1, bbox2)) return []; - var intersections = []; - var a1 = [s1.startcap, s1.forward, s1.back, s1.endcap]; - var a2 = [s2.startcap, s2.forward, s2.back, s2.endcap]; - a1.forEach(function(l1) { - if(l1.virtual) return; - a2.forEach(function(l2) { - if(l2.virtual) return; - var iss = l1.intersects(l2, curveIntersectionThreshold); - if(iss.length>0) { - iss.c1 = l1; - iss.c2 = l2; - iss.s1 = s1; - iss.s2 = s2; - intersections.push(iss); - } - }); - }); - return intersections; - }, - - makeshape: function(forward, back, curveIntersectionThreshold) { - var bpl = back.points.length; - var fpl = forward.points.length; - var start = utils.makeline(back.points[bpl-1], forward.points[0]); - var end = utils.makeline(forward.points[fpl-1], back.points[0]); - var shape = { - startcap: start, - forward: forward, - back: back, - endcap: end, - bbox: utils.findbbox([start, forward, back, end]) - }; - var self = utils; - shape.intersections = function(s2) { - return self.shapeintersections(shape,shape.bbox,s2,s2.bbox, curveIntersectionThreshold); - }; - return shape; - }, - - getminmax: function(curve, d, list) { - if(!list) return { min:0, max:0 }; - var min=0xFFFFFFFFFFFFFFFF, max=-min,t,c; - if(list.indexOf(0)===-1) { list = [0].concat(list); } - if(list.indexOf(1)===-1) { list.push(1); } - for(var i=0,len=list.length; i<len; i++) { - t = list[i]; - c = curve.get(t); - if(c[d] < min) { min = c[d]; } - if(c[d] > max) { max = c[d]; } - } - return { min:min, mid:(min+max)/2, max:max, size:max-min }; - }, - - align: function(points, line) { - var tx = line.p1.x, - ty = line.p1.y, - a = -atan2(line.p2.y-ty, line.p2.x-tx), - d = function(v) { - return { - x: (v.x-tx)*cos(a) - (v.y-ty)*sin(a), - y: (v.x-tx)*sin(a) + (v.y-ty)*cos(a) - }; - }; - return points.map(d); - }, - - roots: function(points, line) { - line = line || {p1:{x:0,y:0},p2:{x:1,y:0}}; - var order = points.length - 1; - var p = utils.align(points, line); - var reduce = function(t) { return 0<=t && t <=1; }; - - if (order === 2) { - var a = p[0].y, - b = p[1].y, - c = p[2].y, - d = a - 2*b + c; - if(d!==0) { - var m1 = -sqrt(b*b-a*c), - m2 = -a+b, - v1 = -( m1+m2)/d, - v2 = -(-m1+m2)/d; - return [v1, v2].filter(reduce); - } - else if(b!==c && d===0) { - return [ (2*b-c)/2*(b-c) ].filter(reduce); - } - return []; - } - - // see http://www.trans4mind.com/personal_development/mathematics/polynomials/cubicAlgebra.htm - var pa = p[0].y, - pb = p[1].y, - pc = p[2].y, - pd = p[3].y, - d = (-pa + 3*pb - 3*pc + pd), - a = (3*pa - 6*pb + 3*pc) / d, - b = (-3*pa + 3*pb) / d, - c = pa / d, - p = (3*b - a*a)/3, - p3 = p/3, - q = (2*a*a*a - 9*a*b + 27*c)/27, - q2 = q/2, - discriminant = q2*q2 + p3*p3*p3, - u1,v1,x1,x2,x3; - if (discriminant < 0) { - var mp3 = -p/3, - mp33 = mp3*mp3*mp3, - r = sqrt( mp33 ), - t = -q/(2*r), - cosphi = t<-1 ? -1 : t>1 ? 1 : t, - phi = acos(cosphi), - crtr = crt(r), - t1 = 2*crtr; - x1 = t1 * cos(phi/3) - a/3; - x2 = t1 * cos((phi+tau)/3) - a/3; - x3 = t1 * cos((phi+2*tau)/3) - a/3; - return [x1, x2, x3].filter(reduce); - } else if(discriminant === 0) { - u1 = q2 < 0 ? crt(-q2) : -crt(q2); - x1 = 2*u1-a/3; - x2 = -u1 - a/3; - return [x1,x2].filter(reduce); - } else { - var sd = sqrt(discriminant); - u1 = crt(-q2+sd); - v1 = crt(q2+sd); - return [u1-v1-a/3].filter(reduce);; - } - }, - - droots: function(p) { - // quadratic roots are easy - if(p.length === 3) { - var a = p[0], - b = p[1], - c = p[2], - d = a - 2*b + c; - if(d!==0) { - var m1 = -sqrt(b*b-a*c), - m2 = -a+b, - v1 = -( m1+m2)/d, - v2 = -(-m1+m2)/d; - return [v1, v2]; - } - else if(b!==c && d===0) { - return [(2*b-c)/(2*(b-c))]; - } - return []; - } - - // linear roots are even easier - if(p.length === 2) { - var a = p[0], b = p[1]; - if(a!==b) { - return [a/(a-b)]; - } - return []; - } - }, - - inflections: function(points) { - if (points.length<4) return []; - - // FIXME: TODO: add in inflection abstraction for quartic+ curves? - - var p = utils.align(points, { p1: points[0], p2: points.slice(-1)[0] }), - a = p[2].x * p[1].y, - b = p[3].x * p[1].y, - c = p[1].x * p[2].y, - d = p[3].x * p[2].y, - v1 = 18 * (-3*a + 2*b + 3*c - d), - v2 = 18 * (3*a - b - 3*c), - v3 = 18 * (c - a); - - if (utils.approximately(v1,0)) return []; - - var trm = v2*v2 - 4*v1*v3, - sq = Math.sqrt(trm), - d = 2 * v1; - - if (utils.approximately(d,0)) return []; - - return [(sq-v2)/d, -(v2+sq)/d].filter(function(r) { - return (0 <= r && r <= 1); - }); - }, - - bboxoverlap: function(b1,b2) { - var dims=['x','y'],len=dims.length,i,dim,l,t,d - for(i=0; i<len; i++) { - dim = dims[i]; - l = b1[dim].mid; - t = b2[dim].mid; - d = (b1[dim].size + b2[dim].size)/2; - if(abs(l-t) >= d) return false; - } - return true; - }, - - expandbox: function(bbox, _bbox) { - if(_bbox.x.min < bbox.x.min) { bbox.x.min = _bbox.x.min; } - if(_bbox.y.min < bbox.y.min) { bbox.y.min = _bbox.y.min; } - if(_bbox.z && _bbox.z.min < bbox.z.min) { bbox.z.min = _bbox.z.min; } - if(_bbox.x.max > bbox.x.max) { bbox.x.max = _bbox.x.max; } - if(_bbox.y.max > bbox.y.max) { bbox.y.max = _bbox.y.max; } - if(_bbox.z && _bbox.z.max > bbox.z.max) { bbox.z.max = _bbox.z.max; } - bbox.x.mid = (bbox.x.min + bbox.x.max)/2; - bbox.y.mid = (bbox.y.min + bbox.y.max)/2; - if(bbox.z) { bbox.z.mid = (bbox.z.min + bbox.z.max)/2; } - bbox.x.size = bbox.x.max - bbox.x.min; - bbox.y.size = bbox.y.max - bbox.y.min; - if(bbox.z) { bbox.z.size = bbox.z.max - bbox.z.min; } - }, - - pairiteration: function(c1, c2, curveIntersectionThreshold) { - var c1b = c1.bbox(), - c2b = c2.bbox(), - r = 100000, - threshold = curveIntersectionThreshold || 0.5; - if(c1b.x.size + c1b.y.size < threshold && c2b.x.size + c2b.y.size < threshold) { - return [ ((r * (c1._t1+c1._t2)/2)|0)/r + "/" + ((r * (c2._t1+c2._t2)/2)|0)/r ]; - } - var cc1 = c1.split(0.5), - cc2 = c2.split(0.5), - pairs = [ - {left: cc1.left, right: cc2.left }, - {left: cc1.left, right: cc2.right }, - {left: cc1.right, right: cc2.right }, - {left: cc1.right, right: cc2.left }]; - pairs = pairs.filter(function(pair) { - return utils.bboxoverlap(pair.left.bbox(),pair.right.bbox()); - }); - var results = []; - if(pairs.length === 0) return results; - pairs.forEach(function(pair) { - results = results.concat( - utils.pairiteration(pair.left, pair.right, threshold) - ); - }) - results = results.filter(function(v,i) { - return results.indexOf(v) === i; - }); - return results; - }, - - getccenter: function(p1,p2,p3) { - var dx1 = (p2.x - p1.x), - dy1 = (p2.y - p1.y), - dx2 = (p3.x - p2.x), - dy2 = (p3.y - p2.y); - var dx1p = dx1 * cos(quart) - dy1 * sin(quart), - dy1p = dx1 * sin(quart) + dy1 * cos(quart), - dx2p = dx2 * cos(quart) - dy2 * sin(quart), - dy2p = dx2 * sin(quart) + dy2 * cos(quart); - // chord midpoints - var mx1 = (p1.x + p2.x)/2, - my1 = (p1.y + p2.y)/2, - mx2 = (p2.x + p3.x)/2, - my2 = (p2.y + p3.y)/2; - // midpoint offsets - var mx1n = mx1 + dx1p, - my1n = my1 + dy1p, - mx2n = mx2 + dx2p, - my2n = my2 + dy2p; - // intersection of these lines: - var arc = utils.lli8(mx1,my1,mx1n,my1n, mx2,my2,mx2n,my2n), - r = utils.dist(arc,p1), - // arc start/end values, over mid point: - s = atan2(p1.y - arc.y, p1.x - arc.x), - m = atan2(p2.y - arc.y, p2.x - arc.x), - e = atan2(p3.y - arc.y, p3.x - arc.x), - _; - // determine arc direction (cw/ccw correction) - if (s<e) { - // if s<m<e, arc(s, e) - // if m<s<e, arc(e, s + tau) - // if s<e<m, arc(e, s + tau) - if (s>m || m>e) { s += tau; } - if (s>e) { _=e; e=s; s=_; } - } else { - // if e<m<s, arc(e, s) - // if m<e<s, arc(s, e + tau) - // if e<s<m, arc(s, e + tau) - if (e<m && m<s) { _=e; e=s; s=_; } else { e += tau; } - } - // assign and done. - arc.s = s; - arc.e = e; - arc.r = r; - return arc; - } - }; - - module.exports = utils; -}()); - - -/***/ }), -/* 72 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -/** - * Copyright (c) 2013-present, Facebook, 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. - * - * @typechecks - */ - -var emptyFunction = __webpack_require__(12); - -/** - * Upstream version of event listener. Does not take into account specific - * nature of platform. - */ -var EventListener = { - /** - * Listen to DOM events during the bubble phase. - * - * @param {DOMEventTarget} target DOM element to register listener on. - * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. - * @param {function} callback Callback function. - * @return {object} Object with a `remove` method. - */ - listen: function listen(target, eventType, callback) { - if (target.addEventListener) { - target.addEventListener(eventType, callback, false); - return { - remove: function remove() { - target.removeEventListener(eventType, callback, false); - } - }; - } else if (target.attachEvent) { - target.attachEvent('on' + eventType, callback); - return { - remove: function remove() { - target.detachEvent('on' + eventType, callback); - } - }; - } - }, - - /** - * Listen to DOM events during the capture phase. - * - * @param {DOMEventTarget} target DOM element to register listener on. - * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. - * @param {function} callback Callback function. - * @return {object} Object with a `remove` method. - */ - capture: function capture(target, eventType, callback) { - if (target.addEventListener) { - target.addEventListener(eventType, callback, true); - return { - remove: function remove() { - target.removeEventListener(eventType, callback, true); - } - }; - } else { - if (process.env.NODE_ENV !== 'production') { - console.error('Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.'); - } - return { - remove: emptyFunction - }; - } - }, - - registerDefault: function registerDefault() {} -}; - -module.exports = EventListener; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 73 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * @param {DOMElement} node input/textarea to focus - */ - -function focusNode(node) { - // IE8 can throw "Can't move focus to the control because it is invisible, - // not enabled, or of a type that does not accept the focus." for all kinds of - // reasons that are too expensive and fragile to test. - try { - node.focus(); - } catch (e) {} -} - -module.exports = focusNode; - -/***/ }), -/* 74 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -/* eslint-disable fb-www/typeof-undefined */ - -/** - * Same as document.activeElement but wraps in a try-catch block. In IE it is - * not safe to call document.activeElement if there is nothing focused. - * - * The activeElement will be null only if the document or document body is not - * yet defined. - */ -function getActiveElement() /*?DOMElement*/{ - if (typeof document === 'undefined') { - return null; - } - try { - return document.activeElement || document.body; - } catch (e) { - return document.body; - } -} - -module.exports = getActiveElement; - -/***/ }), -/* 75 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.addEventListener = addEventListener; -exports.removeEventListener = removeEventListener; -exports.getHashPath = getHashPath; -exports.replaceHashPath = replaceHashPath; -exports.getWindowPath = getWindowPath; -exports.go = go; -exports.getUserConfirmation = getUserConfirmation; -exports.supportsHistory = supportsHistory; -exports.supportsGoWithoutReloadUsingHash = supportsGoWithoutReloadUsingHash; - -function addEventListener(node, event, listener) { - if (node.addEventListener) { - node.addEventListener(event, listener, false); - } else { - node.attachEvent('on' + event, listener); - } -} - -function removeEventListener(node, event, listener) { - if (node.removeEventListener) { - node.removeEventListener(event, listener, false); - } else { - node.detachEvent('on' + event, listener); - } -} - -function getHashPath() { - // We can't use window.location.hash here because it's not - // consistent across browsers - Firefox will pre-decode it! - return window.location.href.split('#')[1] || ''; -} - -function replaceHashPath(path) { - window.location.replace(window.location.pathname + window.location.search + '#' + path); -} - -function getWindowPath() { - return window.location.pathname + window.location.search + window.location.hash; -} - -function go(n) { - if (n) window.history.go(n); -} - -function getUserConfirmation(message, callback) { - callback(window.confirm(message)); -} - -/** - * Returns true if the HTML5 history API is supported. Taken from Modernizr. - * - * https://github.com/Modernizr/Modernizr/blob/master/LICENSE - * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js - * changed to avoid false negatives for Windows Phones: https://github.com/rackt/react-router/issues/586 - */ - -function supportsHistory() { - var ua = navigator.userAgent; - if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) { - return false; - } - // FIXME: Work around our browser history not working correctly on Chrome - // iOS: https://github.com/rackt/react-router/issues/2565 - if (ua.indexOf('CriOS') !== -1) { - return false; - } - return window.history && 'pushState' in window.history; -} - -/** - * Returns false if using go(n) with hash history causes a full page reload. - */ - -function supportsGoWithoutReloadUsingHash() { - var ua = navigator.userAgent; - return ua.indexOf('Firefox') === -1; -} - -/***/ }), -/* 76 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -//import warning from 'warning' - - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _deepEqual = __webpack_require__(211); - -var _deepEqual2 = _interopRequireDefault(_deepEqual); - -var _AsyncUtils = __webpack_require__(228); - -var _Actions = __webpack_require__(29); - -var _createLocation2 = __webpack_require__(232); - -var _createLocation3 = _interopRequireDefault(_createLocation2); - -var _runTransitionHook = __webpack_require__(45); - -var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook); - -var _parsePath = __webpack_require__(24); - -var _parsePath2 = _interopRequireDefault(_parsePath); - -var _deprecate = __webpack_require__(44); - -var _deprecate2 = _interopRequireDefault(_deprecate); - -function createRandomKey(length) { - return Math.random().toString(36).substr(2, length); -} - -function locationsAreEqual(a, b) { - return a.pathname === b.pathname && a.search === b.search && - //a.action === b.action && // Different action !== location change. - a.key === b.key && _deepEqual2['default'](a.state, b.state); -} - -var DefaultKeyLength = 6; - -function createHistory() { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - var getCurrentLocation = options.getCurrentLocation; - var finishTransition = options.finishTransition; - var saveState = options.saveState; - var go = options.go; - var keyLength = options.keyLength; - var getUserConfirmation = options.getUserConfirmation; - - if (typeof keyLength !== 'number') keyLength = DefaultKeyLength; - - var transitionHooks = []; - - function listenBefore(hook) { - transitionHooks.push(hook); - - return function () { - transitionHooks = transitionHooks.filter(function (item) { - return item !== hook; - }); - }; - } - - var allKeys = []; - var changeListeners = []; - var location = undefined; - - function getCurrent() { - if (pendingLocation && pendingLocation.action === _Actions.POP) { - return allKeys.indexOf(pendingLocation.key); - } else if (location) { - return allKeys.indexOf(location.key); - } else { - return -1; - } - } - - function updateLocation(newLocation) { - var current = getCurrent(); - - location = newLocation; - - if (location.action === _Actions.PUSH) { - allKeys = [].concat(allKeys.slice(0, current + 1), [location.key]); - } else if (location.action === _Actions.REPLACE) { - allKeys[current] = location.key; - } - - changeListeners.forEach(function (listener) { - listener(location); - }); - } - - function listen(listener) { - changeListeners.push(listener); - - if (location) { - listener(location); - } else { - var _location = getCurrentLocation(); - allKeys = [_location.key]; - updateLocation(_location); - } - - return function () { - changeListeners = changeListeners.filter(function (item) { - return item !== listener; - }); - }; - } - - function confirmTransitionTo(location, callback) { - _AsyncUtils.loopAsync(transitionHooks.length, function (index, next, done) { - _runTransitionHook2['default'](transitionHooks[index], location, function (result) { - if (result != null) { - done(result); - } else { - next(); - } - }); - }, function (message) { - if (getUserConfirmation && typeof message === 'string') { - getUserConfirmation(message, function (ok) { - callback(ok !== false); - }); - } else { - callback(message !== false); - } - }); - } - - var pendingLocation = undefined; - - function transitionTo(nextLocation) { - if (location && locationsAreEqual(location, nextLocation)) return; // Nothing to do. - - pendingLocation = nextLocation; - - confirmTransitionTo(nextLocation, function (ok) { - if (pendingLocation !== nextLocation) return; // Transition was interrupted. - - if (ok) { - // treat PUSH to current path like REPLACE to be consistent with browsers - if (nextLocation.action === _Actions.PUSH) { - var prevPath = createPath(location); - var nextPath = createPath(nextLocation); - - if (nextPath === prevPath) nextLocation.action = _Actions.REPLACE; - } - - if (finishTransition(nextLocation) !== false) updateLocation(nextLocation); - } else if (location && nextLocation.action === _Actions.POP) { - var prevIndex = allKeys.indexOf(location.key); - var nextIndex = allKeys.indexOf(nextLocation.key); - - if (prevIndex !== -1 && nextIndex !== -1) go(prevIndex - nextIndex); // Restore the URL. - } - }); - } - - function push(location) { - transitionTo(createLocation(location, _Actions.PUSH, createKey())); - } - - function replace(location) { - transitionTo(createLocation(location, _Actions.REPLACE, createKey())); - } - - function goBack() { - go(-1); - } - - function goForward() { - go(1); - } - - function createKey() { - return createRandomKey(keyLength); - } - - function createPath(location) { - if (location == null || typeof location === 'string') return location; - - var pathname = location.pathname; - var search = location.search; - var hash = location.hash; - - var result = pathname; - - if (search) result += search; - - if (hash) result += hash; - - return result; - } - - function createHref(location) { - return createPath(location); - } - - function createLocation(location, action) { - var key = arguments.length <= 2 || arguments[2] === undefined ? createKey() : arguments[2]; - - if (typeof action === 'object') { - //warning( - // false, - // 'The state (2nd) argument to history.createLocation is deprecated; use a ' + - // 'location descriptor instead' - //) - - if (typeof location === 'string') location = _parsePath2['default'](location); - - location = _extends({}, location, { state: action }); - - action = key; - key = arguments[3] || createKey(); - } - - return _createLocation3['default'](location, action, key); - } - - // deprecated - function setState(state) { - if (location) { - updateLocationState(location, state); - updateLocation(location); - } else { - updateLocationState(getCurrentLocation(), state); - } - } - - function updateLocationState(location, state) { - location.state = _extends({}, location.state, state); - saveState(location.key, location.state); - } - - // deprecated - function registerTransitionHook(hook) { - if (transitionHooks.indexOf(hook) === -1) transitionHooks.push(hook); - } - - // deprecated - function unregisterTransitionHook(hook) { - transitionHooks = transitionHooks.filter(function (item) { - return item !== hook; - }); - } - - // deprecated - function pushState(state, path) { - if (typeof path === 'string') path = _parsePath2['default'](path); - - push(_extends({ state: state }, path)); - } - - // deprecated - function replaceState(state, path) { - if (typeof path === 'string') path = _parsePath2['default'](path); - - replace(_extends({ state: state }, path)); - } - - return { - listenBefore: listenBefore, - listen: listen, - transitionTo: transitionTo, - push: push, - replace: replace, - go: go, - goBack: goBack, - goForward: goForward, - createKey: createKey, - createPath: createPath, - createHref: createHref, - createLocation: createLocation, - - setState: _deprecate2['default'](setState, 'setState is deprecated; use location.key to save state instead'), - registerTransitionHook: _deprecate2['default'](registerTransitionHook, 'registerTransitionHook is deprecated; use listenBefore instead'), - unregisterTransitionHook: _deprecate2['default'](unregisterTransitionHook, 'unregisterTransitionHook is deprecated; use the callback returned from listenBefore instead'), - pushState: _deprecate2['default'](pushState, 'pushState is deprecated; use push instead'), - replaceState: _deprecate2['default'](replaceState, 'replaceState is deprecated; use replace instead') - }; -} - -exports['default'] = createHistory; -module.exports = exports['default']; - -/***/ }), -/* 77 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -function extractPath(string) { - var match = string.match(/^https?:\/\/[^\/]*/); - - if (match == null) return string; - - return string.substring(match[0].length); -} - -exports["default"] = extractPath; -module.exports = exports["default"]; - -/***/ }), -/* 78 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * CSS properties which accept numbers but are not in units of "px". - */ - -var isUnitlessNumber = { - animationIterationCount: true, - borderImageOutset: true, - borderImageSlice: true, - borderImageWidth: true, - boxFlex: true, - boxFlexGroup: true, - boxOrdinalGroup: true, - columnCount: true, - flex: true, - flexGrow: true, - flexPositive: true, - flexShrink: true, - flexNegative: true, - flexOrder: true, - gridRow: true, - gridColumn: true, - fontWeight: true, - lineClamp: true, - lineHeight: true, - opacity: true, - order: true, - orphans: true, - tabSize: true, - widows: true, - zIndex: true, - zoom: true, - - // SVG-related properties - fillOpacity: true, - floodOpacity: true, - stopOpacity: true, - strokeDasharray: true, - strokeDashoffset: true, - strokeMiterlimit: true, - strokeOpacity: true, - strokeWidth: true -}; - -/** - * @param {string} prefix vendor-specific prefix, eg: Webkit - * @param {string} key style name, eg: transitionDuration - * @return {string} style name prefixed with `prefix`, properly camelCased, eg: - * WebkitTransitionDuration - */ -function prefixKey(prefix, key) { - return prefix + key.charAt(0).toUpperCase() + key.substring(1); -} - -/** - * Support style names that may come passed in prefixed by adding permutations - * of vendor prefixes. - */ -var prefixes = ['Webkit', 'ms', 'Moz', 'O']; - -// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an -// infinite loop, because it iterates over the newly added props too. -Object.keys(isUnitlessNumber).forEach(function (prop) { - prefixes.forEach(function (prefix) { - isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; - }); -}); - -/** - * Most style properties can be unset by doing .style[prop] = '' but IE8 - * doesn't like doing that with shorthand properties so for the properties that - * IE8 breaks on, which are listed here, we instead unset each of the - * individual properties. See http://bugs.jquery.com/ticket/12385. - * The 4-value 'clock' properties like margin, padding, border-width seem to - * behave without any problems. Curiously, list-style works too without any - * special prodding. - */ -var shorthandPropertyExpansions = { - background: { - backgroundAttachment: true, - backgroundColor: true, - backgroundImage: true, - backgroundPositionX: true, - backgroundPositionY: true, - backgroundRepeat: true - }, - backgroundPosition: { - backgroundPositionX: true, - backgroundPositionY: true - }, - border: { - borderWidth: true, - borderStyle: true, - borderColor: true - }, - borderBottom: { - borderBottomWidth: true, - borderBottomStyle: true, - borderBottomColor: true - }, - borderLeft: { - borderLeftWidth: true, - borderLeftStyle: true, - borderLeftColor: true - }, - borderRight: { - borderRightWidth: true, - borderRightStyle: true, - borderRightColor: true - }, - borderTop: { - borderTopWidth: true, - borderTopStyle: true, - borderTopColor: true - }, - font: { - fontStyle: true, - fontVariant: true, - fontWeight: true, - fontSize: true, - lineHeight: true, - fontFamily: true - }, - outline: { - outlineWidth: true, - outlineStyle: true, - outlineColor: true - } -}; - -var CSSProperty = { - isUnitlessNumber: isUnitlessNumber, - shorthandPropertyExpansions: shorthandPropertyExpansions -}; - -module.exports = CSSProperty; - -/***/ }), -/* 79 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var PooledClass = __webpack_require__(20); - -var invariant = __webpack_require__(2); - -/** - * A specialized pseudo-event module to help keep track of components waiting to - * be notified when their DOM representations are available for use. - * - * This implements `PooledClass`, so you should never need to instantiate this. - * Instead, use `CallbackQueue.getPooled()`. - * - * @class ReactMountReady - * @implements PooledClass - * @internal - */ - -var CallbackQueue = function () { - function CallbackQueue(arg) { - _classCallCheck(this, CallbackQueue); - - this._callbacks = null; - this._contexts = null; - this._arg = arg; - } - - /** - * Enqueues a callback to be invoked when `notifyAll` is invoked. - * - * @param {function} callback Invoked when `notifyAll` is invoked. - * @param {?object} context Context to call `callback` with. - * @internal - */ - - - CallbackQueue.prototype.enqueue = function enqueue(callback, context) { - this._callbacks = this._callbacks || []; - this._callbacks.push(callback); - this._contexts = this._contexts || []; - this._contexts.push(context); - }; - - /** - * Invokes all enqueued callbacks and clears the queue. This is invoked after - * the DOM representation of a component has been created or updated. - * - * @internal - */ - - - CallbackQueue.prototype.notifyAll = function notifyAll() { - var callbacks = this._callbacks; - var contexts = this._contexts; - var arg = this._arg; - if (callbacks && contexts) { - !(callbacks.length === contexts.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Mismatched list of contexts in callback queue') : _prodInvariant('24') : void 0; - this._callbacks = null; - this._contexts = null; - for (var i = 0; i < callbacks.length; i++) { - callbacks[i].call(contexts[i], arg); - } - callbacks.length = 0; - contexts.length = 0; - } - }; - - CallbackQueue.prototype.checkpoint = function checkpoint() { - return this._callbacks ? this._callbacks.length : 0; - }; - - CallbackQueue.prototype.rollback = function rollback(len) { - if (this._callbacks && this._contexts) { - this._callbacks.length = len; - this._contexts.length = len; - } - }; - - /** - * Resets the internal queue. - * - * @internal - */ - - - CallbackQueue.prototype.reset = function reset() { - this._callbacks = null; - this._contexts = null; - }; - - /** - * `PooledClass` looks for this. - */ - - - CallbackQueue.prototype.destructor = function destructor() { - this.reset(); - }; - - return CallbackQueue; -}(); - -module.exports = PooledClass.addPoolingTo(CallbackQueue); -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 80 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMProperty = __webpack_require__(18); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactInstrumentation = __webpack_require__(10); - -var quoteAttributeValueForBrowser = __webpack_require__(307); -var warning = __webpack_require__(3); - -var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + DOMProperty.ATTRIBUTE_NAME_START_CHAR + '][' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$'); -var illegalAttributeNameCache = {}; -var validatedAttributeNameCache = {}; - -function isAttributeNameSafe(attributeName) { - if (validatedAttributeNameCache.hasOwnProperty(attributeName)) { - return true; - } - if (illegalAttributeNameCache.hasOwnProperty(attributeName)) { - return false; - } - if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { - validatedAttributeNameCache[attributeName] = true; - return true; - } - illegalAttributeNameCache[attributeName] = true; - process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid attribute name: `%s`', attributeName) : void 0; - return false; -} - -function shouldIgnoreValue(propertyInfo, value) { - return value == null || propertyInfo.hasBooleanValue && !value || propertyInfo.hasNumericValue && isNaN(value) || propertyInfo.hasPositiveNumericValue && value < 1 || propertyInfo.hasOverloadedBooleanValue && value === false; -} - -/** - * Operations for dealing with DOM properties. - */ -var DOMPropertyOperations = { - - /** - * Creates markup for the ID property. - * - * @param {string} id Unescaped ID. - * @return {string} Markup string. - */ - createMarkupForID: function (id) { - return DOMProperty.ID_ATTRIBUTE_NAME + '=' + quoteAttributeValueForBrowser(id); - }, - - setAttributeForID: function (node, id) { - node.setAttribute(DOMProperty.ID_ATTRIBUTE_NAME, id); - }, - - createMarkupForRoot: function () { - return DOMProperty.ROOT_ATTRIBUTE_NAME + '=""'; - }, - - setAttributeForRoot: function (node) { - node.setAttribute(DOMProperty.ROOT_ATTRIBUTE_NAME, ''); - }, - - /** - * Creates markup for a property. - * - * @param {string} name - * @param {*} value - * @return {?string} Markup string, or null if the property was invalid. - */ - createMarkupForProperty: function (name, value) { - var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; - if (propertyInfo) { - if (shouldIgnoreValue(propertyInfo, value)) { - return ''; - } - var attributeName = propertyInfo.attributeName; - if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { - return attributeName + '=""'; - } - return attributeName + '=' + quoteAttributeValueForBrowser(value); - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - return ''; - } - return name + '=' + quoteAttributeValueForBrowser(value); - } - return null; - }, - - /** - * Creates markup for a custom property. - * - * @param {string} name - * @param {*} value - * @return {string} Markup string, or empty string if the property was invalid. - */ - createMarkupForCustomAttribute: function (name, value) { - if (!isAttributeNameSafe(name) || value == null) { - return ''; - } - return name + '=' + quoteAttributeValueForBrowser(value); - }, - - /** - * Sets the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - * @param {*} value - */ - setValueForProperty: function (node, name, value) { - var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; - if (propertyInfo) { - var mutationMethod = propertyInfo.mutationMethod; - if (mutationMethod) { - mutationMethod(node, value); - } else if (shouldIgnoreValue(propertyInfo, value)) { - this.deleteValueForProperty(node, name); - return; - } else if (propertyInfo.mustUseProperty) { - // Contrary to `setAttribute`, object properties are properly - // `toString`ed by IE8/9. - node[propertyInfo.propertyName] = value; - } else { - var attributeName = propertyInfo.attributeName; - var namespace = propertyInfo.attributeNamespace; - // `setAttribute` with objects becomes only `[object]` in IE8/9, - // ('' + value) makes it output the correct toString()-value. - if (namespace) { - node.setAttributeNS(namespace, attributeName, '' + value); - } else if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { - node.setAttribute(attributeName, ''); - } else { - node.setAttribute(attributeName, '' + value); - } - } - } else if (DOMProperty.isCustomAttribute(name)) { - DOMPropertyOperations.setValueForAttribute(node, name, value); - return; - } - - if (process.env.NODE_ENV !== 'production') { - var payload = {}; - payload[name] = value; - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID, - type: 'update attribute', - payload: payload - }); - } - }, - - setValueForAttribute: function (node, name, value) { - if (!isAttributeNameSafe(name)) { - return; - } - if (value == null) { - node.removeAttribute(name); - } else { - node.setAttribute(name, '' + value); - } - - if (process.env.NODE_ENV !== 'production') { - var payload = {}; - payload[name] = value; - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID, - type: 'update attribute', - payload: payload - }); - } - }, - - /** - * Deletes an attributes from a node. - * - * @param {DOMElement} node - * @param {string} name - */ - deleteValueForAttribute: function (node, name) { - node.removeAttribute(name); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID, - type: 'remove attribute', - payload: name - }); - } - }, - - /** - * Deletes the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - */ - deleteValueForProperty: function (node, name) { - var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; - if (propertyInfo) { - var mutationMethod = propertyInfo.mutationMethod; - if (mutationMethod) { - mutationMethod(node, undefined); - } else if (propertyInfo.mustUseProperty) { - var propName = propertyInfo.propertyName; - if (propertyInfo.hasBooleanValue) { - node[propName] = false; - } else { - node[propName] = ''; - } - } else { - node.removeAttribute(propertyInfo.attributeName); - } - } else if (DOMProperty.isCustomAttribute(name)) { - node.removeAttribute(name); - } - - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID, - type: 'remove attribute', - payload: name - }); - } - } - -}; - -module.exports = DOMPropertyOperations; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 81 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactDOMComponentFlags = { - hasCachedChildNodes: 1 << 0 -}; - -module.exports = ReactDOMComponentFlags; - -/***/ }), -/* 82 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var LinkedValueUtils = __webpack_require__(50); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactUpdates = __webpack_require__(14); - -var warning = __webpack_require__(3); - -var didWarnValueLink = false; -var didWarnValueDefaultValue = false; - -function updateOptionsIfPendingUpdateAndMounted() { - if (this._rootNodeID && this._wrapperState.pendingUpdate) { - this._wrapperState.pendingUpdate = false; - - var props = this._currentElement.props; - var value = LinkedValueUtils.getValue(props); - - if (value != null) { - updateOptions(this, Boolean(props.multiple), value); - } - } -} - -function getDeclarationErrorAddendum(owner) { - if (owner) { - var name = owner.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -var valuePropNames = ['value', 'defaultValue']; - -/** - * Validation function for `value` and `defaultValue`. - * @private - */ -function checkSelectPropTypes(inst, props) { - var owner = inst._currentElement._owner; - LinkedValueUtils.checkPropTypes('select', props, owner); - - if (props.valueLink !== undefined && !didWarnValueLink) { - process.env.NODE_ENV !== 'production' ? warning(false, '`valueLink` prop on `select` is deprecated; set `value` and `onChange` instead.') : void 0; - didWarnValueLink = true; - } - - for (var i = 0; i < valuePropNames.length; i++) { - var propName = valuePropNames[i]; - if (props[propName] == null) { - continue; - } - var isArray = Array.isArray(props[propName]); - if (props.multiple && !isArray) { - process.env.NODE_ENV !== 'production' ? warning(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum(owner)) : void 0; - } else if (!props.multiple && isArray) { - process.env.NODE_ENV !== 'production' ? warning(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum(owner)) : void 0; - } - } -} - -/** - * @param {ReactDOMComponent} inst - * @param {boolean} multiple - * @param {*} propValue A stringable (with `multiple`, a list of stringables). - * @private - */ -function updateOptions(inst, multiple, propValue) { - var selectedValue, i; - var options = ReactDOMComponentTree.getNodeFromInstance(inst).options; - - if (multiple) { - selectedValue = {}; - for (i = 0; i < propValue.length; i++) { - selectedValue['' + propValue[i]] = true; - } - for (i = 0; i < options.length; i++) { - var selected = selectedValue.hasOwnProperty(options[i].value); - if (options[i].selected !== selected) { - options[i].selected = selected; - } - } - } else { - // Do not set `select.value` as exact behavior isn't consistent across all - // browsers for all cases. - selectedValue = '' + propValue; - for (i = 0; i < options.length; i++) { - if (options[i].value === selectedValue) { - options[i].selected = true; - return; - } - } - if (options.length) { - options[0].selected = true; - } - } -} - -/** - * Implements a <select> host component that allows optionally setting the - * props `value` and `defaultValue`. If `multiple` is false, the prop must be a - * stringable. If `multiple` is true, the prop must be an array of stringables. - * - * If `value` is not supplied (or null/undefined), user actions that change the - * selected option will trigger updates to the rendered options. - * - * If it is supplied (and not null/undefined), the rendered options will not - * update in response to user actions. Instead, the `value` prop must change in - * order for the rendered options to update. - * - * If `defaultValue` is provided, any options with the supplied values will be - * selected. - */ -var ReactDOMSelect = { - getHostProps: function (inst, props) { - return _assign({}, props, { - onChange: inst._wrapperState.onChange, - value: undefined - }); - }, - - mountWrapper: function (inst, props) { - if (process.env.NODE_ENV !== 'production') { - checkSelectPropTypes(inst, props); - } - - var value = LinkedValueUtils.getValue(props); - inst._wrapperState = { - pendingUpdate: false, - initialValue: value != null ? value : props.defaultValue, - listeners: null, - onChange: _handleChange.bind(inst), - wasMultiple: Boolean(props.multiple) - }; - - if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0; - didWarnValueDefaultValue = true; - } - }, - - getSelectValueContext: function (inst) { - // ReactDOMOption looks at this initial value so the initial generated - // markup has correct `selected` attributes - return inst._wrapperState.initialValue; - }, - - postUpdateWrapper: function (inst) { - var props = inst._currentElement.props; - - // After the initial mount, we control selected-ness manually so don't pass - // this value down - inst._wrapperState.initialValue = undefined; - - var wasMultiple = inst._wrapperState.wasMultiple; - inst._wrapperState.wasMultiple = Boolean(props.multiple); - - var value = LinkedValueUtils.getValue(props); - if (value != null) { - inst._wrapperState.pendingUpdate = false; - updateOptions(inst, Boolean(props.multiple), value); - } else if (wasMultiple !== Boolean(props.multiple)) { - // For simplicity, reapply `defaultValue` if `multiple` is toggled. - if (props.defaultValue != null) { - updateOptions(inst, Boolean(props.multiple), props.defaultValue); - } else { - // Revert the select back to its default unselected state. - updateOptions(inst, Boolean(props.multiple), props.multiple ? [] : ''); - } - } - } -}; - -function _handleChange(event) { - var props = this._currentElement.props; - var returnValue = LinkedValueUtils.executeOnChange(props, event); - - if (this._rootNodeID) { - this._wrapperState.pendingUpdate = true; - } - ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this); - return returnValue; -} - -module.exports = ReactDOMSelect; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 83 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var emptyComponentFactory; - -var ReactEmptyComponentInjection = { - injectEmptyComponentFactory: function (factory) { - emptyComponentFactory = factory; - } -}; - -var ReactEmptyComponent = { - create: function (instantiate) { - return emptyComponentFactory(instantiate); - } -}; - -ReactEmptyComponent.injection = ReactEmptyComponentInjection; - -module.exports = ReactEmptyComponent; - -/***/ }), -/* 84 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactFeatureFlags = { - // When true, call console.time() before and .timeEnd() after each top-level - // render (both initial renders and updates). Useful when looking at prod-mode - // timeline profiles in Chrome, for example. - logTopLevelRenders: false -}; - -module.exports = ReactFeatureFlags; - -/***/ }), -/* 85 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -var genericComponentClass = null; -var textComponentClass = null; - -var ReactHostComponentInjection = { - // This accepts a class that receives the tag string. This is a catch all - // that can render any kind of tag. - injectGenericComponentClass: function (componentClass) { - genericComponentClass = componentClass; - }, - // This accepts a text component class that takes the text string to be - // rendered as props. - injectTextComponentClass: function (componentClass) { - textComponentClass = componentClass; - } -}; - -/** - * Get a host internal component class for a specific tag. - * - * @param {ReactElement} element The element to create. - * @return {function} The internal class constructor function. - */ -function createInternalComponent(element) { - !genericComponentClass ? process.env.NODE_ENV !== 'production' ? invariant(false, 'There is no registered component for the tag %s', element.type) : _prodInvariant('111', element.type) : void 0; - return new genericComponentClass(element); -} - -/** - * @param {ReactText} text - * @return {ReactComponent} - */ -function createInstanceForText(text) { - return new textComponentClass(text); -} - -/** - * @param {ReactComponent} component - * @return {boolean} - */ -function isTextComponent(component) { - return component instanceof textComponentClass; -} - -var ReactHostComponent = { - createInternalComponent: createInternalComponent, - createInstanceForText: createInstanceForText, - isTextComponent: isTextComponent, - injection: ReactHostComponentInjection -}; - -module.exports = ReactHostComponent; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 86 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactDOMSelection = __webpack_require__(261); - -var containsNode = __webpack_require__(216); -var focusNode = __webpack_require__(73); -var getActiveElement = __webpack_require__(74); - -function isInDocument(node) { - return containsNode(document.documentElement, node); -} - -/** - * @ReactInputSelection: React input selection module. Based on Selection.js, - * but modified to be suitable for react and has a couple of bug fixes (doesn't - * assume buttons have range selections allowed). - * Input selection module for React. - */ -var ReactInputSelection = { - - hasSelectionCapabilities: function (elem) { - var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); - return nodeName && (nodeName === 'input' && elem.type === 'text' || nodeName === 'textarea' || elem.contentEditable === 'true'); - }, - - getSelectionInformation: function () { - var focusedElem = getActiveElement(); - return { - focusedElem: focusedElem, - selectionRange: ReactInputSelection.hasSelectionCapabilities(focusedElem) ? ReactInputSelection.getSelection(focusedElem) : null - }; - }, - - /** - * @restoreSelection: If any selection information was potentially lost, - * restore it. This is useful when performing operations that could remove dom - * nodes and place them back in, resulting in focus being lost. - */ - restoreSelection: function (priorSelectionInformation) { - var curFocusedElem = getActiveElement(); - var priorFocusedElem = priorSelectionInformation.focusedElem; - var priorSelectionRange = priorSelectionInformation.selectionRange; - if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) { - if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) { - ReactInputSelection.setSelection(priorFocusedElem, priorSelectionRange); - } - focusNode(priorFocusedElem); - } - }, - - /** - * @getSelection: Gets the selection bounds of a focused textarea, input or - * contentEditable node. - * -@input: Look up selection bounds of this input - * -@return {start: selectionStart, end: selectionEnd} - */ - getSelection: function (input) { - var selection; - - if ('selectionStart' in input) { - // Modern browser with input or textarea. - selection = { - start: input.selectionStart, - end: input.selectionEnd - }; - } else if (document.selection && input.nodeName && input.nodeName.toLowerCase() === 'input') { - // IE8 input. - var range = document.selection.createRange(); - // There can only be one selection per document in IE, so it must - // be in our element. - if (range.parentElement() === input) { - selection = { - start: -range.moveStart('character', -input.value.length), - end: -range.moveEnd('character', -input.value.length) - }; - } - } else { - // Content editable or old IE textarea. - selection = ReactDOMSelection.getOffsets(input); - } - - return selection || { start: 0, end: 0 }; - }, - - /** - * @setSelection: Sets the selection bounds of a textarea or input and focuses - * the input. - * -@input Set selection bounds of this input or textarea - * -@offsets Object of same form that is returned from get* - */ - setSelection: function (input, offsets) { - var start = offsets.start; - var end = offsets.end; - if (end === undefined) { - end = start; - } - - if ('selectionStart' in input) { - input.selectionStart = start; - input.selectionEnd = Math.min(end, input.value.length); - } else if (document.selection && input.nodeName && input.nodeName.toLowerCase() === 'input') { - var range = input.createTextRange(); - range.collapse(true); - range.moveStart('character', start); - range.moveEnd('character', end - start); - range.select(); - } else { - ReactDOMSelection.setOffsets(input, offsets); - } - } -}; - -module.exports = ReactInputSelection; - -/***/ }), -/* 87 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var DOMLazyTree = __webpack_require__(25); -var DOMProperty = __webpack_require__(18); -var React = __webpack_require__(27); -var ReactBrowserEventEmitter = __webpack_require__(36); -var ReactCurrentOwner = __webpack_require__(15); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactDOMContainerInfo = __webpack_require__(253); -var ReactDOMFeatureFlags = __webpack_require__(255); -var ReactFeatureFlags = __webpack_require__(84); -var ReactInstanceMap = __webpack_require__(32); -var ReactInstrumentation = __webpack_require__(10); -var ReactMarkupChecksum = __webpack_require__(275); -var ReactReconciler = __webpack_require__(26); -var ReactUpdateQueue = __webpack_require__(53); -var ReactUpdates = __webpack_require__(14); - -var emptyObject = __webpack_require__(28); -var instantiateReactComponent = __webpack_require__(95); -var invariant = __webpack_require__(2); -var setInnerHTML = __webpack_require__(40); -var shouldUpdateReactComponent = __webpack_require__(59); -var warning = __webpack_require__(3); - -var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; -var ROOT_ATTR_NAME = DOMProperty.ROOT_ATTRIBUTE_NAME; - -var ELEMENT_NODE_TYPE = 1; -var DOC_NODE_TYPE = 9; -var DOCUMENT_FRAGMENT_NODE_TYPE = 11; - -var instancesByReactRootID = {}; - -/** - * Finds the index of the first character - * that's not common between the two given strings. - * - * @return {number} the index of the character where the strings diverge - */ -function firstDifferenceIndex(string1, string2) { - var minLen = Math.min(string1.length, string2.length); - for (var i = 0; i < minLen; i++) { - if (string1.charAt(i) !== string2.charAt(i)) { - return i; - } - } - return string1.length === string2.length ? -1 : minLen; -} - -/** - * @param {DOMElement|DOMDocument} container DOM element that may contain - * a React component - * @return {?*} DOM element that may have the reactRoot ID, or null. - */ -function getReactRootElementInContainer(container) { - if (!container) { - return null; - } - - if (container.nodeType === DOC_NODE_TYPE) { - return container.documentElement; - } else { - return container.firstChild; - } -} - -function internalGetID(node) { - // If node is something like a window, document, or text node, none of - // which support attributes or a .getAttribute method, gracefully return - // the empty string, as if the attribute were missing. - return node.getAttribute && node.getAttribute(ATTR_NAME) || ''; -} - -/** - * Mounts this component and inserts it into the DOM. - * - * @param {ReactComponent} componentInstance The instance to mount. - * @param {DOMElement} container DOM element to mount into. - * @param {ReactReconcileTransaction} transaction - * @param {boolean} shouldReuseMarkup If true, do not insert markup - */ -function mountComponentIntoNode(wrapperInstance, container, transaction, shouldReuseMarkup, context) { - var markerName; - if (ReactFeatureFlags.logTopLevelRenders) { - var wrappedElement = wrapperInstance._currentElement.props.child; - var type = wrappedElement.type; - markerName = 'React mount: ' + (typeof type === 'string' ? type : type.displayName || type.name); - console.time(markerName); - } - - var markup = ReactReconciler.mountComponent(wrapperInstance, transaction, null, ReactDOMContainerInfo(wrapperInstance, container), context, 0 /* parentDebugID */ - ); - - if (markerName) { - console.timeEnd(markerName); - } - - wrapperInstance._renderedComponent._topLevelWrapper = wrapperInstance; - ReactMount._mountImageIntoNode(markup, container, wrapperInstance, shouldReuseMarkup, transaction); -} - -/** - * Batched mount. - * - * @param {ReactComponent} componentInstance The instance to mount. - * @param {DOMElement} container DOM element to mount into. - * @param {boolean} shouldReuseMarkup If true, do not insert markup - */ -function batchedMountComponentIntoNode(componentInstance, container, shouldReuseMarkup, context) { - var transaction = ReactUpdates.ReactReconcileTransaction.getPooled( - /* useCreateElement */ - !shouldReuseMarkup && ReactDOMFeatureFlags.useCreateElement); - transaction.perform(mountComponentIntoNode, null, componentInstance, container, transaction, shouldReuseMarkup, context); - ReactUpdates.ReactReconcileTransaction.release(transaction); -} - -/** - * Unmounts a component and removes it from the DOM. - * - * @param {ReactComponent} instance React component instance. - * @param {DOMElement} container DOM element to unmount from. - * @final - * @internal - * @see {ReactMount.unmountComponentAtNode} - */ -function unmountComponentFromNode(instance, container, safely) { - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onBeginFlush(); - } - ReactReconciler.unmountComponent(instance, safely); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onEndFlush(); - } - - if (container.nodeType === DOC_NODE_TYPE) { - container = container.documentElement; - } - - // http://jsperf.com/emptying-a-node - while (container.lastChild) { - container.removeChild(container.lastChild); - } -} - -/** - * True if the supplied DOM node has a direct React-rendered child that is - * not a React root element. Useful for warning in `render`, - * `unmountComponentAtNode`, etc. - * - * @param {?DOMElement} node The candidate DOM node. - * @return {boolean} True if the DOM element contains a direct child that was - * rendered by React but is not a root element. - * @internal - */ -function hasNonRootReactChild(container) { - var rootEl = getReactRootElementInContainer(container); - if (rootEl) { - var inst = ReactDOMComponentTree.getInstanceFromNode(rootEl); - return !!(inst && inst._hostParent); - } -} - -/** - * True if the supplied DOM node is a React DOM element and - * it has been rendered by another copy of React. - * - * @param {?DOMElement} node The candidate DOM node. - * @return {boolean} True if the DOM has been rendered by another copy of React - * @internal - */ -function nodeIsRenderedByOtherInstance(container) { - var rootEl = getReactRootElementInContainer(container); - return !!(rootEl && isReactNode(rootEl) && !ReactDOMComponentTree.getInstanceFromNode(rootEl)); -} - -/** - * True if the supplied DOM node is a valid node element. - * - * @param {?DOMElement} node The candidate DOM node. - * @return {boolean} True if the DOM is a valid DOM node. - * @internal - */ -function isValidContainer(node) { - return !!(node && (node.nodeType === ELEMENT_NODE_TYPE || node.nodeType === DOC_NODE_TYPE || node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)); -} - -/** - * True if the supplied DOM node is a valid React node element. - * - * @param {?DOMElement} node The candidate DOM node. - * @return {boolean} True if the DOM is a valid React DOM node. - * @internal - */ -function isReactNode(node) { - return isValidContainer(node) && (node.hasAttribute(ROOT_ATTR_NAME) || node.hasAttribute(ATTR_NAME)); -} - -function getHostRootInstanceInContainer(container) { - var rootEl = getReactRootElementInContainer(container); - var prevHostInstance = rootEl && ReactDOMComponentTree.getInstanceFromNode(rootEl); - return prevHostInstance && !prevHostInstance._hostParent ? prevHostInstance : null; -} - -function getTopLevelWrapperInContainer(container) { - var root = getHostRootInstanceInContainer(container); - return root ? root._hostContainerInfo._topLevelWrapper : null; -} - -/** - * Temporary (?) hack so that we can store all top-level pending updates on - * composites instead of having to worry about different types of components - * here. - */ -var topLevelRootCounter = 1; -var TopLevelWrapper = function () { - this.rootID = topLevelRootCounter++; -}; -TopLevelWrapper.prototype.isReactComponent = {}; -if (process.env.NODE_ENV !== 'production') { - TopLevelWrapper.displayName = 'TopLevelWrapper'; -} -TopLevelWrapper.prototype.render = function () { - return this.props.child; -}; -TopLevelWrapper.isReactTopLevelWrapper = true; - -/** - * Mounting is the process of initializing a React component by creating its - * representative DOM elements and inserting them into a supplied `container`. - * Any prior content inside `container` is destroyed in the process. - * - * ReactMount.render( - * component, - * document.getElementById('container') - * ); - * - * <div id="container"> <-- Supplied `container`. - * <div data-reactid=".3"> <-- Rendered reactRoot of React - * // ... component. - * </div> - * </div> - * - * Inside of `container`, the first element rendered is the "reactRoot". - */ -var ReactMount = { - - TopLevelWrapper: TopLevelWrapper, - - /** - * Used by devtools. The keys are not important. - */ - _instancesByReactRootID: instancesByReactRootID, - - /** - * This is a hook provided to support rendering React components while - * ensuring that the apparent scroll position of its `container` does not - * change. - * - * @param {DOMElement} container The `container` being rendered into. - * @param {function} renderCallback This must be called once to do the render. - */ - scrollMonitor: function (container, renderCallback) { - renderCallback(); - }, - - /** - * Take a component that's already mounted into the DOM and replace its props - * @param {ReactComponent} prevComponent component instance already in the DOM - * @param {ReactElement} nextElement component instance to render - * @param {DOMElement} container container to render into - * @param {?function} callback function triggered on completion - */ - _updateRootComponent: function (prevComponent, nextElement, nextContext, container, callback) { - ReactMount.scrollMonitor(container, function () { - ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement, nextContext); - if (callback) { - ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback); - } - }); - - return prevComponent; - }, - - /** - * Render a new component into the DOM. Hooked by hooks! - * - * @param {ReactElement} nextElement element to render - * @param {DOMElement} container container to render into - * @param {boolean} shouldReuseMarkup if we should skip the markup insertion - * @return {ReactComponent} nextComponent - */ - _renderNewRootComponent: function (nextElement, container, shouldReuseMarkup, context) { - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. - process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, '_renderNewRootComponent(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from ' + 'render is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : void 0; - - !isValidContainer(container) ? process.env.NODE_ENV !== 'production' ? invariant(false, '_registerComponent(...): Target container is not a DOM element.') : _prodInvariant('37') : void 0; - - ReactBrowserEventEmitter.ensureScrollValueMonitoring(); - var componentInstance = instantiateReactComponent(nextElement, false); - - // The initial render is synchronous but any updates that happen during - // rendering, in componentWillMount or componentDidMount, will be batched - // according to the current batching strategy. - - ReactUpdates.batchedUpdates(batchedMountComponentIntoNode, componentInstance, container, shouldReuseMarkup, context); - - var wrapperID = componentInstance._instance.rootID; - instancesByReactRootID[wrapperID] = componentInstance; - - return componentInstance; - }, - - /** - * Renders a React component into the DOM in the supplied `container`. - * - * If the React component was previously rendered into `container`, this will - * perform an update on it and only mutate the DOM as necessary to reflect the - * latest React component. - * - * @param {ReactComponent} parentComponent The conceptual parent of this render tree. - * @param {ReactElement} nextElement Component element to render. - * @param {DOMElement} container DOM element to render into. - * @param {?function} callback function triggered on completion - * @return {ReactComponent} Component instance rendered in `container`. - */ - renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) { - !(parentComponent != null && ReactInstanceMap.has(parentComponent)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'parentComponent must be a valid React Component') : _prodInvariant('38') : void 0; - return ReactMount._renderSubtreeIntoContainer(parentComponent, nextElement, container, callback); - }, - - _renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) { - ReactUpdateQueue.validateCallback(callback, 'ReactDOM.render'); - !React.isValidElement(nextElement) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOM.render(): Invalid component element.%s', typeof nextElement === 'string' ? ' Instead of passing a string like \'div\', pass ' + 'React.createElement(\'div\') or <div />.' : typeof nextElement === 'function' ? ' Instead of passing a class like Foo, pass ' + 'React.createElement(Foo) or <Foo />.' : - // Check if it quacks like an element - nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : _prodInvariant('39', typeof nextElement === 'string' ? ' Instead of passing a string like \'div\', pass ' + 'React.createElement(\'div\') or <div />.' : typeof nextElement === 'function' ? ' Instead of passing a class like Foo, pass ' + 'React.createElement(Foo) or <Foo />.' : nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : void 0; - - process.env.NODE_ENV !== 'production' ? warning(!container || !container.tagName || container.tagName.toUpperCase() !== 'BODY', 'render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.') : void 0; - - var nextWrappedElement = React.createElement(TopLevelWrapper, { child: nextElement }); - - var nextContext; - if (parentComponent) { - var parentInst = ReactInstanceMap.get(parentComponent); - nextContext = parentInst._processChildContext(parentInst._context); - } else { - nextContext = emptyObject; - } - - var prevComponent = getTopLevelWrapperInContainer(container); - - if (prevComponent) { - var prevWrappedElement = prevComponent._currentElement; - var prevElement = prevWrappedElement.props.child; - if (shouldUpdateReactComponent(prevElement, nextElement)) { - var publicInst = prevComponent._renderedComponent.getPublicInstance(); - var updatedCallback = callback && function () { - callback.call(publicInst); - }; - ReactMount._updateRootComponent(prevComponent, nextWrappedElement, nextContext, container, updatedCallback); - return publicInst; - } else { - ReactMount.unmountComponentAtNode(container); - } - } - - var reactRootElement = getReactRootElementInContainer(container); - var containerHasReactMarkup = reactRootElement && !!internalGetID(reactRootElement); - var containerHasNonRootReactChild = hasNonRootReactChild(container); - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(!containerHasNonRootReactChild, 'render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.') : void 0; - - if (!containerHasReactMarkup || reactRootElement.nextSibling) { - var rootElementSibling = reactRootElement; - while (rootElementSibling) { - if (internalGetID(rootElementSibling)) { - process.env.NODE_ENV !== 'production' ? warning(false, 'render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.') : void 0; - break; - } - rootElementSibling = rootElementSibling.nextSibling; - } - } - } - - var shouldReuseMarkup = containerHasReactMarkup && !prevComponent && !containerHasNonRootReactChild; - var component = ReactMount._renderNewRootComponent(nextWrappedElement, container, shouldReuseMarkup, nextContext)._renderedComponent.getPublicInstance(); - if (callback) { - callback.call(component); - } - return component; - }, - - /** - * Renders a React component into the DOM in the supplied `container`. - * See https://facebook.github.io/react/docs/top-level-api.html#reactdom.render - * - * If the React component was previously rendered into `container`, this will - * perform an update on it and only mutate the DOM as necessary to reflect the - * latest React component. - * - * @param {ReactElement} nextElement Component element to render. - * @param {DOMElement} container DOM element to render into. - * @param {?function} callback function triggered on completion - * @return {ReactComponent} Component instance rendered in `container`. - */ - render: function (nextElement, container, callback) { - return ReactMount._renderSubtreeIntoContainer(null, nextElement, container, callback); - }, - - /** - * Unmounts and destroys the React component rendered in the `container`. - * See https://facebook.github.io/react/docs/top-level-api.html#reactdom.unmountcomponentatnode - * - * @param {DOMElement} container DOM element containing a React component. - * @return {boolean} True if a component was found in and unmounted from - * `container` - */ - unmountComponentAtNode: function (container) { - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. (Strictly speaking, unmounting won't cause a - // render but we still don't expect to be in a render call here.) - process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, 'unmountComponentAtNode(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from render ' + 'is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : void 0; - - !isValidContainer(container) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : _prodInvariant('40') : void 0; - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(!nodeIsRenderedByOtherInstance(container), 'unmountComponentAtNode(): The node you\'re attempting to unmount ' + 'was rendered by another copy of React.') : void 0; - } - - var prevComponent = getTopLevelWrapperInContainer(container); - if (!prevComponent) { - // Check if the node being unmounted was rendered by React, but isn't a - // root node. - var containerHasNonRootReactChild = hasNonRootReactChild(container); - - // Check if the container itself is a React root node. - var isContainerReactRoot = container.nodeType === 1 && container.hasAttribute(ROOT_ATTR_NAME); - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(!containerHasNonRootReactChild, 'unmountComponentAtNode(): The node you\'re attempting to unmount ' + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.') : void 0; - } - - return false; - } - delete instancesByReactRootID[prevComponent._instance.rootID]; - ReactUpdates.batchedUpdates(unmountComponentFromNode, prevComponent, container, false); - return true; - }, - - _mountImageIntoNode: function (markup, container, instance, shouldReuseMarkup, transaction) { - !isValidContainer(container) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mountComponentIntoNode(...): Target container is not valid.') : _prodInvariant('41') : void 0; - - if (shouldReuseMarkup) { - var rootElement = getReactRootElementInContainer(container); - if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) { - ReactDOMComponentTree.precacheNode(instance, rootElement); - return; - } else { - var checksum = rootElement.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); - rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); - - var rootMarkup = rootElement.outerHTML; - rootElement.setAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME, checksum); - - var normalizedMarkup = markup; - if (process.env.NODE_ENV !== 'production') { - // because rootMarkup is retrieved from the DOM, various normalizations - // will have occurred which will not be present in `markup`. Here, - // insert markup into a <div> or <iframe> depending on the container - // type to perform the same normalizations before comparing. - var normalizer; - if (container.nodeType === ELEMENT_NODE_TYPE) { - normalizer = document.createElement('div'); - normalizer.innerHTML = markup; - normalizedMarkup = normalizer.innerHTML; - } else { - normalizer = document.createElement('iframe'); - document.body.appendChild(normalizer); - normalizer.contentDocument.write(markup); - normalizedMarkup = normalizer.contentDocument.documentElement.outerHTML; - document.body.removeChild(normalizer); - } - } - - var diffIndex = firstDifferenceIndex(normalizedMarkup, rootMarkup); - var difference = ' (client) ' + normalizedMarkup.substring(diffIndex - 20, diffIndex + 20) + '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20); - - !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\'re trying to render a component to the document using server rendering but the checksum was invalid. This usually means you rendered a different component type or props on the client from the one on the server, or your render() methods are impure. React cannot handle this case due to cross-browser quirks by rendering at the document root. You should look for environment dependent code in your components and ensure the props are the same client and server side:\n%s', difference) : _prodInvariant('42', difference) : void 0; - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(false, 'React attempted to reuse markup in a container but the ' + 'checksum was invalid. This generally means that you are ' + 'using server rendering and the markup generated on the ' + 'server was not what the client was expecting. React injected ' + 'new markup to compensate which works but you have lost many ' + 'of the benefits of server rendering. Instead, figure out ' + 'why the markup being generated is different on the client ' + 'or server:\n%s', difference) : void 0; - } - } - } - - !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\'re trying to render a component to the document but you didn\'t use server rendering. We can\'t do this without using server rendering due to cross-browser quirks. See ReactDOMServer.renderToString() for server rendering.') : _prodInvariant('43') : void 0; - - if (transaction.useCreateElement) { - while (container.lastChild) { - container.removeChild(container.lastChild); - } - DOMLazyTree.insertTreeBefore(container, markup, null); - } else { - setInnerHTML(container, markup); - ReactDOMComponentTree.precacheNode(instance, container.firstChild); - } - - if (process.env.NODE_ENV !== 'production') { - var hostNode = ReactDOMComponentTree.getInstanceFromNode(container.firstChild); - if (hostNode._debugID !== 0) { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: hostNode._debugID, - type: 'mount', - payload: markup.toString() - }); - } - } - } -}; - -module.exports = ReactMount; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 88 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var React = __webpack_require__(27); - -var invariant = __webpack_require__(2); - -var ReactNodeTypes = { - HOST: 0, - COMPOSITE: 1, - EMPTY: 2, - - getType: function (node) { - if (node === null || node === false) { - return ReactNodeTypes.EMPTY; - } else if (React.isValidElement(node)) { - if (typeof node.type === 'function') { - return ReactNodeTypes.COMPOSITE; - } else { - return ReactNodeTypes.HOST; - } - } - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Unexpected node: %s', node) : _prodInvariant('26', node) : void 0; - } -}; - -module.exports = ReactNodeTypes; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 89 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; - -module.exports = ReactPropTypesSecret; - -/***/ }), -/* 90 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ViewportMetrics = { - - currentScrollLeft: 0, - - currentScrollTop: 0, - - refreshScrollValues: function (scrollPosition) { - ViewportMetrics.currentScrollLeft = scrollPosition.x; - ViewportMetrics.currentScrollTop = scrollPosition.y; - } - -}; - -module.exports = ViewportMetrics; - -/***/ }), -/* 91 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -/** - * Accumulates items that must not be null or undefined into the first one. This - * is used to conserve memory by avoiding array allocations, and thus sacrifices - * API cleanness. Since `current` can be null before being passed in and not - * null after this function, make sure to assign it back to `current`: - * - * `a = accumulateInto(a, b);` - * - * This API should be sparingly used. Try `accumulate` for something cleaner. - * - * @return {*|array<*>} An accumulation of items. - */ - -function accumulateInto(current, next) { - !(next != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : _prodInvariant('30') : void 0; - - if (current == null) { - return next; - } - - // Both are not empty. Warning: Never call x.concat(y) when you are not - // certain that x is an Array (x could be a string with concat method). - if (Array.isArray(current)) { - if (Array.isArray(next)) { - current.push.apply(current, next); - return current; - } - current.push(next); - return current; - } - - if (Array.isArray(next)) { - // A bit too dangerous to mutate `next`. - return [current].concat(next); - } - - return [current, next]; -} - -module.exports = accumulateInto; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 92 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/** - * @param {array} arr an "accumulation" of items which is either an Array or - * a single item. Useful when paired with the `accumulate` module. This is a - * simple utility that allows us to reason about a collection of items, but - * handling the case when there is exactly one item (and we do not need to - * allocate an array). - */ - -function forEachAccumulated(arr, cb, scope) { - if (Array.isArray(arr)) { - arr.forEach(cb, scope); - } else if (arr) { - cb.call(scope, arr); - } -} - -module.exports = forEachAccumulated; - -/***/ }), -/* 93 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactNodeTypes = __webpack_require__(88); - -function getHostComponentFromComposite(inst) { - var type; - - while ((type = inst._renderedNodeType) === ReactNodeTypes.COMPOSITE) { - inst = inst._renderedComponent; - } - - if (type === ReactNodeTypes.HOST) { - return inst._renderedComponent; - } else if (type === ReactNodeTypes.EMPTY) { - return null; - } -} - -module.exports = getHostComponentFromComposite; - -/***/ }), -/* 94 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ExecutionEnvironment = __webpack_require__(8); - -var contentKey = null; - -/** - * Gets the key used to access text content on a DOM node. - * - * @return {?string} Key used to access text content. - * @internal - */ -function getTextContentAccessor() { - if (!contentKey && ExecutionEnvironment.canUseDOM) { - // Prefer textContent to innerText because many browsers support both but - // SVG <text> elements don't support innerText even when <div> does. - contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText'; - } - return contentKey; -} - -module.exports = getTextContentAccessor; - -/***/ }), -/* 95 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var ReactCompositeComponent = __webpack_require__(250); -var ReactEmptyComponent = __webpack_require__(83); -var ReactHostComponent = __webpack_require__(85); - -var getNextDebugID = __webpack_require__(304); -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -// To avoid a cyclic dependency, we create the final class in this module -var ReactCompositeComponentWrapper = function (element) { - this.construct(element); -}; -_assign(ReactCompositeComponentWrapper.prototype, ReactCompositeComponent, { - _instantiateReactComponent: instantiateReactComponent -}); - -function getDeclarationErrorAddendum(owner) { - if (owner) { - var name = owner.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -/** - * Check if the type reference is a known internal type. I.e. not a user - * provided composite type. - * - * @param {function} type - * @return {boolean} Returns true if this is a valid internal type. - */ -function isInternalComponentType(type) { - return typeof type === 'function' && typeof type.prototype !== 'undefined' && typeof type.prototype.mountComponent === 'function' && typeof type.prototype.receiveComponent === 'function'; -} - -/** - * Given a ReactNode, create an instance that will actually be mounted. - * - * @param {ReactNode} node - * @param {boolean} shouldHaveDebugID - * @return {object} A new instance of the element's constructor. - * @protected - */ -function instantiateReactComponent(node, shouldHaveDebugID) { - var instance; - - if (node === null || node === false) { - instance = ReactEmptyComponent.create(instantiateReactComponent); - } else if (typeof node === 'object') { - var element = node; - var type = element.type; - if (typeof type !== 'function' && typeof type !== 'string') { - var info = ''; - if (process.env.NODE_ENV !== 'production') { - if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { - info += ' You likely forgot to export your component from the file ' + 'it\'s defined in.'; - } - } - info += getDeclarationErrorAddendum(element._owner); - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s', type == null ? type : typeof type, info) : _prodInvariant('130', type == null ? type : typeof type, info) : void 0; - } - - // Special case string values - if (typeof element.type === 'string') { - instance = ReactHostComponent.createInternalComponent(element); - } else if (isInternalComponentType(element.type)) { - // This is temporarily available for custom components that are not string - // representations. I.e. ART. Once those are updated to use the string - // representation, we can drop this code path. - instance = new element.type(element); - - // We renamed this. Allow the old name for compat. :( - if (!instance.getHostNode) { - instance.getHostNode = instance.getNativeNode; - } - } else { - instance = new ReactCompositeComponentWrapper(element); - } - } else if (typeof node === 'string' || typeof node === 'number') { - instance = ReactHostComponent.createInstanceForText(node); - } else { - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Encountered invalid React node of type %s', typeof node) : _prodInvariant('131', typeof node) : void 0; - } - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(typeof instance.mountComponent === 'function' && typeof instance.receiveComponent === 'function' && typeof instance.getHostNode === 'function' && typeof instance.unmountComponent === 'function', 'Only React Components can be mounted.') : void 0; - } - - // These two fields are used by the DOM and ART diffing algorithms - // respectively. Instead of using expandos on components, we should be - // storing the state needed by the diffing algorithms elsewhere. - instance._mountIndex = 0; - instance._mountImage = null; - - if (process.env.NODE_ENV !== 'production') { - instance._debugID = shouldHaveDebugID ? getNextDebugID() : 0; - } - - // Internal instances should fully constructed at this point, so they should - // not get any new fields added to them at this point. - if (process.env.NODE_ENV !== 'production') { - if (Object.preventExtensions) { - Object.preventExtensions(instance); - } - } - - return instance; -} - -module.exports = instantiateReactComponent; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 96 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/** - * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary - */ - -var supportedInputTypes = { - 'color': true, - 'date': true, - 'datetime': true, - 'datetime-local': true, - 'email': true, - 'month': true, - 'number': true, - 'password': true, - 'range': true, - 'search': true, - 'tel': true, - 'text': true, - 'time': true, - 'url': true, - 'week': true -}; - -function isTextInputElement(elem) { - var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); - - if (nodeName === 'input') { - return !!supportedInputTypes[elem.type]; - } - - if (nodeName === 'textarea') { - return true; - } - - return false; -} - -module.exports = isTextInputElement; - -/***/ }), -/* 97 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ExecutionEnvironment = __webpack_require__(8); -var escapeTextContentForBrowser = __webpack_require__(39); -var setInnerHTML = __webpack_require__(40); - -/** - * Set the textContent property of a node, ensuring that whitespace is preserved - * even in IE8. innerText is a poor substitute for textContent and, among many - * issues, inserts <br> instead of the literal newline chars. innerHTML behaves - * as it should. - * - * @param {DOMElement} node - * @param {string} text - * @internal - */ -var setTextContent = function (node, text) { - if (text) { - var firstChild = node.firstChild; - - if (firstChild && firstChild === node.lastChild && firstChild.nodeType === 3) { - firstChild.nodeValue = text; - return; - } - } - node.textContent = text; -}; - -if (ExecutionEnvironment.canUseDOM) { - if (!('textContent' in document.documentElement)) { - setTextContent = function (node, text) { - if (node.nodeType === 3) { - node.nodeValue = text; - return; - } - setInnerHTML(node, escapeTextContentForBrowser(text)); - }; - } -} - -module.exports = setTextContent; - -/***/ }), -/* 98 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var ReactCurrentOwner = __webpack_require__(15); -var REACT_ELEMENT_TYPE = __webpack_require__(269); - -var getIteratorFn = __webpack_require__(303); -var invariant = __webpack_require__(2); -var KeyEscapeUtils = __webpack_require__(49); -var warning = __webpack_require__(3); - -var SEPARATOR = '.'; -var SUBSEPARATOR = ':'; - -/** - * This is inlined from ReactElement since this file is shared between - * isomorphic and renderers. We could extract this to a - * - */ - -/** - * TODO: Test that a single child and an array with one item have the same key - * pattern. - */ - -var didWarnAboutMaps = false; - -/** - * Generate a key string that identifies a component within a set. - * - * @param {*} component A component that could contain a manual key. - * @param {number} index Index that is used if a manual key is not provided. - * @return {string} - */ -function getComponentKey(component, index) { - // Do some typechecking here since we call this blindly. We want to ensure - // that we don't block potential future ES APIs. - if (component && typeof component === 'object' && component.key != null) { - // Explicit key - return KeyEscapeUtils.escape(component.key); - } - // Implicit key determined by the index in the set - return index.toString(36); -} - -/** - * @param {?*} children Children tree container. - * @param {!string} nameSoFar Name of the key path so far. - * @param {!function} callback Callback to invoke with each child found. - * @param {?*} traverseContext Used to pass information throughout the traversal - * process. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) { - var type = typeof children; - - if (type === 'undefined' || type === 'boolean') { - // All of the above are perceived as null. - children = null; - } - - if (children === null || type === 'string' || type === 'number' || - // The following is inlined from ReactElement. This means we can optimize - // some checks. React Fiber also inlines this logic for similar purposes. - type === 'object' && children.$$typeof === REACT_ELEMENT_TYPE) { - callback(traverseContext, children, - // If it's the only child, treat the name as if it was wrapped in an array - // so that it's consistent if the number of children grows. - nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar); - return 1; - } - - var child; - var nextName; - var subtreeCount = 0; // Count of children found in the current subtree. - var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR; - - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - child = children[i]; - nextName = nextNamePrefix + getComponentKey(child, i); - subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); - } - } else { - var iteratorFn = getIteratorFn(children); - if (iteratorFn) { - var iterator = iteratorFn.call(children); - var step; - if (iteratorFn !== children.entries) { - var ii = 0; - while (!(step = iterator.next()).done) { - child = step.value; - nextName = nextNamePrefix + getComponentKey(child, ii++); - subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); - } - } else { - if (process.env.NODE_ENV !== 'production') { - var mapsAsChildrenAddendum = ''; - if (ReactCurrentOwner.current) { - var mapsAsChildrenOwnerName = ReactCurrentOwner.current.getName(); - if (mapsAsChildrenOwnerName) { - mapsAsChildrenAddendum = ' Check the render method of `' + mapsAsChildrenOwnerName + '`.'; - } - } - process.env.NODE_ENV !== 'production' ? warning(didWarnAboutMaps, 'Using Maps as children is not yet fully supported. It is an ' + 'experimental feature that might be removed. Convert it to a ' + 'sequence / iterable of keyed ReactElements instead.%s', mapsAsChildrenAddendum) : void 0; - didWarnAboutMaps = true; - } - // Iterator will provide entry [k,v] tuples rather than values. - while (!(step = iterator.next()).done) { - var entry = step.value; - if (entry) { - child = entry[1]; - nextName = nextNamePrefix + KeyEscapeUtils.escape(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0); - subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); - } - } - } - } else if (type === 'object') { - var addendum = ''; - if (process.env.NODE_ENV !== 'production') { - addendum = ' If you meant to render a collection of children, use an array ' + 'instead or wrap the object using createFragment(object) from the ' + 'React add-ons.'; - if (children._isReactElement) { - addendum = ' It looks like you\'re using an element created by a different ' + 'version of React. Make sure to use only one copy of React.'; - } - if (ReactCurrentOwner.current) { - var name = ReactCurrentOwner.current.getName(); - if (name) { - addendum += ' Check the render method of `' + name + '`.'; - } - } - } - var childrenString = String(children); - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : _prodInvariant('31', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : void 0; - } - } - - return subtreeCount; -} - -/** - * Traverses children that are typically specified as `props.children`, but - * might also be specified through attributes: - * - * - `traverseAllChildren(this.props.children, ...)` - * - `traverseAllChildren(this.props.leftPanelChildren, ...)` - * - * The `traverseContext` is an optional argument that is passed through the - * entire traversal. It can be used to store accumulations or anything else that - * the callback might find relevant. - * - * @param {?*} children Children tree object. - * @param {!function} callback To invoke upon traversing each child. - * @param {?*} traverseContext Context for traversal. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildren(children, callback, traverseContext) { - if (children == null) { - return 0; - } - - return traverseAllChildrenImpl(children, '', callback, traverseContext); -} - -module.exports = traverseAllChildren; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 99 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _React$PropTypes = _react2['default'].PropTypes; -var bool = _React$PropTypes.bool; -var object = _React$PropTypes.object; -var string = _React$PropTypes.string; -var func = _React$PropTypes.func; - -function isLeftClickEvent(event) { - return event.button === 0; -} - -function isModifiedEvent(event) { - return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); -} - -function isEmptyObject(object) { - for (var p in object) { - if (object.hasOwnProperty(p)) return false; - }return true; -} - -/** - * A <Link> is used to create an <a> element that links to a route. - * When that route is active, the link gets the value of its - * `activeClassName` prop - * - * For example, assuming you have the following route: - * - * <Route path="/posts/:postID" component={Post} /> - * - * You could use the following component to link to that route: - * - * <Link to={`/posts/${post.id}`} /> - * - * Links may pass along location state and/or query string parameters - * in the state/query props, respectively. - * - * <Link ... query={{ show: true }} state={{ the: 'state' }} /> - */ - -var Link = (function (_Component) { - _inherits(Link, _Component); - - function Link() { - _classCallCheck(this, Link); - - _Component.apply(this, arguments); - } - - Link.prototype.handleClick = function handleClick(event) { - var allowTransition = true; - - if (this.props.onClick) this.props.onClick(event); - - if (isModifiedEvent(event) || !isLeftClickEvent(event)) return; - - if (event.defaultPrevented === true) allowTransition = false; - - // If target prop is set (e.g. to "_blank") let browser handle link. - /* istanbul ignore if: untestable with Karma */ - if (this.props.target) { - if (!allowTransition) event.preventDefault(); - - return; - } - - event.preventDefault(); - - if (allowTransition) { - var _props = this.props; - var state = _props.state; - var to = _props.to; - var query = _props.query; - var hash = _props.hash; - - if (hash) to += hash; - - this.context.history.pushState(state, to, query); - } - }; - - Link.prototype.render = function render() { - var _this = this; - - var _props2 = this.props; - var to = _props2.to; - var query = _props2.query; - var hash = _props2.hash; - var state = _props2.state; - var activeClassName = _props2.activeClassName; - var activeStyle = _props2.activeStyle; - var onlyActiveOnIndex = _props2.onlyActiveOnIndex; - - var props = _objectWithoutProperties(_props2, ['to', 'query', 'hash', 'state', 'activeClassName', 'activeStyle', 'onlyActiveOnIndex']); - - // Manually override onClick. - props.onClick = function (e) { - return _this.handleClick(e); - }; - - // Ignore if rendered outside the context of history, simplifies unit testing. - var history = this.context.history; - - if (history) { - props.href = history.createHref(to, query); - - if (hash) props.href += hash; - - if (activeClassName || activeStyle != null && !isEmptyObject(activeStyle)) { - if (history.isActive(to, query, onlyActiveOnIndex)) { - if (activeClassName) props.className += props.className === '' ? activeClassName : ' ' + activeClassName; - - if (activeStyle) props.style = _extends({}, props.style, activeStyle); - } - } - } - - return _react2['default'].createElement('a', props); - }; - - return Link; -})(_react.Component); - -Link.contextTypes = { - history: object -}; - -Link.propTypes = { - to: string.isRequired, - query: object, - hash: string, - state: object, - activeStyle: object, - activeClassName: string, - onlyActiveOnIndex: bool.isRequired, - onClick: func -}; - -Link.defaultProps = { - onlyActiveOnIndex: false, - className: '', - style: {} -}; - -exports['default'] = Link; -module.exports = exports['default']; - -/***/ }), -/* 100 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _RouteUtils = __webpack_require__(19); - -var _PatternUtils = __webpack_require__(34); - -var _PropTypes = __webpack_require__(21); - -var _React$PropTypes = _react2['default'].PropTypes; -var string = _React$PropTypes.string; -var object = _React$PropTypes.object; - -/** - * A <Redirect> is used to declare another URL path a client should - * be sent to when they request a given URL. - * - * Redirects are placed alongside routes in the route configuration - * and are traversed in the same manner. - */ - -var Redirect = (function (_Component) { - _inherits(Redirect, _Component); - - function Redirect() { - _classCallCheck(this, Redirect); - - _Component.apply(this, arguments); - } - - /* istanbul ignore next: sanity check */ - - Redirect.prototype.render = function render() { - true ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, '<Redirect> elements are for router configuration only and should not be rendered') : _invariant2['default'](false) : undefined; - }; - - return Redirect; -})(_react.Component); - -Redirect.createRouteFromReactElement = function (element) { - var route = _RouteUtils.createRouteFromReactElement(element); - - if (route.from) route.path = route.from; - - route.onEnter = function (nextState, replaceState) { - var location = nextState.location; - var params = nextState.params; - - var pathname = undefined; - if (route.to.charAt(0) === '/') { - pathname = _PatternUtils.formatPattern(route.to, params); - } else if (!route.to) { - pathname = location.pathname; - } else { - var routeIndex = nextState.routes.indexOf(route); - var parentPattern = Redirect.getRoutePattern(nextState.routes, routeIndex - 1); - var pattern = parentPattern.replace(/\/*$/, '/') + route.to; - pathname = _PatternUtils.formatPattern(pattern, params); - } - - replaceState(route.state || location.state, pathname, route.query || location.query); - }; - - return route; -}; - -Redirect.getRoutePattern = function (routes, routeIndex) { - var parentPattern = ''; - - for (var i = routeIndex; i >= 0; i--) { - var route = routes[i]; - var pattern = route.path || ''; - parentPattern = pattern.replace(/\/*$/, '/') + parentPattern; - - if (pattern.indexOf('/') === 0) break; - } - - return '/' + parentPattern; -}; - -Redirect.propTypes = { - path: string, - from: string, // Alias for path - to: string.isRequired, - query: object, - state: object, - onEnter: _PropTypes.falsy, - children: _PropTypes.falsy -}; - -exports['default'] = Redirect; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 101 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _RouteUtils = __webpack_require__(19); - -var _getRouteParams = __webpack_require__(320); - -var _getRouteParams2 = _interopRequireDefault(_getRouteParams); - -var _React$PropTypes = _react2['default'].PropTypes; -var array = _React$PropTypes.array; -var func = _React$PropTypes.func; -var object = _React$PropTypes.object; - -/** - * A <RoutingContext> renders the component tree for a given router state - * and sets the history object and the current location in context. - */ - -var RoutingContext = (function (_Component) { - _inherits(RoutingContext, _Component); - - function RoutingContext() { - _classCallCheck(this, RoutingContext); - - _Component.apply(this, arguments); - } - - RoutingContext.prototype.getChildContext = function getChildContext() { - var _props = this.props; - var history = _props.history; - var location = _props.location; - - return { history: history, location: location }; - }; - - RoutingContext.prototype.createElement = function createElement(component, props) { - return component == null ? null : this.props.createElement(component, props); - }; - - RoutingContext.prototype.render = function render() { - var _this = this; - - var _props2 = this.props; - var history = _props2.history; - var location = _props2.location; - var routes = _props2.routes; - var params = _props2.params; - var components = _props2.components; - - var element = null; - - if (components) { - element = components.reduceRight(function (element, components, index) { - if (components == null) return element; // Don't create new children; use the grandchildren. - - var route = routes[index]; - var routeParams = _getRouteParams2['default'](route, params); - var props = { - history: history, - location: location, - params: params, - route: route, - routeParams: routeParams, - routes: routes - }; - - if (_RouteUtils.isReactChildren(element)) { - props.children = element; - } else if (element) { - for (var prop in element) { - if (element.hasOwnProperty(prop)) props[prop] = element[prop]; - } - } - - if (typeof components === 'object') { - var elements = {}; - - for (var key in components) { - if (components.hasOwnProperty(key)) { - // Pass through the key as a prop to createElement to allow - // custom createElement functions to know which named component - // they're rendering, for e.g. matching up to fetched data. - elements[key] = _this.createElement(components[key], _extends({ - key: key }, props)); - } - } - - return elements; - } - - return _this.createElement(components, props); - }, element); - } - - !(element === null || element === false || _react2['default'].isValidElement(element)) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'The root route must render a single element') : _invariant2['default'](false) : undefined; - - return element; - }; - - return RoutingContext; -})(_react.Component); - -RoutingContext.propTypes = { - history: object.isRequired, - createElement: func.isRequired, - location: object.isRequired, - routes: array.isRequired, - params: object.isRequired, - components: array.isRequired -}; - -RoutingContext.defaultProps = { - createElement: _react2['default'].createElement -}; - -RoutingContext.childContextTypes = { - history: object.isRequired, - location: object.isRequired -}; - -exports['default'] = RoutingContext; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 102 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* components */ - - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _Router2 = __webpack_require__(316); - -var _Router3 = _interopRequireDefault(_Router2); - -exports.Router = _Router3['default']; - -var _Link2 = __webpack_require__(99); - -var _Link3 = _interopRequireDefault(_Link2); - -exports.Link = _Link3['default']; - -var _IndexLink2 = __webpack_require__(310); - -var _IndexLink3 = _interopRequireDefault(_IndexLink2); - -exports.IndexLink = _IndexLink3['default']; - -/* components (configuration) */ - -var _IndexRedirect2 = __webpack_require__(311); - -var _IndexRedirect3 = _interopRequireDefault(_IndexRedirect2); - -exports.IndexRedirect = _IndexRedirect3['default']; - -var _IndexRoute2 = __webpack_require__(312); - -var _IndexRoute3 = _interopRequireDefault(_IndexRoute2); - -exports.IndexRoute = _IndexRoute3['default']; - -var _Redirect2 = __webpack_require__(100); - -var _Redirect3 = _interopRequireDefault(_Redirect2); - -exports.Redirect = _Redirect3['default']; - -var _Route2 = __webpack_require__(314); - -var _Route3 = _interopRequireDefault(_Route2); - -exports.Route = _Route3['default']; - -/* mixins */ - -var _History2 = __webpack_require__(309); - -var _History3 = _interopRequireDefault(_History2); - -exports.History = _History3['default']; - -var _Lifecycle2 = __webpack_require__(313); - -var _Lifecycle3 = _interopRequireDefault(_Lifecycle2); - -exports.Lifecycle = _Lifecycle3['default']; - -var _RouteContext2 = __webpack_require__(315); - -var _RouteContext3 = _interopRequireDefault(_RouteContext2); - -exports.RouteContext = _RouteContext3['default']; - -/* utils */ - -var _useRoutes2 = __webpack_require__(62); - -var _useRoutes3 = _interopRequireDefault(_useRoutes2); - -exports.useRoutes = _useRoutes3['default']; - -var _RouteUtils = __webpack_require__(19); - -exports.createRoutes = _RouteUtils.createRoutes; - -var _RoutingContext2 = __webpack_require__(101); - -var _RoutingContext3 = _interopRequireDefault(_RoutingContext2); - -exports.RoutingContext = _RoutingContext3['default']; - -var _PropTypes2 = __webpack_require__(21); - -var _PropTypes3 = _interopRequireDefault(_PropTypes2); - -exports.PropTypes = _PropTypes3['default']; - -var _match2 = __webpack_require__(322); - -var _match3 = _interopRequireDefault(_match2); - -exports.match = _match3['default']; - -var _Router4 = _interopRequireDefault(_Router2); - -exports['default'] = _Router4['default']; - -/***/ }), -/* 103 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -// The Symbol used to tag the ReactElement type. If there is no native Symbol -// nor polyfill, then a plain number is used for performance. - -var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7; - -module.exports = REACT_ELEMENT_TYPE; - -/***/ }), -/* 104 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -/** - * ReactElementValidator provides a wrapper around a element factory - * which validates the props passed to the element. This is intended to be - * used only in DEV and could be replaced by a static type checker for languages - * that support it. - */ - - - -var ReactCurrentOwner = __webpack_require__(15); -var ReactComponentTreeHook = __webpack_require__(9); -var ReactElement = __webpack_require__(22); - -var checkReactTypeSpec = __webpack_require__(332); - -var canDefineProperty = __webpack_require__(66); -var getIteratorFn = __webpack_require__(67); -var warning = __webpack_require__(3); - -function getDeclarationErrorAddendum() { - if (ReactCurrentOwner.current) { - var name = ReactCurrentOwner.current.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -/** - * Warn if there's no key explicitly set on dynamic arrays of children or - * object keys are not valid. This allows us to keep track of children between - * updates. - */ -var ownerHasKeyUseWarning = {}; - -function getCurrentComponentErrorInfo(parentType) { - var info = getDeclarationErrorAddendum(); - - if (!info) { - var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name; - if (parentName) { - info = ' Check the top-level render call using <' + parentName + '>.'; - } - } - return info; -} - -/** - * Warn if the element doesn't have an explicit key assigned to it. - * This element is in an array. The array could grow and shrink or be - * reordered. All children that haven't already been validated are required to - * have a "key" property assigned to it. Error statuses are cached so a warning - * will only be shown once. - * - * @internal - * @param {ReactElement} element Element that requires a key. - * @param {*} parentType element's parent's type. - */ -function validateExplicitKey(element, parentType) { - if (!element._store || element._store.validated || element.key != null) { - return; - } - element._store.validated = true; - - var memoizer = ownerHasKeyUseWarning.uniqueKey || (ownerHasKeyUseWarning.uniqueKey = {}); - - var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType); - if (memoizer[currentComponentErrorInfo]) { - return; - } - memoizer[currentComponentErrorInfo] = true; - - // Usually the current owner is the offender, but if it accepts children as a - // property, it may be the creator of the child that's responsible for - // assigning it a key. - var childOwner = ''; - if (element && element._owner && element._owner !== ReactCurrentOwner.current) { - // Give the component that originally created this child. - childOwner = ' It was passed a child from ' + element._owner.getName() + '.'; - } - - process.env.NODE_ENV !== 'production' ? warning(false, 'Each child in an array or iterator should have a unique "key" prop.' + '%s%s See https://fb.me/react-warning-keys for more information.%s', currentComponentErrorInfo, childOwner, ReactComponentTreeHook.getCurrentStackAddendum(element)) : void 0; -} - -/** - * Ensure that every element either is passed in a static location, in an - * array with an explicit keys property defined, or in an object literal - * with valid key property. - * - * @internal - * @param {ReactNode} node Statically passed child of any type. - * @param {*} parentType node's parent's type. - */ -function validateChildKeys(node, parentType) { - if (typeof node !== 'object') { - return; - } - if (Array.isArray(node)) { - for (var i = 0; i < node.length; i++) { - var child = node[i]; - if (ReactElement.isValidElement(child)) { - validateExplicitKey(child, parentType); - } - } - } else if (ReactElement.isValidElement(node)) { - // This element was passed in a valid location. - if (node._store) { - node._store.validated = true; - } - } else if (node) { - var iteratorFn = getIteratorFn(node); - // Entry iterators provide implicit keys. - if (iteratorFn) { - if (iteratorFn !== node.entries) { - var iterator = iteratorFn.call(node); - var step; - while (!(step = iterator.next()).done) { - if (ReactElement.isValidElement(step.value)) { - validateExplicitKey(step.value, parentType); - } - } - } - } - } -} - -/** - * Given an element, validate that its props follow the propTypes definition, - * provided by the type. - * - * @param {ReactElement} element - */ -function validatePropTypes(element) { - var componentClass = element.type; - if (typeof componentClass !== 'function') { - return; - } - var name = componentClass.displayName || componentClass.name; - if (componentClass.propTypes) { - checkReactTypeSpec(componentClass.propTypes, element.props, 'prop', name, element, null); - } - if (typeof componentClass.getDefaultProps === 'function') { - process.env.NODE_ENV !== 'production' ? warning(componentClass.getDefaultProps.isReactClassApproved, 'getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.') : void 0; - } -} - -var ReactElementValidator = { - - createElement: function (type, props, children) { - var validType = typeof type === 'string' || typeof type === 'function'; - // We warn in this case but don't throw. We expect the element creation to - // succeed and there will likely be errors in render. - if (!validType) { - if (typeof type !== 'function' && typeof type !== 'string') { - var info = ''; - if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { - info += ' You likely forgot to export your component from the file ' + 'it\'s defined in.'; - } - info += getDeclarationErrorAddendum(); - process.env.NODE_ENV !== 'production' ? warning(false, 'React.createElement: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', type == null ? type : typeof type, info) : void 0; - } - } - - var element = ReactElement.createElement.apply(this, arguments); - - // The result can be nullish if a mock or a custom function is used. - // TODO: Drop this when these are no longer allowed as the type argument. - if (element == null) { - return element; - } - - // Skip key warning if the type isn't valid since our key validation logic - // doesn't expect a non-string/function type and can throw confusing errors. - // We don't want exception behavior to differ between dev and prod. - // (Rendering will throw with a helpful message and as soon as the type is - // fixed, the key warnings will appear.) - if (validType) { - for (var i = 2; i < arguments.length; i++) { - validateChildKeys(arguments[i], type); - } - } - - validatePropTypes(element); - - return element; - }, - - createFactory: function (type) { - var validatedFactory = ReactElementValidator.createElement.bind(null, type); - // Legacy hook TODO: Warn if this is accessed - validatedFactory.type = type; - - if (process.env.NODE_ENV !== 'production') { - if (canDefineProperty) { - Object.defineProperty(validatedFactory, 'type', { - enumerable: false, - get: function () { - process.env.NODE_ENV !== 'production' ? warning(false, 'Factory.type is deprecated. Access the class directly ' + 'before passing it to createFactory.') : void 0; - Object.defineProperty(this, 'type', { - value: type - }); - return type; - } - }); - } - } - - return validatedFactory; - }, - - cloneElement: function (element, props, children) { - var newElement = ReactElement.cloneElement.apply(this, arguments); - for (var i = 2; i < arguments.length; i++) { - validateChildKeys(arguments[i], newElement.type); - } - validatePropTypes(newElement); - return newElement; - } - -}; - -module.exports = ReactElementValidator; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 105 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; - -module.exports = ReactPropTypesSecret; - -/***/ }), -/* 106 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); -var ReactDOM = __webpack_require__(237); -var FullArticle = __webpack_require__(112); - -// in the browser, do: -if (typeof document !== "undefined") { - ReactDOM.render(React.createElement(FullArticle, null), document.getElementById("article")); -} - -// in not-the browser, do: -module.exports = { FullArticle: FullArticle }; - -/***/ }), -/* 107 */ -/***/ (function(module, exports) { - -module.exports = function(){}; - - -/***/ }), -/* 108 */ -/***/ (function(module, exports) { - -// https://github.com/thibauts/b-spline -module.exports = function interpolate(t, degree, points, knots, weights, result, scaled) { - - var i,j,s,l; // function-scoped iteration variables - var n = points.length; // points count - var d = points[0].length; // point dimensionality - - if(degree < 1) throw new Error('degree must be at least 1 (linear)'); - if(degree > (n-1)) throw new Error('degree must be less than or equal to point count - 1'); - - if(!weights) { - // build weight vector of length [n] - weights = []; - for(i=0; i<n; i++) { - weights[i] = 1; - } - } - - if(!knots) { - // build knot vector of length [n + degree + 1] - var knots = []; - for(i=0; i<n+degree+1; i++) { - knots[i] = i; - } - } else { - if(knots.length !== n+degree+1) throw new Error('bad knot vector length'); - } - - var domain = [ - degree, - knots.length-1 - degree - ]; - - var low = knots[domain[0]]; - var high = knots[domain[1]]; - - // remap t to the domain where the spline is defined - if (!scaled) { - t = t * (high - low) + low; - } - - if(t < low || t > high) throw new Error('out of bounds'); - - // find s (the spline segment) for the [t] value provided - for(s=domain[0]; s<domain[1]; s++) { - if(t >= knots[s] && t <= knots[s+1]) { - break; - } - } - - // convert points to homogeneous coordinates - var v = []; - for(i=0; i<n; i++) { - v[i] = []; - for(j=0; j<d; j++) { - v[i][j] = points[i][j] * weights[i]; - } - v[i][d] = weights[i]; - } - - // l (level) goes from 1 to the curve degree + 1 - var alpha; - for(l=1; l<=degree+1; l++) { - // build level l of the pyramid - for(i=s; i>s-degree-1+l; i--) { - alpha = (t - knots[i]) / (knots[i+degree+1-l] - knots[i]); - - // interpolate each component - for(j=0; j<d+1; j++) { - v[i][j] = (1 - alpha) * v[i-1][j] + alpha * v[i][j]; - } - } - } - - // convert back to cartesian and return - var result = result || []; - for(i=0; i<d; i++) { - result[i] = v[s][i] / v[s][d]; - } - - return result; -}; - - -/***/ }), -/* 109 */ -/***/ (function(module, exports, __webpack_require__) { - -var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! - * Paper.js v0.9.25 - The Swiss Army Knife of Vector Graphics Scripting. - * http://paperjs.org/ - * - * Copyright (c) 2011 - 2014, Juerg Lehni & Jonathan Puckey - * http://scratchdisk.com/ & http://jonathanpuckey.com/ - * - * Distributed under the MIT license. See LICENSE file for details. - * - * All rights reserved. - * - * Date: Sun Oct 25 11:23:38 2015 +0100 - * - *** - * - * Straps.js - Class inheritance library with support for bean-style accessors - * - * Copyright (c) 2006 - 2013 Juerg Lehni - * http://scratchdisk.com/ - * - * Distributed under the MIT license. - * - *** - * - * Acorn.js - * http://marijnhaverbeke.nl/acorn/ - * - * Acorn is a tiny, fast JavaScript parser written in JavaScript, - * created by Marijn Haverbeke and released under an MIT license. - * - */ - -var paper = new function(undefined) { - -var Base = new function() { - var hidden = /^(statics|enumerable|beans|preserve)$/, - - forEach = [].forEach || function(iter, bind) { - for (var i = 0, l = this.length; i < l; i++) - iter.call(bind, this[i], i, this); - }, - - forIn = function(iter, bind) { - for (var i in this) - if (this.hasOwnProperty(i)) - iter.call(bind, this[i], i, this); - }, - - create = Object.create || function(proto) { - return { __proto__: proto }; - }, - - describe = Object.getOwnPropertyDescriptor || function(obj, name) { - var get = obj.__lookupGetter__ && obj.__lookupGetter__(name); - return get - ? { get: get, set: obj.__lookupSetter__(name), - enumerable: true, configurable: true } - : obj.hasOwnProperty(name) - ? { value: obj[name], enumerable: true, - configurable: true, writable: true } - : null; - }, - - _define = Object.defineProperty || function(obj, name, desc) { - if ((desc.get || desc.set) && obj.__defineGetter__) { - if (desc.get) - obj.__defineGetter__(name, desc.get); - if (desc.set) - obj.__defineSetter__(name, desc.set); - } else { - obj[name] = desc.value; - } - return obj; - }, - - define = function(obj, name, desc) { - delete obj[name]; - return _define(obj, name, desc); - }; - - function inject(dest, src, enumerable, beans, preserve) { - var beansNames = {}; - - function field(name, val) { - val = val || (val = describe(src, name)) - && (val.get ? val : val.value); - if (typeof val === 'string' && val[0] === '#') - val = dest[val.substring(1)] || val; - var isFunc = typeof val === 'function', - res = val, - prev = preserve || isFunc && !val.base - ? (val && val.get ? name in dest : dest[name]) - : null, - bean; - if (!preserve || !prev) { - if (isFunc && prev) - val.base = prev; - if (isFunc && beans !== false - && (bean = name.match(/^([gs]et|is)(([A-Z])(.*))$/))) - beansNames[bean[3].toLowerCase() + bean[4]] = bean[2]; - if (!res || isFunc || !res.get || typeof res.get !== 'function' - || !Base.isPlainObject(res)) - res = { value: res, writable: true }; - if ((describe(dest, name) - || { configurable: true }).configurable) { - res.configurable = true; - res.enumerable = enumerable; - } - define(dest, name, res); - } - } - if (src) { - for (var name in src) { - if (src.hasOwnProperty(name) && !hidden.test(name)) - field(name); - } - for (var name in beansNames) { - var part = beansNames[name], - set = dest['set' + part], - get = dest['get' + part] || set && dest['is' + part]; - if (get && (beans === true || get.length === 0)) - field(name, { get: get, set: set }); - } - } - return dest; - } - - function each(obj, iter, bind) { - if (obj) - ('length' in obj && !obj.getLength - && typeof obj.length === 'number' - ? forEach - : forIn).call(obj, iter, bind = bind || obj); - return bind; - } - - function set(obj, props, exclude) { - for (var key in props) - if (props.hasOwnProperty(key) && !(exclude && exclude[key])) - obj[key] = props[key]; - return obj; - } - - return inject(function Base() { - for (var i = 0, l = arguments.length; i < l; i++) - set(this, arguments[i]); - }, { - inject: function(src) { - if (src) { - var statics = src.statics === true ? src : src.statics, - beans = src.beans, - preserve = src.preserve; - if (statics !== src) - inject(this.prototype, src, src.enumerable, beans, preserve); - inject(this, statics, true, beans, preserve); - } - for (var i = 1, l = arguments.length; i < l; i++) - this.inject(arguments[i]); - return this; - }, - - extend: function() { - var base = this, - ctor, - proto; - for (var i = 0, l = arguments.length; i < l; i++) - if (ctor = arguments[i].initialize) - break; - ctor = ctor || function() { - base.apply(this, arguments); - }; - proto = ctor.prototype = create(this.prototype); - define(proto, 'constructor', - { value: ctor, writable: true, configurable: true }); - inject(ctor, this, true); - if (arguments.length) - this.inject.apply(ctor, arguments); - ctor.base = base; - return ctor; - } - }, true).inject({ - inject: function() { - for (var i = 0, l = arguments.length; i < l; i++) { - var src = arguments[i]; - if (src) - inject(this, src, src.enumerable, src.beans, src.preserve); - } - return this; - }, - - extend: function() { - var res = create(this); - return res.inject.apply(res, arguments); - }, - - each: function(iter, bind) { - return each(this, iter, bind); - }, - - set: function(props) { - return set(this, props); - }, - - clone: function() { - return new this.constructor(this); - }, - - statics: { - each: each, - create: create, - define: define, - describe: describe, - set: set, - - clone: function(obj) { - return set(new obj.constructor(), obj); - }, - - isPlainObject: function(obj) { - var ctor = obj != null && obj.constructor; - return ctor && (ctor === Object || ctor === Base - || ctor.name === 'Object'); - }, - - pick: function(a, b) { - return a !== undefined ? a : b; - } - } - }); -}; - -if (true) - module.exports = Base; - -Base.inject({ - toString: function() { - return this._id != null - ? (this._class || 'Object') + (this._name - ? " '" + this._name + "'" - : ' @' + this._id) - : '{ ' + Base.each(this, function(value, key) { - if (!/^_/.test(key)) { - var type = typeof value; - this.push(key + ': ' + (type === 'number' - ? Formatter.instance.number(value) - : type === 'string' ? "'" + value + "'" : value)); - } - }, []).join(', ') + ' }'; - }, - - getClassName: function() { - return this._class || ''; - }, - - exportJSON: function(options) { - return Base.exportJSON(this, options); - }, - - toJSON: function() { - return Base.serialize(this); - }, - - _set: function(props, exclude, dontCheck) { - if (props && (dontCheck || Base.isPlainObject(props))) { - var keys = Object.keys(props._filtering || props); - for (var i = 0, l = keys.length; i < l; i++) { - var key = keys[i]; - if (!(exclude && exclude[key])) { - var value = props[key]; - if (value !== undefined) - this[key] = value; - } - } - return true; - } - }, - - statics: { - - exports: { - enumerable: true - }, - - extend: function extend() { - var res = extend.base.apply(this, arguments), - name = res.prototype._class; - if (name && !Base.exports[name]) - Base.exports[name] = res; - return res; - }, - - equals: function(obj1, obj2) { - if (obj1 === obj2) - return true; - if (obj1 && obj1.equals) - return obj1.equals(obj2); - if (obj2 && obj2.equals) - return obj2.equals(obj1); - if (obj1 && obj2 - && typeof obj1 === 'object' && typeof obj2 === 'object') { - if (Array.isArray(obj1) && Array.isArray(obj2)) { - var length = obj1.length; - if (length !== obj2.length) - return false; - while (length--) { - if (!Base.equals(obj1[length], obj2[length])) - return false; - } - } else { - var keys = Object.keys(obj1), - length = keys.length; - if (length !== Object.keys(obj2).length) - return false; - while (length--) { - var key = keys[length]; - if (!(obj2.hasOwnProperty(key) - && Base.equals(obj1[key], obj2[key]))) - return false; - } - } - return true; - } - return false; - }, - - read: function(list, start, options, length) { - if (this === Base) { - var value = this.peek(list, start); - list.__index++; - return value; - } - var proto = this.prototype, - readIndex = proto._readIndex, - index = start || readIndex && list.__index || 0; - if (!length) - length = list.length - index; - var obj = list[index]; - if (obj instanceof this - || options && options.readNull && obj == null && length <= 1) { - if (readIndex) - list.__index = index + 1; - return obj && options && options.clone ? obj.clone() : obj; - } - obj = Base.create(this.prototype); - if (readIndex) - obj.__read = true; - obj = obj.initialize.apply(obj, index > 0 || length < list.length - ? Array.prototype.slice.call(list, index, index + length) - : list) || obj; - if (readIndex) { - list.__index = index + obj.__read; - obj.__read = undefined; - } - return obj; - }, - - peek: function(list, start) { - return list[list.__index = start || list.__index || 0]; - }, - - remain: function(list) { - return list.length - (list.__index || 0); - }, - - readAll: function(list, start, options) { - var res = [], - entry; - for (var i = start || 0, l = list.length; i < l; i++) { - res.push(Array.isArray(entry = list[i]) - ? this.read(entry, 0, options) - : this.read(list, i, options, 1)); - } - return res; - }, - - readNamed: function(list, name, start, options, length) { - var value = this.getNamed(list, name), - hasObject = value !== undefined; - if (hasObject) { - var filtered = list._filtered; - if (!filtered) { - filtered = list._filtered = Base.create(list[0]); - filtered._filtering = list[0]; - } - filtered[name] = undefined; - } - return this.read(hasObject ? [value] : list, start, options, length); - }, - - getNamed: function(list, name) { - var arg = list[0]; - if (list._hasObject === undefined) - list._hasObject = list.length === 1 && Base.isPlainObject(arg); - if (list._hasObject) - return name ? arg[name] : list._filtered || arg; - }, - - hasNamed: function(list, name) { - return !!this.getNamed(list, name); - }, - - isPlainValue: function(obj, asString) { - return this.isPlainObject(obj) || Array.isArray(obj) - || asString && typeof obj === 'string'; - }, - - serialize: function(obj, options, compact, dictionary) { - options = options || {}; - - var root = !dictionary, - res; - if (root) { - options.formatter = new Formatter(options.precision); - dictionary = { - length: 0, - definitions: {}, - references: {}, - add: function(item, create) { - var id = '#' + item._id, - ref = this.references[id]; - if (!ref) { - this.length++; - var res = create.call(item), - name = item._class; - if (name && res[0] !== name) - res.unshift(name); - this.definitions[id] = res; - ref = this.references[id] = [id]; - } - return ref; - } - }; - } - if (obj && obj._serialize) { - res = obj._serialize(options, dictionary); - var name = obj._class; - if (name && !compact && !res._compact && res[0] !== name) - res.unshift(name); - } else if (Array.isArray(obj)) { - res = []; - for (var i = 0, l = obj.length; i < l; i++) - res[i] = Base.serialize(obj[i], options, compact, - dictionary); - if (compact) - res._compact = true; - } else if (Base.isPlainObject(obj)) { - res = {}; - var keys = Object.keys(obj); - for (var i = 0, l = keys.length; i < l; i++) { - var key = keys[i]; - res[key] = Base.serialize(obj[key], options, compact, - dictionary); - } - } else if (typeof obj === 'number') { - res = options.formatter.number(obj, options.precision); - } else { - res = obj; - } - return root && dictionary.length > 0 - ? [['dictionary', dictionary.definitions], res] - : res; - }, - - deserialize: function(json, create, _data, _isDictionary) { - var res = json, - isRoot = !_data; - _data = _data || {}; - if (Array.isArray(json)) { - var type = json[0], - isDictionary = type === 'dictionary'; - if (json.length == 1 && /^#/.test(type)) - return _data.dictionary[type]; - type = Base.exports[type]; - res = []; - if (_isDictionary) - _data.dictionary = res; - for (var i = type ? 1 : 0, l = json.length; i < l; i++) - res.push(Base.deserialize(json[i], create, _data, - isDictionary)); - if (type) { - var args = res; - if (create) { - res = create(type, args); - } else { - res = Base.create(type.prototype); - type.apply(res, args); - } - } - } else if (Base.isPlainObject(json)) { - res = {}; - if (_isDictionary) - _data.dictionary = res; - for (var key in json) - res[key] = Base.deserialize(json[key], create, _data); - } - return isRoot && json && json.length && json[0][0] === 'dictionary' - ? res[1] - : res; - }, - - exportJSON: function(obj, options) { - var json = Base.serialize(obj, options); - return options && options.asString === false - ? json - : JSON.stringify(json); - }, - - importJSON: function(json, target) { - return Base.deserialize( - typeof json === 'string' ? JSON.parse(json) : json, - function(type, args) { - var obj = target && target.constructor === type - ? target - : Base.create(type.prototype), - isTarget = obj === target; - if (args.length === 1 && obj instanceof Item - && (isTarget || !(obj instanceof Layer))) { - var arg = args[0]; - if (Base.isPlainObject(arg)) - arg.insert = false; - } - type.apply(obj, args); - if (isTarget) - target = null; - return obj; - }); - }, - - splice: function(list, items, index, remove) { - var amount = items && items.length, - append = index === undefined; - index = append ? list.length : index; - if (index > list.length) - index = list.length; - for (var i = 0; i < amount; i++) - items[i]._index = index + i; - if (append) { - list.push.apply(list, items); - return []; - } else { - var args = [index, remove]; - if (items) - args.push.apply(args, items); - var removed = list.splice.apply(list, args); - for (var i = 0, l = removed.length; i < l; i++) - removed[i]._index = undefined; - for (var i = index + amount, l = list.length; i < l; i++) - list[i]._index = i; - return removed; - } - }, - - capitalize: function(str) { - return str.replace(/\b[a-z]/g, function(match) { - return match.toUpperCase(); - }); - }, - - camelize: function(str) { - return str.replace(/-(.)/g, function(all, chr) { - return chr.toUpperCase(); - }); - }, - - hyphenate: function(str) { - return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); - } - } -}); - -var Emitter = { - on: function(type, func) { - if (typeof type !== 'string') { - Base.each(type, function(value, key) { - this.on(key, value); - }, this); - } else { - var types = this._eventTypes, - entry = types && types[type], - handlers = this._callbacks = this._callbacks || {}; - handlers = handlers[type] = handlers[type] || []; - if (handlers.indexOf(func) === -1) { - handlers.push(func); - if (entry && entry.install && handlers.length === 1) - entry.install.call(this, type); - } - } - return this; - }, - - off: function(type, func) { - if (typeof type !== 'string') { - Base.each(type, function(value, key) { - this.off(key, value); - }, this); - return; - } - var types = this._eventTypes, - entry = types && types[type], - handlers = this._callbacks && this._callbacks[type], - index; - if (handlers) { - if (!func || (index = handlers.indexOf(func)) !== -1 - && handlers.length === 1) { - if (entry && entry.uninstall) - entry.uninstall.call(this, type); - delete this._callbacks[type]; - } else if (index !== -1) { - handlers.splice(index, 1); - } - } - return this; - }, - - once: function(type, func) { - return this.on(type, function() { - func.apply(this, arguments); - this.off(type, func); - }); - }, - - emit: function(type, event) { - var handlers = this._callbacks && this._callbacks[type]; - if (!handlers) - return false; - var args = [].slice.call(arguments, 1); - handlers = handlers.slice(); - for (var i = 0, l = handlers.length; i < l; i++) { - if (handlers[i].apply(this, args) === false) { - if (event && event.stop) - event.stop(); - break; - } - } - return true; - }, - - responds: function(type) { - return !!(this._callbacks && this._callbacks[type]); - }, - - attach: '#on', - detach: '#off', - fire: '#emit', - - _installEvents: function(install) { - var handlers = this._callbacks, - key = install ? 'install' : 'uninstall'; - for (var type in handlers) { - if (handlers[type].length > 0) { - var types = this._eventTypes, - entry = types && types[type], - func = entry && entry[key]; - if (func) - func.call(this, type); - } - } - }, - - statics: { - inject: function inject(src) { - var events = src._events; - if (events) { - var types = {}; - Base.each(events, function(entry, key) { - var isString = typeof entry === 'string', - name = isString ? entry : key, - part = Base.capitalize(name), - type = name.substring(2).toLowerCase(); - types[type] = isString ? {} : entry; - name = '_' + name; - src['get' + part] = function() { - return this[name]; - }; - src['set' + part] = function(func) { - var prev = this[name]; - if (prev) - this.off(type, prev); - if (func) - this.on(type, func); - this[name] = func; - }; - }); - src._eventTypes = types; - } - return inject.base.apply(this, arguments); - } - } -}; - -var PaperScope = Base.extend({ - _class: 'PaperScope', - - initialize: function PaperScope() { - paper = this; - this.settings = new Base({ - applyMatrix: true, - handleSize: 4, - hitTolerance: 0 - }); - this.project = null; - this.projects = []; - this.tools = []; - this.palettes = []; - this._id = PaperScope._id++; - PaperScope._scopes[this._id] = this; - var proto = PaperScope.prototype; - if (!this.support) { - var ctx = CanvasProvider.getContext(1, 1); - proto.support = { - nativeDash: 'setLineDash' in ctx || 'mozDash' in ctx, - nativeBlendModes: BlendMode.nativeModes - }; - CanvasProvider.release(ctx); - } - - if (!this.browser) { - var agent = navigator.userAgent.toLowerCase(), - platform = (/(win)/.exec(agent) - || /(mac)/.exec(agent) - || /(linux)/.exec(agent) - || [])[0], - browser = proto.browser = { platform: platform }; - if (platform) - browser[platform] = true; - agent.replace( - /(opera|chrome|safari|webkit|firefox|msie|trident|atom)\/?\s*([.\d]+)(?:.*version\/([.\d]+))?(?:.*rv\:([.\d]+))?/g, - function(all, n, v1, v2, rv) { - if (!browser.chrome) { - var v = n === 'opera' ? v2 : v1; - if (n === 'trident') { - v = rv; - n = 'msie'; - } - browser.version = v; - browser.versionNumber = parseFloat(v); - browser.name = n; - browser[n] = true; - } - } - ); - if (browser.chrome) - delete browser.webkit; - if (browser.atom) - delete browser.chrome; - } - }, - - version: "0.9.25", - - getView: function() { - return this.project && this.project.getView(); - }, - - getPaper: function() { - return this; - }, - - execute: function(code, url, options) { - paper.PaperScript.execute(code, this, url, options); - View.updateFocus(); - }, - - install: function(scope) { - var that = this; - Base.each(['project', 'view', 'tool'], function(key) { - Base.define(scope, key, { - configurable: true, - get: function() { - return that[key]; - } - }); - }); - for (var key in this) - if (!/^_/.test(key) && this[key]) - scope[key] = this[key]; - }, - - setup: function(element) { - paper = this; - this.project = new Project(element); - return this; - }, - - activate: function() { - paper = this; - }, - - clear: function() { - for (var i = this.projects.length - 1; i >= 0; i--) - this.projects[i].remove(); - for (var i = this.tools.length - 1; i >= 0; i--) - this.tools[i].remove(); - for (var i = this.palettes.length - 1; i >= 0; i--) - this.palettes[i].remove(); - }, - - remove: function() { - this.clear(); - delete PaperScope._scopes[this._id]; - }, - - statics: new function() { - function handleAttribute(name) { - name += 'Attribute'; - return function(el, attr) { - return el[name](attr) || el[name]('data-paper-' + attr); - }; - } - - return { - _scopes: {}, - _id: 0, - - get: function(id) { - return this._scopes[id] || null; - }, - - getAttribute: handleAttribute('get'), - hasAttribute: handleAttribute('has') - }; - } -}); - -var PaperScopeItem = Base.extend(Emitter, { - - initialize: function(activate) { - this._scope = paper; - this._index = this._scope[this._list].push(this) - 1; - if (activate || !this._scope[this._reference]) - this.activate(); - }, - - activate: function() { - if (!this._scope) - return false; - var prev = this._scope[this._reference]; - if (prev && prev !== this) - prev.emit('deactivate'); - this._scope[this._reference] = this; - this.emit('activate', prev); - return true; - }, - - isActive: function() { - return this._scope[this._reference] === this; - }, - - remove: function() { - if (this._index == null) - return false; - Base.splice(this._scope[this._list], null, this._index, 1); - if (this._scope[this._reference] == this) - this._scope[this._reference] = null; - this._scope = null; - return true; - } -}); - -var Formatter = Base.extend({ - initialize: function(precision) { - this.precision = precision || 5; - this.multiplier = Math.pow(10, this.precision); - }, - - number: function(val) { - return Math.round(val * this.multiplier) / this.multiplier; - }, - - pair: function(val1, val2, separator) { - return this.number(val1) + (separator || ',') + this.number(val2); - }, - - point: function(val, separator) { - return this.number(val.x) + (separator || ',') + this.number(val.y); - }, - - size: function(val, separator) { - return this.number(val.width) + (separator || ',') - + this.number(val.height); - }, - - rectangle: function(val, separator) { - return this.point(val, separator) + (separator || ',') - + this.size(val, separator); - } -}); - -Formatter.instance = new Formatter(); - -var Numerical = new function() { - - var abscissas = [ - [ 0.5773502691896257645091488], - [0,0.7745966692414833770358531], - [ 0.3399810435848562648026658,0.8611363115940525752239465], - [0,0.5384693101056830910363144,0.9061798459386639927976269], - [ 0.2386191860831969086305017,0.6612093864662645136613996,0.9324695142031520278123016], - [0,0.4058451513773971669066064,0.7415311855993944398638648,0.9491079123427585245261897], - [ 0.1834346424956498049394761,0.5255324099163289858177390,0.7966664774136267395915539,0.9602898564975362316835609], - [0,0.3242534234038089290385380,0.6133714327005903973087020,0.8360311073266357942994298,0.9681602395076260898355762], - [ 0.1488743389816312108848260,0.4333953941292471907992659,0.6794095682990244062343274,0.8650633666889845107320967,0.9739065285171717200779640], - [0,0.2695431559523449723315320,0.5190961292068118159257257,0.7301520055740493240934163,0.8870625997680952990751578,0.9782286581460569928039380], - [ 0.1252334085114689154724414,0.3678314989981801937526915,0.5873179542866174472967024,0.7699026741943046870368938,0.9041172563704748566784659,0.9815606342467192506905491], - [0,0.2304583159551347940655281,0.4484927510364468528779129,0.6423493394403402206439846,0.8015780907333099127942065,0.9175983992229779652065478,0.9841830547185881494728294], - [ 0.1080549487073436620662447,0.3191123689278897604356718,0.5152486363581540919652907,0.6872929048116854701480198,0.8272013150697649931897947,0.9284348836635735173363911,0.9862838086968123388415973], - [0,0.2011940939974345223006283,0.3941513470775633698972074,0.5709721726085388475372267,0.7244177313601700474161861,0.8482065834104272162006483,0.9372733924007059043077589,0.9879925180204854284895657], - [ 0.0950125098376374401853193,0.2816035507792589132304605,0.4580167776572273863424194,0.6178762444026437484466718,0.7554044083550030338951012,0.8656312023878317438804679,0.9445750230732325760779884,0.9894009349916499325961542] - ]; - - var weights = [ - [1], - [0.8888888888888888888888889,0.5555555555555555555555556], - [0.6521451548625461426269361,0.3478548451374538573730639], - [0.5688888888888888888888889,0.4786286704993664680412915,0.2369268850561890875142640], - [0.4679139345726910473898703,0.3607615730481386075698335,0.1713244923791703450402961], - [0.4179591836734693877551020,0.3818300505051189449503698,0.2797053914892766679014678,0.1294849661688696932706114], - [0.3626837833783619829651504,0.3137066458778872873379622,0.2223810344533744705443560,0.1012285362903762591525314], - [0.3302393550012597631645251,0.3123470770400028400686304,0.2606106964029354623187429,0.1806481606948574040584720,0.0812743883615744119718922], - [0.2955242247147528701738930,0.2692667193099963550912269,0.2190863625159820439955349,0.1494513491505805931457763,0.0666713443086881375935688], - [0.2729250867779006307144835,0.2628045445102466621806889,0.2331937645919904799185237,0.1862902109277342514260976,0.1255803694649046246346943,0.0556685671161736664827537], - [0.2491470458134027850005624,0.2334925365383548087608499,0.2031674267230659217490645,0.1600783285433462263346525,0.1069393259953184309602547,0.0471753363865118271946160], - [0.2325515532308739101945895,0.2262831802628972384120902,0.2078160475368885023125232,0.1781459807619457382800467,0.1388735102197872384636018,0.0921214998377284479144218,0.0404840047653158795200216], - [0.2152638534631577901958764,0.2051984637212956039659241,0.1855383974779378137417166,0.1572031671581935345696019,0.1215185706879031846894148,0.0801580871597602098056333,0.0351194603317518630318329], - [0.2025782419255612728806202,0.1984314853271115764561183,0.1861610000155622110268006,0.1662692058169939335532009,0.1395706779261543144478048,0.1071592204671719350118695,0.0703660474881081247092674,0.0307532419961172683546284], - [0.1894506104550684962853967,0.1826034150449235888667637,0.1691565193950025381893121,0.1495959888165767320815017,0.1246289712555338720524763,0.0951585116824927848099251,0.0622535239386478928628438,0.0271524594117540948517806] - ]; - - var abs = Math.abs, - sqrt = Math.sqrt, - pow = Math.pow, - EPSILON = 1e-12, - MACHINE_EPSILON = 1.12e-16; - - function clip(value, min, max) { - return value < min ? min : value > max ? max : value; - } - - return { - TOLERANCE: 1e-6, - EPSILON: EPSILON, - MACHINE_EPSILON: MACHINE_EPSILON, - CURVETIME_EPSILON: 4e-7, - GEOMETRIC_EPSILON: 2e-7, - WINDING_EPSILON: 2e-7, - TRIGONOMETRIC_EPSILON: 1e-7, - CLIPPING_EPSILON: 1e-7, - KAPPA: 4 * (sqrt(2) - 1) / 3, - - isZero: function(val) { - return val >= -EPSILON && val <= EPSILON; - }, - - integrate: function(f, a, b, n) { - var x = abscissas[n - 2], - w = weights[n - 2], - A = (b - a) * 0.5, - B = A + a, - i = 0, - m = (n + 1) >> 1, - sum = n & 1 ? w[i++] * f(B) : 0; - while (i < m) { - var Ax = A * x[i]; - sum += w[i++] * (f(B + Ax) + f(B - Ax)); - } - return A * sum; - }, - - findRoot: function(f, df, x, a, b, n, tolerance) { - for (var i = 0; i < n; i++) { - var fx = f(x), - dx = fx / df(x), - nx = x - dx; - if (abs(dx) < tolerance) - return nx; - if (fx > 0) { - b = x; - x = nx <= a ? (a + b) * 0.5 : nx; - } else { - a = x; - x = nx >= b ? (a + b) * 0.5 : nx; - } - } - return x; - }, - - solveQuadratic: function(a, b, c, roots, min, max) { - var count = 0, - eMin = min - EPSILON, - eMax = max + EPSILON, - x1, x2 = Infinity, - B = b, - D; - b /= -2; - D = b * b - a * c; - if (D !== 0 && abs(D) < MACHINE_EPSILON) { - var gmC = pow(abs(a * b * c), 1 / 3); - if (gmC < 1e-8) { - var mult = pow(10, - abs(Math.floor(Math.log(gmC) * Math.LOG10E))); - if (!isFinite(mult)) - mult = 0; - a *= mult; - b *= mult; - c *= mult; - D = b * b - a * c; - } - } - if (abs(a) < EPSILON) { - if (abs(B) < EPSILON) - return abs(c) < EPSILON ? -1 : 0; - x1 = -c / B; - } else if (D >= -MACHINE_EPSILON) { - var Q = D < 0 ? 0 : sqrt(D), - R = b + (b < 0 ? -Q : Q); - if (R === 0) { - x1 = c / a; - x2 = -x1; - } else { - x1 = R / a; - x2 = c / R; - } - } - if (isFinite(x1) && (min == null || x1 > eMin && x1 < eMax)) - roots[count++] = min == null ? x1 : clip(x1, min, max); - if (x2 !== x1 - && isFinite(x2) && (min == null || x2 > eMin && x2 < eMax)) - roots[count++] = min == null ? x2 : clip(x2, min, max); - return count; - }, - - solveCubic: function(a, b, c, d, roots, min, max) { - var count = 0, - x, b1, c2; - if (abs(a) < EPSILON) { - a = b; - b1 = c; - c2 = d; - x = Infinity; - } else if (abs(d) < EPSILON) { - b1 = b; - c2 = c; - x = 0; - } else { - var ec = 1 + MACHINE_EPSILON, - x0, q, qd, t, r, s, tmp; - x = -(b / a) / 3; - tmp = a * x, - b1 = tmp + b, - c2 = b1 * x + c, - qd = (tmp + b1) * x + c2, - q = c2 * x + d; - t = q /a; - r = pow(abs(t), 1/3); - s = t < 0 ? -1 : 1; - t = -qd / a; - r = t > 0 ? 1.3247179572 * Math.max(r, sqrt(t)) : r; - x0 = x - s * r; - if (x0 !== x) { - do { - x = x0; - tmp = a * x, - b1 = tmp + b, - c2 = b1 * x + c, - qd = (tmp + b1) * x + c2, - q = c2 * x + d; - x0 = qd === 0 ? x : x - q / qd / ec; - if (x0 === x) { - x = x0; - break; - } - } while (s * x0 > s * x); - if (abs(a) * x * x > abs(d / x)) { - c2 = -d / x; - b1 = (c2 - c) / x; - } - } - } - var count = Numerical.solveQuadratic(a, b1, c2, roots, min, max); - if (isFinite(x) && (count === 0 || x !== roots[count - 1]) - && (min == null || x > min - EPSILON && x < max + EPSILON)) - roots[count++] = min == null ? x : clip(x, min, max); - return count; - } - }; -}; - -var UID = { - _id: 1, - _pools: {}, - - get: function(ctor) { - if (ctor) { - var name = ctor._class, - pool = this._pools[name]; - if (!pool) - pool = this._pools[name] = { _id: 1 }; - return pool._id++; - } else { - return this._id++; - } - } -}; - -var Point = Base.extend({ - _class: 'Point', - _readIndex: true, - - initialize: function Point(arg0, arg1) { - var type = typeof arg0; - if (type === 'number') { - var hasY = typeof arg1 === 'number'; - this.x = arg0; - this.y = hasY ? arg1 : arg0; - if (this.__read) - this.__read = hasY ? 2 : 1; - } else if (type === 'undefined' || arg0 === null) { - this.x = this.y = 0; - if (this.__read) - this.__read = arg0 === null ? 1 : 0; - } else { - if (Array.isArray(arg0)) { - this.x = arg0[0]; - this.y = arg0.length > 1 ? arg0[1] : arg0[0]; - } else if (arg0.x != null) { - this.x = arg0.x; - this.y = arg0.y; - } else if (arg0.width != null) { - this.x = arg0.width; - this.y = arg0.height; - } else if (arg0.angle != null) { - this.x = arg0.length; - this.y = 0; - this.setAngle(arg0.angle); - } else { - this.x = this.y = 0; - if (this.__read) - this.__read = 0; - } - if (this.__read) - this.__read = 1; - } - }, - - set: function(x, y) { - this.x = x; - this.y = y; - return this; - }, - - equals: function(point) { - return this === point || point - && (this.x === point.x && this.y === point.y - || Array.isArray(point) - && this.x === point[0] && this.y === point[1]) - || false; - }, - - clone: function() { - return new Point(this.x, this.y); - }, - - toString: function() { - var f = Formatter.instance; - return '{ x: ' + f.number(this.x) + ', y: ' + f.number(this.y) + ' }'; - }, - - _serialize: function(options) { - var f = options.formatter; - return [f.number(this.x), f.number(this.y)]; - }, - - getLength: function() { - return Math.sqrt(this.x * this.x + this.y * this.y); - }, - - setLength: function(length) { - if (this.isZero()) { - var angle = this._angle || 0; - this.set( - Math.cos(angle) * length, - Math.sin(angle) * length - ); - } else { - var scale = length / this.getLength(); - if (Numerical.isZero(scale)) - this.getAngle(); - this.set( - this.x * scale, - this.y * scale - ); - } - }, - getAngle: function() { - return this.getAngleInRadians.apply(this, arguments) * 180 / Math.PI; - }, - - setAngle: function(angle) { - this.setAngleInRadians.call(this, angle * Math.PI / 180); - }, - - getAngleInDegrees: '#getAngle', - setAngleInDegrees: '#setAngle', - - getAngleInRadians: function() { - if (!arguments.length) { - return this.isZero() - ? this._angle || 0 - : this._angle = Math.atan2(this.y, this.x); - } else { - var point = Point.read(arguments), - div = this.getLength() * point.getLength(); - if (Numerical.isZero(div)) { - return NaN; - } else { - var a = this.dot(point) / div; - return Math.acos(a < -1 ? -1 : a > 1 ? 1 : a); - } - } - }, - - setAngleInRadians: function(angle) { - this._angle = angle; - if (!this.isZero()) { - var length = this.getLength(); - this.set( - Math.cos(angle) * length, - Math.sin(angle) * length - ); - } - }, - - getQuadrant: function() { - return this.x >= 0 ? this.y >= 0 ? 1 : 4 : this.y >= 0 ? 2 : 3; - } -}, { - beans: false, - - getDirectedAngle: function() { - var point = Point.read(arguments); - return Math.atan2(this.cross(point), this.dot(point)) * 180 / Math.PI; - }, - - getDistance: function() { - var point = Point.read(arguments), - x = point.x - this.x, - y = point.y - this.y, - d = x * x + y * y, - squared = Base.read(arguments); - return squared ? d : Math.sqrt(d); - }, - - normalize: function(length) { - if (length === undefined) - length = 1; - var current = this.getLength(), - scale = current !== 0 ? length / current : 0, - point = new Point(this.x * scale, this.y * scale); - if (scale >= 0) - point._angle = this._angle; - return point; - }, - - rotate: function(angle, center) { - if (angle === 0) - return this.clone(); - angle = angle * Math.PI / 180; - var point = center ? this.subtract(center) : this, - sin = Math.sin(angle), - cos = Math.cos(angle); - point = new Point( - point.x * cos - point.y * sin, - point.x * sin + point.y * cos - ); - return center ? point.add(center) : point; - }, - - transform: function(matrix) { - return matrix ? matrix._transformPoint(this) : this; - }, - - add: function() { - var point = Point.read(arguments); - return new Point(this.x + point.x, this.y + point.y); - }, - - subtract: function() { - var point = Point.read(arguments); - return new Point(this.x - point.x, this.y - point.y); - }, - - multiply: function() { - var point = Point.read(arguments); - return new Point(this.x * point.x, this.y * point.y); - }, - - divide: function() { - var point = Point.read(arguments); - return new Point(this.x / point.x, this.y / point.y); - }, - - modulo: function() { - var point = Point.read(arguments); - return new Point(this.x % point.x, this.y % point.y); - }, - - negate: function() { - return new Point(-this.x, -this.y); - }, - - isInside: function() { - return Rectangle.read(arguments).contains(this); - }, - - isClose: function() { - var point = Point.read(arguments), - tolerance = Base.read(arguments); - return this.getDistance(point) < tolerance; - }, - - isCollinear: function() { - var point = Point.read(arguments); - return Point.isCollinear(this.x, this.y, point.x, point.y); - }, - - isColinear: '#isCollinear', - - isOrthogonal: function() { - var point = Point.read(arguments); - return Point.isOrthogonal(this.x, this.y, point.x, point.y); - }, - - isZero: function() { - return Numerical.isZero(this.x) && Numerical.isZero(this.y); - }, - - isNaN: function() { - return isNaN(this.x) || isNaN(this.y); - }, - - dot: function() { - var point = Point.read(arguments); - return this.x * point.x + this.y * point.y; - }, - - cross: function() { - var point = Point.read(arguments); - return this.x * point.y - this.y * point.x; - }, - - project: function() { - var point = Point.read(arguments), - scale = point.isZero() ? 0 : this.dot(point) / point.dot(point); - return new Point( - point.x * scale, - point.y * scale - ); - }, - - statics: { - min: function() { - var point1 = Point.read(arguments), - point2 = Point.read(arguments); - return new Point( - Math.min(point1.x, point2.x), - Math.min(point1.y, point2.y) - ); - }, - - max: function() { - var point1 = Point.read(arguments), - point2 = Point.read(arguments); - return new Point( - Math.max(point1.x, point2.x), - Math.max(point1.y, point2.y) - ); - }, - - random: function() { - return new Point(Math.random(), Math.random()); - }, - - isCollinear: function(x1, y1, x2, y2) { - return Math.abs(x1 * y2 - y1 * x2) - <= Math.sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2)) - * 1e-7; - }, - - isOrthogonal: function(x1, y1, x2, y2) { - return Math.abs(x1 * x2 + y1 * y2) - <= Math.sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2)) - * 1e-7; - } - } -}, Base.each(['round', 'ceil', 'floor', 'abs'], function(name) { - var op = Math[name]; - this[name] = function() { - return new Point(op(this.x), op(this.y)); - }; -}, {})); - -var LinkedPoint = Point.extend({ - initialize: function Point(x, y, owner, setter) { - this._x = x; - this._y = y; - this._owner = owner; - this._setter = setter; - }, - - set: function(x, y, _dontNotify) { - this._x = x; - this._y = y; - if (!_dontNotify) - this._owner[this._setter](this); - return this; - }, - - getX: function() { - return this._x; - }, - - setX: function(x) { - this._x = x; - this._owner[this._setter](this); - }, - - getY: function() { - return this._y; - }, - - setY: function(y) { - this._y = y; - this._owner[this._setter](this); - } -}); - -var Size = Base.extend({ - _class: 'Size', - _readIndex: true, - - initialize: function Size(arg0, arg1) { - var type = typeof arg0; - if (type === 'number') { - var hasHeight = typeof arg1 === 'number'; - this.width = arg0; - this.height = hasHeight ? arg1 : arg0; - if (this.__read) - this.__read = hasHeight ? 2 : 1; - } else if (type === 'undefined' || arg0 === null) { - this.width = this.height = 0; - if (this.__read) - this.__read = arg0 === null ? 1 : 0; - } else { - if (Array.isArray(arg0)) { - this.width = arg0[0]; - this.height = arg0.length > 1 ? arg0[1] : arg0[0]; - } else if (arg0.width != null) { - this.width = arg0.width; - this.height = arg0.height; - } else if (arg0.x != null) { - this.width = arg0.x; - this.height = arg0.y; - } else { - this.width = this.height = 0; - if (this.__read) - this.__read = 0; - } - if (this.__read) - this.__read = 1; - } - }, - - set: function(width, height) { - this.width = width; - this.height = height; - return this; - }, - - equals: function(size) { - return size === this || size && (this.width === size.width - && this.height === size.height - || Array.isArray(size) && this.width === size[0] - && this.height === size[1]) || false; - }, - - clone: function() { - return new Size(this.width, this.height); - }, - - toString: function() { - var f = Formatter.instance; - return '{ width: ' + f.number(this.width) - + ', height: ' + f.number(this.height) + ' }'; - }, - - _serialize: function(options) { - var f = options.formatter; - return [f.number(this.width), - f.number(this.height)]; - }, - - add: function() { - var size = Size.read(arguments); - return new Size(this.width + size.width, this.height + size.height); - }, - - subtract: function() { - var size = Size.read(arguments); - return new Size(this.width - size.width, this.height - size.height); - }, - - multiply: function() { - var size = Size.read(arguments); - return new Size(this.width * size.width, this.height * size.height); - }, - - divide: function() { - var size = Size.read(arguments); - return new Size(this.width / size.width, this.height / size.height); - }, - - modulo: function() { - var size = Size.read(arguments); - return new Size(this.width % size.width, this.height % size.height); - }, - - negate: function() { - return new Size(-this.width, -this.height); - }, - - isZero: function() { - return Numerical.isZero(this.width) && Numerical.isZero(this.height); - }, - - isNaN: function() { - return isNaN(this.width) || isNaN(this.height); - }, - - statics: { - min: function(size1, size2) { - return new Size( - Math.min(size1.width, size2.width), - Math.min(size1.height, size2.height)); - }, - - max: function(size1, size2) { - return new Size( - Math.max(size1.width, size2.width), - Math.max(size1.height, size2.height)); - }, - - random: function() { - return new Size(Math.random(), Math.random()); - } - } -}, Base.each(['round', 'ceil', 'floor', 'abs'], function(name) { - var op = Math[name]; - this[name] = function() { - return new Size(op(this.width), op(this.height)); - }; -}, {})); - -var LinkedSize = Size.extend({ - initialize: function Size(width, height, owner, setter) { - this._width = width; - this._height = height; - this._owner = owner; - this._setter = setter; - }, - - set: function(width, height, _dontNotify) { - this._width = width; - this._height = height; - if (!_dontNotify) - this._owner[this._setter](this); - return this; - }, - - getWidth: function() { - return this._width; - }, - - setWidth: function(width) { - this._width = width; - this._owner[this._setter](this); - }, - - getHeight: function() { - return this._height; - }, - - setHeight: function(height) { - this._height = height; - this._owner[this._setter](this); - } -}); - -var Rectangle = Base.extend({ - _class: 'Rectangle', - _readIndex: true, - beans: true, - - initialize: function Rectangle(arg0, arg1, arg2, arg3) { - var type = typeof arg0, - read = 0; - if (type === 'number') { - this.x = arg0; - this.y = arg1; - this.width = arg2; - this.height = arg3; - read = 4; - } else if (type === 'undefined' || arg0 === null) { - this.x = this.y = this.width = this.height = 0; - read = arg0 === null ? 1 : 0; - } else if (arguments.length === 1) { - if (Array.isArray(arg0)) { - this.x = arg0[0]; - this.y = arg0[1]; - this.width = arg0[2]; - this.height = arg0[3]; - read = 1; - } else if (arg0.x !== undefined || arg0.width !== undefined) { - this.x = arg0.x || 0; - this.y = arg0.y || 0; - this.width = arg0.width || 0; - this.height = arg0.height || 0; - read = 1; - } else if (arg0.from === undefined && arg0.to === undefined) { - this.x = this.y = this.width = this.height = 0; - this._set(arg0); - read = 1; - } - } - if (!read) { - var point = Point.readNamed(arguments, 'from'), - next = Base.peek(arguments); - this.x = point.x; - this.y = point.y; - if (next && next.x !== undefined || Base.hasNamed(arguments, 'to')) { - var to = Point.readNamed(arguments, 'to'); - this.width = to.x - point.x; - this.height = to.y - point.y; - if (this.width < 0) { - this.x = to.x; - this.width = -this.width; - } - if (this.height < 0) { - this.y = to.y; - this.height = -this.height; - } - } else { - var size = Size.read(arguments); - this.width = size.width; - this.height = size.height; - } - read = arguments.__index; - } - if (this.__read) - this.__read = read; - }, - - set: function(x, y, width, height) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - return this; - }, - - clone: function() { - return new Rectangle(this.x, this.y, this.width, this.height); - }, - - equals: function(rect) { - var rt = Base.isPlainValue(rect) - ? Rectangle.read(arguments) - : rect; - return rt === this - || rt && this.x === rt.x && this.y === rt.y - && this.width === rt.width && this.height === rt.height - || false; - }, - - toString: function() { - var f = Formatter.instance; - return '{ x: ' + f.number(this.x) - + ', y: ' + f.number(this.y) - + ', width: ' + f.number(this.width) - + ', height: ' + f.number(this.height) - + ' }'; - }, - - _serialize: function(options) { - var f = options.formatter; - return [f.number(this.x), - f.number(this.y), - f.number(this.width), - f.number(this.height)]; - }, - - getPoint: function(_dontLink) { - var ctor = _dontLink ? Point : LinkedPoint; - return new ctor(this.x, this.y, this, 'setPoint'); - }, - - setPoint: function() { - var point = Point.read(arguments); - this.x = point.x; - this.y = point.y; - }, - - getSize: function(_dontLink) { - var ctor = _dontLink ? Size : LinkedSize; - return new ctor(this.width, this.height, this, 'setSize'); - }, - - setSize: function() { - var size = Size.read(arguments); - if (this._fixX) - this.x += (this.width - size.width) * this._fixX; - if (this._fixY) - this.y += (this.height - size.height) * this._fixY; - this.width = size.width; - this.height = size.height; - this._fixW = 1; - this._fixH = 1; - }, - - getLeft: function() { - return this.x; - }, - - setLeft: function(left) { - if (!this._fixW) - this.width -= left - this.x; - this.x = left; - this._fixX = 0; - }, - - getTop: function() { - return this.y; - }, - - setTop: function(top) { - if (!this._fixH) - this.height -= top - this.y; - this.y = top; - this._fixY = 0; - }, - - getRight: function() { - return this.x + this.width; - }, - - setRight: function(right) { - if (this._fixX !== undefined && this._fixX !== 1) - this._fixW = 0; - if (this._fixW) - this.x = right - this.width; - else - this.width = right - this.x; - this._fixX = 1; - }, - - getBottom: function() { - return this.y + this.height; - }, - - setBottom: function(bottom) { - if (this._fixY !== undefined && this._fixY !== 1) - this._fixH = 0; - if (this._fixH) - this.y = bottom - this.height; - else - this.height = bottom - this.y; - this._fixY = 1; - }, - - getCenterX: function() { - return this.x + this.width * 0.5; - }, - - setCenterX: function(x) { - this.x = x - this.width * 0.5; - this._fixX = 0.5; - }, - - getCenterY: function() { - return this.y + this.height * 0.5; - }, - - setCenterY: function(y) { - this.y = y - this.height * 0.5; - this._fixY = 0.5; - }, - - getCenter: function(_dontLink) { - var ctor = _dontLink ? Point : LinkedPoint; - return new ctor(this.getCenterX(), this.getCenterY(), this, 'setCenter'); - }, - - setCenter: function() { - var point = Point.read(arguments); - this.setCenterX(point.x); - this.setCenterY(point.y); - return this; - }, - - getArea: function() { - return this.width * this.height; - }, - - isEmpty: function() { - return this.width === 0 || this.height === 0; - }, - - contains: function(arg) { - return arg && arg.width !== undefined - || (Array.isArray(arg) ? arg : arguments).length == 4 - ? this._containsRectangle(Rectangle.read(arguments)) - : this._containsPoint(Point.read(arguments)); - }, - - _containsPoint: function(point) { - var x = point.x, - y = point.y; - return x >= this.x && y >= this.y - && x <= this.x + this.width - && y <= this.y + this.height; - }, - - _containsRectangle: function(rect) { - var x = rect.x, - y = rect.y; - return x >= this.x && y >= this.y - && x + rect.width <= this.x + this.width - && y + rect.height <= this.y + this.height; - }, - - intersects: function() { - var rect = Rectangle.read(arguments); - return rect.x + rect.width > this.x - && rect.y + rect.height > this.y - && rect.x < this.x + this.width - && rect.y < this.y + this.height; - }, - - touches: function() { - var rect = Rectangle.read(arguments); - return rect.x + rect.width >= this.x - && rect.y + rect.height >= this.y - && rect.x <= this.x + this.width - && rect.y <= this.y + this.height; - }, - - intersect: function() { - var rect = Rectangle.read(arguments), - x1 = Math.max(this.x, rect.x), - y1 = Math.max(this.y, rect.y), - x2 = Math.min(this.x + this.width, rect.x + rect.width), - y2 = Math.min(this.y + this.height, rect.y + rect.height); - return new Rectangle(x1, y1, x2 - x1, y2 - y1); - }, - - unite: function() { - var rect = Rectangle.read(arguments), - x1 = Math.min(this.x, rect.x), - y1 = Math.min(this.y, rect.y), - x2 = Math.max(this.x + this.width, rect.x + rect.width), - y2 = Math.max(this.y + this.height, rect.y + rect.height); - return new Rectangle(x1, y1, x2 - x1, y2 - y1); - }, - - include: function() { - var point = Point.read(arguments); - var x1 = Math.min(this.x, point.x), - y1 = Math.min(this.y, point.y), - x2 = Math.max(this.x + this.width, point.x), - y2 = Math.max(this.y + this.height, point.y); - return new Rectangle(x1, y1, x2 - x1, y2 - y1); - }, - - expand: function() { - var amount = Size.read(arguments), - hor = amount.width, - ver = amount.height; - return new Rectangle(this.x - hor / 2, this.y - ver / 2, - this.width + hor, this.height + ver); - }, - - scale: function(hor, ver) { - return this.expand(this.width * hor - this.width, - this.height * (ver === undefined ? hor : ver) - this.height); - } -}, Base.each([ - ['Top', 'Left'], ['Top', 'Right'], - ['Bottom', 'Left'], ['Bottom', 'Right'], - ['Left', 'Center'], ['Top', 'Center'], - ['Right', 'Center'], ['Bottom', 'Center'] - ], - function(parts, index) { - var part = parts.join(''); - var xFirst = /^[RL]/.test(part); - if (index >= 4) - parts[1] += xFirst ? 'Y' : 'X'; - var x = parts[xFirst ? 0 : 1], - y = parts[xFirst ? 1 : 0], - getX = 'get' + x, - getY = 'get' + y, - setX = 'set' + x, - setY = 'set' + y, - get = 'get' + part, - set = 'set' + part; - this[get] = function(_dontLink) { - var ctor = _dontLink ? Point : LinkedPoint; - return new ctor(this[getX](), this[getY](), this, set); - }; - this[set] = function() { - var point = Point.read(arguments); - this[setX](point.x); - this[setY](point.y); - }; - }, { - beans: true - } -)); - -var LinkedRectangle = Rectangle.extend({ - initialize: function Rectangle(x, y, width, height, owner, setter) { - this.set(x, y, width, height, true); - this._owner = owner; - this._setter = setter; - }, - - set: function(x, y, width, height, _dontNotify) { - this._x = x; - this._y = y; - this._width = width; - this._height = height; - if (!_dontNotify) - this._owner[this._setter](this); - return this; - } -}, -new function() { - var proto = Rectangle.prototype; - - return Base.each(['x', 'y', 'width', 'height'], function(key) { - var part = Base.capitalize(key); - var internal = '_' + key; - this['get' + part] = function() { - return this[internal]; - }; - - this['set' + part] = function(value) { - this[internal] = value; - if (!this._dontNotify) - this._owner[this._setter](this); - }; - }, Base.each(['Point', 'Size', 'Center', - 'Left', 'Top', 'Right', 'Bottom', 'CenterX', 'CenterY', - 'TopLeft', 'TopRight', 'BottomLeft', 'BottomRight', - 'LeftCenter', 'TopCenter', 'RightCenter', 'BottomCenter'], - function(key) { - var name = 'set' + key; - this[name] = function() { - this._dontNotify = true; - proto[name].apply(this, arguments); - this._dontNotify = false; - this._owner[this._setter](this); - }; - }, { - isSelected: function() { - return this._owner._boundsSelected; - }, - - setSelected: function(selected) { - var owner = this._owner; - if (owner.setSelected) { - owner._boundsSelected = selected; - owner.setSelected(selected || owner._selectedSegmentState > 0); - } - } - }) - ); -}); - -var Matrix = Base.extend({ - _class: 'Matrix', - - initialize: function Matrix(arg) { - var count = arguments.length, - ok = true; - if (count === 6) { - this.set.apply(this, arguments); - } else if (count === 1) { - if (arg instanceof Matrix) { - this.set(arg._a, arg._c, arg._b, arg._d, arg._tx, arg._ty); - } else if (Array.isArray(arg)) { - this.set.apply(this, arg); - } else { - ok = false; - } - } else if (count === 0) { - this.reset(); - } else { - ok = false; - } - if (!ok) - throw new Error('Unsupported matrix parameters'); - }, - - set: function(a, c, b, d, tx, ty, _dontNotify) { - this._a = a; - this._c = c; - this._b = b; - this._d = d; - this._tx = tx; - this._ty = ty; - if (!_dontNotify) - this._changed(); - return this; - }, - - _serialize: function(options) { - return Base.serialize(this.getValues(), options); - }, - - _changed: function() { - var owner = this._owner; - if (owner) { - if (owner._applyMatrix) { - owner.transform(null, true); - } else { - owner._changed(9); - } - } - }, - - clone: function() { - return new Matrix(this._a, this._c, this._b, this._d, - this._tx, this._ty); - }, - - equals: function(mx) { - return mx === this || mx && this._a === mx._a && this._b === mx._b - && this._c === mx._c && this._d === mx._d - && this._tx === mx._tx && this._ty === mx._ty - || false; - }, - - toString: function() { - var f = Formatter.instance; - return '[[' + [f.number(this._a), f.number(this._b), - f.number(this._tx)].join(', ') + '], [' - + [f.number(this._c), f.number(this._d), - f.number(this._ty)].join(', ') + ']]'; - }, - - reset: function(_dontNotify) { - this._a = this._d = 1; - this._c = this._b = this._tx = this._ty = 0; - if (!_dontNotify) - this._changed(); - return this; - }, - - apply: function(recursively, _setApplyMatrix) { - var owner = this._owner; - if (owner) { - owner.transform(null, true, Base.pick(recursively, true), - _setApplyMatrix); - return this.isIdentity(); - } - return false; - }, - - translate: function() { - var point = Point.read(arguments), - x = point.x, - y = point.y; - this._tx += x * this._a + y * this._b; - this._ty += x * this._c + y * this._d; - this._changed(); - return this; - }, - - scale: function() { - var scale = Point.read(arguments), - center = Point.read(arguments, 0, { readNull: true }); - if (center) - this.translate(center); - this._a *= scale.x; - this._c *= scale.x; - this._b *= scale.y; - this._d *= scale.y; - if (center) - this.translate(center.negate()); - this._changed(); - return this; - }, - - rotate: function(angle ) { - angle *= Math.PI / 180; - var center = Point.read(arguments, 1), - x = center.x, - y = center.y, - cos = Math.cos(angle), - sin = Math.sin(angle), - tx = x - x * cos + y * sin, - ty = y - x * sin - y * cos, - a = this._a, - b = this._b, - c = this._c, - d = this._d; - this._a = cos * a + sin * b; - this._b = -sin * a + cos * b; - this._c = cos * c + sin * d; - this._d = -sin * c + cos * d; - this._tx += tx * a + ty * b; - this._ty += tx * c + ty * d; - this._changed(); - return this; - }, - - shear: function() { - var shear = Point.read(arguments), - center = Point.read(arguments, 0, { readNull: true }); - if (center) - this.translate(center); - var a = this._a, - c = this._c; - this._a += shear.y * this._b; - this._c += shear.y * this._d; - this._b += shear.x * a; - this._d += shear.x * c; - if (center) - this.translate(center.negate()); - this._changed(); - return this; - }, - - skew: function() { - var skew = Point.read(arguments), - center = Point.read(arguments, 0, { readNull: true }), - toRadians = Math.PI / 180, - shear = new Point(Math.tan(skew.x * toRadians), - Math.tan(skew.y * toRadians)); - return this.shear(shear, center); - }, - - concatenate: function(mx) { - var a1 = this._a, - b1 = this._b, - c1 = this._c, - d1 = this._d, - a2 = mx._a, - b2 = mx._b, - c2 = mx._c, - d2 = mx._d, - tx2 = mx._tx, - ty2 = mx._ty; - this._a = a2 * a1 + c2 * b1; - this._b = b2 * a1 + d2 * b1; - this._c = a2 * c1 + c2 * d1; - this._d = b2 * c1 + d2 * d1; - this._tx += tx2 * a1 + ty2 * b1; - this._ty += tx2 * c1 + ty2 * d1; - this._changed(); - return this; - }, - - preConcatenate: function(mx) { - var a1 = this._a, - b1 = this._b, - c1 = this._c, - d1 = this._d, - tx1 = this._tx, - ty1 = this._ty, - a2 = mx._a, - b2 = mx._b, - c2 = mx._c, - d2 = mx._d, - tx2 = mx._tx, - ty2 = mx._ty; - this._a = a2 * a1 + b2 * c1; - this._b = a2 * b1 + b2 * d1; - this._c = c2 * a1 + d2 * c1; - this._d = c2 * b1 + d2 * d1; - this._tx = a2 * tx1 + b2 * ty1 + tx2; - this._ty = c2 * tx1 + d2 * ty1 + ty2; - this._changed(); - return this; - }, - - chain: function(mx) { - var a1 = this._a, - b1 = this._b, - c1 = this._c, - d1 = this._d, - tx1 = this._tx, - ty1 = this._ty, - a2 = mx._a, - b2 = mx._b, - c2 = mx._c, - d2 = mx._d, - tx2 = mx._tx, - ty2 = mx._ty; - return new Matrix( - a2 * a1 + c2 * b1, - a2 * c1 + c2 * d1, - b2 * a1 + d2 * b1, - b2 * c1 + d2 * d1, - tx1 + tx2 * a1 + ty2 * b1, - ty1 + tx2 * c1 + ty2 * d1); - }, - - isIdentity: function() { - return this._a === 1 && this._c === 0 && this._b === 0 && this._d === 1 - && this._tx === 0 && this._ty === 0; - }, - - orNullIfIdentity: function() { - return this.isIdentity() ? null : this; - }, - - isInvertible: function() { - return !!this._getDeterminant(); - }, - - isSingular: function() { - return !this._getDeterminant(); - }, - - transform: function( src, dst, count) { - return arguments.length < 3 - ? this._transformPoint(Point.read(arguments)) - : this._transformCoordinates(src, dst, count); - }, - - _transformPoint: function(point, dest, _dontNotify) { - var x = point.x, - y = point.y; - if (!dest) - dest = new Point(); - return dest.set( - x * this._a + y * this._b + this._tx, - x * this._c + y * this._d + this._ty, - _dontNotify - ); - }, - - _transformCoordinates: function(src, dst, count) { - var i = 0, - j = 0, - max = 2 * count; - while (i < max) { - var x = src[i++], - y = src[i++]; - dst[j++] = x * this._a + y * this._b + this._tx; - dst[j++] = x * this._c + y * this._d + this._ty; - } - return dst; - }, - - _transformCorners: function(rect) { - var x1 = rect.x, - y1 = rect.y, - x2 = x1 + rect.width, - y2 = y1 + rect.height, - coords = [ x1, y1, x2, y1, x2, y2, x1, y2 ]; - return this._transformCoordinates(coords, coords, 4); - }, - - _transformBounds: function(bounds, dest, _dontNotify) { - var coords = this._transformCorners(bounds), - min = coords.slice(0, 2), - max = min.slice(); - for (var i = 2; i < 8; i++) { - var val = coords[i], - j = i & 1; - if (val < min[j]) - min[j] = val; - else if (val > max[j]) - max[j] = val; - } - if (!dest) - dest = new Rectangle(); - return dest.set(min[0], min[1], max[0] - min[0], max[1] - min[1], - _dontNotify); - }, - - inverseTransform: function() { - return this._inverseTransform(Point.read(arguments)); - }, - - _getDeterminant: function() { - var det = this._a * this._d - this._b * this._c; - return isFinite(det) && !Numerical.isZero(det) - && isFinite(this._tx) && isFinite(this._ty) - ? det : null; - }, - - _inverseTransform: function(point, dest, _dontNotify) { - var det = this._getDeterminant(); - if (!det) - return null; - var x = point.x - this._tx, - y = point.y - this._ty; - if (!dest) - dest = new Point(); - return dest.set( - (x * this._d - y * this._b) / det, - (y * this._a - x * this._c) / det, - _dontNotify - ); - }, - - decompose: function() { - var a = this._a, b = this._b, c = this._c, d = this._d; - if (Numerical.isZero(a * d - b * c)) - return null; - - var scaleX = Math.sqrt(a * a + b * b); - a /= scaleX; - b /= scaleX; - - var shear = a * c + b * d; - c -= a * shear; - d -= b * shear; - - var scaleY = Math.sqrt(c * c + d * d); - c /= scaleY; - d /= scaleY; - shear /= scaleY; - - if (a * d < b * c) { - a = -a; - b = -b; - shear = -shear; - scaleX = -scaleX; - } - - return { - scaling: new Point(scaleX, scaleY), - rotation: -Math.atan2(b, a) * 180 / Math.PI, - shearing: shear - }; - }, - - getValues: function() { - return [ this._a, this._c, this._b, this._d, this._tx, this._ty ]; - }, - - getTranslation: function() { - return new Point(this._tx, this._ty); - }, - - getScaling: function() { - return (this.decompose() || {}).scaling; - }, - - getRotation: function() { - return (this.decompose() || {}).rotation; - }, - - inverted: function() { - var det = this._getDeterminant(); - return det && new Matrix( - this._d / det, - -this._c / det, - -this._b / det, - this._a / det, - (this._b * this._ty - this._d * this._tx) / det, - (this._c * this._tx - this._a * this._ty) / det); - }, - - shiftless: function() { - return new Matrix(this._a, this._c, this._b, this._d, 0, 0); - }, - - applyToContext: function(ctx) { - ctx.transform(this._a, this._c, this._b, this._d, this._tx, this._ty); - } -}, Base.each(['a', 'c', 'b', 'd', 'tx', 'ty'], function(name) { - var part = Base.capitalize(name), - prop = '_' + name; - this['get' + part] = function() { - return this[prop]; - }; - this['set' + part] = function(value) { - this[prop] = value; - this._changed(); - }; -}, {})); - -var Line = Base.extend({ - _class: 'Line', - - initialize: function Line(arg0, arg1, arg2, arg3, arg4) { - var asVector = false; - if (arguments.length >= 4) { - this._px = arg0; - this._py = arg1; - this._vx = arg2; - this._vy = arg3; - asVector = arg4; - } else { - this._px = arg0.x; - this._py = arg0.y; - this._vx = arg1.x; - this._vy = arg1.y; - asVector = arg2; - } - if (!asVector) { - this._vx -= this._px; - this._vy -= this._py; - } - }, - - getPoint: function() { - return new Point(this._px, this._py); - }, - - getVector: function() { - return new Point(this._vx, this._vy); - }, - - getLength: function() { - return this.getVector().getLength(); - }, - - intersect: function(line, isInfinite) { - return Line.intersect( - this._px, this._py, this._vx, this._vy, - line._px, line._py, line._vx, line._vy, - true, isInfinite); - }, - - getSide: function(point, isInfinite) { - return Line.getSide( - this._px, this._py, this._vx, this._vy, - point.x, point.y, true, isInfinite); - }, - - getDistance: function(point) { - return Math.abs(Line.getSignedDistance( - this._px, this._py, this._vx, this._vy, - point.x, point.y, true)); - }, - - isCollinear: function(line) { - return Point.isCollinear(this._vx, this._vy, line._vx, line._vy); - }, - - isOrthogonal: function(line) { - return Point.isOrthogonal(this._vx, this._vy, line._vx, line._vy); - }, - - statics: { - intersect: function(p1x, p1y, v1x, v1y, p2x, p2y, v2x, v2y, asVector, - isInfinite) { - if (!asVector) { - v1x -= p1x; - v1y -= p1y; - v2x -= p2x; - v2y -= p2y; - } - var cross = v1x * v2y - v1y * v2x; - if (!Numerical.isZero(cross)) { - var dx = p1x - p2x, - dy = p1y - p2y, - u1 = (v2x * dy - v2y * dx) / cross, - u2 = (v1x * dy - v1y * dx) / cross, - epsilon = 1e-12, - uMin = -epsilon, - uMax = 1 + epsilon; - if (isInfinite - || uMin < u1 && u1 < uMax && uMin < u2 && u2 < uMax) { - if (!isInfinite) { - u1 = u1 <= 0 ? 0 : u1 >= 1 ? 1 : u1; - } - return new Point( - p1x + u1 * v1x, - p1y + u1 * v1y); - } - } - }, - - getSide: function(px, py, vx, vy, x, y, asVector, isInfinite) { - if (!asVector) { - vx -= px; - vy -= py; - } - var v2x = x - px, - v2y = y - py, - ccw = v2x * vy - v2y * vx; - if (ccw === 0 && !isInfinite) { - ccw = (v2x * vx + v2x * vx) / (vx * vx + vy * vy); - if (ccw >= 0 && ccw <= 1) - ccw = 0; - } - return ccw < 0 ? -1 : ccw > 0 ? 1 : 0; - }, - - getSignedDistance: function(px, py, vx, vy, x, y, asVector) { - if (!asVector) { - vx -= px; - vy -= py; - } - return vx === 0 ? vy > 0 ? x - px : px - x - : vy === 0 ? vx < 0 ? y - py : py - y - : ((x-px) * vy - (y-py) * vx) / Math.sqrt(vx * vx + vy * vy); - } - } -}); - -var Project = PaperScopeItem.extend({ - _class: 'Project', - _list: 'projects', - _reference: 'project', - - initialize: function Project(element) { - PaperScopeItem.call(this, true); - this.layers = []; - this._activeLayer = null; - this.symbols = []; - this._currentStyle = new Style(null, null, this); - this._view = View.create(this, - element || CanvasProvider.getCanvas(1, 1)); - this._selectedItems = {}; - this._selectedItemCount = 0; - this._updateVersion = 0; - }, - - _serialize: function(options, dictionary) { - return Base.serialize(this.layers, options, true, dictionary); - }, - - clear: function() { - for (var i = this.layers.length - 1; i >= 0; i--) - this.layers[i].remove(); - this.symbols = []; - }, - - isEmpty: function() { - return this.layers.length === 0; - }, - - remove: function remove() { - if (!remove.base.call(this)) - return false; - if (this._view) - this._view.remove(); - return true; - }, - - getView: function() { - return this._view; - }, - - getCurrentStyle: function() { - return this._currentStyle; - }, - - setCurrentStyle: function(style) { - this._currentStyle.initialize(style); - }, - - getIndex: function() { - return this._index; - }, - - getOptions: function() { - return this._scope.settings; - }, - - getActiveLayer: function() { - return this._activeLayer || new Layer({ project: this }); - }, - - getSelectedItems: function() { - var items = []; - for (var id in this._selectedItems) { - var item = this._selectedItems[id]; - if (item.isInserted()) - items.push(item); - } - return items; - }, - - insertChild: function(index, item, _preserve) { - if (item instanceof Layer) { - item._remove(false, true); - Base.splice(this.layers, [item], index, 0); - item._setProject(this, true); - if (this._changes) - item._changed(5); - if (!this._activeLayer) - this._activeLayer = item; - } else if (item instanceof Item) { - (this._activeLayer - || this.insertChild(index, new Layer(Item.NO_INSERT))) - .insertChild(index, item, _preserve); - } else { - item = null; - } - return item; - }, - - addChild: function(item, _preserve) { - return this.insertChild(undefined, item, _preserve); - }, - - _updateSelection: function(item) { - var id = item._id, - selectedItems = this._selectedItems; - if (item._selected) { - if (selectedItems[id] !== item) { - this._selectedItemCount++; - selectedItems[id] = item; - } - } else if (selectedItems[id] === item) { - this._selectedItemCount--; - delete selectedItems[id]; - } - }, - - selectAll: function() { - var layers = this.layers; - for (var i = 0, l = layers.length; i < l; i++) - layers[i].setFullySelected(true); - }, - - deselectAll: function() { - var selectedItems = this._selectedItems; - for (var i in selectedItems) - selectedItems[i].setFullySelected(false); - }, - - hitTest: function() { - var point = Point.read(arguments), - options = HitResult.getOptions(Base.read(arguments)); - for (var i = this.layers.length - 1; i >= 0; i--) { - var res = this.layers[i]._hitTest(point, options); - if (res) return res; - } - return null; - }, - - getItems: function(match) { - return Item._getItems(this.layers, match); - }, - - getItem: function(match) { - return Item._getItems(this.layers, match, null, null, true)[0] || null; - }, - - importJSON: function(json) { - this.activate(); - var layer = this._activeLayer; - return Base.importJSON(json, layer && layer.isEmpty() && layer); - }, - - draw: function(ctx, matrix, pixelRatio) { - this._updateVersion++; - ctx.save(); - matrix.applyToContext(ctx); - var param = new Base({ - offset: new Point(0, 0), - pixelRatio: pixelRatio, - viewMatrix: matrix.isIdentity() ? null : matrix, - matrices: [new Matrix()], - updateMatrix: true - }); - for (var i = 0, layers = this.layers, l = layers.length; i < l; i++) - layers[i].draw(ctx, param); - ctx.restore(); - - if (this._selectedItemCount > 0) { - ctx.save(); - ctx.strokeWidth = 1; - var items = this._selectedItems, - size = this._scope.settings.handleSize, - version = this._updateVersion; - for (var id in items) - items[id]._drawSelection(ctx, matrix, size, items, version); - ctx.restore(); - } - } -}); - -var Symbol = Base.extend({ - _class: 'Symbol', - - initialize: function Symbol(item, dontCenter) { - this._id = UID.get(); - this.project = paper.project; - this.project.symbols.push(this); - if (item) - this.setDefinition(item, dontCenter); - }, - - _serialize: function(options, dictionary) { - return dictionary.add(this, function() { - return Base.serialize([this._class, this._definition], - options, false, dictionary); - }); - }, - - _changed: function(flags) { - if (flags & 8) { - Item._clearBoundsCache(this); - } - if (flags & 1) { - this.project._needsUpdate = true; - } - }, - - getDefinition: function() { - return this._definition; - }, - - setDefinition: function(item, _dontCenter) { - if (item._parentSymbol) - item = item.clone(); - if (this._definition) - this._definition._parentSymbol = null; - this._definition = item; - item.remove(); - item.setSelected(false); - if (!_dontCenter) - item.setPosition(new Point()); - item._parentSymbol = this; - this._changed(9); - }, - - place: function(position) { - return new PlacedSymbol(this, position); - }, - - clone: function() { - return new Symbol(this._definition.clone(false)); - }, - - equals: function(symbol) { - return symbol === this - || symbol && this.definition.equals(symbol.definition) - || false; - } -}); - -var Item = Base.extend(Emitter, { - statics: { - extend: function extend(src) { - if (src._serializeFields) - src._serializeFields = new Base( - this.prototype._serializeFields, src._serializeFields); - return extend.base.apply(this, arguments); - }, - - NO_INSERT: { insert: false } - }, - - _class: 'Item', - _applyMatrix: true, - _canApplyMatrix: true, - _boundsSelected: false, - _selectChildren: false, - _serializeFields: { - name: null, - applyMatrix: null, - matrix: new Matrix(), - pivot: null, - locked: false, - visible: true, - blendMode: 'normal', - opacity: 1, - guide: false, - selected: false, - clipMask: false, - data: {} - }, - - initialize: function Item() { - }, - - _initialize: function(props, point) { - var hasProps = props && Base.isPlainObject(props), - internal = hasProps && props.internal === true, - matrix = this._matrix = new Matrix(), - project = hasProps && props.project || paper.project; - if (!internal) - this._id = UID.get(); - this._applyMatrix = this._canApplyMatrix && paper.settings.applyMatrix; - if (point) - matrix.translate(point); - matrix._owner = this; - this._style = new Style(project._currentStyle, this, project); - if (!this._project) { - if (internal || hasProps && props.insert === false) { - this._setProject(project); - } else if (hasProps && props.parent) { - this.setParent(props.parent); - } else { - (project._activeLayer || new Layer()).addChild(this); - } - } - if (hasProps && props !== Item.NO_INSERT) - this._set(props, { insert: true, project: true, parent: true }, - true); - return hasProps; - }, - - _events: Base.each(['onMouseDown', 'onMouseUp', 'onMouseDrag', 'onClick', - 'onDoubleClick', 'onMouseMove', 'onMouseEnter', 'onMouseLeave'], - function(name) { - this[name] = { - install: function(type) { - this.getView()._installEvent(type); - }, - - uninstall: function(type) { - this.getView()._uninstallEvent(type); - } - }; - }, { - onFrame: { - install: function() { - this.getView()._animateItem(this, true); - }, - - uninstall: function() { - this.getView()._animateItem(this, false); - } - }, - - onLoad: {} - } - ), - - _serialize: function(options, dictionary) { - var props = {}, - that = this; - - function serialize(fields) { - for (var key in fields) { - var value = that[key]; - if (!Base.equals(value, key === 'leading' - ? fields.fontSize * 1.2 : fields[key])) { - props[key] = Base.serialize(value, options, - key !== 'data', dictionary); - } - } - } - - serialize(this._serializeFields); - if (!(this instanceof Group)) - serialize(this._style._defaults); - return [ this._class, props ]; - }, - - _changed: function(flags) { - var symbol = this._parentSymbol, - cacheParent = this._parent || symbol, - project = this._project; - if (flags & 8) { - this._bounds = this._position = this._decomposed = - this._globalMatrix = this._currentPath = undefined; - } - if (cacheParent - && (flags & 40)) { - Item._clearBoundsCache(cacheParent); - } - if (flags & 2) { - Item._clearBoundsCache(this); - } - if (project) { - if (flags & 1) { - project._needsUpdate = true; - } - if (project._changes) { - var entry = project._changesById[this._id]; - if (entry) { - entry.flags |= flags; - } else { - entry = { item: this, flags: flags }; - project._changesById[this._id] = entry; - project._changes.push(entry); - } - } - } - if (symbol) - symbol._changed(flags); - }, - - set: function(props) { - if (props) - this._set(props); - return this; - }, - - getId: function() { - return this._id; - }, - - getName: function() { - return this._name; - }, - - setName: function(name, unique) { - - if (this._name) - this._removeNamed(); - if (name === (+name) + '') - throw new Error( - 'Names consisting only of numbers are not supported.'); - var parent = this._parent; - if (name && parent) { - var children = parent._children, - namedChildren = parent._namedChildren, - orig = name, - i = 1; - while (unique && children[name]) - name = orig + ' ' + (i++); - (namedChildren[name] = namedChildren[name] || []).push(this); - children[name] = this; - } - this._name = name || undefined; - this._changed(128); - }, - - getStyle: function() { - return this._style; - }, - - setStyle: function(style) { - this.getStyle().set(style); - } -}, Base.each(['locked', 'visible', 'blendMode', 'opacity', 'guide'], - function(name) { - var part = Base.capitalize(name), - name = '_' + name; - this['get' + part] = function() { - return this[name]; - }; - this['set' + part] = function(value) { - if (value != this[name]) { - this[name] = value; - this._changed(name === '_locked' - ? 128 : 129); - } - }; - }, -{}), { - beans: true, - - _locked: false, - - _visible: true, - - _blendMode: 'normal', - - _opacity: 1, - - _guide: false, - - isSelected: function() { - if (this._selectChildren) { - var children = this._children; - for (var i = 0, l = children.length; i < l; i++) - if (children[i].isSelected()) - return true; - } - return this._selected; - }, - - setSelected: function(selected, noChildren) { - if (!noChildren && this._selectChildren) { - var children = this._children; - for (var i = 0, l = children.length; i < l; i++) - children[i].setSelected(selected); - } - if ((selected = !!selected) ^ this._selected) { - this._selected = selected; - this._project._updateSelection(this); - this._changed(129); - } - }, - - _selected: false, - - isFullySelected: function() { - var children = this._children; - if (children && this._selected) { - for (var i = 0, l = children.length; i < l; i++) - if (!children[i].isFullySelected()) - return false; - return true; - } - return this._selected; - }, - - setFullySelected: function(selected) { - var children = this._children; - if (children) { - for (var i = 0, l = children.length; i < l; i++) - children[i].setFullySelected(selected); - } - this.setSelected(selected, true); - }, - - isClipMask: function() { - return this._clipMask; - }, - - setClipMask: function(clipMask) { - if (this._clipMask != (clipMask = !!clipMask)) { - this._clipMask = clipMask; - if (clipMask) { - this.setFillColor(null); - this.setStrokeColor(null); - } - this._changed(129); - if (this._parent) - this._parent._changed(1024); - } - }, - - _clipMask: false, - - getData: function() { - if (!this._data) - this._data = {}; - return this._data; - }, - - setData: function(data) { - this._data = data; - }, - - getPosition: function(_dontLink) { - var position = this._position, - ctor = _dontLink ? Point : LinkedPoint; - if (!position) { - var pivot = this._pivot; - position = this._position = pivot - ? this._matrix._transformPoint(pivot) - : this.getBounds().getCenter(true); - } - return new ctor(position.x, position.y, this, 'setPosition'); - }, - - setPosition: function() { - this.translate(Point.read(arguments).subtract(this.getPosition(true))); - }, - - getPivot: function(_dontLink) { - var pivot = this._pivot; - if (pivot) { - var ctor = _dontLink ? Point : LinkedPoint; - pivot = new ctor(pivot.x, pivot.y, this, 'setPivot'); - } - return pivot; - }, - - setPivot: function() { - this._pivot = Point.read(arguments, 0, { clone: true, readNull: true }); - this._position = undefined; - }, - - _pivot: null, -}, Base.each(['bounds', 'strokeBounds', 'handleBounds', 'roughBounds', - 'internalBounds', 'internalRoughBounds'], - function(key) { - var getter = 'get' + Base.capitalize(key), - match = key.match(/^internal(.*)$/), - internalGetter = match ? 'get' + match[1] : null; - this[getter] = function(_matrix) { - var boundsGetter = this._boundsGetter, - name = !internalGetter && (typeof boundsGetter === 'string' - ? boundsGetter : boundsGetter && boundsGetter[getter]) - || getter, - bounds = this._getCachedBounds(name, _matrix, this, - internalGetter); - return key === 'bounds' - ? new LinkedRectangle(bounds.x, bounds.y, bounds.width, - bounds.height, this, 'setBounds') - : bounds; - }; - }, -{ - beans: true, - - _getBounds: function(getter, matrix, cacheItem) { - var children = this._children; - if (!children || children.length == 0) - return new Rectangle(); - Item._updateBoundsCache(this, cacheItem); - var x1 = Infinity, - x2 = -x1, - y1 = x1, - y2 = x2; - for (var i = 0, l = children.length; i < l; i++) { - var child = children[i]; - if (child._visible && !child.isEmpty()) { - var rect = child._getCachedBounds(getter, - matrix && matrix.chain(child._matrix), cacheItem); - x1 = Math.min(rect.x, x1); - y1 = Math.min(rect.y, y1); - x2 = Math.max(rect.x + rect.width, x2); - y2 = Math.max(rect.y + rect.height, y2); - } - } - return isFinite(x1) - ? new Rectangle(x1, y1, x2 - x1, y2 - y1) - : new Rectangle(); - }, - - setBounds: function() { - var rect = Rectangle.read(arguments), - bounds = this.getBounds(), - matrix = new Matrix(), - center = rect.getCenter(); - matrix.translate(center); - if (rect.width != bounds.width || rect.height != bounds.height) { - matrix.scale( - bounds.width != 0 ? rect.width / bounds.width : 1, - bounds.height != 0 ? rect.height / bounds.height : 1); - } - center = bounds.getCenter(); - matrix.translate(-center.x, -center.y); - this.transform(matrix); - }, - - _getCachedBounds: function(getter, matrix, cacheItem, internalGetter) { - matrix = matrix && matrix.orNullIfIdentity(); - var _matrix = internalGetter ? null : this._matrix.orNullIfIdentity(), - cache = (!matrix || matrix.equals(_matrix)) && getter; - Item._updateBoundsCache(this._parent || this._parentSymbol, cacheItem); - if (cache && this._bounds && this._bounds[cache]) - return this._bounds[cache].clone(); - var bounds = this._getBounds(internalGetter || getter, - matrix || _matrix, cacheItem); - if (cache) { - if (!this._bounds) - this._bounds = {}; - var cached = this._bounds[cache] = bounds.clone(); - cached._internal = !!internalGetter; - } - return bounds; - }, - - statics: { - _updateBoundsCache: function(parent, item) { - if (parent) { - var id = item._id, - ref = parent._boundsCache = parent._boundsCache || { - ids: {}, - list: [] - }; - if (!ref.ids[id]) { - ref.list.push(item); - ref.ids[id] = item; - } - } - }, - - _clearBoundsCache: function(item) { - var cache = item._boundsCache; - if (cache) { - item._bounds = item._position = item._boundsCache = undefined; - for (var i = 0, list = cache.list, l = list.length; i < l; i++){ - var other = list[i]; - if (other !== item) { - other._bounds = other._position = undefined; - if (other._boundsCache) - Item._clearBoundsCache(other); - } - } - } - } - } - -}), { - beans: true, - - _decompose: function() { - return this._decomposed = this._matrix.decompose(); - }, - - getRotation: function() { - var decomposed = this._decomposed || this._decompose(); - return decomposed && decomposed.rotation; - }, - - setRotation: function(rotation) { - var current = this.getRotation(); - if (current != null && rotation != null) { - var decomposed = this._decomposed; - this.rotate(rotation - current); - decomposed.rotation = rotation; - this._decomposed = decomposed; - } - }, - - getScaling: function(_dontLink) { - var decomposed = this._decomposed || this._decompose(), - scaling = decomposed && decomposed.scaling, - ctor = _dontLink ? Point : LinkedPoint; - return scaling && new ctor(scaling.x, scaling.y, this, 'setScaling'); - }, - - setScaling: function() { - var current = this.getScaling(); - if (current) { - var scaling = Point.read(arguments, 0, { clone: true }), - decomposed = this._decomposed; - this.scale(scaling.x / current.x, scaling.y / current.y); - decomposed.scaling = scaling; - this._decomposed = decomposed; - } - }, - - getMatrix: function() { - return this._matrix; - }, - - setMatrix: function() { - var matrix = this._matrix; - matrix.initialize.apply(matrix, arguments); - if (this._applyMatrix) { - this.transform(null, true); - } else { - this._changed(9); - } - }, - - getGlobalMatrix: function(_dontClone) { - var matrix = this._globalMatrix, - updateVersion = this._project._updateVersion; - if (matrix && matrix._updateVersion !== updateVersion) - matrix = null; - if (!matrix) { - matrix = this._globalMatrix = this._matrix.clone(); - var parent = this._parent; - if (parent) - matrix.preConcatenate(parent.getGlobalMatrix(true)); - matrix._updateVersion = updateVersion; - } - return _dontClone ? matrix : matrix.clone(); - }, - - getApplyMatrix: function() { - return this._applyMatrix; - }, - - setApplyMatrix: function(apply) { - if (this._applyMatrix = this._canApplyMatrix && !!apply) - this.transform(null, true); - }, - - getTransformContent: '#getApplyMatrix', - setTransformContent: '#setApplyMatrix', -}, { - getProject: function() { - return this._project; - }, - - _setProject: function(project, installEvents) { - if (this._project !== project) { - if (this._project) - this._installEvents(false); - this._project = project; - var children = this._children; - for (var i = 0, l = children && children.length; i < l; i++) - children[i]._setProject(project); - installEvents = true; - } - if (installEvents) - this._installEvents(true); - }, - - getView: function() { - return this._project.getView(); - }, - - _installEvents: function _installEvents(install) { - _installEvents.base.call(this, install); - var children = this._children; - for (var i = 0, l = children && children.length; i < l; i++) - children[i]._installEvents(install); - }, - - getLayer: function() { - var parent = this; - while (parent = parent._parent) { - if (parent instanceof Layer) - return parent; - } - return null; - }, - - getParent: function() { - return this._parent; - }, - - setParent: function(item) { - return item.addChild(this); - }, - - getChildren: function() { - return this._children; - }, - - setChildren: function(items) { - this.removeChildren(); - this.addChildren(items); - }, - - getFirstChild: function() { - return this._children && this._children[0] || null; - }, - - getLastChild: function() { - return this._children && this._children[this._children.length - 1] - || null; - }, - - getNextSibling: function() { - return this._parent && this._parent._children[this._index + 1] || null; - }, - - getPreviousSibling: function() { - return this._parent && this._parent._children[this._index - 1] || null; - }, - - getIndex: function() { - return this._index; - }, - - equals: function(item) { - return item === this || item && this._class === item._class - && this._style.equals(item._style) - && this._matrix.equals(item._matrix) - && this._locked === item._locked - && this._visible === item._visible - && this._blendMode === item._blendMode - && this._opacity === item._opacity - && this._clipMask === item._clipMask - && this._guide === item._guide - && this._equals(item) - || false; - }, - - _equals: function(item) { - return Base.equals(this._children, item._children); - }, - - clone: function(insert) { - return this._clone(new this.constructor(Item.NO_INSERT), insert); - }, - - _clone: function(copy, insert, includeMatrix) { - var keys = ['_locked', '_visible', '_blendMode', '_opacity', - '_clipMask', '_guide'], - children = this._children; - copy.setStyle(this._style); - for (var i = 0, l = children && children.length; i < l; i++) { - copy.addChild(children[i].clone(false), true); - } - for (var i = 0, l = keys.length; i < l; i++) { - var key = keys[i]; - if (this.hasOwnProperty(key)) - copy[key] = this[key]; - } - if (includeMatrix !== false) - copy._matrix.initialize(this._matrix); - copy.setApplyMatrix(this._applyMatrix); - copy.setPivot(this._pivot); - copy.setSelected(this._selected); - copy._data = this._data ? Base.clone(this._data) : null; - if (insert || insert === undefined) - copy.insertAbove(this); - if (this._name) - copy.setName(this._name, true); - return copy; - }, - - copyTo: function(itemOrProject) { - return itemOrProject.addChild(this.clone(false)); - }, - - rasterize: function(resolution) { - var bounds = this.getStrokeBounds(), - scale = (resolution || this.getView().getResolution()) / 72, - topLeft = bounds.getTopLeft().floor(), - bottomRight = bounds.getBottomRight().ceil(), - size = new Size(bottomRight.subtract(topLeft)), - canvas = CanvasProvider.getCanvas(size.multiply(scale)), - ctx = canvas.getContext('2d'), - matrix = new Matrix().scale(scale).translate(topLeft.negate()); - ctx.save(); - matrix.applyToContext(ctx); - this.draw(ctx, new Base({ matrices: [matrix] })); - ctx.restore(); - var raster = new Raster(Item.NO_INSERT); - raster.setCanvas(canvas); - raster.transform(new Matrix().translate(topLeft.add(size.divide(2))) - .scale(1 / scale)); - raster.insertAbove(this); - return raster; - }, - - contains: function() { - return !!this._contains( - this._matrix._inverseTransform(Point.read(arguments))); - }, - - _contains: function(point) { - if (this._children) { - for (var i = this._children.length - 1; i >= 0; i--) { - if (this._children[i].contains(point)) - return true; - } - return false; - } - return point.isInside(this.getInternalBounds()); - }, - - isInside: function() { - return Rectangle.read(arguments).contains(this.getBounds()); - }, - - _asPathItem: function() { - return new Path.Rectangle({ - rectangle: this.getInternalBounds(), - matrix: this._matrix, - insert: false, - }); - }, - - intersects: function(item, _matrix) { - if (!(item instanceof Item)) - return false; - return this._asPathItem().getIntersections(item._asPathItem(), null, - _matrix || item._matrix, true).length > 0; - }, - - hitTest: function() { - return this._hitTest( - Point.read(arguments), - HitResult.getOptions(Base.read(arguments))); - }, - - _hitTest: function(point, options) { - if (this._locked || !this._visible || this._guide && !options.guides - || this.isEmpty()) - return null; - - var matrix = this._matrix, - parentTotalMatrix = options._totalMatrix, - view = this.getView(), - totalMatrix = options._totalMatrix = parentTotalMatrix - ? parentTotalMatrix.chain(matrix) - : this.getGlobalMatrix().preConcatenate(view._matrix), - tolerancePadding = options._tolerancePadding = new Size( - Path._getPenPadding(1, totalMatrix.inverted()) - ).multiply( - Math.max(options.tolerance, 1e-6) - ); - point = matrix._inverseTransform(point); - - if (!this._children && !this.getInternalRoughBounds() - .expand(tolerancePadding.multiply(2))._containsPoint(point)) - return null; - var checkSelf = !(options.guides && !this._guide - || options.selected && !this._selected - || options.type && options.type !== Base.hyphenate(this._class) - || options.class && !(this instanceof options.class)), - that = this, - res; - - function checkBounds(type, part) { - var pt = bounds['get' + part](); - if (point.subtract(pt).divide(tolerancePadding).length <= 1) - return new HitResult(type, that, - { name: Base.hyphenate(part), point: pt }); - } - - if (checkSelf && (options.center || options.bounds) && this._parent) { - var bounds = this.getInternalBounds(); - if (options.center) - res = checkBounds('center', 'Center'); - if (!res && options.bounds) { - var points = [ - 'TopLeft', 'TopRight', 'BottomLeft', 'BottomRight', - 'LeftCenter', 'TopCenter', 'RightCenter', 'BottomCenter' - ]; - for (var i = 0; i < 8 && !res; i++) - res = checkBounds('bounds', points[i]); - } - } - - var children = !res && this._children; - if (children) { - var opts = this._getChildHitTestOptions(options); - for (var i = children.length - 1; i >= 0 && !res; i--) - res = children[i]._hitTest(point, opts); - } - if (!res && checkSelf) - res = this._hitTestSelf(point, options); - if (res && res.point) - res.point = matrix.transform(res.point); - options._totalMatrix = parentTotalMatrix; - return res; - }, - - _getChildHitTestOptions: function(options) { - return options; - }, - - _hitTestSelf: function(point, options) { - if (options.fill && this.hasFill() && this._contains(point)) - return new HitResult('fill', this); - }, - - matches: function(name, compare) { - function matchObject(obj1, obj2) { - for (var i in obj1) { - if (obj1.hasOwnProperty(i)) { - var val1 = obj1[i], - val2 = obj2[i]; - if (Base.isPlainObject(val1) && Base.isPlainObject(val2)) { - if (!matchObject(val1, val2)) - return false; - } else if (!Base.equals(val1, val2)) { - return false; - } - } - } - return true; - } - var type = typeof name; - if (type === 'object') { - for (var key in name) { - if (name.hasOwnProperty(key) && !this.matches(key, name[key])) - return false; - } - } else if (type === 'function') { - return name(this); - } else { - var value = /^(empty|editable)$/.test(name) - ? this['is' + Base.capitalize(name)]() - : name === 'type' - ? Base.hyphenate(this._class) - : this[name]; - if (/^(constructor|class)$/.test(name)) { - if (!(this instanceof compare)) - return false; - } else if (compare instanceof RegExp) { - if (!compare.test(value)) - return false; - } else if (typeof compare === 'function') { - if (!compare(value)) - return false; - } else if (Base.isPlainObject(compare)) { - if (!matchObject(compare, value)) - return false; - } else if (!Base.equals(value, compare)) { - return false; - } - } - return true; - }, - - getItems: function(match) { - return Item._getItems(this._children, match, this._matrix); - }, - - getItem: function(match) { - return Item._getItems(this._children, match, this._matrix, null, true) - [0] || null; - }, - - statics: { - _getItems: function _getItems(children, match, matrix, param, - firstOnly) { - if (!param && typeof match === 'object') { - var overlapping = match.overlapping, - inside = match.inside, - bounds = overlapping || inside, - rect = bounds && Rectangle.read([bounds]); - param = { - items: [], - inside: !!inside, - overlapping: !!overlapping, - rect: rect, - path: overlapping && new Path.Rectangle({ - rectangle: rect, - insert: false - }) - }; - if (bounds) - match = Base.set({}, match, - { inside: true, overlapping: true }); - } - var items = param && param.items, - rect = param && param.rect; - matrix = rect && (matrix || new Matrix()); - for (var i = 0, l = children && children.length; i < l; i++) { - var child = children[i], - childMatrix = matrix && matrix.chain(child._matrix), - add = true; - if (rect) { - var bounds = child.getBounds(childMatrix); - if (!rect.intersects(bounds)) - continue; - if (!(param.inside && rect.contains(bounds)) - && !(param.overlapping && (bounds.contains(rect) - || param.path.intersects(child, childMatrix)))) - add = false; - } - if (add && child.matches(match)) { - items.push(child); - if (firstOnly) - break; - } - _getItems(child._children, match, - childMatrix, param, - firstOnly); - if (firstOnly && items.length > 0) - break; - } - return items; - } - } -}, { - - importJSON: function(json) { - var res = Base.importJSON(json, this); - return res !== this - ? this.addChild(res) - : res; - }, - - addChild: function(item, _preserve) { - return this.insertChild(undefined, item, _preserve); - }, - - insertChild: function(index, item, _preserve) { - var res = item ? this.insertChildren(index, [item], _preserve) : null; - return res && res[0]; - }, - - addChildren: function(items, _preserve) { - return this.insertChildren(this._children.length, items, _preserve); - }, - - insertChildren: function(index, items, _preserve, _proto) { - var children = this._children; - if (children && items && items.length > 0) { - items = Array.prototype.slice.apply(items); - for (var i = items.length - 1; i >= 0; i--) { - var item = items[i]; - if (_proto && !(item instanceof _proto)) { - items.splice(i, 1); - } else { - var shift = item._parent === this && item._index < index; - if (item._remove(false, true) && shift) - index--; - } - } - Base.splice(children, items, index, 0); - var project = this._project, - notifySelf = project && project._changes; - for (var i = 0, l = items.length; i < l; i++) { - var item = items[i]; - item._parent = this; - item._setProject(this._project, true); - if (item._name) - item.setName(item._name); - if (notifySelf) - this._changed(5); - } - this._changed(11); - } else { - items = null; - } - return items; - }, - - _insertSibling: function(index, item, _preserve) { - return this._parent - ? this._parent.insertChild(index, item, _preserve) - : null; - }, - - insertAbove: function(item, _preserve) { - return item._insertSibling(item._index + 1, this, _preserve); - }, - - insertBelow: function(item, _preserve) { - return item._insertSibling(item._index, this, _preserve); - }, - - sendToBack: function() { - return (this._parent || this instanceof Layer && this._project) - .insertChild(0, this); - }, - - bringToFront: function() { - return (this._parent || this instanceof Layer && this._project) - .addChild(this); - }, - - appendTop: '#addChild', - - appendBottom: function(item) { - return this.insertChild(0, item); - }, - - moveAbove: '#insertAbove', - - moveBelow: '#insertBelow', - - reduce: function() { - if (this._children && this._children.length === 1) { - var child = this._children[0].reduce(); - child.insertAbove(this); - child.setStyle(this._style); - this.remove(); - return child; - } - return this; - }, - - _removeNamed: function() { - var parent = this._parent; - if (parent) { - var children = parent._children, - namedChildren = parent._namedChildren, - name = this._name, - namedArray = namedChildren[name], - index = namedArray ? namedArray.indexOf(this) : -1; - if (index !== -1) { - if (children[name] == this) - delete children[name]; - namedArray.splice(index, 1); - if (namedArray.length) { - children[name] = namedArray[namedArray.length - 1]; - } else { - delete namedChildren[name]; - } - } - } - }, - - _remove: function(notifySelf, notifyParent) { - var parent = this._parent; - if (parent) { - if (this._name) - this._removeNamed(); - if (this._index != null) - Base.splice(parent._children, null, this._index, 1); - this._installEvents(false); - if (notifySelf) { - var project = this._project; - if (project && project._changes) - this._changed(5); - } - if (notifyParent) - parent._changed(11); - this._parent = null; - return true; - } - return false; - }, - - remove: function() { - return this._remove(true, true); - }, - - replaceWith: function(item) { - var ok = item && item.insertBelow(this); - if (ok) - this.remove(); - return ok; - }, - - removeChildren: function(from, to) { - if (!this._children) - return null; - from = from || 0; - to = Base.pick(to, this._children.length); - var removed = Base.splice(this._children, null, from, to - from); - for (var i = removed.length - 1; i >= 0; i--) { - removed[i]._remove(true, false); - } - if (removed.length > 0) - this._changed(11); - return removed; - }, - - clear: '#removeChildren', - - reverseChildren: function() { - if (this._children) { - this._children.reverse(); - for (var i = 0, l = this._children.length; i < l; i++) - this._children[i]._index = i; - this._changed(11); - } - }, - - isEmpty: function() { - return !this._children || this._children.length === 0; - }, - - isEditable: function() { - var item = this; - while (item) { - if (!item._visible || item._locked) - return false; - item = item._parent; - } - return true; - }, - - hasFill: function() { - return this.getStyle().hasFill(); - }, - - hasStroke: function() { - return this.getStyle().hasStroke(); - }, - - hasShadow: function() { - return this.getStyle().hasShadow(); - }, - - _getOrder: function(item) { - function getList(item) { - var list = []; - do { - list.unshift(item); - } while (item = item._parent); - return list; - } - var list1 = getList(this), - list2 = getList(item); - for (var i = 0, l = Math.min(list1.length, list2.length); i < l; i++) { - if (list1[i] != list2[i]) { - return list1[i]._index < list2[i]._index ? 1 : -1; - } - } - return 0; - }, - - hasChildren: function() { - return this._children && this._children.length > 0; - }, - - isInserted: function() { - return this._parent ? this._parent.isInserted() : false; - }, - - isAbove: function(item) { - return this._getOrder(item) === -1; - }, - - isBelow: function(item) { - return this._getOrder(item) === 1; - }, - - isParent: function(item) { - return this._parent === item; - }, - - isChild: function(item) { - return item && item._parent === this; - }, - - isDescendant: function(item) { - var parent = this; - while (parent = parent._parent) { - if (parent == item) - return true; - } - return false; - }, - - isAncestor: function(item) { - return item ? item.isDescendant(this) : false; - }, - - isSibling: function(item) { - return this._parent === item._parent; - }, - - isGroupedWith: function(item) { - var parent = this._parent; - while (parent) { - if (parent._parent - && /^(Group|Layer|CompoundPath)$/.test(parent._class) - && item.isDescendant(parent)) - return true; - parent = parent._parent; - } - return false; - }, - - translate: function() { - var mx = new Matrix(); - return this.transform(mx.translate.apply(mx, arguments)); - }, - - rotate: function(angle ) { - return this.transform(new Matrix().rotate(angle, - Point.read(arguments, 1, { readNull: true }) - || this.getPosition(true))); - } -}, Base.each(['scale', 'shear', 'skew'], function(name) { - this[name] = function() { - var point = Point.read(arguments), - center = Point.read(arguments, 0, { readNull: true }); - return this.transform(new Matrix()[name](point, - center || this.getPosition(true))); - }; -}, { - -}), { - transform: function(matrix, _applyMatrix, _applyRecursively, - _setApplyMatrix) { - if (matrix && matrix.isIdentity()) - matrix = null; - var _matrix = this._matrix, - applyMatrix = (_applyMatrix || this._applyMatrix) - && ((!_matrix.isIdentity() || matrix) - || _applyMatrix && _applyRecursively && this._children); - if (!matrix && !applyMatrix) - return this; - if (matrix) - _matrix.preConcatenate(matrix); - if (applyMatrix = applyMatrix && this._transformContent(_matrix, - _applyRecursively, _setApplyMatrix)) { - var pivot = this._pivot, - style = this._style, - fillColor = style.getFillColor(true), - strokeColor = style.getStrokeColor(true); - if (pivot) - _matrix._transformPoint(pivot, pivot, true); - if (fillColor) - fillColor.transform(_matrix); - if (strokeColor) - strokeColor.transform(_matrix); - _matrix.reset(true); - if (_setApplyMatrix && this._canApplyMatrix) - this._applyMatrix = true; - } - var bounds = this._bounds, - position = this._position; - this._changed(9); - var decomp = bounds && matrix && matrix.decompose(); - if (decomp && !decomp.shearing && decomp.rotation % 90 === 0) { - for (var key in bounds) { - var rect = bounds[key]; - if (applyMatrix || !rect._internal) - matrix._transformBounds(rect, rect); - } - var getter = this._boundsGetter, - rect = bounds[getter && getter.getBounds || getter || 'getBounds']; - if (rect) - this._position = rect.getCenter(true); - this._bounds = bounds; - } else if (matrix && position) { - this._position = matrix._transformPoint(position, position); - } - return this; - }, - - _transformContent: function(matrix, applyRecursively, setApplyMatrix) { - var children = this._children; - if (children) { - for (var i = 0, l = children.length; i < l; i++) - children[i].transform(matrix, true, applyRecursively, - setApplyMatrix); - return true; - } - }, - - globalToLocal: function() { - return this.getGlobalMatrix(true)._inverseTransform( - Point.read(arguments)); - }, - - localToGlobal: function() { - return this.getGlobalMatrix(true)._transformPoint( - Point.read(arguments)); - }, - - parentToLocal: function() { - return this._matrix._inverseTransform(Point.read(arguments)); - }, - - localToParent: function() { - return this._matrix._transformPoint(Point.read(arguments)); - }, - - fitBounds: function(rectangle, fill) { - rectangle = Rectangle.read(arguments); - var bounds = this.getBounds(), - itemRatio = bounds.height / bounds.width, - rectRatio = rectangle.height / rectangle.width, - scale = (fill ? itemRatio > rectRatio : itemRatio < rectRatio) - ? rectangle.width / bounds.width - : rectangle.height / bounds.height, - newBounds = new Rectangle(new Point(), - new Size(bounds.width * scale, bounds.height * scale)); - newBounds.setCenter(rectangle.getCenter()); - this.setBounds(newBounds); - }, - - _setStyles: function(ctx) { - var style = this._style, - fillColor = style.getFillColor(), - strokeColor = style.getStrokeColor(), - shadowColor = style.getShadowColor(); - if (fillColor) - ctx.fillStyle = fillColor.toCanvasStyle(ctx); - if (strokeColor) { - var strokeWidth = style.getStrokeWidth(); - if (strokeWidth > 0) { - ctx.strokeStyle = strokeColor.toCanvasStyle(ctx); - ctx.lineWidth = strokeWidth; - var strokeJoin = style.getStrokeJoin(), - strokeCap = style.getStrokeCap(), - miterLimit = style.getMiterLimit(); - if (strokeJoin) - ctx.lineJoin = strokeJoin; - if (strokeCap) - ctx.lineCap = strokeCap; - if (miterLimit) - ctx.miterLimit = miterLimit; - if (paper.support.nativeDash) { - var dashArray = style.getDashArray(), - dashOffset = style.getDashOffset(); - if (dashArray && dashArray.length) { - if ('setLineDash' in ctx) { - ctx.setLineDash(dashArray); - ctx.lineDashOffset = dashOffset; - } else { - ctx.mozDash = dashArray; - ctx.mozDashOffset = dashOffset; - } - } - } - } - } - if (shadowColor) { - var shadowBlur = style.getShadowBlur(); - if (shadowBlur > 0) { - ctx.shadowColor = shadowColor.toCanvasStyle(ctx); - ctx.shadowBlur = shadowBlur; - var offset = this.getShadowOffset(); - ctx.shadowOffsetX = offset.x; - ctx.shadowOffsetY = offset.y; - } - } - }, - - draw: function(ctx, param, parentStrokeMatrix) { - var updateVersion = this._updateVersion = this._project._updateVersion; - if (!this._visible || this._opacity === 0) - return; - var matrices = param.matrices, - viewMatrix = param.viewMatrix, - matrix = this._matrix, - globalMatrix = matrices[matrices.length - 1].chain(matrix); - if (!globalMatrix.isInvertible()) - return; - - function getViewMatrix(matrix) { - return viewMatrix ? viewMatrix.chain(matrix) : matrix; - } - - matrices.push(globalMatrix); - if (param.updateMatrix) { - globalMatrix._updateVersion = updateVersion; - this._globalMatrix = globalMatrix; - } - - var blendMode = this._blendMode, - opacity = this._opacity, - normalBlend = blendMode === 'normal', - nativeBlend = BlendMode.nativeModes[blendMode], - direct = normalBlend && opacity === 1 - || param.dontStart - || param.clip - || (nativeBlend || normalBlend && opacity < 1) - && this._canComposite(), - pixelRatio = param.pixelRatio || 1, - mainCtx, itemOffset, prevOffset; - if (!direct) { - var bounds = this.getStrokeBounds(getViewMatrix(globalMatrix)); - if (!bounds.width || !bounds.height) - return; - prevOffset = param.offset; - itemOffset = param.offset = bounds.getTopLeft().floor(); - mainCtx = ctx; - ctx = CanvasProvider.getContext(bounds.getSize().ceil().add(1) - .multiply(pixelRatio)); - if (pixelRatio !== 1) - ctx.scale(pixelRatio, pixelRatio); - } - ctx.save(); - var strokeMatrix = parentStrokeMatrix - ? parentStrokeMatrix.chain(matrix) - : !this.getStrokeScaling(true) && getViewMatrix(globalMatrix), - clip = !direct && param.clipItem, - transform = !strokeMatrix || clip; - if (direct) { - ctx.globalAlpha = opacity; - if (nativeBlend) - ctx.globalCompositeOperation = blendMode; - } else if (transform) { - ctx.translate(-itemOffset.x, -itemOffset.y); - } - if (transform) - (direct ? matrix : getViewMatrix(globalMatrix)).applyToContext(ctx); - if (clip) - param.clipItem.draw(ctx, param.extend({ clip: true })); - if (strokeMatrix) { - ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); - var offset = param.offset; - if (offset) - ctx.translate(-offset.x, -offset.y); - } - this._draw(ctx, param, strokeMatrix); - ctx.restore(); - matrices.pop(); - if (param.clip && !param.dontFinish) - ctx.clip(); - if (!direct) { - BlendMode.process(blendMode, ctx, mainCtx, opacity, - itemOffset.subtract(prevOffset).multiply(pixelRatio)); - CanvasProvider.release(ctx); - param.offset = prevOffset; - } - }, - - _isUpdated: function(updateVersion) { - var parent = this._parent; - if (parent instanceof CompoundPath) - return parent._isUpdated(updateVersion); - var updated = this._updateVersion === updateVersion; - if (!updated && parent && parent._visible - && parent._isUpdated(updateVersion)) { - this._updateVersion = updateVersion; - updated = true; - } - return updated; - }, - - _drawSelection: function(ctx, matrix, size, selectedItems, updateVersion) { - if ((this._drawSelected || this._boundsSelected) - && this._isUpdated(updateVersion)) { - var color = this.getSelectedColor(true) - || this.getLayer().getSelectedColor(true), - mx = matrix.chain(this.getGlobalMatrix(true)); - ctx.strokeStyle = ctx.fillStyle = color - ? color.toCanvasStyle(ctx) : '#009dec'; - if (this._drawSelected) - this._drawSelected(ctx, mx, selectedItems); - if (this._boundsSelected) { - var half = size / 2, - coords = mx._transformCorners(this.getInternalBounds()); - ctx.beginPath(); - for (var i = 0; i < 8; i++) - ctx[i === 0 ? 'moveTo' : 'lineTo'](coords[i], coords[++i]); - ctx.closePath(); - ctx.stroke(); - for (var i = 0; i < 8; i++) - ctx.fillRect(coords[i] - half, coords[++i] - half, - size, size); - } - } - }, - - _canComposite: function() { - return false; - } -}, Base.each(['down', 'drag', 'up', 'move'], function(name) { - this['removeOn' + Base.capitalize(name)] = function() { - var hash = {}; - hash[name] = true; - return this.removeOn(hash); - }; -}, { - - removeOn: function(obj) { - for (var name in obj) { - if (obj[name]) { - var key = 'mouse' + name, - project = this._project, - sets = project._removeSets = project._removeSets || {}; - sets[key] = sets[key] || {}; - sets[key][this._id] = this; - } - } - return this; - } -})); - -var Group = Item.extend({ - _class: 'Group', - _selectChildren: true, - _serializeFields: { - children: [] - }, - - initialize: function Group(arg) { - this._children = []; - this._namedChildren = {}; - if (!this._initialize(arg)) - this.addChildren(Array.isArray(arg) ? arg : arguments); - }, - - _changed: function _changed(flags) { - _changed.base.call(this, flags); - if (flags & 1026) { - this._clipItem = undefined; - } - }, - - _getClipItem: function() { - var clipItem = this._clipItem; - if (clipItem === undefined) { - clipItem = null; - for (var i = 0, l = this._children.length; i < l; i++) { - var child = this._children[i]; - if (child._clipMask) { - clipItem = child; - break; - } - } - this._clipItem = clipItem; - } - return clipItem; - }, - - isClipped: function() { - return !!this._getClipItem(); - }, - - setClipped: function(clipped) { - var child = this.getFirstChild(); - if (child) - child.setClipMask(clipped); - }, - - _draw: function(ctx, param) { - var clip = param.clip, - clipItem = !clip && this._getClipItem(), - draw = true; - param = param.extend({ clipItem: clipItem, clip: false }); - if (clip) { - if (this._currentPath) { - ctx.currentPath = this._currentPath; - draw = false; - } else { - ctx.beginPath(); - param.dontStart = param.dontFinish = true; - } - } else if (clipItem) { - clipItem.draw(ctx, param.extend({ clip: true })); - } - if (draw) { - for (var i = 0, l = this._children.length; i < l; i++) { - var item = this._children[i]; - if (item !== clipItem) - item.draw(ctx, param); - } - } - if (clip) { - this._currentPath = ctx.currentPath; - } - } -}); - -var Layer = Group.extend({ - _class: 'Layer', - - initialize: function Layer(arg) { - var props = Base.isPlainObject(arg) - ? new Base(arg) - : { children: Array.isArray(arg) ? arg : arguments }, - insert = props.insert; - props.insert = false; - Group.call(this, props); - if (insert || insert === undefined) { - this._project.addChild(this); - this.activate(); - } - }, - - _remove: function _remove(notifySelf, notifyParent) { - if (this._parent) - return _remove.base.call(this, notifySelf, notifyParent); - if (this._index != null) { - var project = this._project; - if (project._activeLayer === this) - project._activeLayer = this.getNextSibling() - || this.getPreviousSibling(); - Base.splice(project.layers, null, this._index, 1); - this._installEvents(false); - if (notifySelf && project._changes) - this._changed(5); - if (notifyParent) { - project._needsUpdate = true; - } - return true; - } - return false; - }, - - getNextSibling: function getNextSibling() { - return this._parent ? getNextSibling.base.call(this) - : this._project.layers[this._index + 1] || null; - }, - - getPreviousSibling: function getPreviousSibling() { - return this._parent ? getPreviousSibling.base.call(this) - : this._project.layers[this._index - 1] || null; - }, - - isInserted: function isInserted() { - return this._parent ? isInserted.base.call(this) : this._index != null; - }, - - activate: function() { - this._project._activeLayer = this; - }, - - _insertSibling: function _insertSibling(index, item, _preserve) { - return !this._parent - ? this._project.insertChild(index, item, _preserve) - : _insertSibling.base.call(this, index, item, _preserve); - } -}); - -var Shape = Item.extend({ - _class: 'Shape', - _applyMatrix: false, - _canApplyMatrix: false, - _boundsSelected: true, - _serializeFields: { - type: null, - size: null, - radius: null - }, - - initialize: function Shape(props) { - this._initialize(props); - }, - - _equals: function(item) { - return this._type === item._type - && this._size.equals(item._size) - && Base.equals(this._radius, item._radius); - }, - - clone: function(insert) { - var copy = new Shape(Item.NO_INSERT); - copy.setType(this._type); - copy.setSize(this._size); - copy.setRadius(this._radius); - return this._clone(copy, insert); - }, - - getType: function() { - return this._type; - }, - - setType: function(type) { - this._type = type; - }, - - getShape: '#getType', - setShape: '#setType', - - getSize: function() { - var size = this._size; - return new LinkedSize(size.width, size.height, this, 'setSize'); - }, - - setSize: function() { - var size = Size.read(arguments); - if (!this._size) { - this._size = size.clone(); - } else if (!this._size.equals(size)) { - var type = this._type, - width = size.width, - height = size.height; - if (type === 'rectangle') { - var radius = Size.min(this._radius, size.divide(2)); - this._radius.set(radius.width, radius.height); - } else if (type === 'circle') { - width = height = (width + height) / 2; - this._radius = width / 2; - } else if (type === 'ellipse') { - this._radius.set(width / 2, height / 2); - } - this._size.set(width, height); - this._changed(9); - } - }, - - getRadius: function() { - var rad = this._radius; - return this._type === 'circle' - ? rad - : new LinkedSize(rad.width, rad.height, this, 'setRadius'); - }, - - setRadius: function(radius) { - var type = this._type; - if (type === 'circle') { - if (radius === this._radius) - return; - var size = radius * 2; - this._radius = radius; - this._size.set(size, size); - } else { - radius = Size.read(arguments); - if (!this._radius) { - this._radius = radius.clone(); - } else { - if (this._radius.equals(radius)) - return; - this._radius.set(radius.width, radius.height); - if (type === 'rectangle') { - var size = Size.max(this._size, radius.multiply(2)); - this._size.set(size.width, size.height); - } else if (type === 'ellipse') { - this._size.set(radius.width * 2, radius.height * 2); - } - } - } - this._changed(9); - }, - - isEmpty: function() { - return false; - }, - - toPath: function(insert) { - var path = this._clone(new Path[Base.capitalize(this._type)]({ - center: new Point(), - size: this._size, - radius: this._radius, - insert: false - }), insert); - if (paper.settings.applyMatrix) - path.setApplyMatrix(true); - return path; - }, - - _draw: function(ctx, param, strokeMatrix) { - var style = this._style, - hasFill = style.hasFill(), - hasStroke = style.hasStroke(), - dontPaint = param.dontFinish || param.clip, - untransformed = !strokeMatrix; - if (hasFill || hasStroke || dontPaint) { - var type = this._type, - radius = this._radius, - isCircle = type === 'circle'; - if (!param.dontStart) - ctx.beginPath(); - if (untransformed && isCircle) { - ctx.arc(0, 0, radius, 0, Math.PI * 2, true); - } else { - var rx = isCircle ? radius : radius.width, - ry = isCircle ? radius : radius.height, - size = this._size, - width = size.width, - height = size.height; - if (untransformed && type === 'rectangle' && rx === 0 && ry === 0) { - ctx.rect(-width / 2, -height / 2, width, height); - } else { - var x = width / 2, - y = height / 2, - kappa = 1 - 0.5522847498307936, - cx = rx * kappa, - cy = ry * kappa, - c = [ - -x, -y + ry, - -x, -y + cy, - -x + cx, -y, - -x + rx, -y, - x - rx, -y, - x - cx, -y, - x, -y + cy, - x, -y + ry, - x, y - ry, - x, y - cy, - x - cx, y, - x - rx, y, - -x + rx, y, - -x + cx, y, - -x, y - cy, - -x, y - ry - ]; - if (strokeMatrix) - strokeMatrix.transform(c, c, 32); - ctx.moveTo(c[0], c[1]); - ctx.bezierCurveTo(c[2], c[3], c[4], c[5], c[6], c[7]); - if (x !== rx) - ctx.lineTo(c[8], c[9]); - ctx.bezierCurveTo(c[10], c[11], c[12], c[13], c[14], c[15]); - if (y !== ry) - ctx.lineTo(c[16], c[17]); - ctx.bezierCurveTo(c[18], c[19], c[20], c[21], c[22], c[23]); - if (x !== rx) - ctx.lineTo(c[24], c[25]); - ctx.bezierCurveTo(c[26], c[27], c[28], c[29], c[30], c[31]); - } - } - ctx.closePath(); - } - if (!dontPaint && (hasFill || hasStroke)) { - this._setStyles(ctx); - if (hasFill) { - ctx.fill(style.getWindingRule()); - ctx.shadowColor = 'rgba(0,0,0,0)'; - } - if (hasStroke) - ctx.stroke(); - } - }, - - _canComposite: function() { - return !(this.hasFill() && this.hasStroke()); - }, - - _getBounds: function(getter, matrix) { - var rect = new Rectangle(this._size).setCenter(0, 0); - if (getter !== 'getBounds' && this.hasStroke()) - rect = rect.expand(this.getStrokeWidth()); - return matrix ? matrix._transformBounds(rect) : rect; - } -}, -new function() { - function getCornerCenter(that, point, expand) { - var radius = that._radius; - if (!radius.isZero()) { - var halfSize = that._size.divide(2); - for (var i = 0; i < 4; i++) { - var dir = new Point(i & 1 ? 1 : -1, i > 1 ? 1 : -1), - corner = dir.multiply(halfSize), - center = corner.subtract(dir.multiply(radius)), - rect = new Rectangle(corner, center); - if ((expand ? rect.expand(expand) : rect).contains(point)) - return center; - } - } - } - - function getEllipseRadius(point, radius) { - var angle = point.getAngleInRadians(), - width = radius.width * 2, - height = radius.height * 2, - x = width * Math.sin(angle), - y = height * Math.cos(angle); - return width * height / (2 * Math.sqrt(x * x + y * y)); - } - - return { - _contains: function _contains(point) { - if (this._type === 'rectangle') { - var center = getCornerCenter(this, point); - return center - ? point.subtract(center).divide(this._radius) - .getLength() <= 1 - : _contains.base.call(this, point); - } else { - return point.divide(this.size).getLength() <= 0.5; - } - }, - - _hitTestSelf: function _hitTestSelf(point, options) { - var hit = false; - if (this.hasStroke()) { - var type = this._type, - radius = this._radius, - strokeWidth = this.getStrokeWidth() + 2 * options.tolerance; - if (type === 'rectangle') { - var center = getCornerCenter(this, point, strokeWidth); - if (center) { - var pt = point.subtract(center); - hit = 2 * Math.abs(pt.getLength() - - getEllipseRadius(pt, radius)) <= strokeWidth; - } else { - var rect = new Rectangle(this._size).setCenter(0, 0), - outer = rect.expand(strokeWidth), - inner = rect.expand(-strokeWidth); - hit = outer._containsPoint(point) - && !inner._containsPoint(point); - } - } else { - if (type === 'ellipse') - radius = getEllipseRadius(point, radius); - hit = 2 * Math.abs(point.getLength() - radius) - <= strokeWidth; - } - } - return hit - ? new HitResult('stroke', this) - : _hitTestSelf.base.apply(this, arguments); - } - }; -}, { - -statics: new function() { - function createShape(type, point, size, radius, args) { - var item = new Shape(Base.getNamed(args)); - item._type = type; - item._size = size; - item._radius = radius; - return item.translate(point); - } - - return { - Circle: function() { - var center = Point.readNamed(arguments, 'center'), - radius = Base.readNamed(arguments, 'radius'); - return createShape('circle', center, new Size(radius * 2), radius, - arguments); - }, - - Rectangle: function() { - var rect = Rectangle.readNamed(arguments, 'rectangle'), - radius = Size.min(Size.readNamed(arguments, 'radius'), - rect.getSize(true).divide(2)); - return createShape('rectangle', rect.getCenter(true), - rect.getSize(true), radius, arguments); - }, - - Ellipse: function() { - var ellipse = Shape._readEllipse(arguments), - radius = ellipse.radius; - return createShape('ellipse', ellipse.center, radius.multiply(2), - radius, arguments); - }, - - _readEllipse: function(args) { - var center, - radius; - if (Base.hasNamed(args, 'radius')) { - center = Point.readNamed(args, 'center'); - radius = Size.readNamed(args, 'radius'); - } else { - var rect = Rectangle.readNamed(args, 'rectangle'); - center = rect.getCenter(true); - radius = rect.getSize(true).divide(2); - } - return { center: center, radius: radius }; - } - }; -}}); - -var Raster = Item.extend({ - _class: 'Raster', - _applyMatrix: false, - _canApplyMatrix: false, - _boundsGetter: 'getBounds', - _boundsSelected: true, - _serializeFields: { - crossOrigin: null, - source: null - }, - - initialize: function Raster(object, position) { - if (!this._initialize(object, - position !== undefined && Point.read(arguments, 1))) { - if (typeof object === 'string') { - this.setSource(object); - } else { - this.setImage(object); - } - } - if (!this._size) { - this._size = new Size(); - this._loaded = false; - } - }, - - _equals: function(item) { - return this.getSource() === item.getSource(); - }, - - clone: function(insert) { - var copy = new Raster(Item.NO_INSERT), - image = this._image, - canvas = this._canvas; - if (image) { - copy.setImage(image); - } else if (canvas) { - var copyCanvas = CanvasProvider.getCanvas(this._size); - copyCanvas.getContext('2d').drawImage(canvas, 0, 0); - copy.setImage(copyCanvas); - } - copy._crossOrigin = this._crossOrigin; - return this._clone(copy, insert); - }, - - getSize: function() { - var size = this._size; - return new LinkedSize(size ? size.width : 0, size ? size.height : 0, - this, 'setSize'); - }, - - setSize: function() { - var size = Size.read(arguments); - if (!size.equals(this._size)) { - if (size.width > 0 && size.height > 0) { - var element = this.getElement(); - this.setImage(CanvasProvider.getCanvas(size)); - if (element) - this.getContext(true).drawImage(element, 0, 0, - size.width, size.height); - } else { - if (this._canvas) - CanvasProvider.release(this._canvas); - this._size = size.clone(); - } - } - }, - - getWidth: function() { - return this._size ? this._size.width : 0; - }, - - setWidth: function(width) { - this.setSize(width, this.getHeight()); - }, - - getHeight: function() { - return this._size ? this._size.height : 0; - }, - - setHeight: function(height) { - this.setSize(this.getWidth(), height); - }, - - isEmpty: function() { - var size = this._size; - return !size || size.width === 0 && size.height === 0; - }, - - getResolution: function() { - var matrix = this._matrix, - orig = new Point(0, 0).transform(matrix), - u = new Point(1, 0).transform(matrix).subtract(orig), - v = new Point(0, 1).transform(matrix).subtract(orig); - return new Size( - 72 / u.getLength(), - 72 / v.getLength() - ); - }, - - getPpi: '#getResolution', - - getImage: function() { - return this._image; - }, - - setImage: function(image) { - if (this._canvas) - CanvasProvider.release(this._canvas); - if (image && image.getContext) { - this._image = null; - this._canvas = image; - this._loaded = true; - } else { - this._image = image; - this._canvas = null; - this._loaded = image && image.complete; - } - this._size = new Size( - image ? image.naturalWidth || image.width : 0, - image ? image.naturalHeight || image.height : 0); - this._context = null; - this._changed(521); - }, - - getCanvas: function() { - if (!this._canvas) { - var ctx = CanvasProvider.getContext(this._size); - try { - if (this._image) - ctx.drawImage(this._image, 0, 0); - this._canvas = ctx.canvas; - } catch (e) { - CanvasProvider.release(ctx); - } - } - return this._canvas; - }, - - setCanvas: '#setImage', - - getContext: function(modify) { - if (!this._context) - this._context = this.getCanvas().getContext('2d'); - if (modify) { - this._image = null; - this._changed(513); - } - return this._context; - }, - - setContext: function(context) { - this._context = context; - }, - - getSource: function() { - return this._image && this._image.src || this.toDataURL(); - }, - - setSource: function(src) { - var that = this, - crossOrigin = this._crossOrigin, - image; - - function loaded() { - var view = that.getView(); - if (view) { - paper = view._scope; - that.setImage(image); - that.emit('load'); - view.update(); - } - } - - image = document.getElementById(src) || new Image(); - if (crossOrigin) - image.crossOrigin = crossOrigin; - if (image.naturalWidth && image.naturalHeight) { - setTimeout(loaded, 0); - } else { - DomEvent.add(image, { load: loaded }); - if (!image.src) - image.src = src; - } - this.setImage(image); - }, - - getCrossOrigin: function() { - return this._image && this._image.crossOrigin || this._crossOrigin || ''; - }, - - setCrossOrigin: function(crossOrigin) { - this._crossOrigin = crossOrigin; - if (this._image) - this._image.crossOrigin = crossOrigin; - }, - - getElement: function() { - return this._canvas || this._loaded && this._image; - } -}, { - beans: false, - - getSubCanvas: function() { - var rect = Rectangle.read(arguments), - ctx = CanvasProvider.getContext(rect.getSize()); - ctx.drawImage(this.getCanvas(), rect.x, rect.y, - rect.width, rect.height, 0, 0, rect.width, rect.height); - return ctx.canvas; - }, - - getSubRaster: function() { - var rect = Rectangle.read(arguments), - raster = new Raster(Item.NO_INSERT); - raster.setImage(this.getSubCanvas(rect)); - raster.translate(rect.getCenter().subtract(this.getSize().divide(2))); - raster._matrix.preConcatenate(this._matrix); - raster.insertAbove(this); - return raster; - }, - - toDataURL: function() { - var src = this._image && this._image.src; - if (/^data:/.test(src)) - return src; - var canvas = this.getCanvas(); - return canvas ? canvas.toDataURL.apply(canvas, arguments) : null; - }, - - drawImage: function(image ) { - var point = Point.read(arguments, 1); - this.getContext(true).drawImage(image, point.x, point.y); - }, - - getAverageColor: function(object) { - var bounds, path; - if (!object) { - bounds = this.getBounds(); - } else if (object instanceof PathItem) { - path = object; - bounds = object.getBounds(); - } else if (object.width) { - bounds = new Rectangle(object); - } else if (object.x) { - bounds = new Rectangle(object.x - 0.5, object.y - 0.5, 1, 1); - } - var sampleSize = 32, - width = Math.min(bounds.width, sampleSize), - height = Math.min(bounds.height, sampleSize); - var ctx = Raster._sampleContext; - if (!ctx) { - ctx = Raster._sampleContext = CanvasProvider.getContext( - new Size(sampleSize)); - } else { - ctx.clearRect(0, 0, sampleSize + 1, sampleSize + 1); - } - ctx.save(); - var matrix = new Matrix() - .scale(width / bounds.width, height / bounds.height) - .translate(-bounds.x, -bounds.y); - matrix.applyToContext(ctx); - if (path) - path.draw(ctx, new Base({ clip: true, matrices: [matrix] })); - this._matrix.applyToContext(ctx); - var element = this.getElement(), - size = this._size; - if (element) - ctx.drawImage(element, -size.width / 2, -size.height / 2); - ctx.restore(); - var pixels = ctx.getImageData(0.5, 0.5, Math.ceil(width), - Math.ceil(height)).data, - channels = [0, 0, 0], - total = 0; - for (var i = 0, l = pixels.length; i < l; i += 4) { - var alpha = pixels[i + 3]; - total += alpha; - alpha /= 255; - channels[0] += pixels[i] * alpha; - channels[1] += pixels[i + 1] * alpha; - channels[2] += pixels[i + 2] * alpha; - } - for (var i = 0; i < 3; i++) - channels[i] /= total; - return total ? Color.read(channels) : null; - }, - - getPixel: function() { - var point = Point.read(arguments); - var data = this.getContext().getImageData(point.x, point.y, 1, 1).data; - return new Color('rgb', [data[0] / 255, data[1] / 255, data[2] / 255], - data[3] / 255); - }, - - setPixel: function() { - var point = Point.read(arguments), - color = Color.read(arguments), - components = color._convert('rgb'), - alpha = color._alpha, - ctx = this.getContext(true), - imageData = ctx.createImageData(1, 1), - data = imageData.data; - data[0] = components[0] * 255; - data[1] = components[1] * 255; - data[2] = components[2] * 255; - data[3] = alpha != null ? alpha * 255 : 255; - ctx.putImageData(imageData, point.x, point.y); - }, - - createImageData: function() { - var size = Size.read(arguments); - return this.getContext().createImageData(size.width, size.height); - }, - - getImageData: function() { - var rect = Rectangle.read(arguments); - if (rect.isEmpty()) - rect = new Rectangle(this._size); - return this.getContext().getImageData(rect.x, rect.y, - rect.width, rect.height); - }, - - setImageData: function(data ) { - var point = Point.read(arguments, 1); - this.getContext(true).putImageData(data, point.x, point.y); - }, - - _getBounds: function(getter, matrix) { - var rect = new Rectangle(this._size).setCenter(0, 0); - return matrix ? matrix._transformBounds(rect) : rect; - }, - - _hitTestSelf: function(point) { - if (this._contains(point)) { - var that = this; - return new HitResult('pixel', that, { - offset: point.add(that._size.divide(2)).round(), - color: { - get: function() { - return that.getPixel(this.offset); - } - } - }); - } - }, - - _draw: function(ctx) { - var element = this.getElement(); - if (element) { - ctx.globalAlpha = this._opacity; - ctx.drawImage(element, - -this._size.width / 2, -this._size.height / 2); - } - }, - - _canComposite: function() { - return true; - } -}); - -var PlacedSymbol = Item.extend({ - _class: 'PlacedSymbol', - _applyMatrix: false, - _canApplyMatrix: false, - _boundsGetter: { getBounds: 'getStrokeBounds' }, - _boundsSelected: true, - _serializeFields: { - symbol: null - }, - - initialize: function PlacedSymbol(arg0, arg1) { - if (!this._initialize(arg0, - arg1 !== undefined && Point.read(arguments, 1))) - this.setSymbol(arg0 instanceof Symbol ? arg0 : new Symbol(arg0)); - }, - - _equals: function(item) { - return this._symbol === item._symbol; - }, - - getSymbol: function() { - return this._symbol; - }, - - setSymbol: function(symbol) { - this._symbol = symbol; - this._changed(9); - }, - - clone: function(insert) { - var copy = new PlacedSymbol(Item.NO_INSERT); - copy.setSymbol(this._symbol); - return this._clone(copy, insert); - }, - - isEmpty: function() { - return this._symbol._definition.isEmpty(); - }, - - _getBounds: function(getter, matrix, cacheItem) { - var definition = this.symbol._definition; - return definition._getCachedBounds(getter, - matrix && matrix.chain(definition._matrix), cacheItem); - }, - - _hitTestSelf: function(point, options) { - var res = this._symbol._definition._hitTest(point, options); - if (res) - res.item = this; - return res; - }, - - _draw: function(ctx, param) { - this.symbol._definition.draw(ctx, param); - } - -}); - -var HitResult = Base.extend({ - _class: 'HitResult', - - initialize: function HitResult(type, item, values) { - this.type = type; - this.item = item; - if (values) { - values.enumerable = true; - this.inject(values); - } - }, - - statics: { - getOptions: function(options) { - return new Base({ - type: null, - tolerance: paper.settings.hitTolerance, - fill: !options, - stroke: !options, - segments: !options, - handles: false, - ends: false, - center: false, - bounds: false, - guides: false, - selected: false - }, options); - } - } -}); - -var Segment = Base.extend({ - _class: 'Segment', - beans: true, - - initialize: function Segment(arg0, arg1, arg2, arg3, arg4, arg5) { - var count = arguments.length, - point, handleIn, handleOut; - if (count === 0) { - } else if (count === 1) { - if ('point' in arg0) { - point = arg0.point; - handleIn = arg0.handleIn; - handleOut = arg0.handleOut; - } else { - point = arg0; - } - } else if (count === 2 && typeof arg0 === 'number') { - point = arguments; - } else if (count <= 3) { - point = arg0; - handleIn = arg1; - handleOut = arg2; - } else { - point = arg0 !== undefined ? [ arg0, arg1 ] : null; - handleIn = arg2 !== undefined ? [ arg2, arg3 ] : null; - handleOut = arg4 !== undefined ? [ arg4, arg5 ] : null; - } - new SegmentPoint(point, this, '_point'); - new SegmentPoint(handleIn, this, '_handleIn'); - new SegmentPoint(handleOut, this, '_handleOut'); - }, - - _serialize: function(options) { - return Base.serialize(this.hasHandles() - ? [this._point, this._handleIn, this._handleOut] - : this._point, - options, true); - }, - - _changed: function(point) { - var path = this._path; - if (!path) - return; - var curves = path._curves, - index = this._index, - curve; - if (curves) { - if ((!point || point === this._point || point === this._handleIn) - && (curve = index > 0 ? curves[index - 1] : path._closed - ? curves[curves.length - 1] : null)) - curve._changed(); - if ((!point || point === this._point || point === this._handleOut) - && (curve = curves[index])) - curve._changed(); - } - path._changed(25); - }, - - getPoint: function() { - return this._point; - }, - - setPoint: function() { - var point = Point.read(arguments); - this._point.set(point.x, point.y); - }, - - getHandleIn: function() { - return this._handleIn; - }, - - setHandleIn: function() { - var point = Point.read(arguments); - this._handleIn.set(point.x, point.y); - }, - - getHandleOut: function() { - return this._handleOut; - }, - - setHandleOut: function() { - var point = Point.read(arguments); - this._handleOut.set(point.x, point.y); - }, - - hasHandles: function() { - return !this._handleIn.isZero() || !this._handleOut.isZero(); - }, - - clearHandles: function() { - this._handleIn.set(0, 0); - this._handleOut.set(0, 0); - }, - - _selectionState: 0, - - isSelected: function(_point) { - var state = this._selectionState; - return !_point ? !!(state & 7) - : _point === this._point ? !!(state & 4) - : _point === this._handleIn ? !!(state & 1) - : _point === this._handleOut ? !!(state & 2) - : false; - }, - - setSelected: function(selected, _point) { - var path = this._path, - selected = !!selected, - state = this._selectionState, - oldState = state, - flag = !_point ? 7 - : _point === this._point ? 4 - : _point === this._handleIn ? 1 - : _point === this._handleOut ? 2 - : 0; - if (selected) { - state |= flag; - } else { - state &= ~flag; - } - this._selectionState = state; - if (path && state !== oldState) { - path._updateSelection(this, oldState, state); - path._changed(129); - } - }, - - getIndex: function() { - return this._index !== undefined ? this._index : null; - }, - - getPath: function() { - return this._path || null; - }, - - getCurve: function() { - var path = this._path, - index = this._index; - if (path) { - if (index > 0 && !path._closed - && index === path._segments.length - 1) - index--; - return path.getCurves()[index] || null; - } - return null; - }, - - getLocation: function() { - var curve = this.getCurve(); - return curve - ? new CurveLocation(curve, this === curve._segment1 ? 0 : 1) - : null; - }, - - getNext: function() { - var segments = this._path && this._path._segments; - return segments && (segments[this._index + 1] - || this._path._closed && segments[0]) || null; - }, - - getPrevious: function() { - var segments = this._path && this._path._segments; - return segments && (segments[this._index - 1] - || this._path._closed && segments[segments.length - 1]) || null; - }, - - isFirst: function() { - return this._index === 0; - }, - - isLast: function() { - var path = this._path; - return path && this._index === path._segments.length - 1 || false; - }, - - reverse: function() { - var handleIn = this._handleIn, - handleOut = this._handleOut, - inX = handleIn._x, - inY = handleIn._y; - handleIn.set(handleOut._x, handleOut._y); - handleOut.set(inX, inY); - }, - - reversed: function() { - return new Segment(this._point, this._handleOut, this._handleIn); - }, - - remove: function() { - return this._path ? !!this._path.removeSegment(this._index) : false; - }, - - clone: function() { - return new Segment(this._point, this._handleIn, this._handleOut); - }, - - equals: function(segment) { - return segment === this || segment && this._class === segment._class - && this._point.equals(segment._point) - && this._handleIn.equals(segment._handleIn) - && this._handleOut.equals(segment._handleOut) - || false; - }, - - toString: function() { - var parts = [ 'point: ' + this._point ]; - if (!this._handleIn.isZero()) - parts.push('handleIn: ' + this._handleIn); - if (!this._handleOut.isZero()) - parts.push('handleOut: ' + this._handleOut); - return '{ ' + parts.join(', ') + ' }'; - }, - - transform: function(matrix) { - this._transformCoordinates(matrix, new Array(6), true); - this._changed(); - }, - - _transformCoordinates: function(matrix, coords, change) { - var point = this._point, - handleIn = !change || !this._handleIn.isZero() - ? this._handleIn : null, - handleOut = !change || !this._handleOut.isZero() - ? this._handleOut : null, - x = point._x, - y = point._y, - i = 2; - coords[0] = x; - coords[1] = y; - if (handleIn) { - coords[i++] = handleIn._x + x; - coords[i++] = handleIn._y + y; - } - if (handleOut) { - coords[i++] = handleOut._x + x; - coords[i++] = handleOut._y + y; - } - if (matrix) { - matrix._transformCoordinates(coords, coords, i / 2); - x = coords[0]; - y = coords[1]; - if (change) { - point._x = x; - point._y = y; - i = 2; - if (handleIn) { - handleIn._x = coords[i++] - x; - handleIn._y = coords[i++] - y; - } - if (handleOut) { - handleOut._x = coords[i++] - x; - handleOut._y = coords[i++] - y; - } - } else { - if (!handleIn) { - coords[i++] = x; - coords[i++] = y; - } - if (!handleOut) { - coords[i++] = x; - coords[i++] = y; - } - } - } - return coords; - } -}); - -var SegmentPoint = Point.extend({ - initialize: function SegmentPoint(point, owner, key) { - var x, y, selected; - if (!point) { - x = y = 0; - } else if ((x = point[0]) !== undefined) { - y = point[1]; - } else { - var pt = point; - if ((x = pt.x) === undefined) { - pt = Point.read(arguments); - x = pt.x; - } - y = pt.y; - selected = pt.selected; - } - this._x = x; - this._y = y; - this._owner = owner; - owner[key] = this; - if (selected) - this.setSelected(true); - }, - - set: function(x, y) { - this._x = x; - this._y = y; - this._owner._changed(this); - return this; - }, - - _serialize: function(options) { - var f = options.formatter, - x = f.number(this._x), - y = f.number(this._y); - return this.isSelected() - ? { x: x, y: y, selected: true } - : [x, y]; - }, - - getX: function() { - return this._x; - }, - - setX: function(x) { - this._x = x; - this._owner._changed(this); - }, - - getY: function() { - return this._y; - }, - - setY: function(y) { - this._y = y; - this._owner._changed(this); - }, - - isZero: function() { - return Numerical.isZero(this._x) && Numerical.isZero(this._y); - }, - - setSelected: function(selected) { - this._owner.setSelected(selected, this); - }, - - isSelected: function() { - return this._owner.isSelected(this); - } -}); - -var Curve = Base.extend({ - _class: 'Curve', - - initialize: function Curve(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) { - var count = arguments.length, - seg1, seg2, - point1, point2, - handle1, handle2; - if (count === 3) { - this._path = arg0; - seg1 = arg1; - seg2 = arg2; - } else if (count === 0) { - seg1 = new Segment(); - seg2 = new Segment(); - } else if (count === 1) { - if ('segment1' in arg0) { - seg1 = new Segment(arg0.segment1); - seg2 = new Segment(arg0.segment2); - } else if ('point1' in arg0) { - point1 = arg0.point1; - handle1 = arg0.handle1; - handle2 = arg0.handle2; - point2 = arg0.point2; - } else if (Array.isArray(arg0)) { - point1 = [arg0[0], arg0[1]]; - point2 = [arg0[6], arg0[7]]; - handle1 = [arg0[2] - arg0[0], arg0[3] - arg0[1]]; - handle2 = [arg0[4] - arg0[6], arg0[5] - arg0[7]]; - } - } else if (count === 2) { - seg1 = new Segment(arg0); - seg2 = new Segment(arg1); - } else if (count === 4) { - point1 = arg0; - handle1 = arg1; - handle2 = arg2; - point2 = arg3; - } else if (count === 8) { - point1 = [arg0, arg1]; - point2 = [arg6, arg7]; - handle1 = [arg2 - arg0, arg3 - arg1]; - handle2 = [arg4 - arg6, arg5 - arg7]; - } - this._segment1 = seg1 || new Segment(point1, null, handle1); - this._segment2 = seg2 || new Segment(point2, handle2, null); - }, - - _serialize: function(options) { - return Base.serialize(this.hasHandles() - ? [this.getPoint1(), this.getHandle1(), this.getHandle2(), - this.getPoint2()] - : [this.getPoint1(), this.getPoint2()], - options, true); - }, - - _changed: function() { - this._length = this._bounds = undefined; - }, - - clone: function() { - return new Curve(this._segment1, this._segment2); - }, - - toString: function() { - var parts = [ 'point1: ' + this._segment1._point ]; - if (!this._segment1._handleOut.isZero()) - parts.push('handle1: ' + this._segment1._handleOut); - if (!this._segment2._handleIn.isZero()) - parts.push('handle2: ' + this._segment2._handleIn); - parts.push('point2: ' + this._segment2._point); - return '{ ' + parts.join(', ') + ' }'; - }, - - remove: function() { - var removed = false; - if (this._path) { - var segment2 = this._segment2, - handleOut = segment2._handleOut; - removed = segment2.remove(); - if (removed) - this._segment1._handleOut.set(handleOut.x, handleOut.y); - } - return removed; - }, - - getPoint1: function() { - return this._segment1._point; - }, - - setPoint1: function() { - var point = Point.read(arguments); - this._segment1._point.set(point.x, point.y); - }, - - getPoint2: function() { - return this._segment2._point; - }, - - setPoint2: function() { - var point = Point.read(arguments); - this._segment2._point.set(point.x, point.y); - }, - - getHandle1: function() { - return this._segment1._handleOut; - }, - - setHandle1: function() { - var point = Point.read(arguments); - this._segment1._handleOut.set(point.x, point.y); - }, - - getHandle2: function() { - return this._segment2._handleIn; - }, - - setHandle2: function() { - var point = Point.read(arguments); - this._segment2._handleIn.set(point.x, point.y); - }, - - getSegment1: function() { - return this._segment1; - }, - - getSegment2: function() { - return this._segment2; - }, - - getPath: function() { - return this._path; - }, - - getIndex: function() { - return this._segment1._index; - }, - - getNext: function() { - var curves = this._path && this._path._curves; - return curves && (curves[this._segment1._index + 1] - || this._path._closed && curves[0]) || null; - }, - - getPrevious: function() { - var curves = this._path && this._path._curves; - return curves && (curves[this._segment1._index - 1] - || this._path._closed && curves[curves.length - 1]) || null; - }, - - isFirst: function() { - return this._segment1._index === 0; - }, - - isLast: function() { - var path = this._path; - return path && this._segment1._index === path._curves.length - 1 - || false; - }, - - isSelected: function() { - return this.getPoint1().isSelected() - && this.getHandle2().isSelected() - && this.getHandle2().isSelected() - && this.getPoint2().isSelected(); - }, - - setSelected: function(selected) { - this.getPoint1().setSelected(selected); - this.getHandle1().setSelected(selected); - this.getHandle2().setSelected(selected); - this.getPoint2().setSelected(selected); - }, - - getValues: function(matrix) { - return Curve.getValues(this._segment1, this._segment2, matrix); - }, - - getPoints: function() { - var coords = this.getValues(), - points = []; - for (var i = 0; i < 8; i += 2) - points.push(new Point(coords[i], coords[i + 1])); - return points; - }, - - getLength: function() { - if (this._length == null) - this._length = Curve.getLength(this.getValues(), 0, 1); - return this._length; - }, - - getArea: function() { - return Curve.getArea(this.getValues()); - }, - - getLine: function() { - return new Line(this._segment1._point, this._segment2._point); - }, - - getPart: function(from, to) { - return new Curve(Curve.getPart(this.getValues(), from, to)); - }, - - getPartLength: function(from, to) { - return Curve.getLength(this.getValues(), from, to); - }, - - getIntersections: function(curve) { - return Curve._getIntersections(this.getValues(), - curve && curve !== this ? curve.getValues() : null, - this, curve, [], {}); - }, - - _getParameter: function(offset, isParameter) { - return isParameter - ? offset - : offset && offset.curve === this - ? offset.parameter - : offset === undefined && isParameter === undefined - ? 0.5 - : this.getParameterAt(offset, 0); - }, - - divide: function(offset, isParameter, _setHandles) { - var parameter = this._getParameter(offset, isParameter), - tMin = 4e-7, - tMax = 1 - tMin, - res = null; - if (parameter >= tMin && parameter <= tMax) { - var parts = Curve.subdivide(this.getValues(), parameter), - left = parts[0], - right = parts[1], - setHandles = _setHandles || this.hasHandles(), - segment1 = this._segment1, - segment2 = this._segment2, - path = this._path; - if (setHandles) { - segment1._handleOut.set(left[2] - left[0], - left[3] - left[1]); - segment2._handleIn.set(right[4] - right[6], - right[5] - right[7]); - } - var x = left[6], y = left[7], - segment = new Segment(new Point(x, y), - setHandles && new Point(left[4] - x, left[5] - y), - setHandles && new Point(right[2] - x, right[3] - y)); - if (path) { - path.insert(segment1._index + 1, segment); - res = this.getNext(); - } else { - this._segment2 = segment; - res = new Curve(segment, segment2); - } - } - return res; - }, - - split: function(offset, isParameter) { - return this._path - ? this._path.split(this._segment1._index, - this._getParameter(offset, isParameter)) - : null; - }, - - reversed: function() { - return new Curve(this._segment2.reversed(), this._segment1.reversed()); - }, - - clearHandles: function() { - this._segment1._handleOut.set(0, 0); - this._segment2._handleIn.set(0, 0); - }, - -statics: { - getValues: function(segment1, segment2, matrix) { - var p1 = segment1._point, - h1 = segment1._handleOut, - h2 = segment2._handleIn, - p2 = segment2._point, - values = [ - p1._x, p1._y, - p1._x + h1._x, p1._y + h1._y, - p2._x + h2._x, p2._y + h2._y, - p2._x, p2._y - ]; - if (matrix) - matrix._transformCoordinates(values, values, 4); - return values; - }, - - subdivide: function(v, t) { - var p1x = v[0], p1y = v[1], - c1x = v[2], c1y = v[3], - c2x = v[4], c2y = v[5], - p2x = v[6], p2y = v[7]; - if (t === undefined) - t = 0.5; - var u = 1 - t, - p3x = u * p1x + t * c1x, p3y = u * p1y + t * c1y, - p4x = u * c1x + t * c2x, p4y = u * c1y + t * c2y, - p5x = u * c2x + t * p2x, p5y = u * c2y + t * p2y, - p6x = u * p3x + t * p4x, p6y = u * p3y + t * p4y, - p7x = u * p4x + t * p5x, p7y = u * p4y + t * p5y, - p8x = u * p6x + t * p7x, p8y = u * p6y + t * p7y; - return [ - [p1x, p1y, p3x, p3y, p6x, p6y, p8x, p8y], - [p8x, p8y, p7x, p7y, p5x, p5y, p2x, p2y] - ]; - }, - - solveCubic: function (v, coord, val, roots, min, max) { - var p1 = v[coord], - c1 = v[coord + 2], - c2 = v[coord + 4], - p2 = v[coord + 6], - c = 3 * (c1 - p1), - b = 3 * (c2 - c1) - c, - a = p2 - p1 - c - b; - return Numerical.solveCubic(a, b, c, p1 - val, roots, min, max); - }, - - getParameterOf: function(v, point) { - var p1 = new Point(v[0], v[1]), - p2 = new Point(v[6], v[7]), - epsilon = 1e-12, - t = point.isClose(p1, epsilon) ? 0 - : point.isClose(p2, epsilon) ? 1 - : null; - if (t !== null) - return t; - var coords = [point.x, point.y], - roots = [], - geomEpsilon = 2e-7; - for (var c = 0; c < 2; c++) { - var count = Curve.solveCubic(v, c, coords[c], roots, 0, 1); - for (var i = 0; i < count; i++) { - t = roots[i]; - if (point.isClose(Curve.getPoint(v, t), geomEpsilon)) - return t; - } - } - return point.isClose(p1, geomEpsilon) ? 0 - : point.isClose(p2, geomEpsilon) ? 1 - : null; - }, - - getNearestParameter: function(v, point) { - if (Curve.isStraight(v)) { - var p1x = v[0], p1y = v[1], - p2x = v[6], p2y = v[7], - vx = p2x - p1x, vy = p2y - p1y, - det = vx * vx + vy * vy; - if (det === 0) - return 0; - var u = ((point.x - p1x) * vx + (point.y - p1y) * vy) / det; - return u < 1e-12 ? 0 - : u > 0.999999999999 ? 1 - : Curve.getParameterOf(v, - new Point(p1x + u * vx, p1y + u * vy)); - } - - var count = 100, - minDist = Infinity, - minT = 0; - - function refine(t) { - if (t >= 0 && t <= 1) { - var dist = point.getDistance(Curve.getPoint(v, t), true); - if (dist < minDist) { - minDist = dist; - minT = t; - return true; - } - } - } - - for (var i = 0; i <= count; i++) - refine(i / count); - - var step = 1 / (count * 2); - while (step > 4e-7) { - if (!refine(minT - step) && !refine(minT + step)) - step /= 2; - } - return minT; - }, - - getPart: function(v, from, to) { - var flip = from > to; - if (flip) { - var tmp = from; - from = to; - to = tmp; - } - if (from > 0) - v = Curve.subdivide(v, from)[1]; - if (to < 1) - v = Curve.subdivide(v, (to - from) / (1 - from))[0]; - return flip - ? [v[6], v[7], v[4], v[5], v[2], v[3], v[0], v[1]] - : v; - }, - - hasHandles: function(v) { - var isZero = Numerical.isZero; - return !(isZero(v[0] - v[2]) && isZero(v[1] - v[3]) - && isZero(v[4] - v[6]) && isZero(v[5] - v[7])); - }, - - isFlatEnough: function(v, tolerance) { - var p1x = v[0], p1y = v[1], - c1x = v[2], c1y = v[3], - c2x = v[4], c2y = v[5], - p2x = v[6], p2y = v[7], - ux = 3 * c1x - 2 * p1x - p2x, - uy = 3 * c1y - 2 * p1y - p2y, - vx = 3 * c2x - 2 * p2x - p1x, - vy = 3 * c2y - 2 * p2y - p1y; - return Math.max(ux * ux, vx * vx) + Math.max(uy * uy, vy * vy) - < 10 * tolerance * tolerance; - }, - - getArea: function(v) { - var p1x = v[0], p1y = v[1], - p2x = v[6], p2y = v[7], - h1x = (v[2] + p1x) / 2, - h1y = (v[3] + p1y) / 2, - h2x = (v[4] + v[6]) / 2, - h2y = (v[5] + v[7]) / 2; - return 6 * ((p1x - h1x) * (h1y + p1y) - + (h1x - h2x) * (h2y + h1y) - + (h2x - p2x) * (p2y + h2y)) / 10; - }, - - getBounds: function(v) { - var min = v.slice(0, 2), - max = min.slice(), - roots = [0, 0]; - for (var i = 0; i < 2; i++) - Curve._addBounds(v[i], v[i + 2], v[i + 4], v[i + 6], - i, 0, min, max, roots); - return new Rectangle(min[0], min[1], max[0] - min[0], max[1] - min[1]); - }, - - _addBounds: function(v0, v1, v2, v3, coord, padding, min, max, roots) { - function add(value, padding) { - var left = value - padding, - right = value + padding; - if (left < min[coord]) - min[coord] = left; - if (right > max[coord]) - max[coord] = right; - } - var a = 3 * (v1 - v2) - v0 + v3, - b = 2 * (v0 + v2) - 4 * v1, - c = v1 - v0, - count = Numerical.solveQuadratic(a, b, c, roots), - tMin = 4e-7, - tMax = 1 - tMin; - add(v3, 0); - for (var i = 0; i < count; i++) { - var t = roots[i], - u = 1 - t; - if (tMin < t && t < tMax) - add(u * u * u * v0 - + 3 * u * u * t * v1 - + 3 * u * t * t * v2 - + t * t * t * v3, - padding); - } - } -}}, Base.each( - ['getBounds', 'getStrokeBounds', 'getHandleBounds', 'getRoughBounds'], - function(name) { - this[name] = function() { - if (!this._bounds) - this._bounds = {}; - var bounds = this._bounds[name]; - if (!bounds) { - var path = this._path; - bounds = this._bounds[name] = Path[name]( - [this._segment1, this._segment2], false, - path && path.getStyle()); - } - return bounds.clone(); - }; - }, -{ - -}), Base.each({ - isStraight: function(l, h1, h2) { - if (h1.isZero() && h2.isZero()) { - return true; - } else if (l.isZero()) { - return false; - } else if (h1.isCollinear(l) && h2.isCollinear(l)) { - var div = l.dot(l), - p1 = l.dot(h1) / div, - p2 = l.dot(h2) / div; - return p1 >= 0 && p1 <= 1 && p2 <= 0 && p2 >= -1; - } - return false; - }, - - isLinear: function(l, h1, h2) { - var third = l.divide(3); - return h1.equals(third) && h2.negate().equals(third); - } -}, function(test, name) { - this[name] = function() { - var seg1 = this._segment1, - seg2 = this._segment2; - return test(seg2._point.subtract(seg1._point), - seg1._handleOut, seg2._handleIn); - }; - - this.statics[name] = function(v) { - var p1x = v[0], p1y = v[1], - p2x = v[6], p2y = v[7]; - return test(new Point(p2x - p1x, p2y - p1y), - new Point(v[2] - p1x, v[3] - p1y), - new Point(v[4] - p2x, v[5] - p2y)); - }; -}, { - statics: {}, - - hasHandles: function() { - return !this._segment1._handleOut.isZero() - || !this._segment2._handleIn.isZero(); - }, - - isCollinear: function(curve) { - return curve && this.isStraight() && curve.isStraight() - && this.getLine().isCollinear(curve.getLine()); - }, - - isHorizontal: function() { - return this.isStraight() && Math.abs(this.getTangentAt(0.5, true).y) - < 1e-7; - }, - - isVertical: function() { - return this.isStraight() && Math.abs(this.getTangentAt(0.5, true).x) - < 1e-7; - } -}), { - beans: false, - - getParameterAt: function(offset, start) { - return Curve.getParameterAt(this.getValues(), offset, start); - }, - - getParameterOf: function() { - return Curve.getParameterOf(this.getValues(), Point.read(arguments)); - }, - - getLocationAt: function(offset, isParameter) { - var t = isParameter ? offset : this.getParameterAt(offset); - return t != null && t >= 0 && t <= 1 - ? new CurveLocation(this, t) - : null; - }, - - getLocationOf: function() { - return this.getLocationAt(this.getParameterOf(Point.read(arguments)), - true); - }, - - getOffsetOf: function() { - var loc = this.getLocationOf.apply(this, arguments); - return loc ? loc.getOffset() : null; - }, - - getNearestLocation: function() { - var point = Point.read(arguments), - values = this.getValues(), - t = Curve.getNearestParameter(values, point), - pt = Curve.getPoint(values, t); - return new CurveLocation(this, t, pt, null, point.getDistance(pt)); - }, - - getNearestPoint: function() { - return this.getNearestLocation.apply(this, arguments).getPoint(); - } - -}, -new function() { - var methods = ['getPoint', 'getTangent', 'getNormal', 'getWeightedTangent', - 'getWeightedNormal', 'getCurvature']; - return Base.each(methods, - function(name) { - this[name + 'At'] = function(offset, isParameter) { - var values = this.getValues(); - return Curve[name](values, isParameter ? offset - : Curve.getParameterAt(values, offset, 0)); - }; - }, { - statics: { - evaluateMethods: methods - } - }) -}, -new function() { - - function getLengthIntegrand(v) { - var p1x = v[0], p1y = v[1], - c1x = v[2], c1y = v[3], - c2x = v[4], c2y = v[5], - p2x = v[6], p2y = v[7], - - ax = 9 * (c1x - c2x) + 3 * (p2x - p1x), - bx = 6 * (p1x + c2x) - 12 * c1x, - cx = 3 * (c1x - p1x), - - ay = 9 * (c1y - c2y) + 3 * (p2y - p1y), - by = 6 * (p1y + c2y) - 12 * c1y, - cy = 3 * (c1y - p1y); - - return function(t) { - var dx = (ax * t + bx) * t + cx, - dy = (ay * t + by) * t + cy; - return Math.sqrt(dx * dx + dy * dy); - }; - } - - function getIterations(a, b) { - return Math.max(2, Math.min(16, Math.ceil(Math.abs(b - a) * 32))); - } - - function evaluate(v, t, type, normalized) { - if (t == null || t < 0 || t > 1) - return null; - var p1x = v[0], p1y = v[1], - c1x = v[2], c1y = v[3], - c2x = v[4], c2y = v[5], - p2x = v[6], p2y = v[7], - tMin = 4e-7, - tMax = 1 - tMin, - x, y; - - if (type === 0 && (t < tMin || t > tMax)) { - var isZero = t < tMin; - x = isZero ? p1x : p2x; - y = isZero ? p1y : p2y; - } else { - var cx = 3 * (c1x - p1x), - bx = 3 * (c2x - c1x) - cx, - ax = p2x - p1x - cx - bx, - - cy = 3 * (c1y - p1y), - by = 3 * (c2y - c1y) - cy, - ay = p2y - p1y - cy - by; - if (type === 0) { - x = ((ax * t + bx) * t + cx) * t + p1x; - y = ((ay * t + by) * t + cy) * t + p1y; - } else { - if (t < tMin) { - x = cx; - y = cy; - } else if (t > tMax) { - x = 3 * (p2x - c2x); - y = 3 * (p2y - c2y); - } else { - x = (3 * ax * t + 2 * bx) * t + cx; - y = (3 * ay * t + 2 * by) * t + cy; - } - if (normalized) { - if (x === 0 && y === 0 && (t < tMin || t > tMax)) { - x = c2x - c1x; - y = c2y - c1y; - } - var len = Math.sqrt(x * x + y * y); - if (len) { - x /= len; - y /= len; - } - } - if (type === 3) { - var x2 = 6 * ax * t + 2 * bx, - y2 = 6 * ay * t + 2 * by, - d = Math.pow(x * x + y * y, 3 / 2); - x = d !== 0 ? (x * y2 - y * x2) / d : 0; - y = 0; - } - } - } - return type === 2 ? new Point(y, -x) : new Point(x, y); - } - - return { statics: { - - getLength: function(v, a, b) { - if (a === undefined) - a = 0; - if (b === undefined) - b = 1; - if (a === 0 && b === 1 && Curve.isStraight(v)) { - var dx = v[6] - v[0], - dy = v[7] - v[1]; - return Math.sqrt(dx * dx + dy * dy); - } - var ds = getLengthIntegrand(v); - return Numerical.integrate(ds, a, b, getIterations(a, b)); - }, - - getParameterAt: function(v, offset, start) { - if (start === undefined) - start = offset < 0 ? 1 : 0 - if (offset === 0) - return start; - var abs = Math.abs, - forward = offset > 0, - a = forward ? start : 0, - b = forward ? 1 : start, - ds = getLengthIntegrand(v), - rangeLength = Numerical.integrate(ds, a, b, - getIterations(a, b)); - if (abs(offset - rangeLength) < 1e-12) { - return forward ? b : a; - } else if (abs(offset) > rangeLength) { - return null; - } - var guess = offset / rangeLength, - length = 0; - function f(t) { - length += Numerical.integrate(ds, start, t, - getIterations(start, t)); - start = t; - return length - offset; - } - return Numerical.findRoot(f, ds, start + guess, a, b, 32, - 1e-12); - }, - - getPoint: function(v, t) { - return evaluate(v, t, 0, false); - }, - - getTangent: function(v, t) { - return evaluate(v, t, 1, true); - }, - - getWeightedTangent: function(v, t) { - return evaluate(v, t, 1, false); - }, - - getNormal: function(v, t) { - return evaluate(v, t, 2, true); - }, - - getWeightedNormal: function(v, t) { - return evaluate(v, t, 2, false); - }, - - getCurvature: function(v, t) { - return evaluate(v, t, 3, false).x; - } - }}; -}, -new function() { - - function addLocation(locations, param, v1, c1, t1, p1, v2, c2, t2, p2, - overlap) { - var startConnected = param.startConnected, - endConnected = param.endConnected, - tMin = 4e-7, - tMax = 1 - tMin; - if (t1 == null) - t1 = Curve.getParameterOf(v1, p1); - if (t1 !== null && t1 >= (startConnected ? tMin : 0) && - t1 <= (endConnected ? tMax : 1)) { - if (t2 == null) - t2 = Curve.getParameterOf(v2, p2); - if (t2 !== null && t2 >= (endConnected ? tMin : 0) && - t2 <= (startConnected ? tMax : 1)) { - var renormalize = param.renormalize; - if (renormalize) { - var res = renormalize(t1, t2); - t1 = res[0]; - t2 = res[1]; - } - var loc1 = new CurveLocation(c1, t1, - p1 || Curve.getPoint(v1, t1), overlap), - loc2 = new CurveLocation(c2, t2, - p2 || Curve.getPoint(v2, t2), overlap), - flip = loc1.getPath() === loc2.getPath() - && loc1.getIndex() > loc2.getIndex(), - loc = flip ? loc2 : loc1, - include = param.include; - loc1._intersection = loc2; - loc2._intersection = loc1; - if (!include || include(loc)) { - CurveLocation.insert(locations, loc, true); - } - } - } - } - - function addCurveIntersections(v1, v2, c1, c2, locations, param, - tMin, tMax, uMin, uMax, oldTDiff, reverse, recursion) { - if (++recursion >= 24) - return; - var q0x = v2[0], q0y = v2[1], q3x = v2[6], q3y = v2[7], - getSignedDistance = Line.getSignedDistance, - d1 = getSignedDistance(q0x, q0y, q3x, q3y, v2[2], v2[3]), - d2 = getSignedDistance(q0x, q0y, q3x, q3y, v2[4], v2[5]), - factor = d1 * d2 > 0 ? 3 / 4 : 4 / 9, - dMin = factor * Math.min(0, d1, d2), - dMax = factor * Math.max(0, d1, d2), - dp0 = getSignedDistance(q0x, q0y, q3x, q3y, v1[0], v1[1]), - dp1 = getSignedDistance(q0x, q0y, q3x, q3y, v1[2], v1[3]), - dp2 = getSignedDistance(q0x, q0y, q3x, q3y, v1[4], v1[5]), - dp3 = getSignedDistance(q0x, q0y, q3x, q3y, v1[6], v1[7]), - hull = getConvexHull(dp0, dp1, dp2, dp3), - top = hull[0], - bottom = hull[1], - tMinClip, - tMaxClip; - if ((tMinClip = clipConvexHull(top, bottom, dMin, dMax)) == null || - (tMaxClip = clipConvexHull(top.reverse(), bottom.reverse(), - dMin, dMax)) == null) - return; - v1 = Curve.getPart(v1, tMinClip, tMaxClip); - var tDiff = tMaxClip - tMinClip, - tMinNew = tMin + (tMax - tMin) * tMinClip, - tMaxNew = tMin + (tMax - tMin) * tMaxClip; - if (oldTDiff > 0.5 && tDiff > 0.5) { - if (tMaxNew - tMinNew > uMax - uMin) { - var parts = Curve.subdivide(v1, 0.5), - t = tMinNew + (tMaxNew - tMinNew) / 2; - addCurveIntersections( - v2, parts[0], c2, c1, locations, param, - uMin, uMax, tMinNew, t, tDiff, !reverse, recursion); - addCurveIntersections( - v2, parts[1], c2, c1, locations, param, - uMin, uMax, t, tMaxNew, tDiff, !reverse, recursion); - } else { - var parts = Curve.subdivide(v2, 0.5), - t = uMin + (uMax - uMin) / 2; - addCurveIntersections( - parts[0], v1, c2, c1, locations, param, - uMin, t, tMinNew, tMaxNew, tDiff, !reverse, recursion); - addCurveIntersections( - parts[1], v1, c2, c1, locations, param, - t, uMax, tMinNew, tMaxNew, tDiff, !reverse, recursion); - } - } else if (Math.max(uMax - uMin, tMaxNew - tMinNew) - < 1e-7) { - var t1 = tMinNew + (tMaxNew - tMinNew) / 2, - t2 = uMin + (uMax - uMin) / 2; - v1 = c1.getValues(); - v2 = c2.getValues(); - addLocation(locations, param, - reverse ? v2 : v1, reverse ? c2 : c1, reverse ? t2 : t1, null, - reverse ? v1 : v2, reverse ? c1 : c2, reverse ? t1 : t2, null); - } else if (tDiff > 1e-12) { - addCurveIntersections(v2, v1, c2, c1, locations, param, - uMin, uMax, tMinNew, tMaxNew, tDiff, !reverse, recursion); - } - } - - function getConvexHull(dq0, dq1, dq2, dq3) { - var p0 = [ 0, dq0 ], - p1 = [ 1 / 3, dq1 ], - p2 = [ 2 / 3, dq2 ], - p3 = [ 1, dq3 ], - dist1 = dq1 - (2 * dq0 + dq3) / 3, - dist2 = dq2 - (dq0 + 2 * dq3) / 3, - hull; - if (dist1 * dist2 < 0) { - hull = [[p0, p1, p3], [p0, p2, p3]]; - } else { - var distRatio = dist1 / dist2; - hull = [ - distRatio >= 2 ? [p0, p1, p3] - : distRatio <= .5 ? [p0, p2, p3] - : [p0, p1, p2, p3], - [p0, p3] - ]; - } - return (dist1 || dist2) < 0 ? hull.reverse() : hull; - } - - function clipConvexHull(hullTop, hullBottom, dMin, dMax) { - if (hullTop[0][1] < dMin) { - return clipConvexHullPart(hullTop, true, dMin); - } else if (hullBottom[0][1] > dMax) { - return clipConvexHullPart(hullBottom, false, dMax); - } else { - return hullTop[0][0]; - } - } - - function clipConvexHullPart(part, top, threshold) { - var px = part[0][0], - py = part[0][1]; - for (var i = 1, l = part.length; i < l; i++) { - var qx = part[i][0], - qy = part[i][1]; - if (top ? qy >= threshold : qy <= threshold) { - return qy === threshold ? qx - : px + (threshold - py) * (qx - px) / (qy - py); - } - px = qx; - py = qy; - } - return null; - } - - function addCurveLineIntersections(v1, v2, c1, c2, locations, param) { - var flip = Curve.isStraight(v1), - vc = flip ? v2 : v1, - vl = flip ? v1 : v2, - lx1 = vl[0], ly1 = vl[1], - lx2 = vl[6], ly2 = vl[7], - ldx = lx2 - lx1, - ldy = ly2 - ly1, - angle = Math.atan2(-ldy, ldx), - sin = Math.sin(angle), - cos = Math.cos(angle), - rvc = []; - for(var i = 0; i < 8; i += 2) { - var x = vc[i] - lx1, - y = vc[i + 1] - ly1; - rvc.push( - x * cos - y * sin, - x * sin + y * cos); - } - var roots = [], - count = Curve.solveCubic(rvc, 1, 0, roots, 0, 1); - for (var i = 0; i < count; i++) { - var tc = roots[i], - pc = Curve.getPoint(vc, tc), - tl = Curve.getParameterOf(vl, pc); - if (tl !== null) { - var pl = Curve.getPoint(vl, tl), - t1 = flip ? tl : tc, - t2 = flip ? tc : tl; - if (!param.endConnected || t2 > Numerical.CURVETIME_EPSILON) { - addLocation(locations, param, - v1, c1, t1, flip ? pl : pc, - v2, c2, t2, flip ? pc : pl); - } - } - } - } - - function addLineIntersection(v1, v2, c1, c2, locations, param) { - var pt = Line.intersect( - v1[0], v1[1], v1[6], v1[7], - v2[0], v2[1], v2[6], v2[7]); - if (pt) { - addLocation(locations, param, v1, c1, null, pt, v2, c2, null, pt); - } - } - - return { statics: { - _getIntersections: function(v1, v2, c1, c2, locations, param) { - if (!v2) { - return Curve._getSelfIntersection(v1, c1, locations, param); - } - var c1p1x = v1[0], c1p1y = v1[1], - c1p2x = v1[6], c1p2y = v1[7], - c2p1x = v2[0], c2p1y = v2[1], - c2p2x = v2[6], c2p2y = v2[7], - c1s1x = (3 * v1[2] + c1p1x) / 4, - c1s1y = (3 * v1[3] + c1p1y) / 4, - c1s2x = (3 * v1[4] + c1p2x) / 4, - c1s2y = (3 * v1[5] + c1p2y) / 4, - c2s1x = (3 * v2[2] + c2p1x) / 4, - c2s1y = (3 * v2[3] + c2p1y) / 4, - c2s2x = (3 * v2[4] + c2p2x) / 4, - c2s2y = (3 * v2[5] + c2p2y) / 4, - min = Math.min, - max = Math.max; - if (!( max(c1p1x, c1s1x, c1s2x, c1p2x) >= - min(c2p1x, c2s1x, c2s2x, c2p2x) && - min(c1p1x, c1s1x, c1s2x, c1p2x) <= - max(c2p1x, c2s1x, c2s2x, c2p2x) && - max(c1p1y, c1s1y, c1s2y, c1p2y) >= - min(c2p1y, c2s1y, c2s2y, c2p2y) && - min(c1p1y, c1s1y, c1s2y, c1p2y) <= - max(c2p1y, c2s1y, c2s2y, c2p2y))) - return locations; - if (!param.startConnected && !param.endConnected) { - var overlaps = Curve.getOverlaps(v1, v2); - if (overlaps) { - for (var i = 0; i < 2; i++) { - var overlap = overlaps[i]; - addLocation(locations, param, - v1, c1, overlap[0], null, - v2, c2, overlap[1], null, true); - } - return locations; - } - } - - var straight1 = Curve.isStraight(v1), - straight2 = Curve.isStraight(v2), - straight = straight1 && straight2, - epsilon = 1e-12, - before = locations.length; - (straight - ? addLineIntersection - : straight1 || straight2 - ? addCurveLineIntersections - : addCurveIntersections)( - v1, v2, c1, c2, locations, param, - 0, 1, 0, 1, 0, false, 0); - if (straight && locations.length > before) - return locations; - var c1p1 = new Point(c1p1x, c1p1y), - c1p2 = new Point(c1p2x, c1p2y), - c2p1 = new Point(c2p1x, c2p1y), - c2p2 = new Point(c2p2x, c2p2y); - if (c1p1.isClose(c2p1, epsilon)) - addLocation(locations, param, v1, c1, 0, c1p1, v2, c2, 0, c2p1); - if (!param.startConnected && c1p1.isClose(c2p2, epsilon)) - addLocation(locations, param, v1, c1, 0, c1p1, v2, c2, 1, c2p2); - if (!param.endConnected && c1p2.isClose(c2p1, epsilon)) - addLocation(locations, param, v1, c1, 1, c1p2, v2, c2, 0, c2p1); - if (c1p2.isClose(c2p2, epsilon)) - addLocation(locations, param, v1, c1, 1, c1p2, v2, c2, 1, c2p2); - return locations; - }, - - _getSelfIntersection: function(v1, c1, locations, param) { - var p1x = v1[0], p1y = v1[1], - h1x = v1[2], h1y = v1[3], - h2x = v1[4], h2y = v1[5], - p2x = v1[6], p2y = v1[7]; - var line = new Line(p1x, p1y, p2x, p2y, false), - side1 = line.getSide(new Point(h1x, h1y), true), - side2 = line.getSide(new Point(h2x, h2y), true); - if (side1 === side2) { - var edgeSum = (p1x - h2x) * (h1y - p2y) - + (h1x - p2x) * (h2y - p1y); - if (edgeSum * side1 > 0) - return locations; - } - var ax = p2x - 3 * h2x + 3 * h1x - p1x, - bx = h2x - 2 * h1x + p1x, - cx = h1x - p1x, - ay = p2y - 3 * h2y + 3 * h1y - p1y, - by = h2y - 2 * h1y + p1y, - cy = h1y - p1y, - ac = ay * cx - ax * cy, - ab = ay * bx - ax * by, - bc = by * cx - bx * cy; - if (ac * ac - 4 * ab * bc < 0) { - var roots = [], - tSplit, - count = Numerical.solveCubic( - ax * ax + ay * ay, - 3 * (ax * bx + ay * by), - 2 * (bx * bx + by * by) + ax * cx + ay * cy, - bx * cx + by * cy, - roots, 0, 1); - if (count > 0) { - for (var i = 0, maxCurvature = 0; i < count; i++) { - var curvature = Math.abs( - c1.getCurvatureAt(roots[i], true)); - if (curvature > maxCurvature) { - maxCurvature = curvature; - tSplit = roots[i]; - } - } - var parts = Curve.subdivide(v1, tSplit); - param.endConnected = true; - param.renormalize = function(t1, t2) { - return [t1 * tSplit, t2 * (1 - tSplit) + tSplit]; - }; - Curve._getIntersections(parts[0], parts[1], c1, c1, - locations, param); - } - } - return locations; - }, - - getOverlaps: function(v1, v2) { - var abs = Math.abs, - timeEpsilon = 4e-7, - geomEpsilon = 2e-7, - straight1 = Curve.isStraight(v1), - straight2 = Curve.isStraight(v2), - straight = straight1 && straight2; - - function getLineLengthSquared(v) { - var x = v[6] - v[0], - y = v[7] - v[1]; - return x * x + y * y; - } - - if (straight) { - var flip = getLineLengthSquared(v1) < getLineLengthSquared(v2), - l1 = flip ? v2 : v1, - l2 = flip ? v1 : v2, - line = new Line(l1[0], l1[1], l1[6], l1[7]); - if (line.getDistance(new Point(l2[0], l2[1])) > geomEpsilon || - line.getDistance(new Point(l2[6], l2[7])) > geomEpsilon) - return null; - } else if (straight1 ^ straight2) { - return null; - } - - var v = [v1, v2], - pairs = []; - for (var i = 0, t1 = 0; - i < 2 && pairs.length < 2; - i += t1 === 0 ? 0 : 1, t1 = t1 ^ 1) { - var t2 = Curve.getParameterOf(v[i ^ 1], new Point( - v[i][t1 === 0 ? 0 : 6], - v[i][t1 === 0 ? 1 : 7])); - if (t2 != null) { - var pair = i === 0 ? [t1, t2] : [t2, t1]; - if (pairs.length === 0 || - abs(pair[0] - pairs[0][0]) > timeEpsilon && - abs(pair[1] - pairs[0][1]) > timeEpsilon) - pairs.push(pair); - } - if (i === 1 && pairs.length === 0) - break; - } - if (pairs.length !== 2) { - pairs = null; - } else if (!straight) { - var o1 = Curve.getPart(v1, pairs[0][0], pairs[1][0]), - o2 = Curve.getPart(v2, pairs[0][1], pairs[1][1]); - if (abs(o2[2] - o1[2]) > geomEpsilon || - abs(o2[3] - o1[3]) > geomEpsilon || - abs(o2[4] - o1[4]) > geomEpsilon || - abs(o2[5] - o1[5]) > geomEpsilon) - pairs = null; - } - return pairs; - } - }}; -}); - -var CurveLocation = Base.extend({ - _class: 'CurveLocation', - beans: true, - - initialize: function CurveLocation(curve, parameter, point, - _overlap, _distance) { - if (parameter > 0.9999996) { - var next = curve.getNext(); - if (next) { - parameter = 0; - curve = next; - } - } - this._id = UID.get(CurveLocation); - this._setCurve(curve); - this._parameter = parameter; - this._point = point || curve.getPointAt(parameter, true); - this._overlap = _overlap; - this._distance = _distance; - this._intersection = this._next = this._prev = null; - }, - - _setCurve: function(curve) { - var path = curve._path; - this._version = path ? path._version : 0; - this._curve = curve; - this._segment = null; - this._segment1 = curve._segment1; - this._segment2 = curve._segment2; - }, - - _setSegment: function(segment) { - this._setCurve(segment.getCurve()); - this._segment = segment; - this._parameter = segment === this._segment1 ? 0 : 1; - this._point = segment._point.clone(); - }, - - getSegment: function() { - var curve = this.getCurve(), - segment = this._segment; - if (!segment) { - var parameter = this.getParameter(); - if (parameter === 0) { - segment = curve._segment1; - } else if (parameter === 1) { - segment = curve._segment2; - } else if (parameter != null) { - segment = curve.getPartLength(0, parameter) - < curve.getPartLength(parameter, 1) - ? curve._segment1 - : curve._segment2; - } - this._segment = segment; - } - return segment; - }, - - getCurve: function() { - var curve = this._curve, - path = curve && curve._path, - that = this; - if (path && path._version !== this._version) { - curve = this._parameter = this._curve = this._offset = null; - } - - function trySegment(segment) { - var curve = segment && segment.getCurve(); - if (curve && (that._parameter = curve.getParameterOf(that._point)) - != null) { - that._setCurve(curve); - that._segment = segment; - return curve; - } - } - - return curve - || trySegment(this._segment) - || trySegment(this._segment1) - || trySegment(this._segment2.getPrevious()); - }, - - getPath: function() { - var curve = this.getCurve(); - return curve && curve._path; - }, - - getIndex: function() { - var curve = this.getCurve(); - return curve && curve.getIndex(); - }, - - getParameter: function() { - var curve = this.getCurve(), - parameter = this._parameter; - return curve && parameter == null - ? this._parameter = curve.getParameterOf(this._point) - : parameter; - }, - - getPoint: function() { - return this._point; - }, - - getOffset: function() { - var offset = this._offset; - if (offset == null) { - offset = 0; - var path = this.getPath(), - index = this.getIndex(); - if (path && index != null) { - var curves = path.getCurves(); - for (var i = 0; i < index; i++) - offset += curves[i].getLength(); - } - this._offset = offset += this.getCurveOffset(); - } - return offset; - }, - - getCurveOffset: function() { - var curve = this.getCurve(), - parameter = this.getParameter(); - return parameter != null && curve && curve.getPartLength(0, parameter); - }, - - getIntersection: function() { - return this._intersection; - }, - - getDistance: function() { - return this._distance; - }, - - divide: function() { - var curve = this.getCurve(), - res = null; - if (curve) { - res = curve.divide(this.getParameter(), true); - if (res) - this._setSegment(res._segment1); - } - return res; - }, - - split: function() { - var curve = this.getCurve(); - return curve ? curve.split(this.getParameter(), true) : null; - }, - - equals: function(loc, _ignoreOther) { - var res = this === loc, - epsilon = 2e-7; - if (!res && loc instanceof CurveLocation - && this.getPath() === loc.getPath() - && this.getPoint().isClose(loc.getPoint(), epsilon)) { - var c1 = this.getCurve(), - c2 = loc.getCurve(), - abs = Math.abs, - diff = abs( - ((c1.isLast() && c2.isFirst() ? -1 : c1.getIndex()) - + this.getParameter()) - - ((c2.isLast() && c1.isFirst() ? -1 : c2.getIndex()) - + loc.getParameter())); - res = (diff < 4e-7 - || ((diff = abs(this.getOffset() - loc.getOffset())) < epsilon - || abs(this.getPath().getLength() - diff) < epsilon)) - && (_ignoreOther - || (!this._intersection && !loc._intersection - || this._intersection && this._intersection.equals( - loc._intersection, true))); - } - return res; - }, - - toString: function() { - var parts = [], - point = this.getPoint(), - f = Formatter.instance; - if (point) - parts.push('point: ' + point); - var index = this.getIndex(); - if (index != null) - parts.push('index: ' + index); - var parameter = this.getParameter(); - if (parameter != null) - parts.push('parameter: ' + f.number(parameter)); - if (this._distance != null) - parts.push('distance: ' + f.number(this._distance)); - return '{ ' + parts.join(', ') + ' }'; - }, - - isTouching: function() { - var inter = this._intersection; - if (inter && this.getTangent().isCollinear(inter.getTangent())) { - var curve1 = this.getCurve(), - curve2 = inter.getCurve(); - return !(curve1.isStraight() && curve2.isStraight() - && curve1.getLine().intersect(curve2.getLine())); - } - return false; - }, - - isCrossing: function() { - var inter = this._intersection; - if (!inter) - return false; - var t1 = this.getParameter(), - t2 = inter.getParameter(), - tMin = 4e-7, - tMax = 1 - tMin; - if (t1 >= tMin && t1 <= tMax || t2 >= tMin && t2 <= tMax) - return !this.isTouching(); - var c2 = this.getCurve(), - c1 = c2.getPrevious(), - c4 = inter.getCurve(), - c3 = c4.getPrevious(), - PI = Math.PI; - if (!c1 || !c3) - return false; - - function isInRange(angle, min, max) { - return min < max - ? angle > min && angle < max - : angle > min && angle <= PI || angle >= -PI && angle < max; - } - - var a1 = c1.getTangentAt(tMax, true).negate().getAngleInRadians(), - a2 = c2.getTangentAt(tMin, true).getAngleInRadians(), - a3 = c3.getTangentAt(tMax, true).negate().getAngleInRadians(), - a4 = c4.getTangentAt(tMin, true).getAngleInRadians(); - - return (isInRange(a3, a1, a2) ^ isInRange(a4, a1, a2)) - && (isInRange(a3, a2, a1) ^ isInRange(a4, a2, a1)); - }, - - isOverlap: function() { - return !!this._overlap; - } -}, Base.each(Curve.evaluateMethods, function(name) { - var get = name + 'At'; - this[name] = function() { - var parameter = this.getParameter(), - curve = this.getCurve(); - return parameter != null && curve && curve[get](parameter, true); - }; -}, { - preserve: true -}), -new function() { - - function insert(locations, loc, merge) { - var length = locations.length, - l = 0, - r = length - 1; - - function search(index, dir) { - for (var i = index + dir; i >= -1 && i <= length; i += dir) { - var loc2 = locations[((i % length) + length) % length]; - if (!loc.getPoint().isClose(loc2.getPoint(), - 2e-7)) - break; - if (loc.equals(loc2)) - return loc2; - } - return null; - } - - while (l <= r) { - var m = (l + r) >>> 1, - loc2 = locations[m], - found; - if (merge && (found = loc.equals(loc2) ? loc2 - : (search(m, -1) || search(m, 1)))) { - if (loc._overlap) { - found._overlap = found._intersection._overlap = true; - } - return found; - } - var path1 = loc.getPath(), - path2 = loc2.getPath(), - diff = path1 === path2 - ? (loc.getIndex() + loc.getParameter()) - - (loc2.getIndex() + loc2.getParameter()) - : path1._id - path2._id; - if (diff < 0) { - r = m - 1; - } else { - l = m + 1; - } - } - locations.splice(l, 0, loc); - return loc; - } - - return { statics: { - insert: insert, - - expand: function(locations) { - var expanded = locations.slice(); - for (var i = 0, l = locations.length; i < l; i++) { - insert(expanded, locations[i]._intersection, false); - } - return expanded; - } - }}; -}); - -var PathItem = Item.extend({ - _class: 'PathItem', - - initialize: function PathItem() { - }, - - getIntersections: function(path, include, _matrix, _returnFirst) { - var self = this === path || !path, - matrix1 = this._matrix.orNullIfIdentity(), - matrix2 = self ? matrix1 - : (_matrix || path._matrix).orNullIfIdentity(); - if (!self && !this.getBounds(matrix1).touches(path.getBounds(matrix2))) - return []; - var curves1 = this.getCurves(), - curves2 = self ? curves1 : path.getCurves(), - length1 = curves1.length, - length2 = self ? length1 : curves2.length, - values2 = [], - arrays = [], - locations, - path; - for (var i = 0; i < length2; i++) - values2[i] = curves2[i].getValues(matrix2); - for (var i = 0; i < length1; i++) { - var curve1 = curves1[i], - values1 = self ? values2[i] : curve1.getValues(matrix1), - path1 = curve1.getPath(); - if (path1 !== path) { - path = path1; - locations = []; - arrays.push(locations); - } - if (self) { - Curve._getSelfIntersection(values1, curve1, locations, { - include: include, - startConnected: length1 === 1 && - curve1.getPoint1().equals(curve1.getPoint2()) - }); - } - for (var j = self ? i + 1 : 0; j < length2; j++) { - if (_returnFirst && locations.length) - return locations; - var curve2 = curves2[j]; - Curve._getIntersections( - values1, values2[j], curve1, curve2, locations, - { - include: include, - startConnected: self && curve1.getPrevious() === curve2, - endConnected: self && curve1.getNext() === curve2 - } - ); - } - } - locations = []; - for (var i = 0, l = arrays.length; i < l; i++) { - locations.push.apply(locations, arrays[i]); - } - return locations; - }, - - getCrossings: function(path) { - return this.getIntersections(path, function(inter) { - return inter.isCrossing(); - }); - }, - - _asPathItem: function() { - return this; - }, - - setPathData: function(data) { - - var parts = data.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig), - coords, - relative = false, - previous, - control, - current = new Point(), - start = new Point(); - - function getCoord(index, coord) { - var val = +coords[index]; - if (relative) - val += current[coord]; - return val; - } - - function getPoint(index) { - return new Point( - getCoord(index, 'x'), - getCoord(index + 1, 'y') - ); - } - - this.clear(); - - for (var i = 0, l = parts && parts.length; i < l; i++) { - var part = parts[i], - command = part[0], - lower = command.toLowerCase(); - coords = part.match(/[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g); - var length = coords && coords.length; - relative = command === lower; - if (previous === 'z' && !/[mz]/.test(lower)) - this.moveTo(current = start); - switch (lower) { - case 'm': - case 'l': - var move = lower === 'm'; - for (var j = 0; j < length; j += 2) - this[j === 0 && move ? 'moveTo' : 'lineTo']( - current = getPoint(j)); - control = current; - if (move) - start = current; - break; - case 'h': - case 'v': - var coord = lower === 'h' ? 'x' : 'y'; - for (var j = 0; j < length; j++) { - current[coord] = getCoord(j, coord); - this.lineTo(current); - } - control = current; - break; - case 'c': - for (var j = 0; j < length; j += 6) { - this.cubicCurveTo( - getPoint(j), - control = getPoint(j + 2), - current = getPoint(j + 4)); - } - break; - case 's': - for (var j = 0; j < length; j += 4) { - this.cubicCurveTo( - /[cs]/.test(previous) - ? current.multiply(2).subtract(control) - : current, - control = getPoint(j), - current = getPoint(j + 2)); - previous = lower; - } - break; - case 'q': - for (var j = 0; j < length; j += 4) { - this.quadraticCurveTo( - control = getPoint(j), - current = getPoint(j + 2)); - } - break; - case 't': - for (var j = 0; j < length; j += 2) { - this.quadraticCurveTo( - control = (/[qt]/.test(previous) - ? current.multiply(2).subtract(control) - : current), - current = getPoint(j)); - previous = lower; - } - break; - case 'a': - for (var j = 0; j < length; j += 7) { - this.arcTo(current = getPoint(j + 5), - new Size(+coords[j], +coords[j + 1]), - +coords[j + 2], +coords[j + 4], +coords[j + 3]); - } - break; - case 'z': - this.closePath(true); - break; - } - previous = lower; - } - }, - - _canComposite: function() { - return !(this.hasFill() && this.hasStroke()); - }, - - _contains: function(point) { - var winding = this._getWinding(point, false, true); - return !!(this.getWindingRule() === 'evenodd' ? winding & 1 : winding); - } - -}); - -var Path = PathItem.extend({ - _class: 'Path', - _serializeFields: { - segments: [], - closed: false - }, - - initialize: function Path(arg) { - this._closed = false; - this._segments = []; - this._version = 0; - var segments = Array.isArray(arg) - ? typeof arg[0] === 'object' - ? arg - : arguments - : arg && (arg.size === undefined && (arg.x !== undefined - || arg.point !== undefined)) - ? arguments - : null; - if (segments && segments.length > 0) { - this.setSegments(segments); - } else { - this._curves = undefined; - this._selectedSegmentState = 0; - if (!segments && typeof arg === 'string') { - this.setPathData(arg); - arg = null; - } - } - this._initialize(!segments && arg); - }, - - _equals: function(item) { - return this._closed === item._closed - && Base.equals(this._segments, item._segments); - }, - - clone: function(insert) { - var copy = new Path(Item.NO_INSERT); - copy.setSegments(this._segments); - copy._closed = this._closed; - if (this._clockwise !== undefined) - copy._clockwise = this._clockwise; - return this._clone(copy, insert); - }, - - _changed: function _changed(flags) { - _changed.base.call(this, flags); - if (flags & 8) { - var parent = this._parent; - if (parent) - parent._currentPath = undefined; - this._length = this._area = this._clockwise = this._monoCurves = - undefined; - if (flags & 16) { - this._version++; - } else if (this._curves) { - for (var i = 0, l = this._curves.length; i < l; i++) - this._curves[i]._changed(); - } - } else if (flags & 32) { - this._bounds = undefined; - } - }, - - getStyle: function() { - var parent = this._parent; - return (parent instanceof CompoundPath ? parent : this)._style; - }, - - getSegments: function() { - return this._segments; - }, - - setSegments: function(segments) { - var fullySelected = this.isFullySelected(); - this._segments.length = 0; - this._selectedSegmentState = 0; - this._curves = undefined; - if (segments && segments.length > 0) - this._add(Segment.readAll(segments)); - if (fullySelected) - this.setFullySelected(true); - }, - - getFirstSegment: function() { - return this._segments[0]; - }, - - getLastSegment: function() { - return this._segments[this._segments.length - 1]; - }, - - getCurves: function() { - var curves = this._curves, - segments = this._segments; - if (!curves) { - var length = this._countCurves(); - curves = this._curves = new Array(length); - for (var i = 0; i < length; i++) - curves[i] = new Curve(this, segments[i], - segments[i + 1] || segments[0]); - } - return curves; - }, - - getFirstCurve: function() { - return this.getCurves()[0]; - }, - - getLastCurve: function() { - var curves = this.getCurves(); - return curves[curves.length - 1]; - }, - - isClosed: function() { - return this._closed; - }, - - setClosed: function(closed) { - if (this._closed != (closed = !!closed)) { - this._closed = closed; - if (this._curves) { - var length = this._curves.length = this._countCurves(); - if (closed) - this._curves[length - 1] = new Curve(this, - this._segments[length - 1], this._segments[0]); - } - this._changed(25); - } - } -}, { - beans: true, - - getPathData: function(_matrix, _precision) { - var segments = this._segments, - length = segments.length, - f = new Formatter(_precision), - coords = new Array(6), - first = true, - curX, curY, - prevX, prevY, - inX, inY, - outX, outY, - parts = []; - - function addSegment(segment, skipLine) { - segment._transformCoordinates(_matrix, coords, false); - curX = coords[0]; - curY = coords[1]; - if (first) { - parts.push('M' + f.pair(curX, curY)); - first = false; - } else { - inX = coords[2]; - inY = coords[3]; - if (inX === curX && inY === curY - && outX === prevX && outY === prevY) { - if (!skipLine) - parts.push('l' + f.pair(curX - prevX, curY - prevY)); - } else { - parts.push('c' + f.pair(outX - prevX, outY - prevY) - + ' ' + f.pair(inX - prevX, inY - prevY) - + ' ' + f.pair(curX - prevX, curY - prevY)); - } - } - prevX = curX; - prevY = curY; - outX = coords[4]; - outY = coords[5]; - } - - if (length === 0) - return ''; - - for (var i = 0; i < length; i++) - addSegment(segments[i]); - if (this._closed && length > 0) { - addSegment(segments[0], true); - parts.push('z'); - } - return parts.join(''); - } -}, { - - isEmpty: function() { - return this._segments.length === 0; - }, - - _transformContent: function(matrix) { - var coords = new Array(6); - for (var i = 0, l = this._segments.length; i < l; i++) - this._segments[i]._transformCoordinates(matrix, coords, true); - return true; - }, - - _add: function(segs, index) { - var segments = this._segments, - curves = this._curves, - amount = segs.length, - append = index == null, - index = append ? segments.length : index; - for (var i = 0; i < amount; i++) { - var segment = segs[i]; - if (segment._path) - segment = segs[i] = segment.clone(); - segment._path = this; - segment._index = index + i; - if (segment._selectionState) - this._updateSelection(segment, 0, segment._selectionState); - } - if (append) { - segments.push.apply(segments, segs); - } else { - segments.splice.apply(segments, [index, 0].concat(segs)); - for (var i = index + amount, l = segments.length; i < l; i++) - segments[i]._index = i; - } - if (curves) { - var total = this._countCurves(), - from = index + amount - 1 === total ? index - 1 : index, - start = from, - to = Math.min(from + amount, total); - if (segs._curves) { - curves.splice.apply(curves, [from, 0].concat(segs._curves)); - start += segs._curves.length; - } - for (var i = start; i < to; i++) - curves.splice(i, 0, new Curve(this, null, null)); - this._adjustCurves(from, to); - } - this._changed(25); - return segs; - }, - - _adjustCurves: function(from, to) { - var segments = this._segments, - curves = this._curves, - curve; - for (var i = from; i < to; i++) { - curve = curves[i]; - curve._path = this; - curve._segment1 = segments[i]; - curve._segment2 = segments[i + 1] || segments[0]; - curve._changed(); - } - if (curve = curves[this._closed && from === 0 ? segments.length - 1 - : from - 1]) { - curve._segment2 = segments[from] || segments[0]; - curve._changed(); - } - if (curve = curves[to]) { - curve._segment1 = segments[to]; - curve._changed(); - } - }, - - _countCurves: function() { - var length = this._segments.length; - return !this._closed && length > 0 ? length - 1 : length; - }, - - add: function(segment1 ) { - return arguments.length > 1 && typeof segment1 !== 'number' - ? this._add(Segment.readAll(arguments)) - : this._add([ Segment.read(arguments) ])[0]; - }, - - insert: function(index, segment1 ) { - return arguments.length > 2 && typeof segment1 !== 'number' - ? this._add(Segment.readAll(arguments, 1), index) - : this._add([ Segment.read(arguments, 1) ], index)[0]; - }, - - addSegment: function() { - return this._add([ Segment.read(arguments) ])[0]; - }, - - insertSegment: function(index ) { - return this._add([ Segment.read(arguments, 1) ], index)[0]; - }, - - addSegments: function(segments) { - return this._add(Segment.readAll(segments)); - }, - - insertSegments: function(index, segments) { - return this._add(Segment.readAll(segments), index); - }, - - removeSegment: function(index) { - return this.removeSegments(index, index + 1)[0] || null; - }, - - removeSegments: function(from, to, _includeCurves) { - from = from || 0; - to = Base.pick(to, this._segments.length); - var segments = this._segments, - curves = this._curves, - count = segments.length, - removed = segments.splice(from, to - from), - amount = removed.length; - if (!amount) - return removed; - for (var i = 0; i < amount; i++) { - var segment = removed[i]; - if (segment._selectionState) - this._updateSelection(segment, segment._selectionState, 0); - segment._index = segment._path = null; - } - for (var i = from, l = segments.length; i < l; i++) - segments[i]._index = i; - if (curves) { - var index = from > 0 && to === count + (this._closed ? 1 : 0) - ? from - 1 - : from, - curves = curves.splice(index, amount); - if (_includeCurves) - removed._curves = curves.slice(1); - this._adjustCurves(index, index); - } - this._changed(25); - return removed; - }, - - clear: '#removeSegments', - - hasHandles: function() { - var segments = this._segments; - for (var i = 0, l = segments.length; i < l; i++) { - if (segments[i].hasHandles()) - return true; - } - return false; - }, - - clearHandles: function() { - var segments = this._segments; - for (var i = 0, l = segments.length; i < l; i++) - segments[i].clearHandles(); - }, - - getLength: function() { - if (this._length == null) { - var curves = this.getCurves(), - length = 0; - for (var i = 0, l = curves.length; i < l; i++) - length += curves[i].getLength(); - this._length = length; - } - return this._length; - }, - - getArea: function() { - if (this._area == null) { - var segments = this._segments, - count = segments.length, - last = count - 1, - area = 0; - for (var i = 0, l = this._closed ? count : last; i < l; i++) { - area += Curve.getArea(Curve.getValues( - segments[i], segments[i < last ? i + 1 : 0])); - } - this._area = area; - } - return this._area; - }, - - isClockwise: function() { - if (this._clockwise !== undefined) - return this._clockwise; - return this.getArea() >= 0; - }, - - setClockwise: function(clockwise) { - if (this.isClockwise() != (clockwise = !!clockwise)) - this.reverse(); - this._clockwise = clockwise; - }, - - isFullySelected: function() { - var length = this._segments.length; - return this._selected && length > 0 && this._selectedSegmentState - === length * 7; - }, - - setFullySelected: function(selected) { - if (selected) - this._selectSegments(true); - this.setSelected(selected); - }, - - setSelected: function setSelected(selected) { - if (!selected) - this._selectSegments(false); - setSelected.base.call(this, selected); - }, - - _selectSegments: function(selected) { - var length = this._segments.length; - this._selectedSegmentState = selected - ? length * 7 : 0; - for (var i = 0; i < length; i++) - this._segments[i]._selectionState = selected - ? 7 : 0; - }, - - _updateSelection: function(segment, oldState, newState) { - segment._selectionState = newState; - var total = this._selectedSegmentState += newState - oldState; - if (total > 0) - this.setSelected(true); - }, - - flatten: function(maxDistance) { - var iterator = new PathIterator(this, 64, 0.1), - pos = 0, - step = iterator.length / Math.ceil(iterator.length / maxDistance), - end = iterator.length + (this._closed ? -step : step) / 2; - var segments = []; - while (pos <= end) { - segments.push(new Segment(iterator.getPointAt(pos))); - pos += step; - } - this.setSegments(segments); - }, - - reduce: function() { - var curves = this.getCurves(); - for (var i = curves.length - 1; i >= 0; i--) { - var curve = curves[i]; - if (!curve.hasHandles() && (curve.getLength() === 0 - || curve.isCollinear(curve.getNext()))) - curve.remove(); - } - return this; - }, - - simplify: function(tolerance) { - if (this._segments.length > 2) { - var fitter = new PathFitter(this, tolerance || 2.5); - this.setSegments(fitter.fit()); - } - }, - - split: function(index, parameter) { - if (parameter === null) - return null; - if (arguments.length === 1) { - var arg = index; - if (typeof arg === 'number') - arg = this.getLocationAt(arg); - if (!arg) - return null - index = arg.index; - parameter = arg.parameter; - } - var tMin = 4e-7, - tMax = 1 - tMin; - if (parameter >= tMax) { - index++; - parameter--; - } - var curves = this.getCurves(); - if (index >= 0 && index < curves.length) { - if (parameter >= tMin) { - curves[index++].divide(parameter, true); - } - var segs = this.removeSegments(index, this._segments.length, true), - path; - if (this._closed) { - this.setClosed(false); - path = this; - } else { - path = new Path(Item.NO_INSERT); - path.insertAbove(this, true); - this._clone(path); - } - path._add(segs, 0); - this.addSegment(segs[0]); - return path; - } - return null; - }, - - reverse: function() { - this._segments.reverse(); - for (var i = 0, l = this._segments.length; i < l; i++) { - var segment = this._segments[i]; - var handleIn = segment._handleIn; - segment._handleIn = segment._handleOut; - segment._handleOut = handleIn; - segment._index = i; - } - this._curves = null; - if (this._clockwise !== undefined) - this._clockwise = !this._clockwise; - this._changed(9); - }, - - join: function(path) { - if (path) { - var segments = path._segments, - last1 = this.getLastSegment(), - last2 = path.getLastSegment(); - if (!last2) - return this; - if (last1 && last1._point.equals(last2._point)) - path.reverse(); - var first2 = path.getFirstSegment(); - if (last1 && last1._point.equals(first2._point)) { - last1.setHandleOut(first2._handleOut); - this._add(segments.slice(1)); - } else { - var first1 = this.getFirstSegment(); - if (first1 && first1._point.equals(first2._point)) - path.reverse(); - last2 = path.getLastSegment(); - if (first1 && first1._point.equals(last2._point)) { - first1.setHandleIn(last2._handleIn); - this._add(segments.slice(0, segments.length - 1), 0); - } else { - this._add(segments.slice()); - } - } - if (path._closed) - this._add([segments[0]]); - path.remove(); - } - var first = this.getFirstSegment(), - last = this.getLastSegment(); - if (first !== last && first._point.equals(last._point)) { - first.setHandleIn(last._handleIn); - last.remove(); - this.setClosed(true); - } - return this; - }, - - toShape: function(insert) { - if (!this._closed) - return null; - - var segments = this._segments, - type, - size, - radius, - topCenter; - - function isCollinear(i, j) { - var seg1 = segments[i], - seg2 = seg1.getNext(), - seg3 = segments[j], - seg4 = seg3.getNext(); - return seg1._handleOut.isZero() && seg2._handleIn.isZero() - && seg3._handleOut.isZero() && seg4._handleIn.isZero() - && seg2._point.subtract(seg1._point).isCollinear( - seg4._point.subtract(seg3._point)); - } - - function isOrthogonal(i) { - var seg2 = segments[i], - seg1 = seg2.getPrevious(), - seg3 = seg2.getNext(); - return seg1._handleOut.isZero() && seg2._handleIn.isZero() - && seg2._handleOut.isZero() && seg3._handleIn.isZero() - && seg2._point.subtract(seg1._point).isOrthogonal( - seg3._point.subtract(seg2._point)); - } - - function isArc(i) { - var seg1 = segments[i], - seg2 = seg1.getNext(), - handle1 = seg1._handleOut, - handle2 = seg2._handleIn, - kappa = 0.5522847498307936; - if (handle1.isOrthogonal(handle2)) { - var pt1 = seg1._point, - pt2 = seg2._point, - corner = new Line(pt1, handle1, true).intersect( - new Line(pt2, handle2, true), true); - return corner && Numerical.isZero(handle1.getLength() / - corner.subtract(pt1).getLength() - kappa) - && Numerical.isZero(handle2.getLength() / - corner.subtract(pt2).getLength() - kappa); - } - return false; - } - - function getDistance(i, j) { - return segments[i]._point.getDistance(segments[j]._point); - } - - if (!this.hasHandles() && segments.length === 4 - && isCollinear(0, 2) && isCollinear(1, 3) && isOrthogonal(1)) { - type = Shape.Rectangle; - size = new Size(getDistance(0, 3), getDistance(0, 1)); - topCenter = segments[1]._point.add(segments[2]._point).divide(2); - } else if (segments.length === 8 && isArc(0) && isArc(2) && isArc(4) - && isArc(6) && isCollinear(1, 5) && isCollinear(3, 7)) { - type = Shape.Rectangle; - size = new Size(getDistance(1, 6), getDistance(0, 3)); - radius = size.subtract(new Size(getDistance(0, 7), - getDistance(1, 2))).divide(2); - topCenter = segments[3]._point.add(segments[4]._point).divide(2); - } else if (segments.length === 4 - && isArc(0) && isArc(1) && isArc(2) && isArc(3)) { - if (Numerical.isZero(getDistance(0, 2) - getDistance(1, 3))) { - type = Shape.Circle; - radius = getDistance(0, 2) / 2; - } else { - type = Shape.Ellipse; - radius = new Size(getDistance(2, 0) / 2, getDistance(3, 1) / 2); - } - topCenter = segments[1]._point; - } - - if (type) { - var center = this.getPosition(true), - shape = this._clone(new type({ - center: center, - size: size, - radius: radius, - insert: false - }), insert, false); - shape.rotate(topCenter.subtract(center).getAngle() + 90); - return shape; - } - return null; - }, - - _hitTestSelf: function(point, options) { - var that = this, - style = this.getStyle(), - segments = this._segments, - numSegments = segments.length, - closed = this._closed, - tolerancePadding = options._tolerancePadding, - strokePadding = tolerancePadding, - join, cap, miterLimit, - area, loc, res, - hitStroke = options.stroke && style.hasStroke(), - hitFill = options.fill && style.hasFill(), - hitCurves = options.curves, - radius = hitStroke - ? style.getStrokeWidth() / 2 - : hitFill && options.tolerance > 0 || hitCurves - ? 0 : null; - if (radius !== null) { - if (radius > 0) { - join = style.getStrokeJoin(); - cap = style.getStrokeCap(); - miterLimit = radius * style.getMiterLimit(); - strokePadding = tolerancePadding.add(new Point(radius, radius)); - } else { - join = cap = 'round'; - } - } - - function isCloseEnough(pt, padding) { - return point.subtract(pt).divide(padding).length <= 1; - } - - function checkSegmentPoint(seg, pt, name) { - if (!options.selected || pt.isSelected()) { - var anchor = seg._point; - if (pt !== anchor) - pt = pt.add(anchor); - if (isCloseEnough(pt, strokePadding)) { - return new HitResult(name, that, { - segment: seg, - point: pt - }); - } - } - } - - function checkSegmentPoints(seg, ends) { - return (ends || options.segments) - && checkSegmentPoint(seg, seg._point, 'segment') - || (!ends && options.handles) && ( - checkSegmentPoint(seg, seg._handleIn, 'handle-in') || - checkSegmentPoint(seg, seg._handleOut, 'handle-out')); - } - - function addToArea(point) { - area.add(point); - } - - function checkSegmentStroke(segment) { - if (join !== 'round' || cap !== 'round') { - area = new Path({ internal: true, closed: true }); - if (closed || segment._index > 0 - && segment._index < numSegments - 1) { - if (join !== 'round' && (segment._handleIn.isZero() - || segment._handleOut.isZero())) - Path._addBevelJoin(segment, join, radius, miterLimit, - addToArea, true); - } else if (cap !== 'round') { - Path._addSquareCap(segment, cap, radius, addToArea, true); - } - if (!area.isEmpty()) { - var loc; - return area.contains(point) - || (loc = area.getNearestLocation(point)) - && isCloseEnough(loc.getPoint(), tolerancePadding); - } - } - return isCloseEnough(segment._point, strokePadding); - } - - if (options.ends && !options.segments && !closed) { - if (res = checkSegmentPoints(segments[0], true) - || checkSegmentPoints(segments[numSegments - 1], true)) - return res; - } else if (options.segments || options.handles) { - for (var i = 0; i < numSegments; i++) - if (res = checkSegmentPoints(segments[i])) - return res; - } - if (radius !== null) { - loc = this.getNearestLocation(point); - if (loc) { - var parameter = loc.getParameter(); - if (parameter === 0 || parameter === 1 && numSegments > 1) { - if (!checkSegmentStroke(loc.getSegment())) - loc = null; - } else if (!isCloseEnough(loc.getPoint(), strokePadding)) { - loc = null; - } - } - if (!loc && join === 'miter' && numSegments > 1) { - for (var i = 0; i < numSegments; i++) { - var segment = segments[i]; - if (point.getDistance(segment._point) <= miterLimit - && checkSegmentStroke(segment)) { - loc = segment.getLocation(); - break; - } - } - } - } - return !loc && hitFill && this._contains(point) - || loc && !hitStroke && !hitCurves - ? new HitResult('fill', this) - : loc - ? new HitResult(hitStroke ? 'stroke' : 'curve', this, { - location: loc, - point: loc.getPoint() - }) - : null; - } - -}, Base.each(Curve.evaluateMethods, - function(name) { - this[name + 'At'] = function(offset, isParameter) { - var loc = this.getLocationAt(offset, isParameter); - return loc && loc[name](); - }; - }, -{ - beans: false, - - getLocationOf: function() { - var point = Point.read(arguments), - curves = this.getCurves(); - for (var i = 0, l = curves.length; i < l; i++) { - var loc = curves[i].getLocationOf(point); - if (loc) - return loc; - } - return null; - }, - - getOffsetOf: function() { - var loc = this.getLocationOf.apply(this, arguments); - return loc ? loc.getOffset() : null; - }, - - getLocationAt: function(offset, isParameter) { - var curves = this.getCurves(), - length = 0; - if (isParameter) { - var index = ~~offset, - curve = curves[index]; - return curve ? curve.getLocationAt(offset - index, true) : null; - } - for (var i = 0, l = curves.length; i < l; i++) { - var start = length, - curve = curves[i]; - length += curve.getLength(); - if (length > offset) { - return curve.getLocationAt(offset - start); - } - } - if (curves.length > 0 && offset <= this.getLength()) - return new CurveLocation(curves[curves.length - 1], 1); - return null; - }, - - getNearestLocation: function() { - var point = Point.read(arguments), - curves = this.getCurves(), - minDist = Infinity, - minLoc = null; - for (var i = 0, l = curves.length; i < l; i++) { - var loc = curves[i].getNearestLocation(point); - if (loc._distance < minDist) { - minDist = loc._distance; - minLoc = loc; - } - } - return minLoc; - }, - - getNearestPoint: function() { - return this.getNearestLocation.apply(this, arguments).getPoint(); - } -}), -new function() { - - function drawHandles(ctx, segments, matrix, size) { - var half = size / 2; - - function drawHandle(index) { - var hX = coords[index], - hY = coords[index + 1]; - if (pX != hX || pY != hY) { - ctx.beginPath(); - ctx.moveTo(pX, pY); - ctx.lineTo(hX, hY); - ctx.stroke(); - ctx.beginPath(); - ctx.arc(hX, hY, half, 0, Math.PI * 2, true); - ctx.fill(); - } - } - - var coords = new Array(6); - for (var i = 0, l = segments.length; i < l; i++) { - var segment = segments[i]; - segment._transformCoordinates(matrix, coords, false); - var state = segment._selectionState, - pX = coords[0], - pY = coords[1]; - if (state & 1) - drawHandle(2); - if (state & 2) - drawHandle(4); - ctx.fillRect(pX - half, pY - half, size, size); - if (!(state & 4)) { - var fillStyle = ctx.fillStyle; - ctx.fillStyle = '#ffffff'; - ctx.fillRect(pX - half + 1, pY - half + 1, size - 2, size - 2); - ctx.fillStyle = fillStyle; - } - } - } - - function drawSegments(ctx, path, matrix) { - var segments = path._segments, - length = segments.length, - coords = new Array(6), - first = true, - curX, curY, - prevX, prevY, - inX, inY, - outX, outY; - - function drawSegment(segment) { - if (matrix) { - segment._transformCoordinates(matrix, coords, false); - curX = coords[0]; - curY = coords[1]; - } else { - var point = segment._point; - curX = point._x; - curY = point._y; - } - if (first) { - ctx.moveTo(curX, curY); - first = false; - } else { - if (matrix) { - inX = coords[2]; - inY = coords[3]; - } else { - var handle = segment._handleIn; - inX = curX + handle._x; - inY = curY + handle._y; - } - if (inX === curX && inY === curY - && outX === prevX && outY === prevY) { - ctx.lineTo(curX, curY); - } else { - ctx.bezierCurveTo(outX, outY, inX, inY, curX, curY); - } - } - prevX = curX; - prevY = curY; - if (matrix) { - outX = coords[4]; - outY = coords[5]; - } else { - var handle = segment._handleOut; - outX = prevX + handle._x; - outY = prevY + handle._y; - } - } - - for (var i = 0; i < length; i++) - drawSegment(segments[i]); - if (path._closed && length > 0) - drawSegment(segments[0]); - } - - return { - _draw: function(ctx, param, strokeMatrix) { - var dontStart = param.dontStart, - dontPaint = param.dontFinish || param.clip, - style = this.getStyle(), - hasFill = style.hasFill(), - hasStroke = style.hasStroke(), - dashArray = style.getDashArray(), - dashLength = !paper.support.nativeDash && hasStroke - && dashArray && dashArray.length; - - if (!dontStart) - ctx.beginPath(); - - if (!dontStart && this._currentPath) { - ctx.currentPath = this._currentPath; - } else if (hasFill || hasStroke && !dashLength || dontPaint) { - drawSegments(ctx, this, strokeMatrix); - if (this._closed) - ctx.closePath(); - if (!dontStart) - this._currentPath = ctx.currentPath; - } - - function getOffset(i) { - return dashArray[((i % dashLength) + dashLength) % dashLength]; - } - - if (!dontPaint && (hasFill || hasStroke)) { - this._setStyles(ctx); - if (hasFill) { - ctx.fill(style.getWindingRule()); - ctx.shadowColor = 'rgba(0,0,0,0)'; - } - if (hasStroke) { - if (dashLength) { - if (!dontStart) - ctx.beginPath(); - var iterator = new PathIterator(this, 32, 0.25, - strokeMatrix), - length = iterator.length, - from = -style.getDashOffset(), to, - i = 0; - from = from % length; - while (from > 0) { - from -= getOffset(i--) + getOffset(i--); - } - while (from < length) { - to = from + getOffset(i++); - if (from > 0 || to > 0) - iterator.drawPart(ctx, - Math.max(from, 0), Math.max(to, 0)); - from = to + getOffset(i++); - } - } - ctx.stroke(); - } - } - }, - - _drawSelected: function(ctx, matrix) { - ctx.beginPath(); - drawSegments(ctx, this, matrix); - ctx.stroke(); - drawHandles(ctx, this._segments, matrix, paper.settings.handleSize); - } - }; -}, -new function() { - function getFirstControlPoints(rhs) { - var n = rhs.length, - x = [], - tmp = [], - b = 2; - x[0] = rhs[0] / b; - for (var i = 1; i < n; i++) { - tmp[i] = 1 / b; - b = (i < n - 1 ? 4 : 2) - tmp[i]; - x[i] = (rhs[i] - x[i - 1]) / b; - } - for (var i = 1; i < n; i++) { - x[n - i - 1] -= tmp[n - i] * x[n - i]; - } - return x; - } - - return { - smooth: function() { - var segments = this._segments, - size = segments.length, - closed = this._closed, - n = size, - overlap = 0; - if (size <= 2) - return; - if (closed) { - overlap = Math.min(size, 4); - n += Math.min(size, overlap) * 2; - } - var knots = []; - for (var i = 0; i < size; i++) - knots[i + overlap] = segments[i]._point; - if (closed) { - for (var i = 0; i < overlap; i++) { - knots[i] = segments[i + size - overlap]._point; - knots[i + size + overlap] = segments[i]._point; - } - } else { - n--; - } - var rhs = []; - - for (var i = 1; i < n - 1; i++) - rhs[i] = 4 * knots[i]._x + 2 * knots[i + 1]._x; - rhs[0] = knots[0]._x + 2 * knots[1]._x; - rhs[n - 1] = 3 * knots[n - 1]._x; - var x = getFirstControlPoints(rhs); - - for (var i = 1; i < n - 1; i++) - rhs[i] = 4 * knots[i]._y + 2 * knots[i + 1]._y; - rhs[0] = knots[0]._y + 2 * knots[1]._y; - rhs[n - 1] = 3 * knots[n - 1]._y; - var y = getFirstControlPoints(rhs); - - if (closed) { - for (var i = 0, j = size; i < overlap; i++, j++) { - var f1 = i / overlap, - f2 = 1 - f1, - ie = i + overlap, - je = j + overlap; - x[j] = x[i] * f1 + x[j] * f2; - y[j] = y[i] * f1 + y[j] * f2; - x[je] = x[ie] * f2 + x[je] * f1; - y[je] = y[ie] * f2 + y[je] * f1; - } - n--; - } - var handleIn = null; - for (var i = overlap; i <= n - overlap; i++) { - var segment = segments[i - overlap]; - if (handleIn) - segment.setHandleIn(handleIn.subtract(segment._point)); - if (i < n) { - segment.setHandleOut( - new Point(x[i], y[i]).subtract(segment._point)); - handleIn = i < n - 1 - ? new Point( - 2 * knots[i + 1]._x - x[i + 1], - 2 * knots[i + 1]._y - y[i + 1]) - : new Point( - (knots[n]._x + x[n - 1]) / 2, - (knots[n]._y + y[n - 1]) / 2); - } - } - if (closed && handleIn) { - var segment = this._segments[0]; - segment.setHandleIn(handleIn.subtract(segment._point)); - } - } - }; -}, -new function() { - function getCurrentSegment(that) { - var segments = that._segments; - if (segments.length === 0) - throw new Error('Use a moveTo() command first'); - return segments[segments.length - 1]; - } - - return { - moveTo: function() { - var segments = this._segments; - if (segments.length === 1) - this.removeSegment(0); - if (!segments.length) - this._add([ new Segment(Point.read(arguments)) ]); - }, - - moveBy: function() { - throw new Error('moveBy() is unsupported on Path items.'); - }, - - lineTo: function() { - this._add([ new Segment(Point.read(arguments)) ]); - }, - - cubicCurveTo: function() { - var handle1 = Point.read(arguments), - handle2 = Point.read(arguments), - to = Point.read(arguments), - current = getCurrentSegment(this); - current.setHandleOut(handle1.subtract(current._point)); - this._add([ new Segment(to, handle2.subtract(to)) ]); - }, - - quadraticCurveTo: function() { - var handle = Point.read(arguments), - to = Point.read(arguments), - current = getCurrentSegment(this)._point; - this.cubicCurveTo( - handle.add(current.subtract(handle).multiply(1 / 3)), - handle.add(to.subtract(handle).multiply(1 / 3)), - to - ); - }, - - curveTo: function() { - var through = Point.read(arguments), - to = Point.read(arguments), - t = Base.pick(Base.read(arguments), 0.5), - t1 = 1 - t, - current = getCurrentSegment(this)._point, - handle = through.subtract(current.multiply(t1 * t1)) - .subtract(to.multiply(t * t)).divide(2 * t * t1); - if (handle.isNaN()) - throw new Error( - 'Cannot put a curve through points with parameter = ' + t); - this.quadraticCurveTo(handle, to); - }, - - arcTo: function() { - var current = getCurrentSegment(this), - from = current._point, - to = Point.read(arguments), - through, - peek = Base.peek(arguments), - clockwise = Base.pick(peek, true), - center, extent, vector, matrix; - if (typeof clockwise === 'boolean') { - var middle = from.add(to).divide(2), - through = middle.add(middle.subtract(from).rotate( - clockwise ? -90 : 90)); - } else if (Base.remain(arguments) <= 2) { - through = to; - to = Point.read(arguments); - } else { - var radius = Size.read(arguments); - if (radius.isZero()) - return this.lineTo(to); - var rotation = Base.read(arguments), - clockwise = !!Base.read(arguments), - large = !!Base.read(arguments), - middle = from.add(to).divide(2), - pt = from.subtract(middle).rotate(-rotation), - x = pt.x, - y = pt.y, - abs = Math.abs, - rx = abs(radius.width), - ry = abs(radius.height), - rxSq = rx * rx, - rySq = ry * ry, - xSq = x * x, - ySq = y * y; - var factor = Math.sqrt(xSq / rxSq + ySq / rySq); - if (factor > 1) { - rx *= factor; - ry *= factor; - rxSq = rx * rx; - rySq = ry * ry; - } - factor = (rxSq * rySq - rxSq * ySq - rySq * xSq) / - (rxSq * ySq + rySq * xSq); - if (abs(factor) < 1e-12) - factor = 0; - if (factor < 0) - throw new Error( - 'Cannot create an arc with the given arguments'); - center = new Point(rx * y / ry, -ry * x / rx) - .multiply((large === clockwise ? -1 : 1) - * Math.sqrt(factor)) - .rotate(rotation).add(middle); - matrix = new Matrix().translate(center).rotate(rotation) - .scale(rx, ry); - vector = matrix._inverseTransform(from); - extent = vector.getDirectedAngle(matrix._inverseTransform(to)); - if (!clockwise && extent > 0) - extent -= 360; - else if (clockwise && extent < 0) - extent += 360; - } - if (through) { - var l1 = new Line(from.add(through).divide(2), - through.subtract(from).rotate(90), true), - l2 = new Line(through.add(to).divide(2), - to.subtract(through).rotate(90), true), - line = new Line(from, to), - throughSide = line.getSide(through); - center = l1.intersect(l2, true); - if (!center) { - if (!throughSide) - return this.lineTo(to); - throw new Error( - 'Cannot create an arc with the given arguments'); - } - vector = from.subtract(center); - extent = vector.getDirectedAngle(to.subtract(center)); - var centerSide = line.getSide(center); - if (centerSide === 0) { - extent = throughSide * Math.abs(extent); - } else if (throughSide === centerSide) { - extent += extent < 0 ? 360 : -360; - } - } - var ext = Math.abs(extent), - count = ext >= 360 ? 4 : Math.ceil(ext / 90), - inc = extent / count, - half = inc * Math.PI / 360, - z = 4 / 3 * Math.sin(half) / (1 + Math.cos(half)), - segments = []; - for (var i = 0; i <= count; i++) { - var pt = to, - out = null; - if (i < count) { - out = vector.rotate(90).multiply(z); - if (matrix) { - pt = matrix._transformPoint(vector); - out = matrix._transformPoint(vector.add(out)) - .subtract(pt); - } else { - pt = center.add(vector); - } - } - if (i === 0) { - current.setHandleOut(out); - } else { - var _in = vector.rotate(-90).multiply(z); - if (matrix) { - _in = matrix._transformPoint(vector.add(_in)) - .subtract(pt); - } - segments.push(new Segment(pt, _in, out)); - } - vector = vector.rotate(inc); - } - this._add(segments); - }, - - lineBy: function() { - var to = Point.read(arguments), - current = getCurrentSegment(this)._point; - this.lineTo(current.add(to)); - }, - - curveBy: function() { - var through = Point.read(arguments), - to = Point.read(arguments), - parameter = Base.read(arguments), - current = getCurrentSegment(this)._point; - this.curveTo(current.add(through), current.add(to), parameter); - }, - - cubicCurveBy: function() { - var handle1 = Point.read(arguments), - handle2 = Point.read(arguments), - to = Point.read(arguments), - current = getCurrentSegment(this)._point; - this.cubicCurveTo(current.add(handle1), current.add(handle2), - current.add(to)); - }, - - quadraticCurveBy: function() { - var handle = Point.read(arguments), - to = Point.read(arguments), - current = getCurrentSegment(this)._point; - this.quadraticCurveTo(current.add(handle), current.add(to)); - }, - - arcBy: function() { - var current = getCurrentSegment(this)._point, - point = current.add(Point.read(arguments)), - clockwise = Base.pick(Base.peek(arguments), true); - if (typeof clockwise === 'boolean') { - this.arcTo(point, clockwise); - } else { - this.arcTo(point, current.add(Point.read(arguments))); - } - }, - - closePath: function(join) { - this.setClosed(true); - if (join) - this.join(); - } - }; -}, { - - _getBounds: function(getter, matrix) { - return Path[getter](this._segments, this._closed, this.getStyle(), - matrix); - }, - -statics: { - getBounds: function(segments, closed, style, matrix, strokePadding) { - var first = segments[0]; - if (!first) - return new Rectangle(); - var coords = new Array(6), - prevCoords = first._transformCoordinates(matrix, new Array(6), false), - min = prevCoords.slice(0, 2), - max = min.slice(), - roots = new Array(2); - - function processSegment(segment) { - segment._transformCoordinates(matrix, coords, false); - for (var i = 0; i < 2; i++) { - Curve._addBounds( - prevCoords[i], - prevCoords[i + 4], - coords[i + 2], - coords[i], - i, strokePadding ? strokePadding[i] : 0, min, max, roots); - } - var tmp = prevCoords; - prevCoords = coords; - coords = tmp; - } - - for (var i = 1, l = segments.length; i < l; i++) - processSegment(segments[i]); - if (closed) - processSegment(first); - return new Rectangle(min[0], min[1], max[0] - min[0], max[1] - min[1]); - }, - - getStrokeBounds: function(segments, closed, style, matrix) { - if (!style.hasStroke()) - return Path.getBounds(segments, closed, style, matrix); - var length = segments.length - (closed ? 0 : 1), - radius = style.getStrokeWidth() / 2, - padding = Path._getPenPadding(radius, matrix), - bounds = Path.getBounds(segments, closed, style, matrix, padding), - join = style.getStrokeJoin(), - cap = style.getStrokeCap(), - miterLimit = radius * style.getMiterLimit(); - var joinBounds = new Rectangle(new Size(padding).multiply(2)); - - function add(point) { - bounds = bounds.include(matrix - ? matrix._transformPoint(point, point) : point); - } - - function addRound(segment) { - bounds = bounds.unite(joinBounds.setCenter(matrix - ? matrix._transformPoint(segment._point) : segment._point)); - } - - function addJoin(segment, join) { - var handleIn = segment._handleIn, - handleOut = segment._handleOut; - if (join === 'round' || !handleIn.isZero() && !handleOut.isZero() - && handleIn.isCollinear(handleOut)) { - addRound(segment); - } else { - Path._addBevelJoin(segment, join, radius, miterLimit, add); - } - } - - function addCap(segment, cap) { - if (cap === 'round') { - addRound(segment); - } else { - Path._addSquareCap(segment, cap, radius, add); - } - } - - for (var i = 1; i < length; i++) - addJoin(segments[i], join); - if (closed) { - addJoin(segments[0], join); - } else if (length > 0) { - addCap(segments[0], cap); - addCap(segments[segments.length - 1], cap); - } - return bounds; - }, - - _getPenPadding: function(radius, matrix) { - if (!matrix) - return [radius, radius]; - var mx = matrix.shiftless(), - hor = mx.transform(new Point(radius, 0)), - ver = mx.transform(new Point(0, radius)), - phi = hor.getAngleInRadians(), - a = hor.getLength(), - b = ver.getLength(); - var sin = Math.sin(phi), - cos = Math.cos(phi), - tan = Math.tan(phi), - tx = -Math.atan(b * tan / a), - ty = Math.atan(b / (tan * a)); - return [Math.abs(a * Math.cos(tx) * cos - b * Math.sin(tx) * sin), - Math.abs(b * Math.sin(ty) * cos + a * Math.cos(ty) * sin)]; - }, - - _addBevelJoin: function(segment, join, radius, miterLimit, addPoint, area) { - var curve2 = segment.getCurve(), - curve1 = curve2.getPrevious(), - point = curve2.getPointAt(0, true), - normal1 = curve1.getNormalAt(1, true), - normal2 = curve2.getNormalAt(0, true), - step = normal1.getDirectedAngle(normal2) < 0 ? -radius : radius; - normal1.setLength(step); - normal2.setLength(step); - if (area) { - addPoint(point); - addPoint(point.add(normal1)); - } - if (join === 'miter') { - var corner = new Line( - point.add(normal1), - new Point(-normal1.y, normal1.x), true - ).intersect(new Line( - point.add(normal2), - new Point(-normal2.y, normal2.x), true - ), true); - if (corner && point.getDistance(corner) <= miterLimit) { - addPoint(corner); - if (!area) - return; - } - } - if (!area) - addPoint(point.add(normal1)); - addPoint(point.add(normal2)); - }, - - _addSquareCap: function(segment, cap, radius, addPoint, area) { - var point = segment._point, - loc = segment.getLocation(), - normal = loc.getNormal().multiply(radius); - if (area) { - addPoint(point.subtract(normal)); - addPoint(point.add(normal)); - } - if (cap === 'square') - point = point.add(normal.rotate(loc.getParameter() === 0 ? -90 : 90)); - addPoint(point.add(normal)); - addPoint(point.subtract(normal)); - }, - - getHandleBounds: function(segments, closed, style, matrix, strokePadding, - joinPadding) { - var coords = new Array(6), - x1 = Infinity, - x2 = -x1, - y1 = x1, - y2 = x2; - for (var i = 0, l = segments.length; i < l; i++) { - var segment = segments[i]; - segment._transformCoordinates(matrix, coords, false); - for (var j = 0; j < 6; j += 2) { - var padding = j === 0 ? joinPadding : strokePadding, - paddingX = padding ? padding[0] : 0, - paddingY = padding ? padding[1] : 0, - x = coords[j], - y = coords[j + 1], - xn = x - paddingX, - xx = x + paddingX, - yn = y - paddingY, - yx = y + paddingY; - if (xn < x1) x1 = xn; - if (xx > x2) x2 = xx; - if (yn < y1) y1 = yn; - if (yx > y2) y2 = yx; - } - } - return new Rectangle(x1, y1, x2 - x1, y2 - y1); - }, - - getRoughBounds: function(segments, closed, style, matrix) { - var strokeRadius = style.hasStroke() ? style.getStrokeWidth() / 2 : 0, - joinRadius = strokeRadius; - if (strokeRadius > 0) { - if (style.getStrokeJoin() === 'miter') - joinRadius = strokeRadius * style.getMiterLimit(); - if (style.getStrokeCap() === 'square') - joinRadius = Math.max(joinRadius, strokeRadius * Math.sqrt(2)); - } - return Path.getHandleBounds(segments, closed, style, matrix, - Path._getPenPadding(strokeRadius, matrix), - Path._getPenPadding(joinRadius, matrix)); - } -}}); - -Path.inject({ statics: new function() { - - var kappa = 0.5522847498307936, - ellipseSegments = [ - new Segment([-1, 0], [0, kappa ], [0, -kappa]), - new Segment([0, -1], [-kappa, 0], [kappa, 0 ]), - new Segment([1, 0], [0, -kappa], [0, kappa ]), - new Segment([0, 1], [kappa, 0 ], [-kappa, 0]) - ]; - - function createPath(segments, closed, args) { - var props = Base.getNamed(args), - path = new Path(props && props.insert === false && Item.NO_INSERT); - path._add(segments); - path._closed = closed; - return path.set(props); - } - - function createEllipse(center, radius, args) { - var segments = new Array(4); - for (var i = 0; i < 4; i++) { - var segment = ellipseSegments[i]; - segments[i] = new Segment( - segment._point.multiply(radius).add(center), - segment._handleIn.multiply(radius), - segment._handleOut.multiply(radius) - ); - } - return createPath(segments, true, args); - } - - return { - Line: function() { - return createPath([ - new Segment(Point.readNamed(arguments, 'from')), - new Segment(Point.readNamed(arguments, 'to')) - ], false, arguments); - }, - - Circle: function() { - var center = Point.readNamed(arguments, 'center'), - radius = Base.readNamed(arguments, 'radius'); - return createEllipse(center, new Size(radius), arguments); - }, - - Rectangle: function() { - var rect = Rectangle.readNamed(arguments, 'rectangle'), - radius = Size.readNamed(arguments, 'radius', 0, - { readNull: true }), - bl = rect.getBottomLeft(true), - tl = rect.getTopLeft(true), - tr = rect.getTopRight(true), - br = rect.getBottomRight(true), - segments; - if (!radius || radius.isZero()) { - segments = [ - new Segment(bl), - new Segment(tl), - new Segment(tr), - new Segment(br) - ]; - } else { - radius = Size.min(radius, rect.getSize(true).divide(2)); - var rx = radius.width, - ry = radius.height, - hx = rx * kappa, - hy = ry * kappa; - segments = [ - new Segment(bl.add(rx, 0), null, [-hx, 0]), - new Segment(bl.subtract(0, ry), [0, hy]), - new Segment(tl.add(0, ry), null, [0, -hy]), - new Segment(tl.add(rx, 0), [-hx, 0], null), - new Segment(tr.subtract(rx, 0), null, [hx, 0]), - new Segment(tr.add(0, ry), [0, -hy], null), - new Segment(br.subtract(0, ry), null, [0, hy]), - new Segment(br.subtract(rx, 0), [hx, 0]) - ]; - } - return createPath(segments, true, arguments); - }, - - RoundRectangle: '#Rectangle', - - Ellipse: function() { - var ellipse = Shape._readEllipse(arguments); - return createEllipse(ellipse.center, ellipse.radius, arguments); - }, - - Oval: '#Ellipse', - - Arc: function() { - var from = Point.readNamed(arguments, 'from'), - through = Point.readNamed(arguments, 'through'), - to = Point.readNamed(arguments, 'to'), - props = Base.getNamed(arguments), - path = new Path(props && props.insert === false - && Item.NO_INSERT); - path.moveTo(from); - path.arcTo(through, to); - return path.set(props); - }, - - RegularPolygon: function() { - var center = Point.readNamed(arguments, 'center'), - sides = Base.readNamed(arguments, 'sides'), - radius = Base.readNamed(arguments, 'radius'), - step = 360 / sides, - three = !(sides % 3), - vector = new Point(0, three ? -radius : radius), - offset = three ? -1 : 0.5, - segments = new Array(sides); - for (var i = 0; i < sides; i++) - segments[i] = new Segment(center.add( - vector.rotate((i + offset) * step))); - return createPath(segments, true, arguments); - }, - - Star: function() { - var center = Point.readNamed(arguments, 'center'), - points = Base.readNamed(arguments, 'points') * 2, - radius1 = Base.readNamed(arguments, 'radius1'), - radius2 = Base.readNamed(arguments, 'radius2'), - step = 360 / points, - vector = new Point(0, -1), - segments = new Array(points); - for (var i = 0; i < points; i++) - segments[i] = new Segment(center.add(vector.rotate(step * i) - .multiply(i % 2 ? radius2 : radius1))); - return createPath(segments, true, arguments); - } - }; -}}); - -var CompoundPath = PathItem.extend({ - _class: 'CompoundPath', - _serializeFields: { - children: [] - }, - - initialize: function CompoundPath(arg) { - this._children = []; - this._namedChildren = {}; - if (!this._initialize(arg)) { - if (typeof arg === 'string') { - this.setPathData(arg); - } else { - this.addChildren(Array.isArray(arg) ? arg : arguments); - } - } - }, - - insertChildren: function insertChildren(index, items, _preserve) { - for (var i = items.length - 1; i >= 0; i--) { - var item = items[i]; - if (item instanceof CompoundPath) { - items.splice.apply(items, [i, 1].concat(item.removeChildren())); - item.remove(); - } - } - items = insertChildren.base.call(this, index, items, _preserve, Path); - for (var i = 0, l = !_preserve && items && items.length; i < l; i++) { - var item = items[i]; - if (item._clockwise === undefined) - item.setClockwise(item._index === 0); - } - return items; - }, - - reverse: function() { - var children = this._children; - for (var i = 0, l = children.length; i < l; i++) - children[i].reverse(); - }, - - smooth: function() { - for (var i = 0, l = this._children.length; i < l; i++) - this._children[i].smooth(); - }, - - reduce: function reduce() { - var children = this._children; - for (var i = children.length - 1; i >= 0; i--) { - var path = children[i].reduce(); - if (path.isEmpty()) - children.splice(i, 1); - } - if (children.length === 0) { - var path = new Path(Item.NO_INSERT); - path.insertAbove(this); - path.setStyle(this._style); - this.remove(); - return path; - } - return reduce.base.call(this); - }, - - isClockwise: function() { - var child = this.getFirstChild(); - return child && child.isClockwise(); - }, - - setClockwise: function(clockwise) { - if (this.isClockwise() !== !!clockwise) - this.reverse(); - }, - - getFirstSegment: function() { - var first = this.getFirstChild(); - return first && first.getFirstSegment(); - }, - - getLastSegment: function() { - var last = this.getLastChild(); - return last && last.getLastSegment(); - }, - - getCurves: function() { - var children = this._children, - curves = []; - for (var i = 0, l = children.length; i < l; i++) - curves.push.apply(curves, children[i].getCurves()); - return curves; - }, - - getFirstCurve: function() { - var first = this.getFirstChild(); - return first && first.getFirstCurve(); - }, - - getLastCurve: function() { - var last = this.getLastChild(); - return last && last.getFirstCurve(); - }, - - getArea: function() { - var children = this._children, - area = 0; - for (var i = 0, l = children.length; i < l; i++) - area += children[i].getArea(); - return area; - } -}, { - beans: true, - - getPathData: function(_matrix, _precision) { - var children = this._children, - paths = []; - for (var i = 0, l = children.length; i < l; i++) { - var child = children[i], - mx = child._matrix; - paths.push(child.getPathData(_matrix && !mx.isIdentity() - ? _matrix.chain(mx) : _matrix, _precision)); - } - return paths.join(' '); - } -}, { - _getChildHitTestOptions: function(options) { - return options.class === Path || options.type === 'path' - ? options - : new Base(options, { fill: false }); - }, - - _draw: function(ctx, param, strokeMatrix) { - var children = this._children; - if (children.length === 0) - return; - - if (this._currentPath) { - ctx.currentPath = this._currentPath; - } else { - param = param.extend({ dontStart: true, dontFinish: true }); - ctx.beginPath(); - for (var i = 0, l = children.length; i < l; i++) - children[i].draw(ctx, param, strokeMatrix); - this._currentPath = ctx.currentPath; - } - - if (!param.clip) { - this._setStyles(ctx); - var style = this._style; - if (style.hasFill()) { - ctx.fill(style.getWindingRule()); - ctx.shadowColor = 'rgba(0,0,0,0)'; - } - if (style.hasStroke()) - ctx.stroke(); - } - }, - - _drawSelected: function(ctx, matrix, selectedItems) { - var children = this._children; - for (var i = 0, l = children.length; i < l; i++) { - var child = children[i], - mx = child._matrix; - if (!selectedItems[child._id]) - child._drawSelected(ctx, mx.isIdentity() ? matrix - : matrix.chain(mx)); - } - } -}, -new function() { - function getCurrentPath(that, check) { - var children = that._children; - if (check && children.length === 0) - throw new Error('Use a moveTo() command first'); - return children[children.length - 1]; - } - - var fields = { - moveTo: function() { - var current = getCurrentPath(this), - path = current && current.isEmpty() ? current - : new Path(Item.NO_INSERT); - if (path !== current) - this.addChild(path); - path.moveTo.apply(path, arguments); - }, - - moveBy: function() { - var current = getCurrentPath(this, true), - last = current && current.getLastSegment(), - point = Point.read(arguments); - this.moveTo(last ? point.add(last._point) : point); - }, - - closePath: function(join) { - getCurrentPath(this, true).closePath(join); - } - }; - - Base.each(['lineTo', 'cubicCurveTo', 'quadraticCurveTo', 'curveTo', 'arcTo', - 'lineBy', 'cubicCurveBy', 'quadraticCurveBy', 'curveBy', 'arcBy'], - function(key) { - fields[key] = function() { - var path = getCurrentPath(this, true); - path[key].apply(path, arguments); - }; - } - ); - - return fields; -}); - -PathItem.inject(new function() { - var operators = { - unite: function(w) { - return w === 1 || w === 0; - }, - - intersect: function(w) { - return w === 2; - }, - - subtract: function(w) { - return w === 1; - }, - - exclude: function(w) { - return w === 1; - } - }; - - function preparePath(path, resolve) { - var res = path.clone(false).reduce().transform(null, true, true); - return resolve ? res.resolveCrossings().reorient() : res; - } - - function finishBoolean(ctor, paths, path1, path2, reduce) { - var result = new ctor(Item.NO_INSERT); - result.addChildren(paths, true); - if (reduce) - result = result.reduce(); - result.insertAbove(path2 && path1.isSibling(path2) - && path1.getIndex() < path2.getIndex() - ? path2 : path1); - result.setStyle(path1._style); - return result; - } - - function computeBoolean(path1, path2, operation) { - if (!path1._children && !path1._closed) - return computeOpenBoolean(path1, path2, operation); - var _path1 = preparePath(path1, true), - _path2 = path2 && path1 !== path2 && preparePath(path2, true); - if (_path2 && /^(subtract|exclude)$/.test(operation) - ^ (_path2.isClockwise() !== _path1.isClockwise())) - _path2.reverse(); - var intersections = CurveLocation.expand( - _path1.getIntersections(_path2, function(inter) { - return _path2 && inter.isOverlap() || inter.isCrossing(); - }) - ); - divideLocations(intersections); - - var segments = [], - monoCurves = []; - - function collect(paths) { - for (var i = 0, l = paths.length; i < l; i++) { - var path = paths[i]; - segments.push.apply(segments, path._segments); - monoCurves.push.apply(monoCurves, path._getMonoCurves()); - } - } - - collect(_path1._children || [_path1]); - if (_path2) - collect(_path2._children || [_path2]); - for (var i = 0, l = intersections.length; i < l; i++) { - propagateWinding(intersections[i]._segment, _path1, _path2, - monoCurves, operation); - } - for (var i = 0, l = segments.length; i < l; i++) { - var segment = segments[i]; - if (segment._winding == null) { - propagateWinding(segment, _path1, _path2, monoCurves, - operation); - } - } - return finishBoolean(CompoundPath, tracePaths(segments, operation), - path1, path2, true); - } - - function computeOpenBoolean(path1, path2, operation) { - if (!path2 || !path2._children && !path2._closed - || !/^(subtract|intersect)$/.test(operation)) - return null; - var _path1 = preparePath(path1, false), - _path2 = preparePath(path2, false), - intersections = _path1.getIntersections(_path2, function(inter) { - return inter.isOverlap() || inter.isCrossing(); - }), - sub = operation === 'subtract', - paths = []; - - function addPath(path) { - if (_path2.contains(path.getPointAt(path.getLength() / 2)) ^ sub) { - paths.unshift(path); - return true; - } - } - - for (var i = intersections.length - 1; i >= 0; i--) { - var path = intersections[i].split(); - if (path) { - if (addPath(path)) - path.getFirstSegment().setHandleIn(0, 0); - _path1.getLastSegment().setHandleOut(0, 0); - } - } - addPath(_path1); - return finishBoolean(Group, paths, path1, path2); - } - - function linkIntersections(from, to) { - var prev = from; - while (prev) { - if (prev === to) - return; - prev = prev._prev; - } - while (from._next && from._next !== to) - from = from._next; - if (!from._next) { - while (to._prev) - to = to._prev; - from._next = to; - to._prev = from; - } - } - - function divideLocations(locations) { - var tMin = 4e-7, - tMax = 1 - tMin, - noHandles = false, - clearSegments = [], - prevCurve, - prevT; - - for (var i = locations.length - 1; i >= 0; i--) { - var loc = locations[i], - curve = loc._curve, - t = loc._parameter, - origT = t; - if (curve !== prevCurve) { - noHandles = !curve.hasHandles(); - } else if (prevT > 0) { - t /= prevT; - } - var segment; - if (t < tMin) { - segment = curve._segment1; - } else if (t > tMax) { - segment = curve._segment2; - } else { - segment = curve.divide(t, true, true)._segment1; - if (noHandles) - clearSegments.push(segment); - } - loc._setSegment(segment); - var inter = segment._intersection, - dest = loc._intersection; - if (inter) { - linkIntersections(inter, dest); - var other = inter; - while (other) { - linkIntersections(other._intersection, inter); - other = other._next; - } - } else { - segment._intersection = dest; - } - prevCurve = curve; - prevT = origT; - } - for (var i = 0, l = clearSegments.length; i < l; i++) { - clearSegments[i].clearHandles(); - } - } - - function getWinding(point, curves, horizontal, testContains) { - var epsilon = 2e-7, - tMin = 4e-7, - tMax = 1 - tMin, - px = point.x, - py = point.y, - windLeft = 0, - windRight = 0, - roots = [], - abs = Math.abs; - if (horizontal) { - var yTop = -Infinity, - yBottom = Infinity, - yBefore = py - epsilon, - yAfter = py + epsilon; - for (var i = 0, l = curves.length; i < l; i++) { - var values = curves[i].values; - if (Curve.solveCubic(values, 0, px, roots, 0, 1) > 0) { - for (var j = roots.length - 1; j >= 0; j--) { - var y = Curve.getPoint(values, roots[j]).y; - if (y < yBefore && y > yTop) { - yTop = y; - } else if (y > yAfter && y < yBottom) { - yBottom = y; - } - } - } - } - yTop = (yTop + py) / 2; - yBottom = (yBottom + py) / 2; - if (yTop > -Infinity) - windLeft = getWinding(new Point(px, yTop), curves, false, - testContains); - if (yBottom < Infinity) - windRight = getWinding(new Point(px, yBottom), curves, false, - testContains); - } else { - var xBefore = px - epsilon, - xAfter = px + epsilon; - var startCounted = false, - prevCurve, - prevT; - for (var i = 0, l = curves.length; i < l; i++) { - var curve = curves[i], - values = curve.values, - winding = curve.winding; - if (winding && (winding === 1 - && py >= values[1] && py <= values[7] - || py >= values[7] && py <= values[1]) - && Curve.solveCubic(values, 1, py, roots, 0, 1) === 1) { - var t = roots[0]; - if (!( - t > tMax && startCounted && curve.next !== curves[i + 1] - || t < tMin && prevT > tMax - && curve.previous === prevCurve)) { - var x = Curve.getPoint(values, t).x, - slope = Curve.getTangent(values, t).y, - counted = false; - if (Numerical.isZero(slope) && !Curve.isStraight(values) - || t < tMin && slope * Curve.getTangent( - curve.previous.values, 1).y < 0 - || t > tMax && slope * Curve.getTangent( - curve.next.values, 0).y < 0) { - if (testContains && x >= xBefore && x <= xAfter) { - ++windLeft; - ++windRight; - counted = true; - } - } else if (x <= xBefore) { - windLeft += winding; - counted = true; - } else if (x >= xAfter) { - windRight += winding; - counted = true; - } - if (curve.previous !== curves[i - 1]) - startCounted = t < tMin && counted; - } - prevCurve = curve; - prevT = t; - } - } - } - return Math.max(abs(windLeft), abs(windRight)); - } - - function propagateWinding(segment, path1, path2, monoCurves, operation) { - var epsilon = 2e-7, - chain = [], - start = segment, - totalLength = 0, - windingSum = 0; - do { - var curve = segment.getCurve(), - length = curve.getLength(); - chain.push({ segment: segment, curve: curve, length: length }); - totalLength += length; - segment = segment.getNext(); - } while (segment && !segment._intersection && segment !== start); - for (var i = 0; i < 3; i++) { - var length = totalLength * (i + 1) / 4; - for (var k = 0, m = chain.length; k < m; k++) { - var node = chain[k], - curveLength = node.length; - if (length <= curveLength) { - if (length < epsilon || curveLength - length < epsilon) - length = curveLength / 2; - var curve = node.curve, - path = curve._path, - parent = path._parent, - pt = curve.getPointAt(length), - hor = curve.isHorizontal(); - if (parent instanceof CompoundPath) - path = parent; - windingSum += operation === 'subtract' && path2 - && (path === path1 && path2._getWinding(pt, hor) - || path === path2 && !path1._getWinding(pt, hor)) - ? 0 - : getWinding(pt, monoCurves, hor); - break; - } - length -= curveLength; - } - } - var winding = Math.round(windingSum / 3); - for (var j = chain.length - 1; j >= 0; j--) - chain[j].segment._winding = winding; - } - - function tracePaths(segments, operation) { - var paths = [], - start, - otherStart, - operator = operators[operation], - overlapWinding = { - unite: { 1: 2 }, - intersect: { 2: 1 } - }[operation]; - - function isValid(seg, adjusted) { - if (seg._visited) - return false; - if (!operator) - return true; - var winding = seg._winding, - inter = seg._intersection; - if (inter && adjusted && overlapWinding && inter.isOverlap()) - winding = overlapWinding[winding] || winding; - return operator(winding); - } - - function isStart(seg) { - return seg === start || seg === otherStart; - } - - function findBestIntersection(inter, strict) { - if (!inter._next) - return inter; - while (inter) { - var seg = inter._segment, - nextSeg = seg.getNext(), - nextInter = nextSeg._intersection; - if (isStart(nextSeg) - || !seg._visited && !nextSeg._visited - && (!operator - || (!strict || isValid(seg)) - && (!(strict && nextInter && nextInter.isOverlap()) - && isValid(nextSeg) - || !strict && nextInter - && isValid(nextInter._segment)) - )) - return inter; - inter = inter._next; - } - return null; - } - - function findStartSegment(inter, next) { - while (inter) { - var seg = inter._segment; - if (isStart(seg)) - return seg; - inter = inter[next ? '_next' : '_prev']; - } - } - - for (var i = 0, l = segments.length; i < l; i++) { - var seg = segments[i], - path = null, - finished = false; - if (!isValid(seg, true)) - continue; - start = otherStart = null; - while (!finished) { - var inter = seg._intersection, - handleIn = path && seg._handleIn; - inter = inter && (findBestIntersection(inter, true) - || findBestIntersection(inter, false)) || inter; - var other = inter && inter._segment; - if (other && isValid(other)) - seg = other; - if (seg._visited) { - finished = isStart(seg); - if (!finished && inter) { - var found = findStartSegment(inter, true) - || findStartSegment(inter, false); - if (found) { - seg = found; - finished = true; - } - } - break; - } - if (!path) { - path = new Path(Item.NO_INSERT); - start = seg; - otherStart = other; - } - path.add(new Segment(seg._point, handleIn, seg._handleOut)); - seg._visited = true; - seg = seg.getNext(); - finished = isStart(seg); - } - if (finished) { - path.firstSegment.setHandleIn(seg._handleIn); - path.setClosed(true); - } else if (path) { - console.error('Boolean operation resulted in open path', - 'segments =', path._segments.length, - 'length =', path.getLength()); - path = null; - } - if (path && (path._segments.length > 8 - || !Numerical.isZero(path.getArea()))) { - paths.push(path); - path = null; - } - } - return paths; - } - - return { - _getWinding: function(point, horizontal, testContains) { - return getWinding(point, this._getMonoCurves(), - horizontal, testContains); - }, - - unite: function(path) { - return computeBoolean(this, path, 'unite'); - }, - - intersect: function(path) { - return computeBoolean(this, path, 'intersect'); - }, - - subtract: function(path) { - return computeBoolean(this, path, 'subtract'); - }, - - exclude: function(path) { - return computeBoolean(this, path, 'exclude'); - }, - - divide: function(path) { - return finishBoolean(Group, - [this.subtract(path), this.intersect(path)], - this, path, true); - }, - - resolveCrossings: function() { - var crossings = this.getCrossings(); - if (!crossings.length) - return this; - divideLocations(CurveLocation.expand(crossings)); - var paths = this._children || [this], - segments = []; - for (var i = 0, l = paths.length; i < l; i++) { - segments.push.apply(segments, paths[i]._segments); - } - return finishBoolean(CompoundPath, tracePaths(segments), - this, null, false); - } - }; -}); - -Path.inject({ - _getMonoCurves: function() { - var monoCurves = this._monoCurves, - prevCurve; - - function insertCurve(v) { - var y0 = v[1], - y1 = v[7], - curve = { - values: v, - winding: y0 === y1 - ? 0 - : y0 > y1 - ? -1 - : 1, - previous: prevCurve, - next: null - }; - if (prevCurve) - prevCurve.next = curve; - monoCurves.push(curve); - prevCurve = curve; - } - - function handleCurve(v) { - if (Curve.getLength(v) === 0) - return; - var y0 = v[1], - y1 = v[3], - y2 = v[5], - y3 = v[7]; - if (Curve.isStraight(v)) { - insertCurve(v); - } else { - var a = 3 * (y1 - y2) - y0 + y3, - b = 2 * (y0 + y2) - 4 * y1, - c = y1 - y0, - tMin = 4e-7, - tMax = 1 - tMin, - roots = [], - n = Numerical.solveQuadratic(a, b, c, roots, tMin, tMax); - if (n === 0) { - insertCurve(v); - } else { - roots.sort(); - var t = roots[0], - parts = Curve.subdivide(v, t); - insertCurve(parts[0]); - if (n > 1) { - t = (roots[1] - t) / (1 - t); - parts = Curve.subdivide(parts[1], t); - insertCurve(parts[0]); - } - insertCurve(parts[1]); - } - } - } - - if (!monoCurves) { - monoCurves = this._monoCurves = []; - var curves = this.getCurves(), - segments = this._segments; - for (var i = 0, l = curves.length; i < l; i++) - handleCurve(curves[i].getValues()); - if (!this._closed && segments.length > 1) { - var p1 = segments[segments.length - 1]._point, - p2 = segments[0]._point, - p1x = p1._x, p1y = p1._y, - p2x = p2._x, p2y = p2._y; - handleCurve([p1x, p1y, p1x, p1y, p2x, p2y, p2x, p2y]); - } - if (monoCurves.length > 0) { - var first = monoCurves[0], - last = monoCurves[monoCurves.length - 1]; - first.previous = last; - last.next = first; - } - } - return monoCurves; - }, - - getInteriorPoint: function() { - var bounds = this.getBounds(), - point = bounds.getCenter(true); - if (!this.contains(point)) { - var curves = this._getMonoCurves(), - roots = [], - y = point.y, - xIntercepts = []; - for (var i = 0, l = curves.length; i < l; i++) { - var values = curves[i].values; - if ((curves[i].winding === 1 - && y >= values[1] && y <= values[7] - || y >= values[7] && y <= values[1]) - && Curve.solveCubic(values, 1, y, roots, 0, 1) > 0) { - for (var j = roots.length - 1; j >= 0; j--) - xIntercepts.push(Curve.getPoint(values, roots[j]).x); - } - if (xIntercepts.length > 1) - break; - } - point.x = (xIntercepts[0] + xIntercepts[1]) / 2; - } - return point; - }, - - reorient: function() { - this.setClockwise(true); - return this; - } -}); - -CompoundPath.inject({ - _getMonoCurves: function() { - var children = this._children, - monoCurves = []; - for (var i = 0, l = children.length; i < l; i++) - monoCurves.push.apply(monoCurves, children[i]._getMonoCurves()); - return monoCurves; - }, - - reorient: function() { - var children = this.removeChildren().sort(function(a, b) { - return b.getBounds().getArea() - a.getBounds().getArea(); - }); - if (children.length > 0) { - this.addChildren(children); - var clockwise = children[0].isClockwise(); - for (var i = 1, l = children.length; i < l; i++) { - var point = children[i].getInteriorPoint(), - counters = 0; - for (var j = i - 1; j >= 0; j--) { - if (children[j].contains(point)) - counters++; - } - children[i].setClockwise(counters % 2 === 0 && clockwise); - } - } - return this; - } -}); - -var PathIterator = Base.extend({ - _class: 'PathIterator', - - initialize: function(path, maxRecursion, tolerance, matrix) { - var curves = [], - parts = [], - length = 0, - minDifference = 1 / (maxRecursion || 32), - segments = path._segments, - segment1 = segments[0], - segment2; - - function addCurve(segment1, segment2) { - var curve = Curve.getValues(segment1, segment2, matrix); - curves.push(curve); - computeParts(curve, segment1._index, 0, 1); - } - - function computeParts(curve, index, minT, maxT) { - if ((maxT - minT) > minDifference - && !Curve.isFlatEnough(curve, tolerance || 0.25)) { - var split = Curve.subdivide(curve, 0.5), - halfT = (minT + maxT) / 2; - computeParts(split[0], index, minT, halfT); - computeParts(split[1], index, halfT, maxT); - } else { - var x = curve[6] - curve[0], - y = curve[7] - curve[1], - dist = Math.sqrt(x * x + y * y); - if (dist > 1e-6) { - length += dist; - parts.push({ - offset: length, - value: maxT, - index: index - }); - } - } - } - - for (var i = 1, l = segments.length; i < l; i++) { - segment2 = segments[i]; - addCurve(segment1, segment2); - segment1 = segment2; - } - if (path._closed) - addCurve(segment2, segments[0]); - - this.curves = curves; - this.parts = parts; - this.length = length; - this.index = 0; - }, - - getParameterAt: function(offset) { - var i, j = this.index; - for (;;) { - i = j; - if (j == 0 || this.parts[--j].offset < offset) - break; - } - for (var l = this.parts.length; i < l; i++) { - var part = this.parts[i]; - if (part.offset >= offset) { - this.index = i; - var prev = this.parts[i - 1]; - var prevVal = prev && prev.index == part.index ? prev.value : 0, - prevLen = prev ? prev.offset : 0; - return { - value: prevVal + (part.value - prevVal) - * (offset - prevLen) / (part.offset - prevLen), - index: part.index - }; - } - } - var part = this.parts[this.parts.length - 1]; - return { - value: 1, - index: part.index - }; - }, - - drawPart: function(ctx, from, to) { - from = this.getParameterAt(from); - to = this.getParameterAt(to); - for (var i = from.index; i <= to.index; i++) { - var curve = Curve.getPart(this.curves[i], - i == from.index ? from.value : 0, - i == to.index ? to.value : 1); - if (i == from.index) - ctx.moveTo(curve[0], curve[1]); - ctx.bezierCurveTo.apply(ctx, curve.slice(2)); - } - } -}, Base.each(Curve.evaluateMethods, - function(name) { - this[name + 'At'] = function(offset, weighted) { - var param = this.getParameterAt(offset); - return Curve[name](this.curves[param.index], param.value, weighted); - }; - }, {}) -); - -var PathFitter = Base.extend({ - initialize: function(path, error) { - var points = this.points = [], - segments = path._segments, - prev; - for (var i = 0, l = segments.length; i < l; i++) { - var point = segments[i].point.clone(); - if (!prev || !prev.equals(point)) { - points.push(point); - prev = point; - } - } - - if (path._closed) { - this.closed = true; - points.unshift(points[points.length - 1]); - points.push(points[1]); - } - - this.error = error; - }, - - fit: function() { - var points = this.points, - length = points.length, - segments = this.segments = length > 0 - ? [new Segment(points[0])] : []; - if (length > 1) - this.fitCubic(0, length - 1, - points[1].subtract(points[0]).normalize(), - points[length - 2].subtract(points[length - 1]).normalize()); - - if (this.closed) { - segments.shift(); - segments.pop(); - } - - return segments; - }, - - fitCubic: function(first, last, tan1, tan2) { - if (last - first == 1) { - var pt1 = this.points[first], - pt2 = this.points[last], - dist = pt1.getDistance(pt2) / 3; - this.addCurve([pt1, pt1.add(tan1.normalize(dist)), - pt2.add(tan2.normalize(dist)), pt2]); - return; - } - var uPrime = this.chordLengthParameterize(first, last), - maxError = Math.max(this.error, this.error * this.error), - split, - parametersInOrder = true; - for (var i = 0; i <= 4; i++) { - var curve = this.generateBezier(first, last, uPrime, tan1, tan2); - var max = this.findMaxError(first, last, curve, uPrime); - if (max.error < this.error && parametersInOrder) { - this.addCurve(curve); - return; - } - split = max.index; - if (max.error >= maxError) - break; - parametersInOrder = this.reparameterize(first, last, uPrime, curve); - maxError = max.error; - } - var V1 = this.points[split - 1].subtract(this.points[split]), - V2 = this.points[split].subtract(this.points[split + 1]), - tanCenter = V1.add(V2).divide(2).normalize(); - this.fitCubic(first, split, tan1, tanCenter); - this.fitCubic(split, last, tanCenter.negate(), tan2); - }, - - addCurve: function(curve) { - var prev = this.segments[this.segments.length - 1]; - prev.setHandleOut(curve[1].subtract(curve[0])); - this.segments.push( - new Segment(curve[3], curve[2].subtract(curve[3]))); - }, - - generateBezier: function(first, last, uPrime, tan1, tan2) { - var epsilon = 1e-12, - pt1 = this.points[first], - pt2 = this.points[last], - C = [[0, 0], [0, 0]], - X = [0, 0]; - - for (var i = 0, l = last - first + 1; i < l; i++) { - var u = uPrime[i], - t = 1 - u, - b = 3 * u * t, - b0 = t * t * t, - b1 = b * t, - b2 = b * u, - b3 = u * u * u, - a1 = tan1.normalize(b1), - a2 = tan2.normalize(b2), - tmp = this.points[first + i] - .subtract(pt1.multiply(b0 + b1)) - .subtract(pt2.multiply(b2 + b3)); - C[0][0] += a1.dot(a1); - C[0][1] += a1.dot(a2); - C[1][0] = C[0][1]; - C[1][1] += a2.dot(a2); - X[0] += a1.dot(tmp); - X[1] += a2.dot(tmp); - } - - var detC0C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1], - alpha1, alpha2; - if (Math.abs(detC0C1) > epsilon) { - var detC0X = C[0][0] * X[1] - C[1][0] * X[0], - detXC1 = X[0] * C[1][1] - X[1] * C[0][1]; - alpha1 = detXC1 / detC0C1; - alpha2 = detC0X / detC0C1; - } else { - var c0 = C[0][0] + C[0][1], - c1 = C[1][0] + C[1][1]; - if (Math.abs(c0) > epsilon) { - alpha1 = alpha2 = X[0] / c0; - } else if (Math.abs(c1) > epsilon) { - alpha1 = alpha2 = X[1] / c1; - } else { - alpha1 = alpha2 = 0; - } - } - - var segLength = pt2.getDistance(pt1), - eps = epsilon * segLength, - handle1, - handle2; - if (alpha1 < eps || alpha2 < eps) { - alpha1 = alpha2 = segLength / 3; - } else { - var line = pt2.subtract(pt1); - handle1 = tan1.normalize(alpha1); - handle2 = tan2.normalize(alpha2); - if (handle1.dot(line) - handle2.dot(line) > segLength * segLength) { - alpha1 = alpha2 = segLength / 3; - handle1 = handle2 = null; - } - } - - return [pt1, pt1.add(handle1 || tan1.normalize(alpha1)), - pt2.add(handle2 || tan2.normalize(alpha2)), pt2]; - }, - - reparameterize: function(first, last, u, curve) { - for (var i = first; i <= last; i++) { - u[i - first] = this.findRoot(curve, this.points[i], u[i - first]); - } - for (var i = 1, l = u.length; i < l; i++) { - if (u[i] <= u[i - 1]) - return false; - } - return true; - }, - - findRoot: function(curve, point, u) { - var curve1 = [], - curve2 = []; - for (var i = 0; i <= 2; i++) { - curve1[i] = curve[i + 1].subtract(curve[i]).multiply(3); - } - for (var i = 0; i <= 1; i++) { - curve2[i] = curve1[i + 1].subtract(curve1[i]).multiply(2); - } - var pt = this.evaluate(3, curve, u), - pt1 = this.evaluate(2, curve1, u), - pt2 = this.evaluate(1, curve2, u), - diff = pt.subtract(point), - df = pt1.dot(pt1) + diff.dot(pt2); - if (Math.abs(df) < 1e-6) - return u; - return u - diff.dot(pt1) / df; - }, - - evaluate: function(degree, curve, t) { - var tmp = curve.slice(); - for (var i = 1; i <= degree; i++) { - for (var j = 0; j <= degree - i; j++) { - tmp[j] = tmp[j].multiply(1 - t).add(tmp[j + 1].multiply(t)); - } - } - return tmp[0]; - }, - - chordLengthParameterize: function(first, last) { - var u = [0]; - for (var i = first + 1; i <= last; i++) { - u[i - first] = u[i - first - 1] - + this.points[i].getDistance(this.points[i - 1]); - } - for (var i = 1, m = last - first; i <= m; i++) { - u[i] /= u[m]; - } - return u; - }, - - findMaxError: function(first, last, curve, u) { - var index = Math.floor((last - first + 1) / 2), - maxDist = 0; - for (var i = first + 1; i < last; i++) { - var P = this.evaluate(3, curve, u[i - first]); - var v = P.subtract(this.points[i]); - var dist = v.x * v.x + v.y * v.y; - if (dist >= maxDist) { - maxDist = dist; - index = i; - } - } - return { - error: maxDist, - index: index - }; - } -}); - -var TextItem = Item.extend({ - _class: 'TextItem', - _boundsSelected: true, - _applyMatrix: false, - _canApplyMatrix: false, - _serializeFields: { - content: null - }, - _boundsGetter: 'getBounds', - - initialize: function TextItem(arg) { - this._content = ''; - this._lines = []; - var hasProps = arg && Base.isPlainObject(arg) - && arg.x === undefined && arg.y === undefined; - this._initialize(hasProps && arg, !hasProps && Point.read(arguments)); - }, - - _equals: function(item) { - return this._content === item._content; - }, - - _clone: function _clone(copy, insert, includeMatrix) { - copy.setContent(this._content); - return _clone.base.call(this, copy, insert, includeMatrix); - }, - - getContent: function() { - return this._content; - }, - - setContent: function(content) { - this._content = '' + content; - this._lines = this._content.split(/\r\n|\n|\r/mg); - this._changed(265); - }, - - isEmpty: function() { - return !this._content; - }, - - getCharacterStyle: '#getStyle', - setCharacterStyle: '#setStyle', - - getParagraphStyle: '#getStyle', - setParagraphStyle: '#setStyle' -}); - -var PointText = TextItem.extend({ - _class: 'PointText', - - initialize: function PointText() { - TextItem.apply(this, arguments); - }, - - clone: function(insert) { - return this._clone(new PointText(Item.NO_INSERT), insert); - }, - - getPoint: function() { - var point = this._matrix.getTranslation(); - return new LinkedPoint(point.x, point.y, this, 'setPoint'); - }, - - setPoint: function() { - var point = Point.read(arguments); - this.translate(point.subtract(this._matrix.getTranslation())); - }, - - _draw: function(ctx) { - if (!this._content) - return; - this._setStyles(ctx); - var style = this._style, - lines = this._lines, - leading = style.getLeading(), - shadowColor = ctx.shadowColor; - ctx.font = style.getFontStyle(); - ctx.textAlign = style.getJustification(); - for (var i = 0, l = lines.length; i < l; i++) { - ctx.shadowColor = shadowColor; - var line = lines[i]; - if (style.hasFill()) { - ctx.fillText(line, 0, 0); - ctx.shadowColor = 'rgba(0,0,0,0)'; - } - if (style.hasStroke()) - ctx.strokeText(line, 0, 0); - ctx.translate(0, leading); - } - }, - - _getBounds: function(getter, matrix) { - var style = this._style, - lines = this._lines, - numLines = lines.length, - justification = style.getJustification(), - leading = style.getLeading(), - width = this.getView().getTextWidth(style.getFontStyle(), lines), - x = 0; - if (justification !== 'left') - x -= width / (justification === 'center' ? 2: 1); - var bounds = new Rectangle(x, - numLines ? - 0.75 * leading : 0, - width, numLines * leading); - return matrix ? matrix._transformBounds(bounds, bounds) : bounds; - } -}); - -var Color = Base.extend(new function() { - var types = { - gray: ['gray'], - rgb: ['red', 'green', 'blue'], - hsb: ['hue', 'saturation', 'brightness'], - hsl: ['hue', 'saturation', 'lightness'], - gradient: ['gradient', 'origin', 'destination', 'highlight'] - }; - - var componentParsers = {}, - colorCache = {}, - colorCtx; - - function fromCSS(string) { - var match = string.match(/^#(\w{1,2})(\w{1,2})(\w{1,2})$/), - components; - if (match) { - components = [0, 0, 0]; - for (var i = 0; i < 3; i++) { - var value = match[i + 1]; - components[i] = parseInt(value.length == 1 - ? value + value : value, 16) / 255; - } - } else if (match = string.match(/^rgba?\((.*)\)$/)) { - components = match[1].split(','); - for (var i = 0, l = components.length; i < l; i++) { - var value = +components[i]; - components[i] = i < 3 ? value / 255 : value; - } - } else { - var cached = colorCache[string]; - if (!cached) { - if (!colorCtx) { - colorCtx = CanvasProvider.getContext(1, 1); - colorCtx.globalCompositeOperation = 'copy'; - } - colorCtx.fillStyle = 'rgba(0,0,0,0)'; - colorCtx.fillStyle = string; - colorCtx.fillRect(0, 0, 1, 1); - var data = colorCtx.getImageData(0, 0, 1, 1).data; - cached = colorCache[string] = [ - data[0] / 255, - data[1] / 255, - data[2] / 255 - ]; - } - components = cached.slice(); - } - return components; - } - - var hsbIndices = [ - [0, 3, 1], - [2, 0, 1], - [1, 0, 3], - [1, 2, 0], - [3, 1, 0], - [0, 1, 2] - ]; - - var converters = { - 'rgb-hsb': function(r, g, b) { - var max = Math.max(r, g, b), - min = Math.min(r, g, b), - delta = max - min, - h = delta === 0 ? 0 - : ( max == r ? (g - b) / delta + (g < b ? 6 : 0) - : max == g ? (b - r) / delta + 2 - : (r - g) / delta + 4) * 60; - return [h, max === 0 ? 0 : delta / max, max]; - }, - - 'hsb-rgb': function(h, s, b) { - h = (((h / 60) % 6) + 6) % 6; - var i = Math.floor(h), - f = h - i, - i = hsbIndices[i], - v = [ - b, - b * (1 - s), - b * (1 - s * f), - b * (1 - s * (1 - f)) - ]; - return [v[i[0]], v[i[1]], v[i[2]]]; - }, - - 'rgb-hsl': function(r, g, b) { - var max = Math.max(r, g, b), - min = Math.min(r, g, b), - delta = max - min, - achromatic = delta === 0, - h = achromatic ? 0 - : ( max == r ? (g - b) / delta + (g < b ? 6 : 0) - : max == g ? (b - r) / delta + 2 - : (r - g) / delta + 4) * 60, - l = (max + min) / 2, - s = achromatic ? 0 : l < 0.5 - ? delta / (max + min) - : delta / (2 - max - min); - return [h, s, l]; - }, - - 'hsl-rgb': function(h, s, l) { - h = (((h / 360) % 1) + 1) % 1; - if (s === 0) - return [l, l, l]; - var t3s = [ h + 1 / 3, h, h - 1 / 3 ], - t2 = l < 0.5 ? l * (1 + s) : l + s - l * s, - t1 = 2 * l - t2, - c = []; - for (var i = 0; i < 3; i++) { - var t3 = t3s[i]; - if (t3 < 0) t3 += 1; - if (t3 > 1) t3 -= 1; - c[i] = 6 * t3 < 1 - ? t1 + (t2 - t1) * 6 * t3 - : 2 * t3 < 1 - ? t2 - : 3 * t3 < 2 - ? t1 + (t2 - t1) * ((2 / 3) - t3) * 6 - : t1; - } - return c; - }, - - 'rgb-gray': function(r, g, b) { - return [r * 0.2989 + g * 0.587 + b * 0.114]; - }, - - 'gray-rgb': function(g) { - return [g, g, g]; - }, - - 'gray-hsb': function(g) { - return [0, 0, g]; - }, - - 'gray-hsl': function(g) { - return [0, 0, g]; - }, - - 'gradient-rgb': function() { - return []; - }, - - 'rgb-gradient': function() { - return []; - } - - }; - - return Base.each(types, function(properties, type) { - componentParsers[type] = []; - Base.each(properties, function(name, index) { - var part = Base.capitalize(name), - hasOverlap = /^(hue|saturation)$/.test(name), - parser = componentParsers[type][index] = name === 'gradient' - ? function(value) { - var current = this._components[0]; - value = Gradient.read(Array.isArray(value) ? value - : arguments, 0, { readNull: true }); - if (current !== value) { - if (current) - current._removeOwner(this); - if (value) - value._addOwner(this); - } - return value; - } - : type === 'gradient' - ? function() { - return Point.read(arguments, 0, { - readNull: name === 'highlight', - clone: true - }); - } - : function(value) { - return value == null || isNaN(value) ? 0 : value; - }; - - this['get' + part] = function() { - return this._type === type - || hasOverlap && /^hs[bl]$/.test(this._type) - ? this._components[index] - : this._convert(type)[index]; - }; - - this['set' + part] = function(value) { - if (this._type !== type - && !(hasOverlap && /^hs[bl]$/.test(this._type))) { - this._components = this._convert(type); - this._properties = types[type]; - this._type = type; - } - this._components[index] = parser.call(this, value); - this._changed(); - }; - }, this); - }, { - _class: 'Color', - _readIndex: true, - - initialize: function Color(arg) { - var slice = Array.prototype.slice, - args = arguments, - read = 0, - type, - components, - alpha, - values; - if (Array.isArray(arg)) { - args = arg; - arg = args[0]; - } - var argType = arg != null && typeof arg; - if (argType === 'string' && arg in types) { - type = arg; - arg = args[1]; - if (Array.isArray(arg)) { - components = arg; - alpha = args[2]; - } else { - if (this.__read) - read = 1; - args = slice.call(args, 1); - argType = typeof arg; - } - } - if (!components) { - values = argType === 'number' - ? args - : argType === 'object' && arg.length != null - ? arg - : null; - if (values) { - if (!type) - type = values.length >= 3 - ? 'rgb' - : 'gray'; - var length = types[type].length; - alpha = values[length]; - if (this.__read) - read += values === arguments - ? length + (alpha != null ? 1 : 0) - : 1; - if (values.length > length) - values = slice.call(values, 0, length); - } else if (argType === 'string') { - type = 'rgb'; - components = fromCSS(arg); - if (components.length === 4) { - alpha = components[3]; - components.length--; - } - } else if (argType === 'object') { - if (arg.constructor === Color) { - type = arg._type; - components = arg._components.slice(); - alpha = arg._alpha; - if (type === 'gradient') { - for (var i = 1, l = components.length; i < l; i++) { - var point = components[i]; - if (point) - components[i] = point.clone(); - } - } - } else if (arg.constructor === Gradient) { - type = 'gradient'; - values = args; - } else { - type = 'hue' in arg - ? 'lightness' in arg - ? 'hsl' - : 'hsb' - : 'gradient' in arg || 'stops' in arg - || 'radial' in arg - ? 'gradient' - : 'gray' in arg - ? 'gray' - : 'rgb'; - var properties = types[type], - parsers = componentParsers[type]; - this._components = components = []; - for (var i = 0, l = properties.length; i < l; i++) { - var value = arg[properties[i]]; - if (value == null && i === 0 && type === 'gradient' - && 'stops' in arg) { - value = { - stops: arg.stops, - radial: arg.radial - }; - } - value = parsers[i].call(this, value); - if (value != null) - components[i] = value; - } - alpha = arg.alpha; - } - } - if (this.__read && type) - read = 1; - } - this._type = type || 'rgb'; - this._id = UID.get(Color); - if (!components) { - this._components = components = []; - var parsers = componentParsers[this._type]; - for (var i = 0, l = parsers.length; i < l; i++) { - var value = parsers[i].call(this, values && values[i]); - if (value != null) - components[i] = value; - } - } - this._components = components; - this._properties = types[this._type]; - this._alpha = alpha; - if (this.__read) - this.__read = read; - }, - - _serialize: function(options, dictionary) { - var components = this.getComponents(); - return Base.serialize( - /^(gray|rgb)$/.test(this._type) - ? components - : [this._type].concat(components), - options, true, dictionary); - }, - - _changed: function() { - this._canvasStyle = null; - if (this._owner) - this._owner._changed(65); - }, - - _convert: function(type) { - var converter; - return this._type === type - ? this._components.slice() - : (converter = converters[this._type + '-' + type]) - ? converter.apply(this, this._components) - : converters['rgb-' + type].apply(this, - converters[this._type + '-rgb'].apply(this, - this._components)); - }, - - convert: function(type) { - return new Color(type, this._convert(type), this._alpha); - }, - - getType: function() { - return this._type; - }, - - setType: function(type) { - this._components = this._convert(type); - this._properties = types[type]; - this._type = type; - }, - - getComponents: function() { - var components = this._components.slice(); - if (this._alpha != null) - components.push(this._alpha); - return components; - }, - - getAlpha: function() { - return this._alpha != null ? this._alpha : 1; - }, - - setAlpha: function(alpha) { - this._alpha = alpha == null ? null : Math.min(Math.max(alpha, 0), 1); - this._changed(); - }, - - hasAlpha: function() { - return this._alpha != null; - }, - - equals: function(color) { - var col = Base.isPlainValue(color, true) - ? Color.read(arguments) - : color; - return col === this || col && this._class === col._class - && this._type === col._type - && this._alpha === col._alpha - && Base.equals(this._components, col._components) - || false; - }, - - toString: function() { - var properties = this._properties, - parts = [], - isGradient = this._type === 'gradient', - f = Formatter.instance; - for (var i = 0, l = properties.length; i < l; i++) { - var value = this._components[i]; - if (value != null) - parts.push(properties[i] + ': ' - + (isGradient ? value : f.number(value))); - } - if (this._alpha != null) - parts.push('alpha: ' + f.number(this._alpha)); - return '{ ' + parts.join(', ') + ' }'; - }, - - toCSS: function(hex) { - var components = this._convert('rgb'), - alpha = hex || this._alpha == null ? 1 : this._alpha; - function convert(val) { - return Math.round((val < 0 ? 0 : val > 1 ? 1 : val) * 255); - } - components = [ - convert(components[0]), - convert(components[1]), - convert(components[2]) - ]; - if (alpha < 1) - components.push(alpha < 0 ? 0 : alpha); - return hex - ? '#' + ((1 << 24) + (components[0] << 16) - + (components[1] << 8) - + components[2]).toString(16).slice(1) - : (components.length == 4 ? 'rgba(' : 'rgb(') - + components.join(',') + ')'; - }, - - toCanvasStyle: function(ctx) { - if (this._canvasStyle) - return this._canvasStyle; - if (this._type !== 'gradient') - return this._canvasStyle = this.toCSS(); - var components = this._components, - gradient = components[0], - stops = gradient._stops, - origin = components[1], - destination = components[2], - canvasGradient; - if (gradient._radial) { - var radius = destination.getDistance(origin), - highlight = components[3]; - if (highlight) { - var vector = highlight.subtract(origin); - if (vector.getLength() > radius) - highlight = origin.add(vector.normalize(radius - 0.1)); - } - var start = highlight || origin; - canvasGradient = ctx.createRadialGradient(start.x, start.y, - 0, origin.x, origin.y, radius); - } else { - canvasGradient = ctx.createLinearGradient(origin.x, origin.y, - destination.x, destination.y); - } - for (var i = 0, l = stops.length; i < l; i++) { - var stop = stops[i]; - canvasGradient.addColorStop(stop._rampPoint, - stop._color.toCanvasStyle()); - } - return this._canvasStyle = canvasGradient; - }, - - transform: function(matrix) { - if (this._type === 'gradient') { - var components = this._components; - for (var i = 1, l = components.length; i < l; i++) { - var point = components[i]; - matrix._transformPoint(point, point, true); - } - this._changed(); - } - }, - - statics: { - _types: types, - - random: function() { - var random = Math.random; - return new Color(random(), random(), random()); - } - } - }); -}, -new function() { - var operators = { - add: function(a, b) { - return a + b; - }, - - subtract: function(a, b) { - return a - b; - }, - - multiply: function(a, b) { - return a * b; - }, - - divide: function(a, b) { - return a / b; - } - }; - - return Base.each(operators, function(operator, name) { - this[name] = function(color) { - color = Color.read(arguments); - var type = this._type, - components1 = this._components, - components2 = color._convert(type); - for (var i = 0, l = components1.length; i < l; i++) - components2[i] = operator(components1[i], components2[i]); - return new Color(type, components2, - this._alpha != null - ? operator(this._alpha, color.getAlpha()) - : null); - }; - }, { - }); -}); - -var Gradient = Base.extend({ - _class: 'Gradient', - - initialize: function Gradient(stops, radial) { - this._id = UID.get(); - if (stops && this._set(stops)) - stops = radial = null; - if (!this._stops) - this.setStops(stops || ['white', 'black']); - if (this._radial == null) - this.setRadial(typeof radial === 'string' && radial === 'radial' - || radial || false); - }, - - _serialize: function(options, dictionary) { - return dictionary.add(this, function() { - return Base.serialize([this._stops, this._radial], - options, true, dictionary); - }); - }, - - _changed: function() { - for (var i = 0, l = this._owners && this._owners.length; i < l; i++) - this._owners[i]._changed(); - }, - - _addOwner: function(color) { - if (!this._owners) - this._owners = []; - this._owners.push(color); - }, - - _removeOwner: function(color) { - var index = this._owners ? this._owners.indexOf(color) : -1; - if (index != -1) { - this._owners.splice(index, 1); - if (this._owners.length === 0) - this._owners = undefined; - } - }, - - clone: function() { - var stops = []; - for (var i = 0, l = this._stops.length; i < l; i++) - stops[i] = this._stops[i].clone(); - return new Gradient(stops, this._radial); - }, - - getStops: function() { - return this._stops; - }, - - setStops: function(stops) { - if (this.stops) { - for (var i = 0, l = this._stops.length; i < l; i++) - this._stops[i]._owner = undefined; - } - if (stops.length < 2) - throw new Error( - 'Gradient stop list needs to contain at least two stops.'); - this._stops = GradientStop.readAll(stops, 0, { clone: true }); - for (var i = 0, l = this._stops.length; i < l; i++) { - var stop = this._stops[i]; - stop._owner = this; - if (stop._defaultRamp) - stop.setRampPoint(i / (l - 1)); - } - this._changed(); - }, - - getRadial: function() { - return this._radial; - }, - - setRadial: function(radial) { - this._radial = radial; - this._changed(); - }, - - equals: function(gradient) { - if (gradient === this) - return true; - if (gradient && this._class === gradient._class - && this._stops.length === gradient._stops.length) { - for (var i = 0, l = this._stops.length; i < l; i++) { - if (!this._stops[i].equals(gradient._stops[i])) - return false; - } - return true; - } - return false; - } -}); - -var GradientStop = Base.extend({ - _class: 'GradientStop', - - initialize: function GradientStop(arg0, arg1) { - if (arg0) { - var color, rampPoint; - if (arg1 === undefined && Array.isArray(arg0)) { - color = arg0[0]; - rampPoint = arg0[1]; - } else if (arg0.color) { - color = arg0.color; - rampPoint = arg0.rampPoint; - } else { - color = arg0; - rampPoint = arg1; - } - this.setColor(color); - this.setRampPoint(rampPoint); - } - }, - - clone: function() { - return new GradientStop(this._color.clone(), this._rampPoint); - }, - - _serialize: function(options, dictionary) { - return Base.serialize([this._color, this._rampPoint], options, true, - dictionary); - }, - - _changed: function() { - if (this._owner) - this._owner._changed(65); - }, - - getRampPoint: function() { - return this._rampPoint; - }, - - setRampPoint: function(rampPoint) { - this._defaultRamp = rampPoint == null; - this._rampPoint = rampPoint || 0; - this._changed(); - }, - - getColor: function() { - return this._color; - }, - - setColor: function(color) { - this._color = Color.read(arguments); - if (this._color === color) - this._color = color.clone(); - this._color._owner = this; - this._changed(); - }, - - equals: function(stop) { - return stop === this || stop && this._class === stop._class - && this._color.equals(stop._color) - && this._rampPoint == stop._rampPoint - || false; - } -}); - -var Style = Base.extend(new function() { - var defaults = { - fillColor: undefined, - strokeColor: undefined, - strokeWidth: 1, - strokeCap: 'butt', - strokeJoin: 'miter', - strokeScaling: true, - miterLimit: 10, - dashOffset: 0, - dashArray: [], - windingRule: 'nonzero', - shadowColor: undefined, - shadowBlur: 0, - shadowOffset: new Point(), - selectedColor: undefined, - fontFamily: 'sans-serif', - fontWeight: 'normal', - fontSize: 12, - font: 'sans-serif', - leading: null, - justification: 'left' - }; - - var flags = { - strokeWidth: 97, - strokeCap: 97, - strokeJoin: 97, - strokeScaling: 105, - miterLimit: 97, - fontFamily: 9, - fontWeight: 9, - fontSize: 9, - font: 9, - leading: 9, - justification: 9 - }; - - var item = { beans: true }, - fields = { - _defaults: defaults, - _textDefaults: new Base(defaults, { - fillColor: new Color() - }), - beans: true - }; - - Base.each(defaults, function(value, key) { - var isColor = /Color$/.test(key), - isPoint = key === 'shadowOffset', - part = Base.capitalize(key), - flag = flags[key], - set = 'set' + part, - get = 'get' + part; - - fields[set] = function(value) { - var owner = this._owner, - children = owner && owner._children; - if (children && children.length > 0 - && !(owner instanceof CompoundPath)) { - for (var i = 0, l = children.length; i < l; i++) - children[i]._style[set](value); - } else { - var old = this._values[key]; - if (old !== value) { - if (isColor) { - if (old) - old._owner = undefined; - if (value && value.constructor === Color) { - if (value._owner) - value = value.clone(); - value._owner = owner; - } - } - this._values[key] = value; - if (owner) - owner._changed(flag || 65); - } - } - }; - - fields[get] = function(_dontMerge) { - var owner = this._owner, - children = owner && owner._children, - value; - if (!children || children.length === 0 || _dontMerge - || owner instanceof CompoundPath) { - var value = this._values[key]; - if (value === undefined) { - value = this._defaults[key]; - if (value && value.clone) - value = value.clone(); - } else { - var ctor = isColor ? Color : isPoint ? Point : null; - if (ctor && !(value && value.constructor === ctor)) { - this._values[key] = value = ctor.read([value], 0, - { readNull: true, clone: true }); - if (value && isColor) - value._owner = owner; - } - } - return value; - } - for (var i = 0, l = children.length; i < l; i++) { - var childValue = children[i]._style[get](); - if (i === 0) { - value = childValue; - } else if (!Base.equals(value, childValue)) { - return undefined; - } - } - return value; - }; - - item[get] = function(_dontMerge) { - return this._style[get](_dontMerge); - }; - - item[set] = function(value) { - this._style[set](value); - }; - }); - - Item.inject(item); - return fields; -}, { - _class: 'Style', - - initialize: function Style(style, _owner, _project) { - this._values = {}; - this._owner = _owner; - this._project = _owner && _owner._project || _project || paper.project; - if (_owner instanceof TextItem) - this._defaults = this._textDefaults; - if (style) - this.set(style); - }, - - set: function(style) { - var isStyle = style instanceof Style, - values = isStyle ? style._values : style; - if (values) { - for (var key in values) { - if (key in this._defaults) { - var value = values[key]; - this[key] = value && isStyle && value.clone - ? value.clone() : value; - } - } - } - }, - - equals: function(style) { - return style === this || style && this._class === style._class - && Base.equals(this._values, style._values) - || false; - }, - - hasFill: function() { - return !!this.getFillColor(); - }, - - hasStroke: function() { - return !!this.getStrokeColor() && this.getStrokeWidth() > 0; - }, - - hasShadow: function() { - return !!this.getShadowColor() && this.getShadowBlur() > 0; - }, - - getView: function() { - return this._project.getView(); - }, - - getFontStyle: function() { - var fontSize = this.getFontSize(); - return this.getFontWeight() - + ' ' + fontSize + (/[a-z]/i.test(fontSize + '') ? ' ' : 'px ') - + this.getFontFamily(); - }, - - getFont: '#getFontFamily', - setFont: '#setFontFamily', - - getLeading: function getLeading() { - var leading = getLeading.base.call(this), - fontSize = this.getFontSize(); - if (/pt|em|%|px/.test(fontSize)) - fontSize = this.getView().getPixelSize(fontSize); - return leading != null ? leading : fontSize * 1.2; - } - -}); - -var DomElement = new function() { - function handlePrefix(el, name, set, value) { - var prefixes = ['', 'webkit', 'moz', 'Moz', 'ms', 'o'], - suffix = name[0].toUpperCase() + name.substring(1); - for (var i = 0; i < 6; i++) { - var prefix = prefixes[i], - key = prefix ? prefix + suffix : name; - if (key in el) { - if (set) { - el[key] = value; - } else { - return el[key]; - } - break; - } - } - } - - return { - getStyles: function(el) { - var doc = el && el.nodeType !== 9 ? el.ownerDocument : el, - view = doc && doc.defaultView; - return view && view.getComputedStyle(el, ''); - }, - - getBounds: function(el, viewport) { - var doc = el.ownerDocument, - body = doc.body, - html = doc.documentElement, - rect; - try { - rect = el.getBoundingClientRect(); - } catch (e) { - rect = { left: 0, top: 0, width: 0, height: 0 }; - } - var x = rect.left - (html.clientLeft || body.clientLeft || 0), - y = rect.top - (html.clientTop || body.clientTop || 0); - if (!viewport) { - var view = doc.defaultView; - x += view.pageXOffset || html.scrollLeft || body.scrollLeft; - y += view.pageYOffset || html.scrollTop || body.scrollTop; - } - return new Rectangle(x, y, rect.width, rect.height); - }, - - getViewportBounds: function(el) { - var doc = el.ownerDocument, - view = doc.defaultView, - html = doc.documentElement; - return new Rectangle(0, 0, - view.innerWidth || html.clientWidth, - view.innerHeight || html.clientHeight - ); - }, - - getOffset: function(el, viewport) { - return DomElement.getBounds(el, viewport).getPoint(); - }, - - getSize: function(el) { - return DomElement.getBounds(el, true).getSize(); - }, - - isInvisible: function(el) { - return DomElement.getSize(el).equals(new Size(0, 0)); - }, - - isInView: function(el) { - return !DomElement.isInvisible(el) - && DomElement.getViewportBounds(el).intersects( - DomElement.getBounds(el, true)); - }, - - getPrefixed: function(el, name) { - return handlePrefix(el, name); - }, - - setPrefixed: function(el, name, value) { - if (typeof name === 'object') { - for (var key in name) - handlePrefix(el, key, true, name[key]); - } else { - handlePrefix(el, name, true, value); - } - } - }; -}; - -var DomEvent = { - add: function(el, events) { - for (var type in events) { - var func = events[type], - parts = type.split(/[\s,]+/g); - for (var i = 0, l = parts.length; i < l; i++) - el.addEventListener(parts[i], func, false); - } - }, - - remove: function(el, events) { - for (var type in events) { - var func = events[type], - parts = type.split(/[\s,]+/g); - for (var i = 0, l = parts.length; i < l; i++) - el.removeEventListener(parts[i], func, false); - } - }, - - getPoint: function(event) { - var pos = event.targetTouches - ? event.targetTouches.length - ? event.targetTouches[0] - : event.changedTouches[0] - : event; - return new Point( - pos.pageX || pos.clientX + document.documentElement.scrollLeft, - pos.pageY || pos.clientY + document.documentElement.scrollTop - ); - }, - - getTarget: function(event) { - return event.target || event.srcElement; - }, - - getRelatedTarget: function(event) { - return event.relatedTarget || event.toElement; - }, - - getOffset: function(event, target) { - return DomEvent.getPoint(event).subtract(DomElement.getOffset( - target || DomEvent.getTarget(event))); - }, - - stop: function(event) { - event.stopPropagation(); - event.preventDefault(); - } -}; - -DomEvent.requestAnimationFrame = new function() { - var nativeRequest = DomElement.getPrefixed(window, 'requestAnimationFrame'), - requested = false, - callbacks = [], - focused = true, - timer; - - DomEvent.add(window, { - focus: function() { - focused = true; - }, - blur: function() { - focused = false; - } - }); - - function handleCallbacks() { - for (var i = callbacks.length - 1; i >= 0; i--) { - var entry = callbacks[i], - func = entry[0], - el = entry[1]; - if (!el || (PaperScope.getAttribute(el, 'keepalive') == 'true' - || focused) && DomElement.isInView(el)) { - callbacks.splice(i, 1); - func(); - } - } - if (nativeRequest) { - if (callbacks.length) { - nativeRequest(handleCallbacks); - } else { - requested = false; - } - } - } - - return function(callback, element) { - callbacks.push([callback, element]); - if (nativeRequest) { - if (!requested) { - nativeRequest(handleCallbacks); - requested = true; - } - } else if (!timer) { - timer = setInterval(handleCallbacks, 1000 / 60); - } - }; -}; - -var View = Base.extend(Emitter, { - _class: 'View', - - initialize: function View(project, element) { - this._project = project; - this._scope = project._scope; - this._element = element; - var size; - if (!this._pixelRatio) - this._pixelRatio = window.devicePixelRatio || 1; - this._id = element.getAttribute('id'); - if (this._id == null) - element.setAttribute('id', this._id = 'view-' + View._id++); - DomEvent.add(element, this._viewEvents); - var none = 'none'; - DomElement.setPrefixed(element.style, { - userSelect: none, - touchAction: none, - touchCallout: none, - contentZooming: none, - userDrag: none, - tapHighlightColor: 'rgba(0,0,0,0)' - }); - - function getSize(name) { - return element[name] || parseInt(element.getAttribute(name), 10); - }; - - function getCanvasSize() { - var size = DomElement.getSize(element); - return size.isNaN() || size.isZero() - ? new Size(getSize('width'), getSize('height')) - : size; - }; - - if (PaperScope.hasAttribute(element, 'resize')) { - var that = this; - DomEvent.add(window, this._windowEvents = { - resize: function() { - that.setViewSize(getCanvasSize()); - } - }); - } - this._setViewSize(size = getCanvasSize()); - if (PaperScope.hasAttribute(element, 'stats') - && typeof Stats !== 'undefined') { - this._stats = new Stats(); - var stats = this._stats.domElement, - style = stats.style, - offset = DomElement.getOffset(element); - style.position = 'absolute'; - style.left = offset.x + 'px'; - style.top = offset.y + 'px'; - document.body.appendChild(stats); - } - View._views.push(this); - View._viewsById[this._id] = this; - this._viewSize = size; - (this._matrix = new Matrix())._owner = this; - this._zoom = 1; - if (!View._focused) - View._focused = this; - this._frameItems = {}; - this._frameItemCount = 0; - }, - - remove: function() { - if (!this._project) - return false; - if (View._focused === this) - View._focused = null; - View._views.splice(View._views.indexOf(this), 1); - delete View._viewsById[this._id]; - if (this._project._view === this) - this._project._view = null; - DomEvent.remove(this._element, this._viewEvents); - DomEvent.remove(window, this._windowEvents); - this._element = this._project = null; - this.off('frame'); - this._animate = false; - this._frameItems = {}; - return true; - }, - - _events: Base.each(['onResize', 'onMouseDown', 'onMouseUp', 'onMouseMove'], - function(name) { - this[name] = { - install: function(type) { - this._installEvent(type); - }, - - uninstall: function(type) { - this._uninstallEvent(type); - } - }; - }, { - onFrame: { - install: function() { - this.play(); - }, - - uninstall: function() { - this.pause(); - } - } - } - ), - - _animate: false, - _time: 0, - _count: 0, - - _requestFrame: function() { - var that = this; - DomEvent.requestAnimationFrame(function() { - that._requested = false; - if (!that._animate) - return; - that._requestFrame(); - that._handleFrame(); - }, this._element); - this._requested = true; - }, - - _handleFrame: function() { - paper = this._scope; - var now = Date.now() / 1000, - delta = this._before ? now - this._before : 0; - this._before = now; - this._handlingFrame = true; - this.emit('frame', new Base({ - delta: delta, - time: this._time += delta, - count: this._count++ - })); - if (this._stats) - this._stats.update(); - this._handlingFrame = false; - this.update(); - }, - - _animateItem: function(item, animate) { - var items = this._frameItems; - if (animate) { - items[item._id] = { - item: item, - time: 0, - count: 0 - }; - if (++this._frameItemCount === 1) - this.on('frame', this._handleFrameItems); - } else { - delete items[item._id]; - if (--this._frameItemCount === 0) { - this.off('frame', this._handleFrameItems); - } - } - }, - - _handleFrameItems: function(event) { - for (var i in this._frameItems) { - var entry = this._frameItems[i]; - entry.item.emit('frame', new Base(event, { - time: entry.time += event.delta, - count: entry.count++ - })); - } - }, - - _update: function() { - this._project._needsUpdate = true; - if (this._handlingFrame) - return; - if (this._animate) { - this._handleFrame(); - } else { - this.update(); - } - }, - - _changed: function(flags) { - if (flags & 1) - this._project._needsUpdate = true; - }, - - _transform: function(matrix) { - this._matrix.concatenate(matrix); - this._bounds = null; - this._update(); - }, - - getElement: function() { - return this._element; - }, - - getPixelRatio: function() { - return this._pixelRatio; - }, - - getResolution: function() { - return this._pixelRatio * 72; - }, - - getViewSize: function() { - var size = this._viewSize; - return new LinkedSize(size.width, size.height, this, 'setViewSize'); - }, - - setViewSize: function() { - var size = Size.read(arguments), - delta = size.subtract(this._viewSize); - if (delta.isZero()) - return; - this._viewSize.set(size.width, size.height); - this._setViewSize(size); - this._bounds = null; - this.emit('resize', { - size: size, - delta: delta - }); - this._update(); - }, - - _setViewSize: function(size) { - var element = this._element; - element.width = size.width; - element.height = size.height; - }, - - getBounds: function() { - if (!this._bounds) - this._bounds = this._matrix.inverted()._transformBounds( - new Rectangle(new Point(), this._viewSize)); - return this._bounds; - }, - - getSize: function() { - return this.getBounds().getSize(); - }, - - getCenter: function() { - return this.getBounds().getCenter(); - }, - - setCenter: function() { - var center = Point.read(arguments); - this.scrollBy(center.subtract(this.getCenter())); - }, - - getZoom: function() { - return this._zoom; - }, - - setZoom: function(zoom) { - this._transform(new Matrix().scale(zoom / this._zoom, - this.getCenter())); - this._zoom = zoom; - }, - - isVisible: function() { - return DomElement.isInView(this._element); - }, - - scrollBy: function() { - this._transform(new Matrix().translate(Point.read(arguments).negate())); - }, - - play: function() { - this._animate = true; - if (!this._requested) - this._requestFrame(); - }, - - pause: function() { - this._animate = false; - }, - - draw: function() { - this.update(); - }, - - projectToView: function() { - return this._matrix._transformPoint(Point.read(arguments)); - }, - - viewToProject: function() { - return this._matrix._inverseTransform(Point.read(arguments)); - } - -}, { - statics: { - _views: [], - _viewsById: {}, - _id: 0, - - create: function(project, element) { - if (typeof element === 'string') - element = document.getElementById(element); - return new CanvasView(project, element); - } - } -}, -new function() { - var tool, - prevFocus, - tempFocus, - dragging = false; - - function getView(event) { - var target = DomEvent.getTarget(event); - return target.getAttribute && View._viewsById[target.getAttribute('id')]; - } - - function viewToProject(view, event) { - return view.viewToProject(DomEvent.getOffset(event, view._element)); - } - - function updateFocus() { - if (!View._focused || !View._focused.isVisible()) { - for (var i = 0, l = View._views.length; i < l; i++) { - var view = View._views[i]; - if (view && view.isVisible()) { - View._focused = tempFocus = view; - break; - } - } - } - } - - function handleMouseMove(view, point, event) { - view._handleEvent('mousemove', point, event); - var tool = view._scope.tool; - if (tool) { - tool._handleEvent(dragging && tool.responds('mousedrag') - ? 'mousedrag' : 'mousemove', point, event); - } - view.update(); - return tool; - } - - var navigator = window.navigator, - mousedown, mousemove, mouseup; - if (navigator.pointerEnabled || navigator.msPointerEnabled) { - mousedown = 'pointerdown MSPointerDown'; - mousemove = 'pointermove MSPointerMove'; - mouseup = 'pointerup pointercancel MSPointerUp MSPointerCancel'; - } else { - mousedown = 'touchstart'; - mousemove = 'touchmove'; - mouseup = 'touchend touchcancel'; - if (!('ontouchstart' in window && navigator.userAgent.match( - /mobile|tablet|ip(ad|hone|od)|android|silk/i))) { - mousedown += ' mousedown'; - mousemove += ' mousemove'; - mouseup += ' mouseup'; - } - } - - var viewEvents = { - 'selectstart dragstart': function(event) { - if (dragging) - event.preventDefault(); - } - }; - - var docEvents = { - mouseout: function(event) { - var view = View._focused, - target = DomEvent.getRelatedTarget(event); - if (view && (!target || target.nodeName === 'HTML')) - handleMouseMove(view, viewToProject(view, event), event); - }, - - scroll: updateFocus - }; - - viewEvents[mousedown] = function(event) { - var view = View._focused = getView(event), - point = viewToProject(view, event); - dragging = true; - view._handleEvent('mousedown', point, event); - if (tool = view._scope.tool) - tool._handleEvent('mousedown', point, event); - view.update(); - }; - - docEvents[mousemove] = function(event) { - var view = View._focused; - if (!dragging) { - var target = getView(event); - if (target) { - if (view !== target) - handleMouseMove(view, viewToProject(view, event), event); - prevFocus = view; - view = View._focused = tempFocus = target; - } else if (tempFocus && tempFocus === view) { - view = View._focused = prevFocus; - updateFocus(); - } - } - if (view) { - var point = viewToProject(view, event); - if (dragging || view.getBounds().contains(point)) - tool = handleMouseMove(view, point, event); - } - }; - - docEvents[mouseup] = function(event) { - var view = View._focused; - if (!view || !dragging) - return; - var point = viewToProject(view, event); - dragging = false; - view._handleEvent('mouseup', point, event); - if (tool) - tool._handleEvent('mouseup', point, event); - view.update(); - }; - - DomEvent.add(document, docEvents); - - DomEvent.add(window, { - load: updateFocus - }); - - var mouseFlags = { - mousedown: { - mousedown: 1, - mousedrag: 1, - click: 1, - doubleclick: 1 - }, - mouseup: { - mouseup: 1, - mousedrag: 1, - click: 1, - doubleclick: 1 - }, - mousemove: { - mousedrag: 1, - mousemove: 1, - mouseenter: 1, - mouseleave: 1 - } - }; - - return { - _viewEvents: viewEvents, - - _handleEvent: function() {}, - - _installEvent: function(type) { - var counters = this._eventCounters; - if (counters) { - for (var key in mouseFlags) { - counters[key] = (counters[key] || 0) - + (mouseFlags[key][type] || 0); - } - } - }, - - _uninstallEvent: function(type) { - var counters = this._eventCounters; - if (counters) { - for (var key in mouseFlags) - counters[key] -= mouseFlags[key][type] || 0; - } - }, - - statics: { - updateFocus: updateFocus - } - }; -}); - -var CanvasView = View.extend({ - _class: 'CanvasView', - - initialize: function CanvasView(project, canvas) { - if (!(canvas instanceof HTMLCanvasElement)) { - var size = Size.read(arguments, 1); - if (size.isZero()) - throw new Error( - 'Cannot create CanvasView with the provided argument: ' - + [].slice.call(arguments, 1)); - canvas = CanvasProvider.getCanvas(size); - } - this._context = canvas.getContext('2d'); - this._eventCounters = {}; - this._pixelRatio = 1; - if (!/^off|false$/.test(PaperScope.getAttribute(canvas, 'hidpi'))) { - var deviceRatio = window.devicePixelRatio || 1, - backingStoreRatio = DomElement.getPrefixed(this._context, - 'backingStorePixelRatio') || 1; - this._pixelRatio = deviceRatio / backingStoreRatio; - } - View.call(this, project, canvas); - }, - - _setViewSize: function(size) { - var element = this._element, - pixelRatio = this._pixelRatio, - width = size.width, - height = size.height; - element.width = width * pixelRatio; - element.height = height * pixelRatio; - if (pixelRatio !== 1) { - if (!PaperScope.hasAttribute(element, 'resize')) { - var style = element.style; - style.width = width + 'px'; - style.height = height + 'px'; - } - this._context.scale(pixelRatio, pixelRatio); - } - }, - - getPixelSize: function(size) { - var browser = paper.browser, - pixels; - if (browser && browser.firefox) { - var parent = this._element.parentNode, - temp = document.createElement('div'); - temp.style.fontSize = size; - parent.appendChild(temp); - pixels = parseFloat(DomElement.getStyles(temp).fontSize); - parent.removeChild(temp); - } else { - var ctx = this._context, - prevFont = ctx.font; - ctx.font = size + ' serif'; - pixels = parseFloat(ctx.font); - ctx.font = prevFont; - } - return pixels; - }, - - getTextWidth: function(font, lines) { - var ctx = this._context, - prevFont = ctx.font, - width = 0; - ctx.font = font; - for (var i = 0, l = lines.length; i < l; i++) - width = Math.max(width, ctx.measureText(lines[i]).width); - ctx.font = prevFont; - return width; - }, - - update: function(force) { - var project = this._project; - if (!project || !force && !project._needsUpdate) - return false; - var ctx = this._context, - size = this._viewSize; - ctx.clearRect(0, 0, size.width + 1, size.height + 1); - project.draw(ctx, this._matrix, this._pixelRatio); - project._needsUpdate = false; - return true; - } -}, -new function() { - var downPoint, - lastPoint, - overPoint, - downItem, - lastItem, - overItem, - dragItem, - dblClick, - clickTime; - - function callEvent(view, type, event, point, target, lastPoint) { - var item = target, - mouseEvent; - - function call(obj) { - if (obj.responds(type)) { - if (!mouseEvent) { - mouseEvent = new MouseEvent(type, event, point, target, - lastPoint ? point.subtract(lastPoint) : null); - } - if (obj.emit(type, mouseEvent) && mouseEvent.isStopped) { - event.preventDefault(); - return true; - } - } - } - - while (item) { - if (call(item)) - return true; - item = item.getParent(); - } - if (call(view)) - return true; - return false; - } - - return { - _handleEvent: function(type, point, event) { - if (!this._eventCounters[type]) - return; - var project = this._project, - hit = project.hitTest(point, { - tolerance: 0, - fill: true, - stroke: true - }), - item = hit && hit.item, - stopped = false; - switch (type) { - case 'mousedown': - stopped = callEvent(this, type, event, point, item); - dblClick = lastItem == item && (Date.now() - clickTime < 300); - downItem = lastItem = item; - downPoint = lastPoint = overPoint = point; - dragItem = !stopped && item; - while (dragItem && !dragItem.responds('mousedrag')) - dragItem = dragItem._parent; - break; - case 'mouseup': - stopped = callEvent(this, type, event, point, item, downPoint); - if (dragItem) { - if (lastPoint && !lastPoint.equals(point)) - callEvent(this, 'mousedrag', event, point, dragItem, - lastPoint); - if (item !== dragItem) { - overPoint = point; - callEvent(this, 'mousemove', event, point, item, - overPoint); - } - } - if (!stopped && item && item === downItem) { - clickTime = Date.now(); - callEvent(this, dblClick && downItem.responds('doubleclick') - ? 'doubleclick' : 'click', event, downPoint, item); - dblClick = false; - } - downItem = dragItem = null; - break; - case 'mousemove': - if (dragItem) - stopped = callEvent(this, 'mousedrag', event, point, - dragItem, lastPoint); - if (!stopped) { - if (item !== overItem) - overPoint = point; - stopped = callEvent(this, type, event, point, item, - overPoint); - } - lastPoint = overPoint = point; - if (item !== overItem) { - callEvent(this, 'mouseleave', event, point, overItem); - overItem = item; - callEvent(this, 'mouseenter', event, point, item); - } - break; - } - return stopped; - } - }; -}); - -var Event = Base.extend({ - _class: 'Event', - - initialize: function Event(event) { - this.event = event; - }, - - isPrevented: false, - isStopped: false, - - preventDefault: function() { - this.isPrevented = true; - this.event.preventDefault(); - }, - - stopPropagation: function() { - this.isStopped = true; - this.event.stopPropagation(); - }, - - stop: function() { - this.stopPropagation(); - this.preventDefault(); - }, - - getModifiers: function() { - return Key.modifiers; - } -}); - -var KeyEvent = Event.extend({ - _class: 'KeyEvent', - - initialize: function KeyEvent(down, key, character, event) { - Event.call(this, event); - this.type = down ? 'keydown' : 'keyup'; - this.key = key; - this.character = character; - }, - - toString: function() { - return "{ type: '" + this.type - + "', key: '" + this.key - + "', character: '" + this.character - + "', modifiers: " + this.getModifiers() - + " }"; - } -}); - -var Key = new function() { - - var specialKeys = { - 8: 'backspace', - 9: 'tab', - 13: 'enter', - 16: 'shift', - 17: 'control', - 18: 'option', - 19: 'pause', - 20: 'caps-lock', - 27: 'escape', - 32: 'space', - 35: 'end', - 36: 'home', - 37: 'left', - 38: 'up', - 39: 'right', - 40: 'down', - 46: 'delete', - 91: 'command', - 93: 'command', - 224: 'command' - }, - - specialChars = { - 9: true, - 13: true, - 32: true - }, - - modifiers = new Base({ - shift: false, - control: false, - option: false, - command: false, - capsLock: false, - space: false - }), - - charCodeMap = {}, - keyMap = {}, - commandFixMap, - downCode; - - function handleKey(down, keyCode, charCode, event) { - var character = charCode ? String.fromCharCode(charCode) : '', - specialKey = specialKeys[keyCode], - key = specialKey || character.toLowerCase(), - type = down ? 'keydown' : 'keyup', - view = View._focused, - scope = view && view.isVisible() && view._scope, - tool = scope && scope.tool, - name; - keyMap[key] = down; - if (down) { - charCodeMap[keyCode] = charCode; - } else { - delete charCodeMap[keyCode]; - } - if (specialKey && (name = Base.camelize(specialKey)) in modifiers) { - modifiers[name] = down; - var browser = paper.browser; - if (name === 'command' && browser && browser.mac) { - if (down) { - commandFixMap = {}; - } else { - for (var code in commandFixMap) { - if (code in charCodeMap) - handleKey(false, code, commandFixMap[code], event); - } - commandFixMap = null; - } - } - } else if (down && commandFixMap) { - commandFixMap[keyCode] = charCode; - } - if (tool && tool.responds(type)) { - paper = scope; - tool.emit(type, new KeyEvent(down, key, character, event)); - if (view) - view.update(); - } - } - - DomEvent.add(document, { - keydown: function(event) { - var code = event.which || event.keyCode; - if (code in specialKeys || modifiers.command) { - handleKey(true, code, - code in specialChars || modifiers.command ? code : 0, - event); - } else { - downCode = code; - } - }, - - keypress: function(event) { - if (downCode != null) { - handleKey(true, downCode, event.which || event.keyCode, event); - downCode = null; - } - }, - - keyup: function(event) { - var code = event.which || event.keyCode; - if (code in charCodeMap) - handleKey(false, code, charCodeMap[code], event); - } - }); - - DomEvent.add(window, { - blur: function(event) { - for (var code in charCodeMap) - handleKey(false, code, charCodeMap[code], event); - } - }); - - return { - modifiers: modifiers, - - isDown: function(key) { - return !!keyMap[key]; - } - }; -}; - -var MouseEvent = Event.extend({ - _class: 'MouseEvent', - - initialize: function MouseEvent(type, event, point, target, delta) { - Event.call(this, event); - this.type = type; - this.point = point; - this.target = target; - this.delta = delta; - }, - - toString: function() { - return "{ type: '" + this.type - + "', point: " + this.point - + ', target: ' + this.target - + (this.delta ? ', delta: ' + this.delta : '') - + ', modifiers: ' + this.getModifiers() - + ' }'; - } -}); - -var ToolEvent = Event.extend({ - _class: 'ToolEvent', - _item: null, - - initialize: function ToolEvent(tool, type, event) { - this.tool = tool; - this.type = type; - this.event = event; - }, - - _choosePoint: function(point, toolPoint) { - return point ? point : toolPoint ? toolPoint.clone() : null; - }, - - getPoint: function() { - return this._choosePoint(this._point, this.tool._point); - }, - - setPoint: function(point) { - this._point = point; - }, - - getLastPoint: function() { - return this._choosePoint(this._lastPoint, this.tool._lastPoint); - }, - - setLastPoint: function(lastPoint) { - this._lastPoint = lastPoint; - }, - - getDownPoint: function() { - return this._choosePoint(this._downPoint, this.tool._downPoint); - }, - - setDownPoint: function(downPoint) { - this._downPoint = downPoint; - }, - - getMiddlePoint: function() { - if (!this._middlePoint && this.tool._lastPoint) { - return this.tool._point.add(this.tool._lastPoint).divide(2); - } - return this._middlePoint; - }, - - setMiddlePoint: function(middlePoint) { - this._middlePoint = middlePoint; - }, - - getDelta: function() { - return !this._delta && this.tool._lastPoint - ? this.tool._point.subtract(this.tool._lastPoint) - : this._delta; - }, - - setDelta: function(delta) { - this._delta = delta; - }, - - getCount: function() { - return /^mouse(down|up)$/.test(this.type) - ? this.tool._downCount - : this.tool._count; - }, - - setCount: function(count) { - this.tool[/^mouse(down|up)$/.test(this.type) ? 'downCount' : 'count'] - = count; - }, - - getItem: function() { - if (!this._item) { - var result = this.tool._scope.project.hitTest(this.getPoint()); - if (result) { - var item = result.item, - parent = item._parent; - while (/^(Group|CompoundPath)$/.test(parent._class)) { - item = parent; - parent = parent._parent; - } - this._item = item; - } - } - return this._item; - }, - - setItem: function(item) { - this._item = item; - }, - - toString: function() { - return '{ type: ' + this.type - + ', point: ' + this.getPoint() - + ', count: ' + this.getCount() - + ', modifiers: ' + this.getModifiers() - + ' }'; - } -}); - -var Tool = PaperScopeItem.extend({ - _class: 'Tool', - _list: 'tools', - _reference: 'tool', - _events: [ 'onActivate', 'onDeactivate', 'onEditOptions', - 'onMouseDown', 'onMouseUp', 'onMouseDrag', 'onMouseMove', - 'onKeyDown', 'onKeyUp' ], - - initialize: function Tool(props) { - PaperScopeItem.call(this); - this._firstMove = true; - this._count = 0; - this._downCount = 0; - this._set(props); - }, - - getMinDistance: function() { - return this._minDistance; - }, - - setMinDistance: function(minDistance) { - this._minDistance = minDistance; - if (minDistance != null && this._maxDistance != null - && minDistance > this._maxDistance) { - this._maxDistance = minDistance; - } - }, - - getMaxDistance: function() { - return this._maxDistance; - }, - - setMaxDistance: function(maxDistance) { - this._maxDistance = maxDistance; - if (this._minDistance != null && maxDistance != null - && maxDistance < this._minDistance) { - this._minDistance = maxDistance; - } - }, - - getFixedDistance: function() { - return this._minDistance == this._maxDistance - ? this._minDistance : null; - }, - - setFixedDistance: function(distance) { - this._minDistance = this._maxDistance = distance; - }, - - _updateEvent: function(type, point, minDistance, maxDistance, start, - needsChange, matchMaxDistance) { - if (!start) { - if (minDistance != null || maxDistance != null) { - var minDist = minDistance != null ? minDistance : 0, - vector = point.subtract(this._point), - distance = vector.getLength(); - if (distance < minDist) - return false; - if (maxDistance != null && maxDistance != 0) { - if (distance > maxDistance) { - point = this._point.add(vector.normalize(maxDistance)); - } else if (matchMaxDistance) { - return false; - } - } - } - if (needsChange && point.equals(this._point)) - return false; - } - this._lastPoint = start && type == 'mousemove' ? point : this._point; - this._point = point; - switch (type) { - case 'mousedown': - this._lastPoint = this._downPoint; - this._downPoint = this._point; - this._downCount++; - break; - case 'mouseup': - this._lastPoint = this._downPoint; - break; - } - this._count = start ? 0 : this._count + 1; - return true; - }, - - _fireEvent: function(type, event) { - var sets = paper.project._removeSets; - if (sets) { - if (type === 'mouseup') - sets.mousedrag = null; - var set = sets[type]; - if (set) { - for (var id in set) { - var item = set[id]; - for (var key in sets) { - var other = sets[key]; - if (other && other != set) - delete other[item._id]; - } - item.remove(); - } - sets[type] = null; - } - } - return this.responds(type) - && this.emit(type, new ToolEvent(this, type, event)); - }, - - _handleEvent: function(type, point, event) { - paper = this._scope; - var called = false; - switch (type) { - case 'mousedown': - this._updateEvent(type, point, null, null, true, false, false); - called = this._fireEvent(type, event); - break; - case 'mousedrag': - var needsChange = false, - matchMaxDistance = false; - while (this._updateEvent(type, point, this.minDistance, - this.maxDistance, false, needsChange, matchMaxDistance)) { - called = this._fireEvent(type, event) || called; - needsChange = true; - matchMaxDistance = true; - } - break; - case 'mouseup': - if (!point.equals(this._point) - && this._updateEvent('mousedrag', point, this.minDistance, - this.maxDistance, false, false, false)) { - called = this._fireEvent('mousedrag', event); - } - this._updateEvent(type, point, null, this.maxDistance, false, - false, false); - called = this._fireEvent(type, event) || called; - this._updateEvent(type, point, null, null, true, false, false); - this._firstMove = true; - break; - case 'mousemove': - while (this._updateEvent(type, point, this.minDistance, - this.maxDistance, this._firstMove, true, false)) { - called = this._fireEvent(type, event) || called; - this._firstMove = false; - } - break; - } - if (called) - event.preventDefault(); - return called; - } - -}); - -var Http = { - request: function(method, url, callback, async) { - async = (async === undefined) ? true : async; - var xhr = new (window.ActiveXObject || XMLHttpRequest)( - 'Microsoft.XMLHTTP'); - xhr.open(method.toUpperCase(), url, async); - if ('overrideMimeType' in xhr) - xhr.overrideMimeType('text/plain'); - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var status = xhr.status; - if (status === 0 || status === 200) { - callback.call(xhr, xhr.responseText); - } else { - throw new Error('Could not load ' + url + ' (Error ' - + status + ')'); - } - } - }; - return xhr.send(null); - } -}; - -var CanvasProvider = { - canvases: [], - - getCanvas: function(width, height) { - var canvas, - clear = true; - if (typeof width === 'object') { - height = width.height; - width = width.width; - } - if (this.canvases.length) { - canvas = this.canvases.pop(); - } else { - canvas = document.createElement('canvas'); - } - var ctx = canvas.getContext('2d'); - if (canvas.width === width && canvas.height === height) { - if (clear) - ctx.clearRect(0, 0, width + 1, height + 1); - } else { - canvas.width = width; - canvas.height = height; - } - ctx.save(); - return canvas; - }, - - getContext: function(width, height) { - return this.getCanvas(width, height).getContext('2d'); - }, - - release: function(obj) { - var canvas = obj.canvas ? obj.canvas : obj; - canvas.getContext('2d').restore(); - this.canvases.push(canvas); - } -}; - -var BlendMode = new function() { - var min = Math.min, - max = Math.max, - abs = Math.abs, - sr, sg, sb, sa, - br, bg, bb, ba, - dr, dg, db; - - function getLum(r, g, b) { - return 0.2989 * r + 0.587 * g + 0.114 * b; - } - - function setLum(r, g, b, l) { - var d = l - getLum(r, g, b); - dr = r + d; - dg = g + d; - db = b + d; - var l = getLum(dr, dg, db), - mn = min(dr, dg, db), - mx = max(dr, dg, db); - if (mn < 0) { - var lmn = l - mn; - dr = l + (dr - l) * l / lmn; - dg = l + (dg - l) * l / lmn; - db = l + (db - l) * l / lmn; - } - if (mx > 255) { - var ln = 255 - l, - mxl = mx - l; - dr = l + (dr - l) * ln / mxl; - dg = l + (dg - l) * ln / mxl; - db = l + (db - l) * ln / mxl; - } - } - - function getSat(r, g, b) { - return max(r, g, b) - min(r, g, b); - } - - function setSat(r, g, b, s) { - var col = [r, g, b], - mx = max(r, g, b), - mn = min(r, g, b), - md; - mn = mn === r ? 0 : mn === g ? 1 : 2; - mx = mx === r ? 0 : mx === g ? 1 : 2; - md = min(mn, mx) === 0 ? max(mn, mx) === 1 ? 2 : 1 : 0; - if (col[mx] > col[mn]) { - col[md] = (col[md] - col[mn]) * s / (col[mx] - col[mn]); - col[mx] = s; - } else { - col[md] = col[mx] = 0; - } - col[mn] = 0; - dr = col[0]; - dg = col[1]; - db = col[2]; - } - - var modes = { - multiply: function() { - dr = br * sr / 255; - dg = bg * sg / 255; - db = bb * sb / 255; - }, - - screen: function() { - dr = br + sr - (br * sr / 255); - dg = bg + sg - (bg * sg / 255); - db = bb + sb - (bb * sb / 255); - }, - - overlay: function() { - dr = br < 128 ? 2 * br * sr / 255 : 255 - 2 * (255 - br) * (255 - sr) / 255; - dg = bg < 128 ? 2 * bg * sg / 255 : 255 - 2 * (255 - bg) * (255 - sg) / 255; - db = bb < 128 ? 2 * bb * sb / 255 : 255 - 2 * (255 - bb) * (255 - sb) / 255; - }, - - 'soft-light': function() { - var t = sr * br / 255; - dr = t + br * (255 - (255 - br) * (255 - sr) / 255 - t) / 255; - t = sg * bg / 255; - dg = t + bg * (255 - (255 - bg) * (255 - sg) / 255 - t) / 255; - t = sb * bb / 255; - db = t + bb * (255 - (255 - bb) * (255 - sb) / 255 - t) / 255; - }, - - 'hard-light': function() { - dr = sr < 128 ? 2 * sr * br / 255 : 255 - 2 * (255 - sr) * (255 - br) / 255; - dg = sg < 128 ? 2 * sg * bg / 255 : 255 - 2 * (255 - sg) * (255 - bg) / 255; - db = sb < 128 ? 2 * sb * bb / 255 : 255 - 2 * (255 - sb) * (255 - bb) / 255; - }, - - 'color-dodge': function() { - dr = br === 0 ? 0 : sr === 255 ? 255 : min(255, 255 * br / (255 - sr)); - dg = bg === 0 ? 0 : sg === 255 ? 255 : min(255, 255 * bg / (255 - sg)); - db = bb === 0 ? 0 : sb === 255 ? 255 : min(255, 255 * bb / (255 - sb)); - }, - - 'color-burn': function() { - dr = br === 255 ? 255 : sr === 0 ? 0 : max(0, 255 - (255 - br) * 255 / sr); - dg = bg === 255 ? 255 : sg === 0 ? 0 : max(0, 255 - (255 - bg) * 255 / sg); - db = bb === 255 ? 255 : sb === 0 ? 0 : max(0, 255 - (255 - bb) * 255 / sb); - }, - - darken: function() { - dr = br < sr ? br : sr; - dg = bg < sg ? bg : sg; - db = bb < sb ? bb : sb; - }, - - lighten: function() { - dr = br > sr ? br : sr; - dg = bg > sg ? bg : sg; - db = bb > sb ? bb : sb; - }, - - difference: function() { - dr = br - sr; - if (dr < 0) - dr = -dr; - dg = bg - sg; - if (dg < 0) - dg = -dg; - db = bb - sb; - if (db < 0) - db = -db; - }, - - exclusion: function() { - dr = br + sr * (255 - br - br) / 255; - dg = bg + sg * (255 - bg - bg) / 255; - db = bb + sb * (255 - bb - bb) / 255; - }, - - hue: function() { - setSat(sr, sg, sb, getSat(br, bg, bb)); - setLum(dr, dg, db, getLum(br, bg, bb)); - }, - - saturation: function() { - setSat(br, bg, bb, getSat(sr, sg, sb)); - setLum(dr, dg, db, getLum(br, bg, bb)); - }, - - luminosity: function() { - setLum(br, bg, bb, getLum(sr, sg, sb)); - }, - - color: function() { - setLum(sr, sg, sb, getLum(br, bg, bb)); - }, - - add: function() { - dr = min(br + sr, 255); - dg = min(bg + sg, 255); - db = min(bb + sb, 255); - }, - - subtract: function() { - dr = max(br - sr, 0); - dg = max(bg - sg, 0); - db = max(bb - sb, 0); - }, - - average: function() { - dr = (br + sr) / 2; - dg = (bg + sg) / 2; - db = (bb + sb) / 2; - }, - - negation: function() { - dr = 255 - abs(255 - sr - br); - dg = 255 - abs(255 - sg - bg); - db = 255 - abs(255 - sb - bb); - } - }; - - var nativeModes = this.nativeModes = Base.each([ - 'source-over', 'source-in', 'source-out', 'source-atop', - 'destination-over', 'destination-in', 'destination-out', - 'destination-atop', 'lighter', 'darker', 'copy', 'xor' - ], function(mode) { - this[mode] = true; - }, {}); - - var ctx = CanvasProvider.getContext(1, 1); - Base.each(modes, function(func, mode) { - var darken = mode === 'darken', - ok = false; - ctx.save(); - try { - ctx.fillStyle = darken ? '#300' : '#a00'; - ctx.fillRect(0, 0, 1, 1); - ctx.globalCompositeOperation = mode; - if (ctx.globalCompositeOperation === mode) { - ctx.fillStyle = darken ? '#a00' : '#300'; - ctx.fillRect(0, 0, 1, 1); - ok = ctx.getImageData(0, 0, 1, 1).data[0] !== darken ? 170 : 51; - } - } catch (e) {} - ctx.restore(); - nativeModes[mode] = ok; - }); - CanvasProvider.release(ctx); - - this.process = function(mode, srcContext, dstContext, alpha, offset) { - var srcCanvas = srcContext.canvas, - normal = mode === 'normal'; - if (normal || nativeModes[mode]) { - dstContext.save(); - dstContext.setTransform(1, 0, 0, 1, 0, 0); - dstContext.globalAlpha = alpha; - if (!normal) - dstContext.globalCompositeOperation = mode; - dstContext.drawImage(srcCanvas, offset.x, offset.y); - dstContext.restore(); - } else { - var process = modes[mode]; - if (!process) - return; - var dstData = dstContext.getImageData(offset.x, offset.y, - srcCanvas.width, srcCanvas.height), - dst = dstData.data, - src = srcContext.getImageData(0, 0, - srcCanvas.width, srcCanvas.height).data; - for (var i = 0, l = dst.length; i < l; i += 4) { - sr = src[i]; - br = dst[i]; - sg = src[i + 1]; - bg = dst[i + 1]; - sb = src[i + 2]; - bb = dst[i + 2]; - sa = src[i + 3]; - ba = dst[i + 3]; - process(); - var a1 = sa * alpha / 255, - a2 = 1 - a1; - dst[i] = a1 * dr + a2 * br; - dst[i + 1] = a1 * dg + a2 * bg; - dst[i + 2] = a1 * db + a2 * bb; - dst[i + 3] = sa * alpha + a2 * ba; - } - dstContext.putImageData(dstData, offset.x, offset.y); - } - }; -}; - -var SVGStyles = Base.each({ - fillColor: ['fill', 'color'], - strokeColor: ['stroke', 'color'], - strokeWidth: ['stroke-width', 'number'], - strokeCap: ['stroke-linecap', 'string'], - strokeJoin: ['stroke-linejoin', 'string'], - strokeScaling: ['vector-effect', 'lookup', { - true: 'none', - false: 'non-scaling-stroke' - }, function(item, value) { - return !value - && (item instanceof PathItem - || item instanceof Shape - || item instanceof TextItem); - }], - miterLimit: ['stroke-miterlimit', 'number'], - dashArray: ['stroke-dasharray', 'array'], - dashOffset: ['stroke-dashoffset', 'number'], - fontFamily: ['font-family', 'string'], - fontWeight: ['font-weight', 'string'], - fontSize: ['font-size', 'number'], - justification: ['text-anchor', 'lookup', { - left: 'start', - center: 'middle', - right: 'end' - }], - opacity: ['opacity', 'number'], - blendMode: ['mix-blend-mode', 'string'] -}, function(entry, key) { - var part = Base.capitalize(key), - lookup = entry[2]; - this[key] = { - type: entry[1], - property: key, - attribute: entry[0], - toSVG: lookup, - fromSVG: lookup && Base.each(lookup, function(value, name) { - this[value] = name; - }, {}), - exportFilter: entry[3], - get: 'get' + part, - set: 'set' + part - }; -}, {}); - -var SVGNamespaces = { - href: 'http://www.w3.org/1999/xlink', - xlink: 'http://www.w3.org/2000/xmlns' -}; - -new function() { - var formatter; - - function setAttributes(node, attrs) { - for (var key in attrs) { - var val = attrs[key], - namespace = SVGNamespaces[key]; - if (typeof val === 'number') - val = formatter.number(val); - if (namespace) { - node.setAttributeNS(namespace, key, val); - } else { - node.setAttribute(key, val); - } - } - return node; - } - - function createElement(tag, attrs) { - return setAttributes( - document.createElementNS('http://www.w3.org/2000/svg', tag), attrs); - } - - function getTransform(matrix, coordinates, center) { - var attrs = new Base(), - trans = matrix.getTranslation(); - if (coordinates) { - matrix = matrix.shiftless(); - var point = matrix._inverseTransform(trans); - attrs[center ? 'cx' : 'x'] = point.x; - attrs[center ? 'cy' : 'y'] = point.y; - trans = null; - } - if (!matrix.isIdentity()) { - var decomposed = matrix.decompose(); - if (decomposed && !decomposed.shearing) { - var parts = [], - angle = decomposed.rotation, - scale = decomposed.scaling; - if (trans && !trans.isZero()) - parts.push('translate(' + formatter.point(trans) + ')'); - if (!Numerical.isZero(scale.x - 1) - || !Numerical.isZero(scale.y - 1)) - parts.push('scale(' + formatter.point(scale) +')'); - if (angle) - parts.push('rotate(' + formatter.number(angle) + ')'); - attrs.transform = parts.join(' '); - } else { - attrs.transform = 'matrix(' + matrix.getValues().join(',') + ')'; - } - } - return attrs; - } - - function exportGroup(item, options) { - var attrs = getTransform(item._matrix), - children = item._children; - var node = createElement('g', attrs); - for (var i = 0, l = children.length; i < l; i++) { - var child = children[i]; - var childNode = exportSVG(child, options); - if (childNode) { - if (child.isClipMask()) { - var clip = createElement('clipPath'); - clip.appendChild(childNode); - setDefinition(child, clip, 'clip'); - setAttributes(node, { - 'clip-path': 'url(#' + clip.id + ')' - }); - } else { - node.appendChild(childNode); - } - } - } - return node; - } - - function exportRaster(item, options) { - var attrs = getTransform(item._matrix, true), - size = item.getSize(), - image = item.getImage(); - attrs.x -= size.width / 2; - attrs.y -= size.height / 2; - attrs.width = size.width; - attrs.height = size.height; - attrs.href = options.embedImages === false && image && image.src - || item.toDataURL(); - return createElement('image', attrs); - } - - function exportPath(item, options) { - var matchShapes = options.matchShapes; - if (matchShapes) { - var shape = item.toShape(false); - if (shape) - return exportShape(shape, options); - } - var segments = item._segments, - type, - attrs = getTransform(item._matrix); - if (segments.length === 0) - return null; - if (matchShapes && !item.hasHandles()) { - if (segments.length >= 3) { - type = item._closed ? 'polygon' : 'polyline'; - var parts = []; - for(var i = 0, l = segments.length; i < l; i++) - parts.push(formatter.point(segments[i]._point)); - attrs.points = parts.join(' '); - } else { - type = 'line'; - var first = segments[0]._point, - last = segments[segments.length - 1]._point; - attrs.set({ - x1: first.x, - y1: first.y, - x2: last.x, - y2: last.y - }); - } - } else { - type = 'path'; - attrs.d = item.getPathData(null, options.precision); - } - return createElement(type, attrs); - } - - function exportShape(item) { - var type = item._type, - radius = item._radius, - attrs = getTransform(item._matrix, true, type !== 'rectangle'); - if (type === 'rectangle') { - type = 'rect'; - var size = item._size, - width = size.width, - height = size.height; - attrs.x -= width / 2; - attrs.y -= height / 2; - attrs.width = width; - attrs.height = height; - if (radius.isZero()) - radius = null; - } - if (radius) { - if (type === 'circle') { - attrs.r = radius; - } else { - attrs.rx = radius.width; - attrs.ry = radius.height; - } - } - return createElement(type, attrs); - } - - function exportCompoundPath(item, options) { - var attrs = getTransform(item._matrix); - var data = item.getPathData(null, options.precision); - if (data) - attrs.d = data; - return createElement('path', attrs); - } - - function exportPlacedSymbol(item, options) { - var attrs = getTransform(item._matrix, true), - symbol = item.getSymbol(), - symbolNode = getDefinition(symbol, 'symbol'), - definition = symbol.getDefinition(), - bounds = definition.getBounds(); - if (!symbolNode) { - symbolNode = createElement('symbol', { - viewBox: formatter.rectangle(bounds) - }); - symbolNode.appendChild(exportSVG(definition, options)); - setDefinition(symbol, symbolNode, 'symbol'); - } - attrs.href = '#' + symbolNode.id; - attrs.x += bounds.x; - attrs.y += bounds.y; - attrs.width = formatter.number(bounds.width); - attrs.height = formatter.number(bounds.height); - attrs.overflow = 'visible'; - return createElement('use', attrs); - } - - function exportGradient(color) { - var gradientNode = getDefinition(color, 'color'); - if (!gradientNode) { - var gradient = color.getGradient(), - radial = gradient._radial, - origin = color.getOrigin().transform(), - destination = color.getDestination().transform(), - attrs; - if (radial) { - attrs = { - cx: origin.x, - cy: origin.y, - r: origin.getDistance(destination) - }; - var highlight = color.getHighlight(); - if (highlight) { - highlight = highlight.transform(); - attrs.fx = highlight.x; - attrs.fy = highlight.y; - } - } else { - attrs = { - x1: origin.x, - y1: origin.y, - x2: destination.x, - y2: destination.y - }; - } - attrs.gradientUnits = 'userSpaceOnUse'; - gradientNode = createElement( - (radial ? 'radial' : 'linear') + 'Gradient', attrs); - var stops = gradient._stops; - for (var i = 0, l = stops.length; i < l; i++) { - var stop = stops[i], - stopColor = stop._color, - alpha = stopColor.getAlpha(); - attrs = { - offset: stop._rampPoint, - 'stop-color': stopColor.toCSS(true) - }; - if (alpha < 1) - attrs['stop-opacity'] = alpha; - gradientNode.appendChild(createElement('stop', attrs)); - } - setDefinition(color, gradientNode, 'color'); - } - return 'url(#' + gradientNode.id + ')'; - } - - function exportText(item) { - var node = createElement('text', getTransform(item._matrix, true)); - node.textContent = item._content; - return node; - } - - var exporters = { - Group: exportGroup, - Layer: exportGroup, - Raster: exportRaster, - Path: exportPath, - Shape: exportShape, - CompoundPath: exportCompoundPath, - PlacedSymbol: exportPlacedSymbol, - PointText: exportText - }; - - function applyStyle(item, node, isRoot) { - var attrs = {}, - parent = !isRoot && item.getParent(); - - if (item._name != null) - attrs.id = item._name; - - Base.each(SVGStyles, function(entry) { - var get = entry.get, - type = entry.type, - value = item[get](); - if (entry.exportFilter - ? entry.exportFilter(item, value) - : !parent || !Base.equals(parent[get](), value)) { - if (type === 'color' && value != null) { - var alpha = value.getAlpha(); - if (alpha < 1) - attrs[entry.attribute + '-opacity'] = alpha; - } - attrs[entry.attribute] = value == null - ? 'none' - : type === 'number' - ? formatter.number(value) - : type === 'color' - ? value.gradient - ? exportGradient(value, item) - : value.toCSS(true) - : type === 'array' - ? value.join(',') - : type === 'lookup' - ? entry.toSVG[value] - : value; - } - }); - - if (attrs.opacity === 1) - delete attrs.opacity; - - if (!item._visible) - attrs.visibility = 'hidden'; - - return setAttributes(node, attrs); - } - - var definitions; - function getDefinition(item, type) { - if (!definitions) - definitions = { ids: {}, svgs: {} }; - return item && definitions.svgs[type + '-' + item._id]; - } - - function setDefinition(item, node, type) { - if (!definitions) - getDefinition(); - var id = definitions.ids[type] = (definitions.ids[type] || 0) + 1; - node.id = type + '-' + id; - definitions.svgs[type + '-' + item._id] = node; - } - - function exportDefinitions(node, options) { - var svg = node, - defs = null; - if (definitions) { - svg = node.nodeName.toLowerCase() === 'svg' && node; - for (var i in definitions.svgs) { - if (!defs) { - if (!svg) { - svg = createElement('svg'); - svg.appendChild(node); - } - defs = svg.insertBefore(createElement('defs'), - svg.firstChild); - } - defs.appendChild(definitions.svgs[i]); - } - definitions = null; - } - return options.asString - ? new XMLSerializer().serializeToString(svg) - : svg; - } - - function exportSVG(item, options, isRoot) { - var exporter = exporters[item._class], - node = exporter && exporter(item, options); - if (node) { - var onExport = options.onExport; - if (onExport) - node = onExport(item, node, options) || node; - var data = JSON.stringify(item._data); - if (data && data !== '{}' && data !== 'null') - node.setAttribute('data-paper-data', data); - } - return node && applyStyle(item, node, isRoot); - } - - function setOptions(options) { - if (!options) - options = {}; - formatter = new Formatter(options.precision); - return options; - } - - Item.inject({ - exportSVG: function(options) { - options = setOptions(options); - return exportDefinitions(exportSVG(this, options, true), options); - } - }); - - Project.inject({ - exportSVG: function(options) { - options = setOptions(options); - var layers = this.layers, - view = this.getView(), - size = view.getViewSize(), - node = createElement('svg', { - x: 0, - y: 0, - width: size.width, - height: size.height, - version: '1.1', - xmlns: 'http://www.w3.org/2000/svg', - 'xmlns:xlink': 'http://www.w3.org/1999/xlink' - }), - parent = node, - matrix = view._matrix; - if (!matrix.isIdentity()) - parent = node.appendChild( - createElement('g', getTransform(matrix))); - for (var i = 0, l = layers.length; i < l; i++) - parent.appendChild(exportSVG(layers[i], options, true)); - return exportDefinitions(node, options); - } - }); -}; - -new function() { - - function getValue(node, name, isString, allowNull) { - var namespace = SVGNamespaces[name], - value = namespace - ? node.getAttributeNS(namespace, name) - : node.getAttribute(name); - if (value === 'null') - value = null; - return value == null - ? allowNull - ? null - : isString - ? '' - : 0 - : isString - ? value - : parseFloat(value); - } - - function getPoint(node, x, y, allowNull) { - x = getValue(node, x, false, allowNull); - y = getValue(node, y, false, allowNull); - return allowNull && (x == null || y == null) ? null - : new Point(x, y); - } - - function getSize(node, w, h, allowNull) { - w = getValue(node, w, false, allowNull); - h = getValue(node, h, false, allowNull); - return allowNull && (w == null || h == null) ? null - : new Size(w, h); - } - - function convertValue(value, type, lookup) { - return value === 'none' - ? null - : type === 'number' - ? parseFloat(value) - : type === 'array' - ? value ? value.split(/[\s,]+/g).map(parseFloat) : [] - : type === 'color' - ? getDefinition(value) || value - : type === 'lookup' - ? lookup[value] - : value; - } - - function importGroup(node, type, options, isRoot) { - var nodes = node.childNodes, - isClip = type === 'clippath', - item = new Group(), - project = item._project, - currentStyle = project._currentStyle, - children = []; - if (!isClip) { - item = applyAttributes(item, node, isRoot); - project._currentStyle = item._style.clone(); - } - if (isRoot) { - var defs = node.querySelectorAll('defs'); - for (var i = 0, l = defs.length; i < l; i++) { - importSVG(defs[i], options, false); - } - } - for (var i = 0, l = nodes.length; i < l; i++) { - var childNode = nodes[i], - child; - if (childNode.nodeType === 1 - && childNode.nodeName.toLowerCase() !== 'defs' - && (child = importSVG(childNode, options, false)) - && !(child instanceof Symbol)) - children.push(child); - } - item.addChildren(children); - if (isClip) - item = applyAttributes(item.reduce(), node, isRoot); - project._currentStyle = currentStyle; - if (isClip || type === 'defs') { - item.remove(); - item = null; - } - return item; - } - - function importPoly(node, type) { - var coords = node.getAttribute('points').match( - /[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g), - points = []; - for (var i = 0, l = coords.length; i < l; i += 2) - points.push(new Point( - parseFloat(coords[i]), - parseFloat(coords[i + 1]))); - var path = new Path(points); - if (type === 'polygon') - path.closePath(); - return path; - } - - function importPath(node) { - var data = node.getAttribute('d'), - param = { pathData: data }; - return (data.match(/m/gi) || []).length > 1 || /z\S+/i.test(data) - ? new CompoundPath(param) - : new Path(param); - } - - function importGradient(node, type) { - var id = (getValue(node, 'href', true) || '').substring(1), - isRadial = type === 'radialgradient', - gradient; - if (id) { - gradient = definitions[id].getGradient(); - } else { - var nodes = node.childNodes, - stops = []; - for (var i = 0, l = nodes.length; i < l; i++) { - var child = nodes[i]; - if (child.nodeType === 1) - stops.push(applyAttributes(new GradientStop(), child)); - } - gradient = new Gradient(stops, isRadial); - } - var origin, destination, highlight; - if (isRadial) { - origin = getPoint(node, 'cx', 'cy'); - destination = origin.add(getValue(node, 'r'), 0); - highlight = getPoint(node, 'fx', 'fy', true); - } else { - origin = getPoint(node, 'x1', 'y1'); - destination = getPoint(node, 'x2', 'y2'); - } - applyAttributes( - new Color(gradient, origin, destination, highlight), node); - return null; - } - - var importers = { - '#document': function (node, type, options, isRoot) { - var nodes = node.childNodes; - for (var i = 0, l = nodes.length; i < l; i++) { - var child = nodes[i]; - if (child.nodeType === 1) { - var next = child.nextSibling; - document.body.appendChild(child); - var item = importSVG(child, options, isRoot); - if (next) { - node.insertBefore(child, next); - } else { - node.appendChild(child); - } - return item; - } - } - }, - g: importGroup, - svg: importGroup, - clippath: importGroup, - polygon: importPoly, - polyline: importPoly, - path: importPath, - lineargradient: importGradient, - radialgradient: importGradient, - - image: function (node) { - var raster = new Raster(getValue(node, 'href', true)); - raster.on('load', function() { - var size = getSize(node, 'width', 'height'); - this.setSize(size); - var center = this._matrix._transformPoint( - getPoint(node, 'x', 'y').add(size.divide(2))); - this.translate(center); - }); - return raster; - }, - - symbol: function(node, type, options, isRoot) { - return new Symbol(importGroup(node, type, options, isRoot), true); - }, - - defs: importGroup, - - use: function(node) { - var id = (getValue(node, 'href', true) || '').substring(1), - definition = definitions[id], - point = getPoint(node, 'x', 'y'); - return definition - ? definition instanceof Symbol - ? definition.place(point) - : definition.clone().translate(point) - : null; - }, - - circle: function(node) { - return new Shape.Circle(getPoint(node, 'cx', 'cy'), - getValue(node, 'r')); - }, - - ellipse: function(node) { - return new Shape.Ellipse({ - center: getPoint(node, 'cx', 'cy'), - radius: getSize(node, 'rx', 'ry') - }); - }, - - rect: function(node) { - var point = getPoint(node, 'x', 'y'), - size = getSize(node, 'width', 'height'), - radius = getSize(node, 'rx', 'ry'); - return new Shape.Rectangle(new Rectangle(point, size), radius); - }, - - line: function(node) { - return new Path.Line(getPoint(node, 'x1', 'y1'), - getPoint(node, 'x2', 'y2')); - }, - - text: function(node) { - var text = new PointText(getPoint(node, 'x', 'y') - .add(getPoint(node, 'dx', 'dy'))); - text.setContent(node.textContent.trim() || ''); - return text; - } - }; - - function applyTransform(item, value, name, node) { - var transforms = (node.getAttribute(name) || '').split(/\)\s*/g), - matrix = new Matrix(); - for (var i = 0, l = transforms.length; i < l; i++) { - var transform = transforms[i]; - if (!transform) - break; - var parts = transform.split(/\(\s*/), - command = parts[0], - v = parts[1].split(/[\s,]+/g); - for (var j = 0, m = v.length; j < m; j++) - v[j] = parseFloat(v[j]); - switch (command) { - case 'matrix': - matrix.concatenate( - new Matrix(v[0], v[1], v[2], v[3], v[4], v[5])); - break; - case 'rotate': - matrix.rotate(v[0], v[1], v[2]); - break; - case 'translate': - matrix.translate(v[0], v[1]); - break; - case 'scale': - matrix.scale(v); - break; - case 'skewX': - matrix.skew(v[0], 0); - break; - case 'skewY': - matrix.skew(0, v[0]); - break; - } - } - item.transform(matrix); - } - - function applyOpacity(item, value, name) { - var color = item[name === 'fill-opacity' ? 'getFillColor' - : 'getStrokeColor'](); - if (color) - color.setAlpha(parseFloat(value)); - } - - var attributes = Base.set(Base.each(SVGStyles, function(entry) { - this[entry.attribute] = function(item, value) { - item[entry.set](convertValue(value, entry.type, entry.fromSVG)); - if (entry.type === 'color' && item instanceof Shape) { - var color = item[entry.get](); - if (color) - color.transform(new Matrix().translate( - item.getPosition(true).negate())); - } - }; - }, {}), { - id: function(item, value) { - definitions[value] = item; - if (item.setName) - item.setName(value); - }, - - 'clip-path': function(item, value) { - var clip = getDefinition(value); - if (clip) { - clip = clip.clone(); - clip.setClipMask(true); - if (item instanceof Group) { - item.insertChild(0, clip); - } else { - return new Group(clip, item); - } - } - }, - - gradientTransform: applyTransform, - transform: applyTransform, - - 'fill-opacity': applyOpacity, - 'stroke-opacity': applyOpacity, - - visibility: function(item, value) { - item.setVisible(value === 'visible'); - }, - - display: function(item, value) { - item.setVisible(value !== null); - }, - - 'stop-color': function(item, value) { - if (item.setColor) - item.setColor(value); - }, - - 'stop-opacity': function(item, value) { - if (item._color) - item._color.setAlpha(parseFloat(value)); - }, - - offset: function(item, value) { - var percentage = value.match(/(.*)%$/); - item.setRampPoint(percentage - ? percentage[1] / 100 - : parseFloat(value)); - }, - - viewBox: function(item, value, name, node, styles) { - var rect = new Rectangle(convertValue(value, 'array')), - size = getSize(node, 'width', 'height', true); - if (item instanceof Group) { - var scale = size ? rect.getSize().divide(size) : 1, - matrix = new Matrix().translate(rect.getPoint()).scale(scale); - item.transform(matrix.inverted()); - } else if (item instanceof Symbol) { - if (size) - rect.setSize(size); - var clip = getAttribute(node, 'overflow', styles) != 'visible', - group = item._definition; - if (clip && !rect.contains(group.getBounds())) { - clip = new Shape.Rectangle(rect).transform(group._matrix); - clip.setClipMask(true); - group.addChild(clip); - } - } - } - }); - - function getAttribute(node, name, styles) { - var attr = node.attributes[name], - value = attr && attr.value; - if (!value) { - var style = Base.camelize(name); - value = node.style[style]; - if (!value && styles.node[style] !== styles.parent[style]) - value = styles.node[style]; - } - return !value - ? undefined - : value === 'none' - ? null - : value; - } - - function applyAttributes(item, node, isRoot) { - var styles = { - node: DomElement.getStyles(node) || {}, - parent: !isRoot && DomElement.getStyles(node.parentNode) || {} - }; - Base.each(attributes, function(apply, name) { - var value = getAttribute(node, name, styles); - if (value !== undefined) - item = Base.pick(apply(item, value, name, node, styles), item); - }); - return item; - } - - var definitions = {}; - function getDefinition(value) { - var match = value && value.match(/\((?:#|)([^)']+)/); - return match && definitions[match[1]]; - } - - function importSVG(source, options, isRoot) { - if (!source) - return null; - if (!options) { - options = {}; - } else if (typeof options === 'function') { - options = { onLoad: options }; - } - - var node = source, - scope = paper; - - function onLoadCallback(svg) { - paper = scope; - var item = importSVG(svg, options, isRoot), - onLoad = options.onLoad, - view = scope.project && scope.getView(); - if (onLoad) - onLoad.call(this, item); - view.update(); - } - - if (isRoot) { - if (typeof source === 'string' && !/^.*</.test(source)) { - node = document.getElementById(source); - if (node) { - source = null; - } else { - return Http.request('get', source, onLoadCallback); - } - } else if (typeof File !== 'undefined' && source instanceof File) { - var reader = new FileReader(); - reader.onload = function() { - onLoadCallback(reader.result); - }; - return reader.readAsText(source); - } - } - - if (typeof source === 'string') - node = new DOMParser().parseFromString(source, 'image/svg+xml'); - if (!node.nodeName) - throw new Error('Unsupported SVG source: ' + source); - var type = node.nodeName.toLowerCase(), - importer = importers[type], - item, - data = node.getAttribute && node.getAttribute('data-paper-data'), - settings = scope.settings, - applyMatrix = settings.applyMatrix; - settings.applyMatrix = false; - item = importer && importer(node, type, options, isRoot) || null; - settings.applyMatrix = applyMatrix; - if (item) { - if (type !== '#document' && !(item instanceof Group)) - item = applyAttributes(item, node, isRoot); - var onImport = options.onImport; - if (onImport) - item = onImport(node, item, options) || item; - if (options.expandShapes && item instanceof Shape) { - item.remove(); - item = item.toPath(); - } - if (data) - item._data = JSON.parse(data); - } - if (isRoot) { - definitions = {}; - if (item && Base.pick(options.applyMatrix, applyMatrix)) - item.matrix.apply(true, true); - } - return item; - } - - Item.inject({ - importSVG: function(node, options) { - return this.addChild(importSVG(node, options, true)); - } - }); - - Project.inject({ - importSVG: function(node, options) { - this.activate(); - return importSVG(node, options, true); - } - }); -}; - -paper = new (PaperScope.inject(Base.exports, { - enumerable: true, - Base: Base, - Numerical: Numerical, - Key: Key -}))(); - -if (true) { - !(__WEBPACK_AMD_DEFINE_FACTORY__ = (paper), - __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? - (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : - __WEBPACK_AMD_DEFINE_FACTORY__), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); -} else if (typeof module === 'object' && module) { - module.exports = paper; -} - -return paper; -}; - - -/***/ }), -/* 110 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var interpolate = __webpack_require__(108); - -var BSplineGraphic = React.createClass({ - displayName: "BSplineGraphic", - componentWillMount: function componentWillMount() { - var _this = this; - - // lots of instance binding, because we want instance binding, not proto/class binding. - this.cvs = undefined; - this.ctx = undefined; - this.key = undefined; - this.keyCode = undefined; - this.mouseX = undefined; - this.mouseY = undefined; - this.isMouseDown = undefined; - this.width = 0; - this.height = 0; - this.activeDistance = 9; - this.points = []; - this.knots = []; - this.weights = []; - this.nodes = []; - this.cp = undefined; - this.dx = undefined; - this.dy = undefined; - // and sketch value binding. - var sketch = this.props.sketch; - Object.keys(sketch).forEach(function (fn) { - _this[fn] = sketch[fn]; - // rebind "this" if we're dealing with a function - if (typeof _this[fn] === "function") { - _this[fn] = _this[fn].bind(_this); - } - }); - }, - - - render: function render() { - return React.createElement("canvas", { className: "bspline-graphic", ref: "sketch" }); - }, - - keydownlisten: function keydownlisten(e) { - this.setKeyboardValues(e);this.keyDown(); - }, - keyuplisten: function keyuplisten(e) { - this.setKeyboardValues(e);this.keyUp(); - }, - keypresslisten: function keypresslisten(e) { - this.setKeyboardValues(e);this.keyPressed(); - }, - mousedownlisten: function mousedownlisten(e) { - this.setMouseValues(e);this.mouseDown(); - }, - mouseuplisten: function mouseuplisten(e) { - this.setMouseValues(e);this.mouseUp(); - }, - mousemovelisten: function mousemovelisten(e) { - this.setMouseValues(e);this.mouseMove();if (this.isMouseDown && this.mouseDrag) { - this.mouseDrag(); - } - }, - wheellissten: function wheellissten(e) { - e.preventDefault();this.scrolled(e.deltaY < 0 ? 1 : -1); - }, - componentDidMount: function componentDidMount() { - var cvs = this.cvs = this.refs.sketch; - // Keyboard event handling - cvs.addEventListener("keydown", this.keydownlisten); - cvs.addEventListener("keyup", this.keyuplisten); - cvs.addEventListener("keypress", this.keypresslisten); - // Mouse event handling - cvs.addEventListener("mousedown", this.mousedownlisten); - cvs.addEventListener("mouseup", this.mouseuplisten); - cvs.addEventListener("mousemove", this.mousemovelisten); - // Scroll event handling - if (this.props.scrolling) { - cvs.addEventListener("wheel", this.wheellissten); - } - // Boom let's go - this.setup(); - }, - componentWillUnmount: function componentWillUnmount() { - var cvs = this.cvs = this.refs.sketch; - cvs.removeEventListener("keydown", this.keydownlisten); - cvs.removeEventListener("keyup", this.keyuplisten); - cvs.removeEventListener("keypress", this.keypresslisten); - cvs.removeEventListener("mousedown", this.mousedownlisten); - cvs.removeEventListener("mouseup", this.mouseuplisten); - cvs.removeEventListener("mousemove", this.mousemovelisten); - if (this.props.scrolling) { - cvs.removeEventListener("wheel", this.wheellissten); - } - }, - - - // base API - - drawCurve: function drawCurve(points) { - points = points || this.points; - var ctx = this.ctx; - var weights = this.weights.length > 0 ? this.weights : false; - ctx.beginPath(); - var p = interpolate(0, this.degree, points, this.knots, weights); - ctx.moveTo(p[0], p[1]); - for (var t = 0.01; t < 1; t += 0.01) { - p = interpolate(t, this.degree, points, this.knots, weights); - ctx.lineTo(p[0], p[1]); - } - p = interpolate(1, this.degree, points, this.knots, weights); - ctx.lineTo(p[0], p[1]); - ctx.stroke(); - ctx.closePath(); - }, - drawKnots: function drawKnots(points) { - var _this2 = this; - - var knots = this.knots; - var weights = this.weights.length > 0 ? this.weights : false; - knots.forEach(function (knot, i) { - if (i < _this2.degree) return; - if (i > knots.length - 1 - _this2.degree) return; - var p = interpolate(knot, _this2.degree, points, knots, weights, false, true); - _this2.circle(p[0], p[1], 3); - }); - }, - - - // FIXME: TODO: these do not seem correct using uniform knots - drawNodes: function drawNodes(points) { - var _this3 = this; - - var i = 0, - p; - this.stroke(150); - this.nodes.forEach(function (node, i) { - try { - p = interpolate(node, _this3.degree, points, _this3.knots, false, false, true); - _this3.line(p[0], p[1], points[i][0], points[i++][1]); - } catch (e) { - console.error(e); - } - }); - }, - - - // FIXME: this doesn't work with a degree change - formKnots: function formKnots(points, open) { - open = open === true ? true : false; - if (!open) return this.formUniformKnots(points); - - var l = points.length, - knots = [], - m = l - this.degree, - i; - - // form the open-uniform knot vector - for (i = 1; i < l - this.degree; i++) { - knots.push(i + this.degree); - } - // add [degree] zeroes at the front - for (i = 0; i <= this.degree; i++) { - knots = [this.degree].concat(knots); - } - // add [degree] max-values to the back - for (i = 0; i <= this.degree; i++) { - knots.push(m + this.degree); - } - - return knots; - }, - formUniformKnots: function formUniformKnots(points) { - var knots = []; - for (var i = this.points.length + this.degree; i >= 0; i--) { - knots.push(i); - } - return knots.reverse(); - }, - formNodes: function formNodes(knots, points) { - var domain = [this.degree, knots.length - 1 - this.degree]; - var nodes = [], - node, - k, - offset; - for (k = 0; k < this.points.length; k++) { - node = 0; - for (offset = 1; offset <= this.degree; offset++) { - node += knots[k + offset]; - } - node /= this.degree; - if (node < knots[domain[0]]) continue; - if (node > knots[domain[1]]) continue; - nodes.push(node); - } - return nodes; - }, - formWeights: function formWeights(points) { - var weights = []; - points.forEach(function (p) { - return weights.push(1); - }); - return weights; - }, - setDegree: function setDegree(d) { - this.degree += d; - this.knots = this.formKnots(this.points); - this.nodes = this.formNodes(this.knots, this.points); - }, - near: function near(p, x, y) { - var dx = p.x - x, - dy = p.y - y, - d = Math.sqrt(dx * dx + dy * dy); - return d < this.activeDistance; - }, - getCurrentPoint: function getCurrentPoint(x, y) { - for (var i = 0; i < this.points.length; i++) { - if (this.near(this.points[i], x, y)) { - return this.points[i]; - } - } - }, - - - // Interaction stuffs - - keyDown: function keyDown() { - if (this.key === 'ArrowUp') { - this.setDegree(1); - } - if (this.key === 'ArrowDown') { - if (this.degree > 1) { - this.setDegree(-1); - } - } - this.redraw(); - }, - keyUp: function keyUp() { - // ... do nothing? - }, - keyPressed: function keyPressed() { - // ... do nothing? - }, - mouseDown: function mouseDown() { - this.isMouseDown = true; - this.cp = this.getCurrentPoint(this.mouseX, this.mouseY); - if (!this.cp) { - this.points.push({ x: this.mouseX, y: this.mouseY }); - this.knots = this.formKnots(this.points); - this.nodes = this.formNodes(this.knots, this.points); - } - this.redraw(); - }, - mouseUp: function mouseUp() { - this.isMouseDown = false; - this.cp = false; - this.redraw(); - }, - mouseDrag: function mouseDrag() { - if (this.cp) { - this.cp.x = this.mouseX; - this.cp.y = this.mouseY; - this.redraw(); - } - }, - mouseMove: function mouseMove() { - // ... do nothing? - }, - scrolled: function scrolled(direction) { - this.cp = this.getCurrentPoint(this.mouseX, this.mouseY); - if (!this.cp) return; - // base case - var pos = this.points.indexOf(this.cp); - if (this.weights.length > pos) { - this.weights[pos] += direction * 0.1; - if (this.weights[pos] < 0) { - this.weights[pos] = 0; - } - } - // possible multiplicity due to "closed" curves - pos = this.points.indexOf(this.cp, pos + 1); - if (pos !== -1 && this.weights.length > pos) { - this.weights[pos] += direction * 0.1; - if (this.weights[pos] < 0) { - this.weights[pos] = 0; - } - } - this.redraw(); - }, - - - // keyboard events - setKeyboardValues: function setKeyboardValues(e) { - if (!e.ctrlKey && !e.metaKey && !e.altKey) { - e.preventDefault(); - } - this.key = e.key; - this.keyCode = e.code; - }, - - - // mouse events - setMouseValues: function setMouseValues(e) { - var brect = this.cvs.getBoundingClientRect(); - this.mouseX = e.clientX - brect.left; - this.mouseY = e.clientY - brect.top; - }, - - - // API stuffs - - size: function size(w, h) { - this.width = w | 0; - this.height = (h || w) | 0; - this.cvs.width = this.width; - this.cvs.height = this.height; - this.ctx = this.cvs.getContext("2d"); - }, - redraw: function redraw() { - this.draw(); - }, - clear: function clear() { - this.ctx.clearRect(0, 0, this.width, this.height); - }, - grid: function grid(spacing) { - spacing = ((spacing || 10) | 0) + 0.5; - this.stroke(200, 200, 220); - for (var x = spacing; x < this.width - 1; x += spacing) { - this.line(x, 0, x, this.height); - } - for (var y = spacing; y < this.height - 1; y += spacing) { - this.line(0, y, this.width, y); - } - }, - circle: function circle(x, y, r) { - var hr = r / 2; - var ctx = this.ctx; - ctx.beginPath(); - ctx.moveTo(x, y); - ctx.arc(x, y, r, 0, Math.PI * 2); - ctx.stroke(); - ctx.closePath(); - }, - line: function line(a, b, c, d) { - var ctx = this.ctx; - ctx.beginPath(); - ctx.moveTo(a, b); - ctx.lineTo(c, d); - ctx.stroke(); - ctx.closePath(); - }, - stroke: function stroke(r, g, b, a) { - if (typeof r === "string") { - return this.ctx.strokeStyle = r; - } - if (g === undefined) { - g = r;b = r; - } - if (a === undefined) { - a = 1; - } - this.ctx.strokeStyle = this.rgba(r, g, b, a); - }, - noStroke: function noStroke() { - this.ctx.strokeStyle = "none"; - }, - fill: function fill(r, g, b, a) { - if (typeof r === "string") { - return this.ctx.fillStyle = r; - } - if (g === undefined) { - g = r;b = r; - } - if (a === undefined) { - a = 1; - } - this.ctx.fillStyle = this.rgba(r, g, b, a); - }, - noFill: function noFill() { - this.ctx.fillStyle = "none"; - }, - rgba: function rgba(r, g, b, a) { - return "rgba(" + r + "," + g + "," + b + "," + a + ")"; - }, - beginPath: function beginPath() { - this.ctx.beginPath();this.bp = true; - }, - vertex: function vertex(x, y) { - if (!this.bp) { - return this.ctx.lineTo(x, y); - } - this.ctx.moveTo(x, y); - this.bp = false; - }, - endPath: function endPath() { - this.ctx.stroke(); - this.ctx.closePath(); - } -}); - -module.exports = BSplineGraphic; - -/***/ }), -/* 111 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var Footer = React.createClass({ - displayName: "Footer", - - - render: function render() { - return React.createElement( - "footer", - { className: "copyright" }, - "This article is © 2011-2016 to me, Mike \"Pomax\" Kamermans, but the text, code, and images are ", - React.createElement( - "a", - { href: "https://github.com/Pomax/bezierinfo/blob/gh-pages/LICENSE.md" }, - "almost no rights reserved" - ), - ". Go do something cool with it!" - ); - } - -}); - -module.exports = Footer; - -/***/ }), -/* 112 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); -var Page = __webpack_require__(117); - -var sectionList = __webpack_require__(41), - sectionMap = function sectionMap(mapping) { - return Object.keys(sectionList).map(mapping); -}, - allSections = sectionMap(function (name, entry) { - var Type = sectionList[name]; - return React.createElement(Type, { key: name, name: name, number: entry }); -}); - -var FullArticle = React.createClass({ - displayName: "FullArticle", - - render: function render() { - return React.createElement( - Page, - null, - allSections - ); - } -}); - -module.exports = FullArticle; - -/***/ }), -/* 113 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var baseClass = { - render: function render() { - return React.createElement( - "figure", - { className: this.props.inline ? "inline" : false }, - React.createElement("canvas", { ref: "canvas", - tabIndex: "0", - style: { - width: this.panelCount * this.defaultWidth + "px", - height: this.defaultHeight + "px" - }, - onMouseDown: this.mouseDown, - onMouseMove: this.mouseMove, - onMouseUp: this.mouseUp, - onClick: this.onClick, - onKeyUp: this.onKeyUp, - onKeyDown: this.onKeyDown, - onKeyPress: this.onKeyPress - }), - React.createElement( - "figcaption", - null, - this.props.title, - " ", - this.props.children - ) - ); - }, - - componentDidMount: function componentDidMount() { - var cvs = this.refs.canvas; - var dpr = this.getPixelRatio(); - cvs.width = this.defaultWidth * dpr; - cvs.height = this.defaultHeight * dpr; - this.cvs = cvs; - var ctx = cvs.getContext("2d"); - this.ctx = ctx; - this.ctx.scale(dpr, dpr); - - if (this.props.paperjs) { - var Paper = this.Paper = __webpack_require__(109); - Paper.setup(cvs); - } - - if (this.props.setup) { - this.props.setup(this); - } - - if (this.props.draw) { - this.props.draw(this, this.curve); - } - - if (this.props.autoplay) { - this.play(); - } - } -}; - -// For some reason we can copy from gfx into base but -// not the other way around, while preserving context. -var gfxObject = __webpack_require__(121); -Object.keys(gfxObject).forEach(function (fname) { - baseClass[fname] = gfxObject[fname]; -}); - -module.exports = React.createClass(baseClass); - -/***/ }), -/* 114 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var Header = React.createClass({ - displayName: 'Header', - - render: function render() { - return React.createElement( - 'header', - null, - React.createElement( - 'h1', - null, - 'A Primer on Bézier Curves' - ), - React.createElement( - 'h2', - null, - 'A free, online book for when you really need to know how to do Bézier things.' - ) - ); - } -}); - -module.exports = Header; - -/***/ }), -/* 115 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var KnotController = React.createClass({ - displayName: 'KnotController', - getInitialState: function getInitialState() { - return { - owner: false, - knots: [] - }; - }, - bindKnots: function bindKnots(owner, knots) { - this.setState({ owner: owner, knots: knots }); - }, - render: function render() { - var _this = this; - - var type = 'range'; - var min = 0; - var max = this.state.knots.length; - var step = 1; - return React.createElement( - 'section', - { className: 'knot-controls' }, - React.createElement( - 'h2', - null, - 'knot values' - ), - this.state.knots.map(function (value, position) { - var props = { - type: type, min: min, max: max, step: step, - value: value, - onChange: function onChange(e) { - var k = _this.state.knots; - k[position] = e.target.value; - _this.setState({ knots: k }, function () { - _this.state.owner.redraw(); - }); - } - }; - return React.createElement( - 'div', - { key: 'knot' + position }, - min, - React.createElement('input', props), - max, - ' (= ', - value, - ')' - ); - }) - ); - } -}); - -module.exports = KnotController; - -/***/ }), -/* 116 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); -var ReactRouter = __webpack_require__(102); -var Link = ReactRouter.Link; - -var sections = __webpack_require__(41); -var sectionPages = Object.keys(sections); - -var SectionHeader = __webpack_require__(69); - -var Navigation = React.createClass({ - displayName: 'Navigation', - - generateNavItem: function generateNavItem(name, entry) { - var Type = sections[name]; - var title = Type.getDefaultProps().title; - var locale = SectionHeader.locale; - if (typeof window !== "undefined" && window.location.toString().indexOf(locale) === -1) { - locale = ''; - } - var fragmentid = (locale ? './' + locale + '/' : '.') + '#' + name; - var link = React.createElement( - 'a', - { href: fragmentid }, - title - ); - if (this.props.fullNav) { - link = React.createElement( - Link, - { to: name }, - title - ); - } - var last = sectionPages.length - 1; - if (entry === last) entry = null; - return React.createElement( - 'li', - { key: name, 'data-number': entry }, - link - ); - }, - - generateNav: function generateNav() { - if (this.props.compact) return null; - - return React.createElement( - 'div', - { ref: 'navigation' }, - React.createElement( - 'navigation', - { className: this.props.compact ? "compact" : null }, - React.createElement( - 'ul', - { className: 'navigation' }, - sectionPages.map(this.generateNavItem) - ) - ) - ); - }, - - render: function render() { - return this.generateNav(); - } -}); - -module.exports = Navigation; - -/***/ }), -/* 117 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var Ribbon = __webpack_require__(119); -var Header = __webpack_require__(114); -var Relatives = __webpack_require__(118); -var LocaleSwitcher = __webpack_require__(123).LocaleSwitcher; -var Navigation = __webpack_require__(116); -var Footer = __webpack_require__(111); - -var Page = React.createClass({ - displayName: "Page", - - renderCompactContent: function renderCompactContent(nav) { - return React.createElement( - "div", - null, - React.createElement(Relatives, { prev: this.props.prev, next: this.props.next, position: "before" }), - this.props.children, - React.createElement(Relatives, { prev: this.props.prev, next: this.props.next, position: "after" }) - ); - }, - - renderCompactRoot: function renderCompactRoot(nav) { - return React.createElement( - "div", - null, - this.props.children, - nav - ); - }, - - renderPageContent: function renderPageContent(nav) { - return React.createElement( - "div", - null, - React.createElement(LocaleSwitcher, null), - nav, - this.props.children - ); - }, - - render: function render() { - var content; - var compact = this.props.compact; - var isRoot = this.props.name === '/'; - var nav = React.createElement(Navigation, { compact: compact && !isRoot }); - - if (compact) { - if (isRoot) { - content = this.renderCompactRoot(nav); - } else { - content = this.renderCompactContent(nav); - } - } else { - content = this.renderPageContent(nav); - } - - return React.createElement( - "div", - null, - React.createElement(Ribbon, null), - React.createElement(Header, null), - content, - React.createElement(Footer, null) - ); - } -}); - -module.exports = Page; - -/***/ }), -/* 118 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); -var ReactRouter = __webpack_require__(102); -var Link = ReactRouter.Link; - -var sections = __webpack_require__(41); -var pageIDs = Object.keys(sections); - -var Relatives = React.createClass({ - displayName: 'Relatives', - getInitialState: function getInitialState() { - var prev = this.props.prev; - if (prev > -1) { - prev = { - to: pageIDs[prev], - title: sections[pageIDs[prev]].getDefaultProps().title - }; - } else { - prev = false; - } - - var next = this.props.next; - if (next < pageIDs.length) { - next = { - to: pageIDs[next], - title: sections[pageIDs[next]].getDefaultProps().title - }; - } else { - next = false; - } - - return { - prev: prev, - next: next - }; - }, - - - render: function render() { - if (!this.props.prev && !this.props.next) return null; - return React.createElement( - 'table', - { className: "relatives " + this.props.position }, - React.createElement( - 'tbody', - null, - React.createElement( - 'tr', - null, - React.createElement( - 'td', - null, - !this.state.prev ? null : React.createElement( - Link, - { className: 'prev', to: this.state.prev.to }, - this.props.prev + ". " + this.state.prev.title - ) - ), - React.createElement( - 'td', - { className: 'toc' }, - React.createElement( - Link, - { to: '/' }, - 'ToC' - ) - ), - React.createElement( - 'td', - null, - !this.state.next ? null : React.createElement( - Link, - { className: 'next', to: this.state.next.to }, - this.props.next + ". " + this.state.next.title - ) - ) - ) - ) - ); - } -}); - -module.exports = Relatives; - -/***/ }), -/* 119 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var Ribbon = React.createClass({ - displayName: "Ribbon", - - getInitialState: function getInitialState() { - return { - href: "http://github.com/pomax/BezierInfo-2" - }; - }, - - render: function render() { - return React.createElement( - "div", - { className: "ribbon" }, - React.createElement("img", { src: "images/ribbon.png", alt: "This page on GitHub", style: { border: "none" }, useMap: "#githubmap", width: "200px", height: "149px" }), - React.createElement( - "map", - { name: "githubmap" }, - React.createElement("area", { shape: "poly", coords: "30,0, 200,0, 200,114", href: this.state.href, alt: "This page on GitHub" }) - ) - ); - } -}); - -module.exports = Ribbon; - -/***/ }), -/* 120 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var WeightController = React.createClass({ - displayName: 'WeightController', - getInitialState: function getInitialState() { - return { - owner: false, - weights: [], - closed: false - }; - }, - bindWeights: function bindWeights(owner, weights, closed) { - this.setState({ owner: owner, weights: weights, closed: closed }); - }, - render: function render() { - var _this = this; - - var type = 'range'; - var min = 0; - var max = this.state.weights.length; - var step = 1; - - var overlap = this.state.closed; - var baselength = this.state.weights.length; - if (overlap !== false) { - baselength -= overlap; - } - - return React.createElement( - 'section', - { className: 'knot-controls' }, - React.createElement( - 'h2', - null, - 'weight values' - ), - this.state.weights.map(function (value, position) { - if (overlap && position >= baselength) { - return null; - } - var props = { - type: type, min: min, max: max, step: step, - value: value, - onChange: function onChange(e) { - var k = _this.state.weights; - k[position] = e.target.value; - if (overlap && position < overlap) { - k[position + baselength] = e.target.value; - } - _this.setState({ weights: k }, function () { - _this.state.owner.redraw(); - }); - } - }; - return React.createElement( - 'div', - { key: 'knot' + position }, - min, - React.createElement('input', props), - max, - ' (= ', - value, - ')' - ); - }) - ); - } -}); - -module.exports = WeightController; - -/***/ }), -/* 121 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var hasWindow = typeof window !== "undefined"; -var chroma = /*hasWindow ? window.chroma : */__webpack_require__(210); -var Bezier = /*hasWindow ? window.Bezier : */__webpack_require__(208); - -// event coordinate fix -var fix = function fix(e) { - e = e || window.event; - var target = e.target || e.srcElement, - rect = target.getBoundingClientRect(); - e.offsetX = e.clientX - rect.left; - e.offsetY = e.clientY - rect.top; -}; - -var API = { - Paper: false, - - defaultWidth: 275, - defaultHeight: 275, - panelCount: 1, - - Bezier: Bezier, - utils: Bezier.getUtils(), - curve: false, - mx: 0, - my: 0, - cx: 0, - cy: 0, - mp: false, - offset: { x: 0, y: 0 }, - lpts: [], - colorSeed: 0, - playing: false, - frame: 0, - playinterval: 33, - - animate: function animate() { - if (this.playing) { - this.frame++; - // requestAnimationFrame is spectacularly too fast - setTimeout(this.animate, this.playinterval); - this.props.draw(this, this.curve); - } - }, - - getFrame: function getFrame() { - return this.frame; - }, - getPlayInterval: function getPlayInterval() { - return this.playinterval; - }, - play: function play() { - this.playing = true;this.animate(); - }, - pause: function pause() { - this.playing = false; - }, - redraw: function redraw() { - if (this.props.draw) { - this.props.draw(this, this.curve); - } - }, - - mouseDown: function mouseDown(evt) { - var _this = this; - - fix(evt); - this.mx = evt.offsetX; - this.my = evt.offsetY; - - this.movingPoint = false; - this.dragging = false; - this.down = true; - - this.lpts.forEach(function (p, idx) { - if (Math.abs(_this.mx - p.x) < 10 && Math.abs(_this.my - p.y) < 10) { - _this.movingPoint = true; - _this.mp = p; - _this.mp_idx = idx; - _this.cx = p.x; - _this.cy = p.y; - } - }); - - if (this.props.onMouseDown) { - this.props.onMouseDown(evt, this); - } - - if ('setCapture' in evt.target) { - evt.target.setCapture(); - } - }, - - mouseMove: function mouseMove(evt) { - fix(evt); - - if (!this.props.static) { - - if (this.down) { - this.dragging = true; - } - - var found = false; - this.lpts.forEach(function (p) { - var mx = evt.offsetX; - var my = evt.offsetY; - if (Math.abs(mx - p.x) < 10 && Math.abs(my - p.y) < 10) { - found = found || true; - } - }); - this.cvs.style.cursor = found ? "pointer" : "default"; - - this.hover = { - x: evt.offsetX, - y: evt.offsetY - }; - - if (this.movingPoint) { - this.ox = evt.offsetX - this.mx; - this.oy = evt.offsetY - this.my; - this.mp.x = Math.max(0, Math.min(this.defaultWidth, this.cx + this.ox)); - this.mp.y = Math.max(0, Math.min(this.defaultHeight, this.cy + this.oy)); - if (this.curve.forEach) { - for (var i = 0, c, _pts; i < this.curve.length; i++) { - c = this.curve[i]; - _pts = c.points; - if (_pts.indexOf(this.mp) > -1) { - c.update(); - break; - } - } - } else if (this.curve && this.curve.update) { - this.curve.update(); - } - } - } - - if (this.props.onMouseMove) { - this.props.onMouseMove(evt, this); - } - - if (this.dragging && this.props.onMouseDrag) { - this.props.onMouseDrag(evt, this); - } - - if (!this.props.static && !this.playing && this.props.draw) { - this.props.draw(this, this.curve); - } - }, - - mouseUp: function mouseUp(evt) { - this.down = false; - if (!this.movingPoint) { - if (this.props.onMouseUp) { - this.props.onMouseUp(evt, this); - } - return; - } - this.movingPoint = false; - this.mp = false; - if (this.props.onMouseUp) { - this.props.onMouseUp(evt, this); - } - }, - - onClick: function onClick(evt) { - fix(evt); - this.mx = evt.offsetX; - this.my = evt.offsetY; - if (!this.dragging && this.props.onClick) { - this.props.onClick(evt, this); - } - }, - - onKeyUp: function onKeyUp(evt) { - if (this.props.onKeyUp) { - this.props.onKeyUp(evt, this); - if (!this.playing && this.props.draw) { - this.props.draw(this, this.curve); - } - } - }, - - onKeyDown: function onKeyDown(evt) { - if (this.props.onKeyDown) { - this.props.onKeyDown(evt, this); - if (!this.playing && this.props.draw) { - this.props.draw(this, this.curve); - } - } - }, - - onKeyPress: function onKeyPress(evt) { - if (this.props.onKeyPress) { - this.props.onKeyPress(evt, this); - if (!this.playing && this.props.draw) { - this.props.draw(this, this.curve); - } - } - }, - - /** - * API for curve drawing. - */ - - reset: function reset() { - this.refs.canvas.width = this.refs.canvas.width; - this.ctx.strokeStyle = "black"; - this.ctx.lineWidth = 1; - this.ctx.fillStyle = "none"; - var dpr = this.getPixelRatio(); - this.ctx.scale(dpr, dpr); - this.offset = { x: 0, y: 0 }; - this.colorSeed = 0; - }, - - setSize: function setSize(w, h) { - this.defaultWidth = w; - this.defaultHeight = h; - - var cvs = this.refs.canvas; - cvs.style.width = this.panelCount * w + "px"; - cvs.style.height = h + "px"; - - var dpr = this.getPixelRatio(); - cvs.width = this.panelCount * w * dpr; - cvs.height = h * dpr; - this.ctx.scale(dpr, dpr); - }, - - setCurves: function setCurves(c) { - this.setCurve(c); - }, - - setCurve: function setCurve(c) { - var pts = []; - c = c instanceof Array ? c : Array.prototype.slice.call(arguments); - c.forEach(function (nc) { - pts = pts.concat(nc.points); - }); - this.curve = c.length === 1 ? c[0] : c; - this.lpts = pts; - }, - - getPanelWidth: function getPanelWidth() { - return this.defaultWidth; - }, - - getPanelHeight: function getPanelHeight() { - return this.defaultHeight; - }, - - getDefaultQuadratic: function getDefaultQuadratic() { - return new this.Bezier(70, 250, 20, 110, 250, 60); - }, - - getDefaultCubic: function getDefaultCubic() { - return new this.Bezier(120, 160, 35, 200, 220, 260, 220, 40); - }, - - getPixelRatio: function getPixelRatio() { - return window.devicePixelRatio || 1; - }, - - toImage: function toImage() { - var dataURL = this.refs.canvas.toDataURL(); - var img = new Image(); - img.src = dataURL; - img.devicePixelRatio = this.getPixelRatio(); - return img; - }, - - setPanelCount: function setPanelCount(c) { - this.panelCount = c; - var cvs = this.refs.canvas; - cvs.width = c * this.defaultWidth * this.getPixelRatio(); - cvs.style.width = c * this.defaultWidth + "px"; - }, - - setOffset: function setOffset(f) { - this.offset = f; - }, - - setColor: function setColor(c) { - this.ctx.strokeStyle = c; - }, - - getColor: function getColor() { - return this.ctx.strokeStyle || "black"; - }, - - setWeight: function setWeight(c) { - this.ctx.lineWidth = c; - }, - - noColor: function noColor(c) { - this.ctx.strokeStyle = "transparent"; - }, - - setRandomColor: function setRandomColor(a) { - a = typeof a === "undefined" ? 1 : a; - var h = this.colorSeed % 360, - s = 1.0, - l = 0.34; - this.colorSeed += 87; - this.ctx.strokeStyle = chroma.hsl(h, s, l).alpha(a).css(); - }, - - setRandomFill: function setRandomFill(a) { - a = typeof a === "undefined" ? 1 : a; - var h = this.colorSeed % 360, - s = 1.0, - l = 0.34; - this.colorSeed += 87; - this.ctx.fillStyle = chroma.hsl(h, s, l).alpha(a).css(); - }, - - setFill: function setFill(c) { - this.ctx.fillStyle = c; - }, - - getFill: function getFill() { - return this.ctx.fillStyle || "transparent"; - }, - - noFill: function noFill() { - this.ctx.fillStyle = "transparent"; - }, - - drawSkeleton: function drawSkeleton(curve, offset, nocoords) { - offset = offset || { x: 0, y: 0 }; - var pts = curve.points; - if (pts.length > 2) { - this.ctx.strokeStyle = "lightgrey"; - this.drawLine(pts[0], pts[1], offset); - var last = pts.length - 2; - for (var i = 1; i < last; i++) { - this.drawLine(pts[i], pts[i + 1], offset); - } - this.drawLine(pts[last], pts[last + 1], offset); - } - this.ctx.strokeStyle = "black"; - this.drawPoints(pts, offset); - if (!nocoords) { - this.drawCoordinates(curve, offset); - } - }, - - drawGrid: function drawGrid(xcount, ycount, offset) { - var w = this.defaultWidth, - h = this.defaultHeight, - xstep = w / xcount, - ox = xstep / 2, - ystep = h / ycount, - oy = ystep / 2, - x, - xv, - y, - yv, - p1, - p2; - for (x = 0; x < xcount; x++) { - xv = ox + x * xstep; - p1 = { x: xv, y: 0 }; - p2 = { x: xv, y: h }; - this.drawLine(p1, p2, offset); - } - for (y = 0; y < ycount; y++) { - yv = oy + y * ystep; - p1 = { x: 0, y: yv }; - p2 = { x: w, y: yv }; - this.drawLine(p1, p2, offset); - } - }, - - drawHull: function drawHull(curve, t, offset) { - var hull = curve instanceof Array ? curve : curve.hull(t); - if (hull.length === 6) { - this.drawLine(hull[0], hull[1], offset); - this.drawLine(hull[1], hull[2], offset); - this.drawLine(hull[3], hull[4], offset); - } else { - this.drawLine(hull[0], hull[1], offset); - this.drawLine(hull[1], hull[2], offset); - this.drawLine(hull[2], hull[3], offset); - this.drawLine(hull[4], hull[5], offset); - this.drawLine(hull[5], hull[6], offset); - this.drawLine(hull[7], hull[8], offset); - } - return hull; - }, - - drawCoordinates: function drawCoordinates(curve, offset) { - var _this2 = this; - - offset = offset || { x: 0, y: 0 }; - var pts = curve.points; - this.setFill("black"); - pts.forEach(function (p) { - _this2.text("(" + p.x + "," + p.y + ")", { x: p.x + offset.x + 5, y: p.y + offset.y + 10 }); - }); - }, - - drawFunction: function drawFunction(generator, offset) { - var start = generator.start || 0, - p0 = generator(start), - end = generator.end || 1, - plast = generator(end), - step = generator.step || 0.01, - scale = generator.scale || 1, - p, - t; - for (t = step; t < end; t += step) { - p = generator(t, scale); - this.drawLine(p0, p, offset); - p0 = p; - } - this.drawLine(p, plast, offset); - }, - - drawCurve: function drawCurve(curve, offset) { - var _this3 = this; - - offset = offset || { x: 0, y: 0 }; - var p = curve.points; - - if (p.length <= 3 || 5 <= p.length) { - var points = curve.getLUT(100); - var p0 = points[0]; - points.forEach(function (p1, i) { - if (!i) return; - _this3.drawLine(p0, p1, offset); - p0 = p1; - }); - return; - } - - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - this.ctx.beginPath(); - this.ctx.moveTo(p[0].x + ox, p[0].y + oy); - if (p.length === 3) { - this.ctx.quadraticCurveTo(p[1].x + ox, p[1].y + oy, p[2].x + ox, p[2].y + oy); - } else if (p.length === 4) { - this.ctx.bezierCurveTo(p[1].x + ox, p[1].y + oy, p[2].x + ox, p[2].y + oy, p[3].x + ox, p[3].y + oy); - } - this.ctx.stroke(); - this.ctx.closePath(); - }, - - drawLine: function drawLine(p1, p2, offset) { - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - this.ctx.beginPath(); - this.ctx.moveTo(p1.x + ox, p1.y + oy); - this.ctx.lineTo(p2.x + ox, p2.y + oy); - this.ctx.stroke(); - }, - - drawPoint: function drawPoint(p, offset) { - this.drawCircle(p, 1, offset); - }, - - drawPoints: function drawPoints(points, offset) { - offset = offset || { x: 0, y: 0 }; - points.forEach(function (p) { - this.drawCircle(p, offset.x !== 0 || offset.y !== 0 ? 1.5 : 3, offset); - }.bind(this)); - }, - - drawArc: function drawArc(p, offset) { - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - this.ctx.beginPath(); - this.ctx.moveTo(p.x + ox, p.y + oy); - this.ctx.arc(p.x + ox, p.y + oy, p.r, p.s, p.e); - this.ctx.lineTo(p.x + ox, p.y + oy); - this.ctx.fill(); - this.ctx.stroke(); - }, - - drawCircle: function drawCircle(p, r, offset) { - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - this.ctx.beginPath(); - this.ctx.arc(p.x + ox, p.y + oy, r, 0, 2 * Math.PI); - this.ctx.stroke(); - }, - - drawbbox: function drawbbox(bbox, offset) { - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - this.ctx.beginPath(); - this.ctx.moveTo(bbox.x.min + ox, bbox.y.min + oy); - this.ctx.lineTo(bbox.x.min + ox, bbox.y.max + oy); - this.ctx.lineTo(bbox.x.max + ox, bbox.y.max + oy); - this.ctx.lineTo(bbox.x.max + ox, bbox.y.min + oy); - this.ctx.closePath(); - this.ctx.stroke(); - }, - - drawRect: function drawRect(p1, p2, offset) { - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - var x = p1.x + ox, - y = p1.y + oy, - w = p2.x - p1.x, - h = p2.y - p1.y; - this.ctx.beginPath(); - this.ctx.moveTo(x, y); - this.ctx.lineTo(x + w, y); - this.ctx.lineTo(x + w, y + h); - this.ctx.lineTo(x, y + h); - this.ctx.closePath(); - this.ctx.fill(); - this.ctx.stroke(); - }, - - drawPath: function drawPath(path, offset) { - var _this4 = this; - - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - this.ctx.beginPath(); - path.forEach(function (p, idx) { - if (idx === 0) { - return _this4.ctx.moveTo(p.x + ox, p.y + oy); - } - _this4.ctx.lineTo(p.x + ox, p.y + oy); - }); - if (closed) this.ctx.closePath(); - this.ctx.fill(); - this.ctx.stroke(); - }, - - drawShape: function drawShape(shape, offset) { - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - var order = shape.forward.points.length - 1; - this.ctx.beginPath(); - this.ctx.moveTo(ox + shape.startcap.points[0].x, oy + shape.startcap.points[0].y); - this.ctx.lineTo(ox + shape.startcap.points[3].x, oy + shape.startcap.points[3].y); - if (order === 3) { - this.ctx.bezierCurveTo(ox + shape.forward.points[1].x, oy + shape.forward.points[1].y, ox + shape.forward.points[2].x, oy + shape.forward.points[2].y, ox + shape.forward.points[3].x, oy + shape.forward.points[3].y); - } else { - this.ctx.quadraticCurveTo(ox + shape.forward.points[1].x, oy + shape.forward.points[1].y, ox + shape.forward.points[2].x, oy + shape.forward.points[2].y); - } - this.ctx.lineTo(ox + shape.endcap.points[3].x, oy + shape.endcap.points[3].y); - if (order === 3) { - this.ctx.bezierCurveTo(ox + shape.back.points[1].x, oy + shape.back.points[1].y, ox + shape.back.points[2].x, oy + shape.back.points[2].y, ox + shape.back.points[3].x, oy + shape.back.points[3].y); - } else { - this.ctx.quadraticCurveTo(ox + shape.back.points[1].x, oy + shape.back.points[1].y, ox + shape.back.points[2].x, oy + shape.back.points[2].y); - } - this.ctx.closePath(); - this.ctx.fill(); - this.ctx.stroke(); - }, - - text: function text(_text, coord, offset) { - offset = offset || { x: 0, y: 0 }; - if (this.offset) { - offset.x += this.offset.x; - offset.y += this.offset.y; - } - this.ctx.fillText(_text, coord.x + offset.x, coord.y + offset.y); - }, - - image: function image(_image, offset) { - var _this5 = this; - - offset = offset || { x: 0, y: 0 }; - if (this.offset) { - offset.x += this.offset.x; - offset.y += this.offset.y; - } - var dpr = _image.devicePixelRatio || 1; - if (_image.loaded) { - this.ctx.drawImage(_image, offset.x, offset.y, _image.width / dpr, _image.height / dpr); - } else { - _image.onload = function () { - _image.loaded = true; - _this5.ctx.drawImage(_image, offset.x, offset.y, _image.width / dpr, _image.height / dpr); - }; - } - }, - - drawAxes: function drawAxes(pad, xlabel, xs, xe, ylabel, ys, ye, offset) { - offset = offset || { x: 0, y: 0 }; - var dim = this.getPanelWidth(); - - this.drawLine({ x: pad, y: pad }, { x: dim - pad, y: pad }, offset); - this.drawLine({ x: pad, y: pad }, { x: pad, y: dim - pad }, offset); - - this.setFill("black"); - - this.text(xlabel + " →", { x: offset.x + dim / 2, y: offset.y + 15 }); - this.text(xs, { x: offset.x + pad, y: offset.y + 15 }); - this.text(xe, { x: offset.x + dim - pad, y: offset.y + 15 }); - - this.text(ylabel, { x: offset.x + 5, y: offset.y + dim / 2 - pad }); - this.text("↓", { x: offset.x + 5, y: offset.y + dim / 2 }); - this.text(ys, { x: offset.x + 4, y: offset.y + pad + 5 }); - this.text(ye, { x: offset.x + 2, y: offset.y + dim - pad + 10 }); - } -}; - -if (hasWindow) { - window["Bezier Graphics API"] = API; -} -if (true) { - module.exports = API; -} - -/***/ }), -/* 122 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var Locale = __webpack_require__(68); -var locale = new Locale(); -var page = "locale-switcher"; - -module.exports = function (props) { - return React.createElement( - "div", - { className: "locale-switcher" }, - locale.getContent(page, this) - ); -}; - -/***/ }), -/* 123 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - "LocaleSwitcher": __webpack_require__(122) -}; - -/***/ }), -/* 124 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - onClick: function onClick(evt, api) { - api.t = api.curve.on({ x: evt.offsetX, y: evt.offsetY }, 7); - if (api.t < 0.05 || api.t > 0.95) api.t = false; - api.redraw(); - }, - - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - curve.points[0].y -= 10; - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - curve.points[2].y -= 20; - api.setCurve(curve); - api.lut = curve.getLUT(100); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var h = api.getPanelHeight(); - - api.setColor("black"); - if (api.t) { - api.drawCircle(api.curve.get(api.t), 3); - api.setColor("lightgrey"); - var hull = api.drawHull(curve, api.t); - var utils = api.utils; - - var A, B, C; - - if (hull.length === 6) { - A = curve.points[1]; - B = hull[5]; - C = utils.lli4(A, B, curve.points[0], curve.points[2]); - api.setColor("lightgrey"); - api.drawLine(curve.points[0], curve.points[2]); - } else if (hull.length === 10) { - A = hull[5]; - B = hull[9]; - C = utils.lli4(A, B, curve.points[0], curve.points[3]); - api.setColor("lightgrey"); - api.drawLine(curve.points[0], curve.points[3]); - } - - api.setColor("#00FF00"); - api.drawLine(A, B); - api.setColor("red"); - api.drawLine(B, C); - api.setColor("black"); - api.drawCircle(C, 3); - - api.setFill("black"); - api.text("A", { x: 10 + A.x, y: A.y }); - api.text("B (t = " + api.utils.round(api.t, 2) + ")", { x: 10 + B.x, y: B.y }); - api.text("C", { x: 10 + C.x, y: C.y }); - - var d1 = utils.dist(A, B); - var d2 = utils.dist(B, C); - var ratio = d1 / d2; - - api.text("d1 (A-B): " + utils.round(d1, 2) + ", d2 (B-C): " + utils.round(d2, 2) + ", ratio (d1/d2): " + utils.round(ratio, 4), { x: 10, y: h - 7 }); - } - }, - - setCT: function setCT(evt, api) { - api.t = evt.offsetX / api.getPanelWidth(); - }, - - drawCTgraph: function drawCTgraph(api) { - api.reset(); - api.setColor("black"); - var w = api.getPanelWidth(); - var pad = 20; - var fwh = w - 2 * pad; - api.drawAxes(pad, "t", 0, 1, "u", 0, 1); - api.setColor("blue"); - var uPoint = function uPoint(t) { - var value = api.u(t), - res = { x: pad + t * fwh, y: pad + value * fwh }; - return res; - }; - api.drawFunction(uPoint); - if (api.t) { - var v = api.u(api.t), - v1 = api.utils.round(v, 3), - v2 = api.utils.round(1 - v, 3), - up = uPoint(api.t); - api.drawLine({ x: up.x, y: pad }, up); - api.drawLine({ x: pad, y: up.y }, up); - api.drawCircle(up, 3); - api.setFill("blue"); - api.text(" t = " + api.utils.round(api.t, 3), { x: up.x + 10, y: up.y - 7 }); - api.text("u(t) = " + api.utils.round(v, 3), { x: up.x + 10, y: up.y + 7 }); - api.setFill("black"); - api.text("C = " + v1 + " * start + " + v2 + " * end", { x: w / 2 - pad, y: pad + fwh }); - } - }, - - drawQCT: function drawQCT(api) { - api.u = api.u || function (t) { - var top = (t - 1) * (t - 1), - bottom = 2 * t * t - 2 * t + 1; - return top / bottom; - }; - this.drawCTgraph(api); - }, - - drawCCT: function drawCCT(api) { - api.u = api.u || function (t) { - var top = (1 - t) * (1 - t) * (1 - t), - bottom = t * t * t + top; - return top / bottom; - }; - this.drawCTgraph(api); - } -}; - -/***/ }), -/* 125 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(124); -var generateBase = __webpack_require__(1); -module.exports = generateBase("abc", handler); - -/***/ }), -/* 126 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - align: function align(points, line) { - var tx = line.p1.x, - ty = line.p1.y, - a = -Math.atan2(line.p2.y - ty, line.p2.x - tx), - cos = Math.cos, - sin = Math.sin, - d = function d(v) { - return { - x: (v.x - tx) * cos(a) - (v.y - ty) * sin(a), - y: (v.x - tx) * sin(a) + (v.y - ty) * cos(a) - }; - }; - return points.map(d); - }, - - draw: function draw(api, curve) { - api.setPanelCount(2); - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var pts = curve.points; - var line = { p1: pts[0], p2: pts[pts.length - 1] }; - var apts = this.align(pts, line); - var aligned = new api.Bezier(apts); - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - - var offset = { x: w, y: 0 }; - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - offset.x += w / 4; - offset.y += h / 2; - api.setColor("grey"); - api.drawLine({ x: 0, y: -h / 2 }, { x: 0, y: h / 2 }, offset); - api.drawLine({ x: -w / 4, y: 0 }, { x: w, y: 0 }, offset); - api.setFill("grey"); - - api.setColor("black"); - api.drawSkeleton(aligned, offset); - api.drawCurve(aligned, offset); - } -}; - -/***/ }), -/* 127 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(126); -var generateBase = __webpack_require__(1); -module.exports = generateBase("aligning", handler); - -/***/ }), -/* 128 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var atan2 = Math.atan2, - PI = Math.PI, - TAU = 2 * PI, - cos = Math.cos, - sin = Math.sin; - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "error", - values: { - "38": 0.1, // up arrow - "40": -0.1 // down arrow - }, - controller: function controller(api) { - if (api.error < 0.1) { - api.error = 0.1; - } - } - } - }, - - setupCircle: function setupCircle(api) { - var curve = new api.Bezier(70, 70, 140, 40, 240, 130); - api.setCurve(curve); - }, - - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - api.error = 0.5; - }, - - getCCenter: function getCCenter(api, p1, p2, p3) { - // deltas - var dx1 = p2.x - p1.x, - dy1 = p2.y - p1.y, - dx2 = p3.x - p2.x, - dy2 = p3.y - p2.y; - - // perpendiculars (quarter circle turned) - var dx1p = dx1 * cos(PI / 2) - dy1 * sin(PI / 2), - dy1p = dx1 * sin(PI / 2) + dy1 * cos(PI / 2), - dx2p = dx2 * cos(PI / 2) - dy2 * sin(PI / 2), - dy2p = dx2 * sin(PI / 2) + dy2 * cos(PI / 2); - - // chord midpoints - var mx1 = (p1.x + p2.x) / 2, - my1 = (p1.y + p2.y) / 2, - mx2 = (p2.x + p3.x) / 2, - my2 = (p2.y + p3.y) / 2; - - // midpoint offsets - var mx1n = mx1 + dx1p, - my1n = my1 + dy1p, - mx2n = mx2 + dx2p, - my2n = my2 + dy2p; - - // intersection of these lines: - var i = api.utils.lli8(mx1, my1, mx1n, my1n, mx2, my2, mx2n, my2n); - var r = api.utils.dist(i, p1); - - // arc start/end values, over mid point - var s = atan2(p1.y - i.y, p1.x - i.x), - m = atan2(p2.y - i.y, p2.x - i.x), - e = atan2(p3.y - i.y, p3.x - i.x); - - // determine arc direction (cw/ccw correction) - var __; - if (s < e) { - // if s<m<e, arc(s, e) - // if m<s<e, arc(e, s + TAU) - // if s<e<m, arc(e, s + TAU) - if (s > m || m > e) { - s += TAU; - } - if (s > e) { - __ = e;e = s;s = __; - } - } else { - // if e<m<s, arc(e, s) - // if m<e<s, arc(s, e + TAU) - // if e<s<m, arc(s, e + TAU) - if (e < m && m < s) { - __ = e;e = s;s = __; - } else { - e += TAU; - } - } - - // assign and done. - i.s = s; - i.e = e; - i.r = r; - return i; - }, - - drawCircle: function drawCircle(api, curve) { - api.reset(); - var pts = curve.points; - - // get center - var C = this.getCCenter(api, pts[0], pts[1], pts[2]); - // outer circle - api.setColor("grey"); - api.drawCircle(C, api.utils.dist(C, pts[0])); - - // controllable points - api.setColor("black"); - pts.forEach(function (p) { - return api.drawCircle(p, 3); - }); - - // chords and perpendicular lines - var m; - - api.setColor("blue"); - api.drawLine(pts[0], pts[1]); - m = { x: (pts[0].x + pts[1].x) / 2, y: (pts[0].y + pts[1].y) / 2 }; - api.drawLine(m, { x: C.x + (C.x - m.x), y: C.y + (C.y - m.y) }); - - api.setColor("red"); - api.drawLine(pts[1], pts[2]); - m = { x: (pts[1].x + pts[2].x) / 2, y: (pts[1].y + pts[2].y) / 2 }; - api.drawLine(m, { x: C.x + (C.x - m.x), y: C.y + (C.y - m.y) }); - - api.setColor("green"); - api.drawLine(pts[2], pts[0]); - m = { x: (pts[2].x + pts[0].x) / 2, y: (pts[2].y + pts[0].y) / 2 }; - api.drawLine(m, { x: C.x + (C.x - m.x), y: C.y + (C.y - m.y) }); - - // center - api.setColor("black"); - api.drawPoint(C); - api.setFill("black"); - api.text("Intersection point", C, { x: -25, y: 10 }); - }, - - drawSingleArc: function drawSingleArc(api, curve) { - api.reset(); - var arcs = curve.arcs(api.error); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var a = arcs[0]; - api.setColor("red"); - api.setFill("rgba(255,0,0,0.2)"); - api.debug = true; - api.drawArc(a); - - api.setFill("black"); - api.text("Arc approximation with total error " + api.utils.round(api.error, 1), { x: 10, y: 15 }); - }, - - drawArcs: function drawArcs(api, curve) { - api.reset(); - var arcs = curve.arcs(api.error); - api.drawSkeleton(curve); - api.drawCurve(curve); - arcs.forEach(function (a) { - api.setRandomColor(0.3); - api.setFill(api.getColor()); - api.drawArc(a); - }); - - api.setFill("black"); - api.text("Arc approximation with total error " + api.utils.round(api.error, 1) + " per arc segment", { x: 10, y: 15 }); - } -}; - -/***/ }), -/* 129 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(128); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("arcapproximation", handler)); - -/***/ }), -/* 130 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var sin = Math.sin; -var tau = Math.PI * 2; - -module.exports = { - setup: function setup(api) { - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - var generator; - if (!this.generator) { - generator = function generator(v, scale) { - scale = scale || 1; - return { - x: v * w / tau, - y: scale * sin(v) - }; - }; - generator.start = 0; - generator.end = tau; - generator.step = 0.1; - generator.scale = h / 3; - this.generator = generator; - } - }, - - drawSine: function drawSine(api, dheight) { - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - var generator = this.generator; - generator.dheight = dheight; - - api.setColor("black"); - api.drawLine({ x: 0, y: h / 2 }, { x: w, y: h / 2 }); - api.drawFunction(generator, { x: 0, y: h / 2 }); - }, - - drawSlices: function drawSlices(api, steps) { - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - var f = w / tau; - var area = 0; - var c = steps <= 25 ? 1 : 0; - api.reset(); - api.setColor("transparent"); - api.setFill("rgba(150,150,255, 0.4)"); - for (var step = tau / steps, i = step / 2, v, p1, p2; i < tau + step / 2; i += step) { - v = this.generator(i); - p1 = { x: v.x - f * step / 2 + c, y: 0 }; - p2 = { x: v.x + f * step / 2 - c, y: v.y * this.generator.scale }; - - if (!c) { - api.setFill("rgba(150,150,255," + (0.4 + 0.3 * Math.random()) + ")"); - } - api.drawRect(p1, p2, { x: 0, y: h / 2 }); - area += step * Math.abs(v.y * this.generator.scale); - } - api.setFill("black"); - var trueArea = (100 * 4 * h / 3 | 0) / 100; - var currArea = (100 * area | 0) / 100; - api.text("Approximating with " + steps + " strips (true area: " + trueArea + "): " + currArea, { x: 10, y: h - 15 }); - }, - - drawCoarseIntegral: function drawCoarseIntegral(api) { - api.reset(); - this.drawSlices(api, 10); - this.drawSine(api); - }, - - drawFineIntegral: function drawFineIntegral(api) { - api.reset(); - this.drawSlices(api, 24); - this.drawSine(api); - }, - - drawSuperFineIntegral: function drawSuperFineIntegral(api) { - api.reset(); - this.drawSlices(api, 99); - this.drawSine(api); - }, - - setupCurve: function setupCurve(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - drawCurve: function drawCurve(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - var len = curve.length(); - api.setFill("black"); - api.text("Curve length: " + len + " pixels", { x: 10, y: 15 }); - } -}; - -/***/ }), -/* 131 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(130); -var generateBase = __webpack_require__(1); -module.exports = generateBase("arclength", handler); - -/***/ }), -/* 132 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "steps", - values: { - "38": 1, // up arrow - "40": -1 // down arrow - }, - controller: function controller(api) { - if (api.steps < 1) { - api.steps = 1; - } - } - } - }, - - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - api.steps = 10; - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - api.steps = 16; - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - - var pts = curve.getLUT(api.steps); - - var step = 1 / api.steps; - var p0 = curve.points[0], - pc; - for (var t = step; t < 1.0 + step; t += step) { - pc = curve.get(Math.min(t, 1)); - api.setColor("red"); - api.drawLine(p0, pc); - p0 = pc; - } - - var len = curve.length(); - var alen = 0; - for (var i = 0, p1, dx, dy; i < pts.length - 1; i++) { - p0 = pts[i]; - p1 = pts[i + 1]; - dx = p1.x - p0.x; - dy = p1.y - p0.y; - alen += Math.sqrt(dx * dx + dy * dy); - } - alen = (100 * alen | 0) / 100; - len = (100 * len | 0) / 100; - - api.text("Approximate length, " + api.steps + " steps: " + alen + " (true: " + len + ")", { x: 10, y: 15 }); - } -}; - -/***/ }), -/* 133 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(132); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("arclengthapprox", handler)); - -/***/ }), -/* 134 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.reset(); - api.setColor("#00FF00"); - api.drawbbox(curve.bbox()); - api.setColor("black"); - api.drawSkeleton(curve); - api.drawCurve(curve); - api.setColor("red"); - curve.extrema().values.forEach(function (t) { - api.drawCircle(curve.get(t), 3); - }); - } -}; - -/***/ }), -/* 135 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(134); -var generateBase = __webpack_require__(1); -module.exports = generateBase("boundingbox", handler); - -/***/ }), -/* 136 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - degree: 3, - activeDistance: 9, - - setup: function setup() { - this.size(600, 300); - this.draw(); - }, - draw: function draw() { - var _this = this; - - this.clear(); - this.grid(25); - var p = this.points[0]; - this.points.forEach(function (n) { - _this.stroke(200); - _this.line(n.x, n.y, p.x, p.y); - p = n; - _this.stroke(0); - _this.circle(p.x, p.y, 4); - }); - this.drawSplineData(); - }, - drawSplineData: function drawSplineData() { - if (this.points.length <= this.degree) return; - var mapped = this.points.map(function (p) { - return [p.x, p.y]; - }); - this.drawCurve(mapped); - this.drawKnots(mapped); - } -}; - -/***/ }), -/* 137 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - degree: 3, - activeDistance: 9, - - setup: function setup() { - this.size(400, 400); - - var TAU = Math.PI * 2; - for (var i = 0; i < TAU; i += TAU / 9) { - this.points.push({ - x: this.width / 2 + 100 * Math.cos(i), - y: this.height / 2 + 100 * Math.sin(i) - }); - } - - this.knots = this.formKnots(this.points); - var m = Math.round(this.points.length / 2) | 0; - this.knots[m + 0] = this.knots[m]; - this.knots[m + 1] = this.knots[m]; - this.knots[m + 2] = this.knots[m]; - for (var _i = m + 3; _i < this.knots.length; _i++) { - this.knots[_i] = this.knots[_i - 1] + 1; - } - - if (this.props.controller) { - this.props.controller(this, this.knots); - } - - this.draw(); - }, - draw: function draw() { - var _this = this; - - this.clear(); - this.grid(25); - var p = this.points[0]; - this.points.forEach(function (n) { - _this.stroke(200); - _this.line(n.x, n.y, p.x, p.y); - p = n; - _this.stroke(0); - _this.circle(p.x, p.y, 4); - }); - this.drawSplineData(); - }, - drawSplineData: function drawSplineData() { - if (this.points.length <= this.degree) return; - var mapped = this.points.map(function (p) { - return [p.x, p.y]; - }); - this.drawCurve(mapped); - this.drawKnots(mapped); - } -}; - -/***/ }), -/* 138 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - basicSketch: __webpack_require__(136), - interpolationGraph: __webpack_require__(140), - uniformBSpline: __webpack_require__(143), - centerCutBSpline: __webpack_require__(137), - openUniformBSpline: __webpack_require__(141), - rationalUniformBSpline: __webpack_require__(142), - - bindKnots: function bindKnots(owner, knots, ref) { - this.refs[ref].bindKnots(owner, knots); - }, - - bindWeights: function bindWeights(owner, weights, closed, ref) { - this.refs[ref].bindWeights(owner, weights, closed); - } -}; - -/***/ }), -/* 139 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(138); -var generateBase = __webpack_require__(1); -module.exports = generateBase("bsplines", handler); - -/***/ }), -/* 140 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var colors = ['#C00', '#CC0', '#0C0', '#0CC', '#00C', '#C0C', '#600', '#660', '#060', '#066', '#006', '#606']; - -module.exports = { - degree: 3, - activeDistance: 9, - cache: { N: [] }, - - setup: function setup() { - this.size(600, 300); - this.points = [{ x: 0, y: 0 }, { x: 100, y: -100 }, { x: 200, y: 100 }, { x: 300, y: -100 }, { x: 400, y: 100 }, { x: 500, y: 0 }]; - this.knots = this.formKnots(this.points); - if (this.props.controller) { - this.props.controller(this, this.knots); - } - this.draw(); - }, - draw: function draw() { - this.clear(); - var pad = 25; - this.grid(pad); - this.stroke(0); - this.line(pad, 0, pad, this.height); - var y = this.height - pad; - this.line(0, y, this.width, y); - - var k = this.degree; - var n = this.points.length || 4; - - for (var i = 0; i < n + 1 + k; i++) { - this.drawN(i, k, pad, (this.width - pad) / (2 * (n + 2)), this.height - 2 * pad); - } - }, - drawN: function drawN(i, k, pad, w, h) { - this.stroke(colors[i]); - var knots = this.knots; - this.beginPath(); - for (var start = i - 1, t = start, step = 0.1, end = i + k + 1; t < end; t += step) { - var x = pad + i * w + t * w; - var y = this.height - pad - this.N(i, k, t) * h; - this.vertex(x, y); - } - this.endPath(); - }, - N: function N(i, k, t) { - var t_i = this.knots[i]; - var t_i1 = this.knots[i + 1]; - var t_ik1 = this.knots[i + k - 1]; - var t_ik = this.knots[i + k]; - - if (k === 1) { - return t_i <= t && t <= t_i1 ? 1 : 0; - } - - var n1 = t - t_i; - var d1 = t_ik1 - t_i; - var a1 = d1 === 0 ? 0 : n1 / d1; - - var n2 = t_ik - t; - var d2 = t_ik - t_i1; - var a2 = d2 === 0 ? 0 : n2 / d2; - - var N1 = 0; - if (a1 !== 0) { - var n1v = this.ensureN(i, k - 1, t); - N1 = n1v === undefined ? this.N(i, k - 1, t) : n1v; - } - - var N2 = 0; - if (a2 !== 0) { - var n2v = this.ensureN(i + 1, k - 1, t); - N2 = n2v === undefined ? this.N(i + 1, k - 1, t) : n2v; - } - - this.cacheN(i, k, t, a1 * N1 + a2 * N2); - return this.cache.N[i][k][t]; - }, - ensureN: function ensureN(i, k, t) { - if (!this.cache.N) { - this.cache.N = []; - } - var N = this.cache.N; - if (!N[i]) { - N[i] = []; - } - if (!N[i][k]) { - N[i][k] = []; - } - return N[i][k][t]; - }, - cacheN: function cacheN(i, k, t, value) { - this.ensureN(i, k, t); - this.cache.N[i][k][t] = value; - } -}; - -/***/ }), -/* 141 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - degree: 3, - activeDistance: 9, - - setup: function setup() { - this.size(400, 400); - - var TAU = Math.PI * 2; - for (var i = 0; i < TAU; i += TAU / 10) { - this.points.push({ - x: this.width / 2 + 100 * Math.cos(i), - y: this.height / 2 + 100 * Math.sin(i) - }); - } - - this.knots = this.formKnots(this.points, true); - - if (this.props.controller) { - this.props.controller(this, this.knots); - } - - this.draw(); - }, - draw: function draw() { - var _this = this; - - this.clear(); - this.grid(25); - var p = this.points[0]; - this.points.forEach(function (n) { - _this.stroke(200); - _this.line(n.x, n.y, p.x, p.y); - p = n; - _this.stroke(0); - _this.circle(p.x, p.y, 4); - }); - this.drawSplineData(); - }, - drawSplineData: function drawSplineData() { - if (this.points.length <= this.degree) return; - var mapped = this.points.map(function (p) { - return [p.x, p.y]; - }); - this.drawCurve(mapped); - this.drawKnots(mapped); - } -}; - -/***/ }), -/* 142 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - degree: 3, - activeDistance: 9, - weights: [], - - setup: function setup() { - this.size(400, 400); - - var TAU = Math.PI * 2; - var r = this.width / 3; - for (var i = 0; i < 6; i++) { - this.points.push({ - x: this.width / 2 + r * Math.cos(i / 6 * TAU), - y: this.height / 2 + r * Math.sin(i / 6 * TAU) - }); - } - this.points = this.points.concat(this.points.slice(0, 3)); - this.closed = this.degree; - - this.knots = this.formKnots(this.points); - this.weights = this.formWeights(this.points); - - if (this.props.controller) { - this.props.controller(this, this.knots, this.weights, this.closed); - } - - this.draw(); - }, - draw: function draw() { - var _this = this; - - this.clear(); - this.grid(25); - var p = this.points[0]; - this.points.forEach(function (n) { - _this.stroke(200); - _this.line(n.x, n.y, p.x, p.y); - p = n; - _this.stroke(0); - _this.circle(p.x, p.y, 4); - }); - this.drawSplineData(); - }, - drawSplineData: function drawSplineData() { - if (this.points.length <= this.degree) return; - var mapped = this.points.map(function (p) { - return [p.x, p.y]; - }); - this.drawCurve(mapped); - this.drawKnots(mapped); - } -}; - -/***/ }), -/* 143 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - degree: 3, - activeDistance: 9, - - setup: function setup() { - this.size(400, 400); - - var TAU = Math.PI * 2; - for (var i = 0; i < TAU; i += TAU / 10) { - this.points.push({ - x: this.width / 2 + 100 * Math.cos(i), - y: this.height / 2 + 100 * Math.sin(i) - }); - } - - this.knots = this.formKnots(this.points); - if (this.props.controller) { - this.props.controller(this, this.knots); - } - this.draw(); - }, - draw: function draw() { - var _this = this; - - this.clear(); - this.grid(25); - var p = this.points[0]; - this.points.forEach(function (n) { - _this.stroke(200); - _this.line(n.x, n.y, p.x, p.y); - p = n; - _this.stroke(0); - _this.circle(p.x, p.y, 4); - }); - this.drawSplineData(); - }, - drawSplineData: function drawSplineData() { - if (this.points.length <= this.degree) return; - var mapped = this.points.map(function (p) { - return [p.x, p.y]; - }); - this.drawCurve(mapped); - this.drawKnots(mapped); - } -}; - -/***/ }), -/* 144 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setup: function setup(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - api.reset(); - api._map_loaded = false; - }, - - draw: function draw(api, curve) { - var w = 400, - h = w, - unit = this.unit, - center = { x: w / 2, y: h / 2 }; - - api.setSize(w, h); - api.setPanelCount(2); - api.reset(); - - api.drawSkeleton(curve); - api.drawCurve(curve); - - api.offset.x += 400; - - if (api._map_loaded) { - api.image(api._map_image); - } else { - setTimeout(function () { - this.drawBase(api, curve); - this.draw(api, curve); - }.bind(this), 100); - } - - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }); - - var npts = [{ x: 0, y: 0 }, { x: 0, y: unit }, { x: unit, y: unit }, this.forwardTransform(curve.points, unit)]; - - var canonical = new api.Bezier(npts); - api.setColor("blue"); - api.drawCurve(canonical, center); - api.drawCircle(npts[3], 3, center); - }, - - forwardTransform: function forwardTransform(pts, s) { - s = s || 1; - var p1 = pts[0], - p2 = pts[1], - p3 = pts[2], - p4 = pts[3]; - - var xn = -p1.x + p4.x - (-p1.x + p2.x) * (-p1.y + p4.y) / (-p1.y + p2.y); - var xd = -p1.x + p3.x - (-p1.x + p2.x) * (-p1.y + p3.y) / (-p1.y + p2.y); - var np4x = s * xn / xd; - - var yt1 = s * (-p1.y + p4.y) / (-p1.y + p2.y); - var yt2 = s - s * (-p1.y + p3.y) / (-p1.y + p2.y); - var yp = yt2 * xn / xd; - var np4y = yt1 + yp; - - return { x: np4x, y: np4y }; - }, - - drawBase: function drawBase(api, curve) { - api.reset(); - - var w = 400, - h = w, - unit = this.unit = w / 5, - center = { x: w / 2, y: h / 2 }; - - api.setSize(w, h); - - // axes + gridlines - api.setColor("lightgrey"); - for (var x = 0; x < w; x += unit / 2) { - api.drawLine({ x: x, y: 0 }, { x: x, y: h }); - } - for (var y = 0; y < h; y += unit / 2) { - api.drawLine({ x: 0, y: y }, { x: w, y: y }); - } - api.setColor("black"); - api.drawLine({ x: w / 2, y: 0 }, { x: w / 2, y: h }); - api.drawLine({ x: 0, y: h / 2 }, { x: w, y: h / 2 }); - - // Inflection border: - api.setColor("green"); - api.drawLine({ x: -w / 2, y: unit }, { x: w / 2, y: unit }, center); - - // the three stable points - api.setColor("black"); - api.setFill("black"); - api.drawCircle({ x: 0, y: 0 }, 4, center); - api.text("(0,0)", { x: 5 + center.x, y: 15 + center.y }); - api.drawCircle({ x: 0, y: unit }, 4, center); - api.text("(0,1)", { x: 5 + center.x, y: unit + 15 + center.y }); - api.drawCircle({ x: unit, y: unit }, 4, center); - api.text("(1,1)", { x: unit + 5 + center.x, y: unit + 15 + center.y }); - - // cusp parabola: - api.setWeight(1.5); - api.setColor("#FF0000"); - api.setFill(api.getColor()); - var pts = []; - var px = 1, - py = 1; - for (x = -10; x <= 1; x += 0.01) { - y = (-x * x + 2 * x + 3) / 4; - if (x > -10) { - pts.push({ x: unit * px, y: unit * py }); - api.drawLine({ x: unit * px, y: unit * py }, { x: unit * x, y: unit * y }, center); - } - px = x; - py = y; - } - pts.push({ x: unit * px, y: unit * py }); - api.text("Curve form has cusp →", { x: w / 2 - unit * 2, y: h / 2 + unit / 2.5 }); - - // loop/arch transition boundary, elliptical section - api.setColor("#FF00FF"); - api.setFill(api.getColor()); - var sqrt = Math.sqrt; - for (x = 1; x >= 0; x -= 0.005) { - pts.push({ x: unit * px, y: unit * py }); - y = 0.5 * (sqrt(3) * sqrt(4 * x - x * x) - x); - api.drawLine({ x: unit * px, y: unit * py }, { x: unit * x, y: unit * y }, center); - px = x; - py = y; - } - pts.push({ x: unit * px, y: unit * py }); - api.text("← Curve forms a loop at t = 1", { x: w / 2 + unit / 4, y: h / 2 + unit / 1.5 }); - - // loop/arch transition boundary, parabolic section - api.setColor("#3300FF"); - api.setFill(api.getColor()); - for (x = 0; x > -w; x -= 0.01) { - pts.push({ x: unit * px, y: unit * py }); - y = (-x * x + 3 * x) / 3; - api.drawLine({ x: unit * px, y: unit * py }, { x: unit * x, y: unit * y }, center); - px = x; - py = y; - } - pts.push({ x: unit * px, y: unit * py }); - api.text("← Curve forms a loop at t = 0", { x: w / 2 - unit + 10, y: h / 2 - unit * 1.25 }); - - // shape fill - api.setColor("transparent"); - api.setFill("rgba(255,120,100,0.2)"); - api.drawPath(pts, center); - pts = [{ x: -w / 2, y: unit }, { x: w / 2, y: unit }, { x: w / 2, y: h }, { x: -w / 2, y: h }]; - api.setFill("rgba(0,200,0,0.2)"); - api.drawPath(pts, center); - - // further labels - api.setColor("black"); - api.setFill(api.getColor()); - api.text("← Curve form has one inflection →", { x: w / 2 - unit, y: h / 2 + unit * 1.75 }); - api.text("← Plain curve ↕", { x: w / 2 + unit / 2, y: h / 6 }); - api.text("↕ Double inflection", { x: 10, y: h / 2 - 10 }); - - api._map_image = api.toImage(); - api._map_loaded = true; - } -}; - -/***/ }), -/* 145 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(144); -var generateBase = __webpack_require__(1); -module.exports = generateBase("canonical", handler); - -/***/ }), -/* 146 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var generateBase = __webpack_require__(1); -module.exports = generateBase("catmullconv"); - -/***/ }), -/* 147 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "distance", - values: { - "38": 1, // up arrow - "40": -1 // down arrow - } - } - }, - - setup: function setup(api) { - api.setPanelCount(3); - api.lpts = [{ x: 56, y: 153 }, { x: 144, y: 83 }, { x: 188, y: 185 }]; - api.distance = 0; - }, - - convert: function convert(p1, p2, p3, p4) { - var t = 0.5; - return [p2, { - x: p2.x + (p3.x - p1.x) / (6 * t), - y: p2.y + (p3.y - p1.y) / (6 * t) - }, { - x: p3.x - (p4.x - p2.x) / (6 * t), - y: p3.y - (p4.y - p2.y) / (6 * t) - }, p3]; - }, - - draw: function draw(api) { - api.reset(); - api.setColor("lightblue"); - api.drawGrid(10, 10); - - var pts = api.lpts; - api.setColor("black"); - api.setFill("black"); - pts.forEach(function (p, pos) { - api.drawCircle(p, 3); - api.text("point " + (pos + 1), p, { x: 10, y: 7 }); - }); - - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - var offset = { x: w, y: 0 }; - api.setColor("lightblue"); - api.drawGrid(10, 10, offset); - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - - pts.forEach(function (p, pos) { - api.drawCircle(p, 3, offset); - }); - var p1 = pts[0], - p2 = pts[1], - p3 = pts[2]; - var dx = p3.x - p1.x, - dy = p3.y - p1.y, - m = Math.sqrt(dx * dx + dy * dy); - dx /= m; - dy /= m; - api.drawLine(p1, p3, offset); - - var p0 = { - x: p1.x + (p3.x - p2.x) - api.distance * dx, - y: p1.y + (p3.y - p2.y) - api.distance * dy - }; - var p4 = { - x: p1.x + (p3.x - p2.x) + api.distance * dx, - y: p1.y + (p3.y - p2.y) + api.distance * dy - }; - var center = api.utils.lli4(p1, p3, p2, { - x: (p0.x + p4.x) / 2, - y: (p0.y + p4.y) / 2 - }); - api.setColor("blue"); - api.drawCircle(center, 3, offset); - api.drawLine(pts[1], center, offset); - api.setColor("#666"); - api.drawLine(center, p0, offset); - api.drawLine(center, p4, offset); - - api.setFill("blue"); - api.text("p0", p0, { x: -20 + offset.x, y: offset.y + 2 }); - api.text("p4", p4, { x: +10 + offset.x, y: offset.y + 2 }); - - // virtual point p0 - api.setColor("red"); - api.drawCircle(p0, 3, offset); - api.drawLine(p2, p0, offset); - api.drawLine(p1, { - x: p1.x + (p2.x - p0.x) / 5, - y: p1.y + (p2.y - p0.y) / 5 - }, offset); - - // virtual point p4 - api.setColor("#00FF00"); - api.drawCircle(p4, 3, offset); - api.drawLine(p2, p4, offset); - api.drawLine(p3, { - x: p3.x + (p4.x - p2.x) / 5, - y: p3.y + (p4.y - p2.y) / 5 - }, offset); - - // Catmull-Rom curve for p0-p1-p2-p3-p4 - var c1 = new api.Bezier(this.convert(p0, p1, p2, p3)), - c2 = new api.Bezier(this.convert(p1, p2, p3, p4)); - api.setColor("lightgrey"); - api.drawCurve(c1, offset); - api.drawCurve(c2, offset); - - offset.x += w; - api.setColor("lightblue"); - api.drawGrid(10, 10, offset); - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - - api.drawCurve(c1, offset); - api.drawCurve(c2, offset); - api.drawPoints(c1.points, offset); - api.drawPoints(c2.points, offset); - api.setColor("lightgrey"); - api.drawLine(c1.points[0], c1.points[1], offset); - api.drawLine(c1.points[2], c2.points[1], offset); - api.drawLine(c2.points[2], c2.points[3], offset); - } -}; - -/***/ }), -/* 148 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(147); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("catmullmoulding", handler)); - -/***/ }), -/* 149 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var sin = Math.sin, - cos = Math.cos; - -module.exports = { - setup: function setup(api) { - api.w = api.getPanelWidth(); - api.h = api.getPanelHeight(); - api.pad = 20; - api.r = api.w / 2 - api.pad; - api.mousePt = false; - api.angle = 0; - var spt = { x: api.w - api.pad, y: api.h / 2 }; - api.setCurve(new api.Bezier(spt, spt, spt)); - }, - - draw: function draw(api, curve) { - api.reset(); - api.setColor("lightgrey"); - api.drawGrid(1, 1); - api.setColor("red"); - api.drawCircle({ x: api.w / 2, y: api.h / 2 }, api.r); - api.setColor("transparent"); - api.setFill("rgba(100,255,100,0.4)"); - var p = { - x: api.w / 2, - y: api.h / 2, - r: api.r, - s: api.angle < 0 ? api.angle : 0, - e: api.angle < 0 ? 0 : api.angle - }; - api.drawArc(p); - api.setColor("black"); - api.drawSkeleton(curve); - api.drawCurve(curve); - }, - - onMouseMove: function onMouseMove(evt, api) { - var x = evt.offsetX - api.w / 2, - y = evt.offsetY - api.h / 2; - var angle = Math.atan2(y, x); - var pts = api.curve.points; - // new control - var r = api.r, - b = (cos(angle) - 1) / sin(angle); - pts[1] = { - x: api.w / 2 + r * (cos(angle) - b * sin(angle)), - y: api.w / 2 + r * (sin(angle) + b * cos(angle)) - }; - // new endpoint - pts[2] = { - x: api.w / 2 + api.r * cos(angle), - y: api.w / 2 + api.r * sin(angle) - }; - api.setCurve(new api.Bezier(pts)); - api.angle = angle; - } -}; - -/***/ }), -/* 150 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(149); -var generateBase = __webpack_require__(1); -module.exports = generateBase("circles", handler); - -/***/ }), -/* 151 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var sin = Math.sin, - cos = Math.cos, - tan = Math.tan; - -module.exports = { - setup: function setup(api) { - api.setSize(400, 400); - api.w = api.getPanelWidth(); - api.h = api.getPanelHeight(); - api.pad = 80; - api.r = api.w / 2 - api.pad; - api.mousePt = false; - api.angle = 0; - var spt = { x: api.w - api.pad, y: api.h / 2 }; - api.setCurve(new api.Bezier(spt, spt, spt, spt)); - }, - - guessCurve: function guessCurve(S, B, E) { - var C = { - x: (S.x + E.x) / 2, - y: (S.y + E.y) / 2 - }, - A = { - x: B.x + (B.x - C.x) / 3, // cubic ratio at t=0.5 is 1/3 - y: B.y + (B.y - C.y) / 3 - }, - bx = (E.x - S.x) / 4, - by = (E.y - S.y) / 4, - e1 = { - x: B.x - bx, - y: B.y - by - }, - e2 = { - x: B.x + bx, - y: B.y + by - }, - v1 = { - x: A.x + (e1.x - A.x) * 2, - y: A.y + (e1.y - A.y) * 2 - }, - v2 = { - x: A.x + (e2.x - A.x) * 2, - y: A.y + (e2.y - A.y) * 2 - }, - nc1 = { - x: S.x + (v1.x - S.x) * 2, - y: S.y + (v1.y - S.y) * 2 - }, - nc2 = { - x: E.x + (v2.x - E.x) * 2, - y: E.y + (v2.y - E.y) * 2 - }; - return [nc1, nc2]; - }, - - draw: function draw(api, curve) { - api.reset(); - - api.setColor("lightgrey"); - api.drawGrid(1, 1); - api.setColor("rgba(255,0,0,0.4)"); - api.drawCircle({ x: api.w / 2, y: api.h / 2 }, api.r); - api.setColor("transparent"); - api.setFill("rgba(100,255,100,0.4)"); - var p = { - x: api.w / 2, - y: api.h / 2, - r: api.r, - s: api.angle < 0 ? api.angle : 0, - e: api.angle < 0 ? 0 : api.angle - }; - api.drawArc(p); - - // guessed curve - var B = { - x: api.w / 2 + api.r * cos(api.angle / 2), - y: api.w / 2 + api.r * sin(api.angle / 2) - }; - var S = curve.points[0], - E = curve.points[3], - nc = this.guessCurve(S, B, E); - var guess = new api.Bezier([S, nc[0], nc[1], E]); - api.setColor("rgb(140,140,255)"); - api.drawLine(guess.points[0], guess.points[1]); - api.drawLine(guess.points[1], guess.points[2]); - api.drawLine(guess.points[2], guess.points[3]); - api.setColor("blue"); - api.drawCurve(guess); - api.drawCircle(guess.points[1], 3); - api.drawCircle(guess.points[2], 3); - - // real curve - api.drawSkeleton(curve); - api.setColor("black"); - api.drawLine(curve.points[1], curve.points[2]); - api.drawCurve(curve); - }, - - onMouseMove: function onMouseMove(evt, api) { - var x = evt.offsetX - api.w / 2, - y = evt.offsetY - api.h / 2; - if (x > api.w / 2) return; - - var angle = Math.atan2(y, x); - if (angle < 0) { - angle = 2 * Math.PI + angle; - } - var pts = api.curve.points; - // new control 1 - var r = api.r, - f = 4 * tan(angle / 4) / 3; - pts[1] = { - x: api.w / 2 + r, - y: api.w / 2 + r * f - }; - // new control 2 - pts[2] = { - x: api.w / 2 + api.r * (cos(angle) + f * sin(angle)), - y: api.w / 2 + api.r * (sin(angle) - f * cos(angle)) - }; - // new endpoint - pts[3] = { - x: api.w / 2 + api.r * cos(angle), - y: api.w / 2 + api.r * sin(angle) - }; - api.setCurve(new api.Bezier(pts)); - api.angle = angle; - }, - - drawCircle: function drawCircle(api) { - api.setSize(325, 325); - api.reset(); - - var w = api.getPanelWidth(), - h = api.getPanelHeight(), - pad = 60, - r = w / 2 - pad, - k = 0.55228, - offset = { x: -pad / 2, y: -pad / 4 }; - - var curve = new api.Bezier([{ x: w / 2 + r, y: h / 2 }, { x: w / 2 + r, y: h / 2 + k * r }, { x: w / 2 + k * r, y: h / 2 + r }, { x: w / 2, y: h / 2 + r }]); - - api.setColor("lightgrey"); - api.drawLine({ x: 0, y: h / 2 }, { x: w + pad, y: h / 2 }, offset); - api.drawLine({ x: w / 2, y: 0 }, { x: w / 2, y: h + pad }, offset); - - var pts = curve.points; - - api.setColor("red"); - api.drawPoint(pts[0], offset); - api.drawPoint(pts[1], offset); - api.drawPoint(pts[2], offset); - api.drawPoint(pts[3], offset); - api.drawCurve(curve, offset); - api.setColor("rgb(255,160,160)"); - api.drawLine(pts[0], pts[1], offset); - api.drawLine(pts[1], pts[2], offset); - api.drawLine(pts[2], pts[3], offset); - - api.setFill("red"); - api.text(pts[0].x - w / 2 + "," + (pts[0].y - h / 2), { x: pts[0].x + 7, y: pts[0].y + 3 }, offset); - api.text(pts[1].x - w / 2 + "," + (pts[1].y - h / 2), { x: pts[1].x + 7, y: pts[1].y + 3 }, offset); - api.text(pts[2].x - w / 2 + "," + (pts[2].y - h / 2), { x: pts[2].x + 7, y: pts[2].y + 7 }, offset); - api.text(pts[3].x - w / 2 + "," + (pts[3].y - h / 2), { x: pts[3].x, y: pts[3].y + 13 }, offset); - - pts.forEach(function (p) { - p.x = -(p.x - w); - }); - api.setColor("blue"); - api.drawCurve(curve, offset); - api.drawLine(pts[2], pts[3], offset); - api.drawPoint(pts[2], offset); - api.setFill("blue"); - api.text("reflected", { x: pts[2].x - pad / 2, y: pts[2].y + 13 }, offset); - api.setColor("rgb(200,200,255)"); - api.drawLine(pts[1], pts[0], offset); - api.drawPoint(pts[1], offset); - - pts.forEach(function (p) { - p.y = -(p.y - h); - }); - api.setColor("green"); - api.drawCurve(curve, offset); - - pts.forEach(function (p) { - p.x = -(p.x - w); - }); - api.setColor("purple"); - api.drawCurve(curve, offset); - api.drawLine(pts[1], pts[0], offset); - api.drawPoint(pts[1], offset); - api.setFill("purple"); - api.text("reflected", { x: pts[1].x + 10, y: pts[1].y + 3 }, offset); - api.setColor("rgb(200,200,255)"); - api.drawLine(pts[2], pts[3], offset); - api.drawPoint(pts[2], offset); - - api.setColor("black"); - api.setFill("black"); - api.drawLine({ x: w / 2, y: h / 2 }, { x: w / 2 + r - 2, y: h / 2 }, offset); - api.drawLine({ x: w / 2, y: h / 2 }, { x: w / 2, y: h / 2 + r - 2 }, offset); - api.text("r = " + r, { x: w / 2 + r / 3, y: h / 2 + 10 }, offset); - } -}; - -/***/ }), -/* 152 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(151); -var generateBase = __webpack_require__(1); -module.exports = generateBase("circles_cubic", handler); - -/***/ }), -/* 153 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - componentDidMount: function componentDidMount() { - if (typeof document !== "undefined") { - var script = document.createElement("script"); - script.src = "lib/site/disqus.js"; - script.async = true; - document.head.appendChild(script); - } - } -}; - -/***/ }), -/* 154 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(153); -var generateBase = __webpack_require__(1); -module.exports = generateBase("comments", handler); - -/***/ }), -/* 155 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - curve.points[2].x = 210; - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.setPanelCount(3); - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var tf = curve.order, - pad = 20, - pts = curve.points, - w = api.getPanelWidth(), - wp = w - 2 * pad, - h = api.getPanelHeight(), - offset = { x: w, y: 0 }; - - var x_pts = JSON.parse(JSON.stringify(pts)).map(function (p, t) { - return { x: wp * t / tf, y: p.x }; - }); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - api.drawAxes(pad, "t", 0, 1, "x", 0, w, offset); - offset.x += pad; - api.drawCurve(new api.Bezier(x_pts), offset); - - offset.x += w - pad; - var y_pts = JSON.parse(JSON.stringify(pts)).map(function (p, t) { - return { x: wp * t / tf, y: p.y }; - }); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - api.drawAxes(pad, "t", 0, 1, "y", 0, w, offset); - offset.x += pad; - api.drawCurve(new api.Bezier(y_pts), offset); - } -}; - -/***/ }), -/* 156 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(155); -var generateBase = __webpack_require__(1); -module.exports = generateBase("components", handler); - -/***/ }), -/* 157 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - drawCubic: function drawCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - drawCurve: function drawCurve(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - }, - - drawFunction: function drawFunction(api, label, where, generator) { - api.setRandomColor(); - api.drawFunction(generator); - api.setFill(api.getColor()); - if (label) api.text(label, where); - }, - - drawLerpBox: function drawLerpBox(api, dim, pad, p) { - api.noColor(); - api.setFill("rgba(0,0,100,0.2)"); - var p1 = { x: p.x - 5, y: pad }, - p2 = { x: p.x + 5, y: dim }; - api.drawRect(p1, p2); - api.setColor("black"); - }, - - drawLerpPoint: function drawLerpPoint(api, tf, pad, fwh, p) { - p.y = pad + tf * fwh; - api.drawCircle(p, 3); - api.setFill("black"); - api.text((tf * 10000 | 0) / 100 + "%", { x: p.x + 10, y: p.y + 4 }); - api.noFill(); - }, - - drawQuadraticLerp: function drawQuadraticLerp(api) { - api.reset(); - - var dim = api.getPanelWidth(), - pad = 20, - fwh = dim - pad * 2; - - api.drawAxes(pad, "t", 0, 1, "S", "0%", "100%"); - - var p = api.hover; - if (p && p.x >= pad && p.x <= dim - pad) { - this.drawLerpBox(api, dim, pad, p); - var t = (p.x - pad) / fwh; - this.drawLerpPoint(api, (1 - t) * (1 - t), pad, fwh, p); - this.drawLerpPoint(api, 2 * (1 - t) * t, pad, fwh, p); - this.drawLerpPoint(api, t * t, pad, fwh, p); - } - - this.drawFunction(api, "first term", { x: pad * 2, y: fwh }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * (1 - t) * (1 - t) - }; - }); - this.drawFunction(api, "second term", { x: dim / 2 - 1.5 * pad, y: dim / 2 + pad }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * 2 * (1 - t) * t - }; - }); - this.drawFunction(api, "third term", { x: fwh - pad * 2.5, y: fwh }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * t * t - }; - }); - }, - - drawCubicLerp: function drawCubicLerp(api) { - api.reset(); - - var dim = api.getPanelWidth(), - pad = 20, - fwh = dim - pad * 2; - - api.drawAxes(pad, "t", 0, 1, "S", "0%", "100%"); - - var p = api.hover; - if (p && p.x >= pad && p.x <= dim - pad) { - this.drawLerpBox(api, dim, pad, p); - var t = (p.x - pad) / fwh; - this.drawLerpPoint(api, (1 - t) * (1 - t) * (1 - t), pad, fwh, p); - this.drawLerpPoint(api, 3 * (1 - t) * (1 - t) * t, pad, fwh, p); - this.drawLerpPoint(api, 3 * (1 - t) * t * t, pad, fwh, p); - this.drawLerpPoint(api, t * t * t, pad, fwh, p); - } - - this.drawFunction(api, "first term", { x: pad * 2, y: fwh }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * (1 - t) * (1 - t) * (1 - t) - }; - }); - this.drawFunction(api, "second term", { x: dim / 2 - 4 * pad, y: dim / 2 }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * 3 * (1 - t) * (1 - t) * t - }; - }); - this.drawFunction(api, "third term", { x: dim / 2 + 2 * pad, y: dim / 2 }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * 3 * (1 - t) * t * t - }; - }); - this.drawFunction(api, "fourth term", { x: fwh - pad * 2.5, y: fwh }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * t * t * t - }; - }); - }, - - draw15thLerp: function draw15thLerp(api) { - api.reset(); - - var dim = api.getPanelWidth(), - pad = 20, - fwh = dim - pad * 2; - - api.drawAxes(pad, "t", 0, 1, "S", "0%", "100%"); - - var factors = [1, 15, 105, 455, 1365, 3003, 5005, 6435, 6435, 5005, 3003, 1365, 455, 105, 15, 1]; - - var p = api.hover, - n; - if (p && p.x >= pad && p.x <= dim - pad) { - this.drawLerpBox(api, dim, pad, p); - for (n = 0; n <= 15; n++) { - var t = (p.x - pad) / fwh, - tf = factors[n] * Math.pow(1 - t, 15 - n) * Math.pow(t, n); - this.drawLerpPoint(api, tf, pad, fwh, p); - } - } - - for (n = 0; n <= 15; n++) { - var label = false, - position = false; - if (n === 0) { - label = "first term"; - position = { x: pad + 5, y: fwh }; - } - if (n === 15) { - label = "last term"; - position = { x: dim - 3.5 * pad, y: fwh }; - } - this.drawFunction(api, label, position, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * factors[n] * Math.pow(1 - t, 15 - n) * Math.pow(t, n) - }; - }); - } - } -}; - -/***/ }), -/* 158 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(157); -var generateBase = __webpack_require__(1); -module.exports = generateBase("control", handler); - -/***/ }), -/* 159 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var abs = Math.abs; - -module.exports = { - setup: function setup(api) { - this.api = api; - api.setPanelCount(3); - var curve1 = new api.Bezier(10, 100, 90, 30, 40, 140, 220, 220); - var curve2 = new api.Bezier(5, 150, 180, 20, 80, 250, 210, 190); - api.setCurve(curve1, curve2); - this.pairReset(); - }, - - pairReset: function pairReset() { - this.prevstep = 0; - this.step = 0; - }, - - draw: function draw(api, curves) { - var _this = this; - - api.reset(); - var offset = { x: 0, y: 0 }; - curves.forEach(function (curve) { - api.drawSkeleton(curve); - api.drawCurve(curve); - }); - - // next panel: iterations - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - offset.x += w; - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - - if (this.step === 0) { - this.pairs = [{ c1: curves[0], c2: curves[1] }]; - } - - if (this.step !== this.prevstep) { - var pairs = this.pairs; - this.pairs = []; - this.finals = []; - pairs.forEach(function (p) { - - if (p.c1.length() < 0.6 && p.c2.length() < 0.6) { - return _this.finals.push(p); - } - - var s1 = p.c1.split(0.5); - api.setColor("black"); - api.drawCurve(p.c1, offset); - api.setColor("red"); - api.drawbbox(s1.left.bbox(), offset); - api.drawbbox(s1.right.bbox(), offset); - - var s2 = p.c2.split(0.5); - api.setColor("black"); - api.drawCurve(p.c2, offset); - api.setColor("blue"); - api.drawbbox(s2.left.bbox(), offset); - api.drawbbox(s2.right.bbox(), offset); - - if (s1.left.overlaps(s2.left)) { - _this.pairs.push({ c1: s1.left, c2: s2.left }); - } - if (s1.left.overlaps(s2.right)) { - _this.pairs.push({ c1: s1.left, c2: s2.right }); - } - if (s1.right.overlaps(s2.left)) { - _this.pairs.push({ c1: s1.right, c2: s2.left }); - } - if (s1.right.overlaps(s2.right)) { - _this.pairs.push({ c1: s1.right, c2: s2.right }); - } - }); - this.prevstep = this.step; - } else { - this.pairs.forEach(function (p) { - api.setColor("black"); - api.drawCurve(p.c1, offset); - api.drawCurve(p.c2, offset); - api.setColor("red"); - api.drawbbox(p.c1.bbox(), offset); - api.setColor("blue"); - api.drawbbox(p.c2.bbox(), offset); - }); - } - - if (this.pairs.length === 0) { - this.pairReset(); - this.draw(api, curves); - } - - // next panel: results - offset.x += w; - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - - // get intersections as coordinates - var results = curves[0].intersects(curves[1]).map(function (s) { - var tvals = s.split('/').map(function (v) { - return parseFloat(v); - }); - return { t1: tvals[0], t2: tvals[1] }; - }); - - // filter out likely duplicates - var curr = results[0], - _, - i, - same = function same(a, b) { - return abs(a.t1 - b.t1) < 0.01 && abs(a.t2 - b.t2) < 0.01; - }; - for (i = 1; i < results.length; i++) { - _ = results[i]; - if (same(curr, _)) { - results.splice(i--, 1); - } else { - curr = _; - } - } - - api.setColor("lightblue"); - api.drawCurve(curves[0], offset); - api.drawCurve(curves[1], offset); - - api.setColor("blue"); - results.forEach(function (tvals) { - api.drawCircle(curves[0].get(tvals.t1), 3, offset); - }); - }, - - stepUp: function stepUp() { - this.step++; - this.api.redraw(); - } -}; - -/***/ }), -/* 160 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(159); -var generateBase = __webpack_require__(1); -module.exports = generateBase("curveintersection", handler); - -/***/ }), -/* 161 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setup: function setup(api) { - var points = [{ x: 90, y: 110 }, { x: 25, y: 40 }, { x: 230, y: 40 }, { x: 150, y: 240 }]; - api.setCurve(new api.Bezier(points)); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - if (api.hover) { - api.setColor("rgb(200,100,100)"); - var dim = api.getPanelWidth(); - var t = api.hover.x / dim; - var hull = api.drawHull(curve, t); - - for (var i = 4; i <= 8; i++) { - api.drawCircle(hull[i], 3); - } - - var p = curve.get(t); - api.drawCircle(p, 5); - api.setFill("black"); - api.drawCircle(p, 3); - var perc = t * 100 | 0; - t = perc / 100; - api.text("Sequential interpolation for " + perc + "% (t=" + t + ")", { x: 10, y: 15 }); - } - } -}; - -/***/ }), -/* 162 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(161); -var generateBase = __webpack_require__(1); -module.exports = generateBase("decasteljau", handler); - -/***/ }), -/* 163 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var generateBase = __webpack_require__(1); -module.exports = generateBase("derivatives"); - -/***/ }), -/* 164 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "step", - values: { - "38": 0.1, // up arrow - "40": -0.1 // down arrow - }, - controller: function controller(api) { - if (api.step < 0.1) { - api.step = 0.1; - } - } - } - }, - - setup: function setup(api) { - api.step = 5; - }, - - draw: function draw(api, curve) { - var dim = api.getPanelWidth(), - w = dim, - h = dim, - w2 = w / 2, - h2 = h / 2, - w4 = w2 / 2, - h4 = h2 / 2; - - api.reset(); - api.setColor("black"); - api.drawLine({ x: 0, y: h2 }, { x: w, y: h2 }); - api.drawLine({ x: w2, y: 0 }, { x: w2, y: h }); - - var offset = { x: w2, y: h2 }; - for (var t = 0, p; t <= api.step; t += 0.1) { - p = { - x: w4 * Math.cos(t), - y: h4 * Math.sin(t) - }; - api.drawPoint(p, offset); - var modulo = t % 1; - if (modulo < 0.05 || modulo > 0.95) { - api.text("t = " + Math.round(t), { - x: offset.x + 1.25 * w4 * Math.cos(t) - 10, - y: offset.y + 1.25 * h4 * Math.sin(t) + 5 - }); - api.drawCircle(p, 2, offset); - } - } - } -}; - -/***/ }), -/* 165 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(164); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("explanation", handler)); - -/***/ }), -/* 166 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = new api.Bezier(70, 155, 20, 110, 100, 75); - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = new api.Bezier(60, 105, 75, 30, 215, 115, 140, 160); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - api.setColor("lightgrey"); - - var t, - step = 0.05, - min = -10; - var pt = curve.get(min - step), - pn; - for (t = min; t <= step; t += step) { - pn = curve.get(t); - api.drawLine(pt, pn); - pt = pn; - } - - pt = curve.get(1); - var max = 10; - for (t = 1 + step; t <= max; t += step) { - pn = curve.get(t); - api.drawLine(pt, pn); - pt = pn; - } - } -}; - -/***/ }), -/* 167 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(166); -var generateBase = __webpack_require__(1); -module.exports = generateBase("extended", handler); - -/***/ }), -/* 168 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - curve.points[2].x = 210; - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.setPanelCount(3); - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var tf = curve.order + 1, - pad = 20, - pts = curve.points, - w = api.getPanelWidth(), - h = api.getPanelHeight(), - offset = { x: w, y: 0 }; - - var x_pts = JSON.parse(JSON.stringify(pts)).map(function (p, t) { - return { x: w * t / tf, y: p.x }; - }); - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - api.drawAxes(pad, "t", 0, 1, "x", 0, w, offset); - offset.x += pad; - var xcurve = new api.Bezier(x_pts); - api.drawCurve(xcurve, offset); - api.setColor("red"); - xcurve.extrema().y.forEach(function (t) { - var p = xcurve.get(t); - api.drawCircle(p, 3, offset); - }); - - offset.x += w - pad; - var y_pts = JSON.parse(JSON.stringify(pts)).map(function (p, t) { - return { x: w * t / tf, y: p.y }; - }); - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - api.drawAxes(pad, "t", 0, 1, "y", 0, w, offset); - offset.x += pad; - var ycurve = new api.Bezier(y_pts); - api.drawCurve(ycurve, offset); - api.setColor("red"); - ycurve.extrema().y.forEach(function (t) { - var p = ycurve.get(t); - api.drawCircle(p, 3, offset); - }); - } -}; - -/***/ }), -/* 169 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(168); -var generateBase = __webpack_require__(1); -module.exports = generateBase("extremities", handler); - -/***/ }), -/* 170 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "steps", - values: { - "38": 1, // up arrow - "40": -1 // down arrow - }, - controller: function controller(api) { - if (api.steps < 1) { - api.steps = 1; - } - } - } - }, - - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - api.steps = 3; - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - api.steps = 5; - }, - - drawFlattened: function drawFlattened(api, curve) { - api.reset(); - api.setColor("#DDD"); - api.drawSkeleton(curve); - api.setColor("#DDD"); - api.drawCurve(curve); - var step = 1 / api.steps; - var p0 = curve.points[0], - pc; - for (var t = step; t < 1.0 + step; t += step) { - pc = curve.get(Math.min(t, 1)); - api.setColor("red"); - api.drawLine(p0, pc); - p0 = pc; - } - api.setFill("black"); - api.text("Curve approximation using " + api.steps + " segments", { x: 10, y: 15 }); - }, - - values: { - "38": 1, // up arrow - "40": -1 // down arrow - }, - - onKeyDown: function onKeyDown(e, api) { - var v = this.values[e.keyCode]; - if (v) { - e.preventDefault(); - api.steps += v; - if (api.steps < 1) { - api.steps = 1; - } - } - } -}; - -/***/ }), -/* 171 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(170); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("flattening", handler)); - -/***/ }), -/* 172 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "distance", - values: { - "38": 1, // up arrow - "40": -1 // down arrow - } - } - }, - - setup: function setup(api, curve) { - api.setCurve(curve); - api.distance = 20; - }, - - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - this.setup(api, curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - this.setup(api, curve); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - api.setColor("blue"); - var outline = curve.outline(0, 0, api.distance, api.distance); - outline.curves.forEach(function (c) { - return api.drawCurve(c); - }); - } -}; - -/***/ }), -/* 173 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(172); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("graduatedoffset", handler)); - -/***/ }), -/* 174 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupCubic: function setupCubic(api) { - var curve = new api.Bezier(135, 25, 25, 135, 215, 75, 215, 240); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - api.setColor("red"); - curve.inflections().forEach(function (t) { - api.drawCircle(curve.get(t), 5); - }); - } -}; - -/***/ }), -/* 175 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(174); -var generateBase = __webpack_require__(1); -module.exports = generateBase("inflections", handler); - -/***/ }), -/* 176 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var min = Math.min, - max = Math.max; - -module.exports = { - setupLines: function setupLines(api) { - var curve1 = new api.Bezier([50, 50, 150, 110]); - var curve2 = new api.Bezier([50, 250, 170, 170]); - api.setCurve(curve1, curve2); - }, - - drawLineIntersection: function drawLineIntersection(api, curves) { - api.reset(); - - var lli = api.utils.lli4; - var p = lli(curves[0].points[0], curves[0].points[1], curves[1].points[0], curves[1].points[1]); - - var mark = 0; - curves.forEach(function (curve) { - api.drawSkeleton(curve); - api.setColor("black"); - if (p) { - var pts = curve.points, - mx = min(pts[0].x, pts[1].x), - my = min(pts[0].y, pts[1].y), - Mx = max(pts[0].x, pts[1].x), - My = max(pts[0].y, pts[1].y); - if (mx <= p.x && my <= p.y && Mx >= p.x && My >= p.y) { - api.setColor("#00FF00"); - mark++; - } - } - api.drawCurve(curve); - }); - - if (p) { - api.setColor(mark < 2 ? "red" : "#00FF00"); - api.drawCircle(p, 3); - } - }, - - setupQuadratic: function setupQuadratic(api) { - var curve1 = api.getDefaultQuadratic(); - var curve2 = new api.Bezier([15, 250, 220, 20]); - api.setCurve(curve1, curve2); - }, - - setupCubic: function setupCubic(api) { - var curve1 = new api.Bezier([100, 240, 30, 60, 210, 230, 160, 30]); - var curve2 = new api.Bezier([25, 260, 230, 20]); - api.setCurve(curve1, curve2); - }, - - draw: function draw(api, curves) { - api.reset(); - curves.forEach(function (curve) { - api.drawSkeleton(curve); - api.drawCurve(curve); - }); - - var utils = api.utils; - var line = { p1: curves[1].points[0], p2: curves[1].points[1] }; - var acpts = utils.align(curves[0].points, line); - var nB = new api.Bezier(acpts); - var roots = utils.roots(nB.points); - roots.forEach(function (t) { - var p = curves[0].get(t); - api.drawCircle(p, 3); - api.text("t = " + t, { x: p.x + 5, y: p.y + 10 }); - }); - } -}; - -/***/ }), -/* 177 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(176); -var generateBase = __webpack_require__(1); -module.exports = generateBase("intersections", handler); - -/***/ }), -/* 178 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - drawQuadratic: function drawQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - }, - - drawCubic: function drawCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - drawCurve: function drawCurve(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - } -}; - -/***/ }), -/* 179 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(178); -var generateBase = __webpack_require__(1); -module.exports = generateBase("introduction", handler); - -/***/ }), -/* 180 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var generateBase = __webpack_require__(1); -module.exports = generateBase("matrix"); - -/***/ }), -/* 181 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var generateBase = __webpack_require__(1); -module.exports = generateBase("matrixsplit"); - -/***/ }), -/* 182 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var abs = Math.abs; - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - api.setPanelCount(3); - var curve = api.getDefaultQuadratic(); - curve.points[2].x -= 30; - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - api.setPanelCount(3); - var curve = new api.Bezier([100, 230, 30, 160, 200, 50, 210, 160]); - curve.points[2].y -= 20; - api.setCurve(curve); - api.lut = curve.getLUT(100); - }, - - saveCurve: function saveCurve(evt, api) { - if (!api.t) return; - api.setCurve(api.newcurve); - api.t = false; - api.redraw(); - }, - - findTValue: function findTValue(evt, api) { - var t = api.curve.on({ x: evt.offsetX, y: evt.offsetY }, 7); - if (t < 0.05 || t > 0.95) return false; - return t; - }, - - markQB: function markQB(evt, api) { - api.t = this.findTValue(evt, api); - if (api.t) { - var t = api.t, - t2 = 2 * t, - top = t2 * t - t2, - bottom = top + 1, - ratio = abs(top / bottom), - curve = api.curve, - A = api.A = curve.points[1], - B = api.B = curve.get(t); - api.C = api.utils.lli4(A, B, curve.points[0], curve.points[2]); - api.ratio = ratio; - } - }, - - markCB: function markCB(evt, api) { - api.t = this.findTValue(evt, api); - if (api.t) { - var t = api.t, - mt = 1 - t, - t3 = t * t * t, - mt3 = mt * mt * mt, - bottom = t3 + mt3, - top = bottom - 1, - ratio = abs(top / bottom), - curve = api.curve, - hull = curve.hull(t), - A = api.A = hull[5], - B = api.B = curve.get(t); - api.db = curve.derivative(t); - api.C = api.utils.lli4(A, B, curve.points[0], curve.points[3]); - api.ratio = ratio; - } - }, - - drag: function drag(evt, api) { - if (!api.t) return; - - var newB = api.newB = { - x: evt.offsetX, - y: evt.offsetY - }; - - // now that we know A, B, C and the AB:BC ratio, we can compute the new A' based on the desired B' - api.newA = { - x: newB.x - (api.C.x - newB.x) / api.ratio, - y: newB.y - (api.C.y - newB.y) / api.ratio - }; - }, - - dragQB: function dragQB(evt, api) { - if (!api.t) return; - this.drag(evt, api); - api.update = [api.newA]; - }, - - dragCB: function dragCB(evt, api) { - if (!api.t) return; - this.drag(evt, api); - - // preserve struts for B when repositioning - var curve = api.curve, - hull = curve.hull(api.t), - B = api.B, - Bl = hull[7], - Br = hull[8], - dbl = { x: Bl.x - B.x, y: Bl.y - B.y }, - dbr = { x: Br.x - B.x, y: Br.y - B.y }, - pts = curve.points, - - // find new point on s--c1 - p1 = { x: api.newB.x + dbl.x, y: api.newB.y + dbl.y }, - sc1 = { - x: api.newA.x - (api.newA.x - p1.x) / (1 - api.t), - y: api.newA.y - (api.newA.y - p1.y) / (1 - api.t) - }, - - // find new point on c2--e - p2 = { x: api.newB.x + dbr.x, y: api.newB.y + dbr.y }, - sc2 = { - x: api.newA.x + (p2.x - api.newA.x) / api.t, - y: api.newA.y + (p2.y - api.newA.y) / api.t - }, - - // construct new c1` based on the fact that s--sc1 is s--c1 * t - nc1 = { - x: pts[0].x + (sc1.x - pts[0].x) / api.t, - y: pts[0].y + (sc1.y - pts[0].y) / api.t - }, - - // construct new c2` based on the fact that e--sc2 is e--c2 * (1-t) - nc2 = { - x: pts[3].x - (pts[3].x - sc2.x) / (1 - api.t), - y: pts[3].y - (pts[3].y - sc2.y) / (1 - api.t) - }; - - api.p1 = p1; - api.p2 = p2; - api.sc1 = sc1; - api.sc2 = sc2; - api.nc1 = nc1; - api.nc2 = nc2; - - api.update = [nc1, nc2]; - }, - - drawMould: function drawMould(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var w = api.getPanelWidth(), - h = api.getPanelHeight(), - offset = { x: w, y: 0 }, - round = api.utils.round; - - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - api.drawLine({ x: w, y: 0 }, { x: w, y: h }, offset); - - if (api.t) { - api.drawCircle(curve.get(api.t), 3); - api.npts = [curve.points[0]].concat(api.update).concat([curve.points.slice(-1)[0]]); - api.newcurve = new api.Bezier(api.npts); - - api.setColor("lightgrey"); - api.drawCurve(api.newcurve); - var newhull = api.drawHull(api.newcurve, api.t, offset); - api.drawLine(api.npts[0], api.npts.slice(-1)[0], offset); - api.drawLine(api.newA, api.newB, offset); - - api.setColor("grey"); - api.drawCircle(api.newA, 3, offset); - api.setColor("blue"); - api.drawCircle(api.B, 3, offset); - api.drawCircle(api.C, 3, offset); - api.drawCircle(api.newB, 3, offset); - api.drawLine(api.B, api.C, offset); - api.drawLine(api.newB, api.C, offset); - - api.setFill("black"); - api.text("A'", api.newA, { x: offset.x + 7, y: offset.y + 1 }); - api.text("start", curve.get(0), { x: offset.x + 7, y: offset.y + 1 }); - api.text("end", curve.get(1), { x: offset.x + 7, y: offset.y + 1 }); - api.setFill("blue"); - api.text("B'", api.newB, { x: offset.x + 7, y: offset.y + 1 }); - api.text("B, at t = " + round(api.t, 2), api.B, { x: offset.x + 7, y: offset.y + 1 }); - api.text("C", api.C, { x: offset.x + 7, y: offset.y + 1 }); - - if (curve.order === 3) { - var hull = curve.hull(api.t); - api.drawLine(hull[7], hull[8], offset); - api.drawLine(newhull[7], newhull[8], offset); - api.drawCircle(newhull[7], 3, offset); - api.drawCircle(newhull[8], 3, offset); - api.text("e1", newhull[7], { x: offset.x + 7, y: offset.y + 1 }); - api.text("e2", newhull[8], { x: offset.x + 7, y: offset.y + 1 }); - } - - offset.x += w; - - api.setColor("lightgrey"); - api.drawSkeleton(api.newcurve, offset); - api.setColor("black"); - api.drawCurve(api.newcurve, offset); - } else { - offset.x += w; - api.drawCurve(curve, offset); - } - } -}; - -/***/ }), -/* 183 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(182); -var generateBase = __webpack_require__(1); -module.exports = generateBase("moulding", handler); - -/***/ }), -/* 184 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "distance", - values: { - "38": 1, // up arrow - "40": -1 // down arrow - } - } - }, - - setup: function setup(api, curve) { - api.setCurve(curve); - api.distance = 20; - }, - - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - this.setup(api, curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - this.setup(api, curve); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - - var reduced = curve.reduce(); - reduced.forEach(function (c) { - api.setRandomColor(); - api.drawCurve(c); - api.drawCircle(c.points[0], 1); - }); - var last = reduced.slice(-1)[0]; - api.drawPoint(last.points[3] || last.points[2]); - - api.setColor("red"); - var offset = curve.offset(api.distance); - offset.forEach(function (c) { - api.drawPoint(c.points[0]); - api.drawCurve(c); - }); - last = offset.slice(-1)[0]; - api.drawPoint(last.points[3] || last.points[2]); - - api.setColor("blue"); - offset = curve.offset(-api.distance); - offset.forEach(function (c) { - api.drawPoint(c.points[0]); - api.drawCurve(c); - }); - last = offset.slice(-1)[0]; - api.drawPoint(last.points[3] || last.points[2]); - } -}; - -/***/ }), -/* 185 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(184); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("offsetting", handler)); - -/***/ }), -/* 186 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var abs = Math.abs; - -module.exports = { - setup: function setup(api) { - api.lpts = [{ x: 56, y: 153 }, { x: 144, y: 83 }, { x: 188, y: 185 }]; - }, - - onClick: function onClick(evt, api) { - if (api.lpts.length == 3) { - api.lpts = []; - } - api.lpts.push({ - x: evt.offsetX, - y: evt.offsetY - }); - api.redraw(); - }, - - getQRatio: function getQRatio(t) { - var t2 = 2 * t, - top = t2 * t - t2, - bottom = top + 1; - return abs(top / bottom); - }, - - getCRatio: function getCRatio(t) { - var mt = 1 - t, - t3 = t * t * t, - mt3 = mt * mt * mt, - bottom = t3 + mt3, - top = bottom - 1; - return abs(top / bottom); - }, - - drawQuadratic: function drawQuadratic(api, curve) { - var labels = ["start", "t=0.5", "end"]; - - api.reset(); - - api.setColor("lightblue"); - api.drawGrid(10, 10); - - api.setFill("black"); - api.setColor("black"); - api.lpts.forEach(function (p, i) { - api.drawCircle(p, 3); - api.text(labels[i], p, { x: 5, y: 2 }); - }); - - if (api.lpts.length === 3) { - var S = api.lpts[0], - E = api.lpts[2], - B = api.lpts[1], - C = { - x: (S.x + E.x) / 2, - y: (S.y + E.y) / 2 - }; - api.setColor("blue"); - api.drawLine(S, E); - api.drawLine(B, C); - api.drawCircle(C, 3); - var ratio = this.getQRatio(0.5), - A = { - x: B.x + (B.x - C.x) / ratio, - y: B.y + (B.y - C.y) / ratio - }; - curve = new api.Bezier([S, A, E]); - api.setColor("lightgrey"); - api.drawLine(A, B); - api.drawLine(A, S); - api.drawLine(A, E); - api.setColor("black"); - api.drawCircle(A, 1); - api.drawCurve(curve); - } - }, - - drawCubic: function drawCubic(api, curve) { - var labels = ["start", "t=0.5", "end"]; - - api.reset(); - - api.setFill("black"); - api.setColor("black"); - api.lpts.forEach(function (p, i) { - api.drawCircle(p, 3); - api.text(labels[i], p, { x: 5, y: 2 }); - }); - - api.setColor("lightblue"); - api.drawGrid(10, 10); - - if (api.lpts.length === 3) { - var S = api.lpts[0], - E = api.lpts[2], - B = api.lpts[1], - C = { - x: (S.x + E.x) / 2, - y: (S.y + E.y) / 2 - }; - - api.setColor("blue"); - api.drawLine(S, E); - api.drawLine(B, C); - api.drawCircle(C, 1); - - var ratio = this.getCRatio(0.5), - A = { - x: B.x + (B.x - C.x) / ratio, - y: B.y + (B.y - C.y) / ratio - }, - selen = api.utils.dist(S, E), - bclen_min = selen / 8, - bclen = api.utils.dist(B, C), - aesthetics = 4, - be12dist = bclen_min + bclen / aesthetics, - bx = be12dist * (E.x - S.x) / selen, - by = be12dist * (E.y - S.y) / selen, - e1 = { - x: B.x - bx, - y: B.y - by - }, - e2 = { - x: B.x + bx, - y: B.y + by - }, - v1 = { - x: A.x + (e1.x - A.x) * 2, - y: A.y + (e1.y - A.y) * 2 - }, - v2 = { - x: A.x + (e2.x - A.x) * 2, - y: A.y + (e2.y - A.y) * 2 - }, - nc1 = { - x: S.x + (v1.x - S.x) * 2, - y: S.y + (v1.y - S.y) * 2 - }, - nc2 = { - x: E.x + (v2.x - E.x) * 2, - y: E.y + (v2.y - E.y) * 2 - }; - - curve = new api.Bezier([S, nc1, nc2, E]); - api.drawLine(e1, e2); - api.setColor("lightgrey"); - api.drawLine(A, C); - api.drawLine(A, v1); - api.drawLine(A, v2); - api.drawLine(S, nc1); - api.drawLine(E, nc2); - api.drawLine(nc1, nc2); - api.setColor("black"); - api.drawCircle(A, 1); - api.drawCircle(nc1, 1); - api.drawCircle(nc2, 1); - api.drawCurve(curve); - } - } -}; - -/***/ }), -/* 187 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(186); -var generateBase = __webpack_require__(1); -module.exports = generateBase("pointcurves", handler); - -/***/ }), -/* 188 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - - var i, - t, - p, - tg, - n, - m, - nd = 20; - for (i = 0; i <= 10; i++) { - t = i / 10.0; - p = curve.get(t); - tg = curve.derivative(t); - m = Math.sqrt(tg.x * tg.x + tg.y * tg.y); - tg = { x: tg.x / m, y: tg.y / m }; - n = curve.normal(t); - api.setColor("blue"); - api.drawLine(p, { x: p.x + tg.x * nd, y: p.y + tg.y * nd }); - api.setColor("red"); - api.drawLine(p, { x: p.x + n.x * nd, y: p.y + n.y * nd }); - api.setColor("black"); - api.drawCircle(p, 3); - } - } -}; - -/***/ }), -/* 189 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(188); -var generateBase = __webpack_require__(1); -module.exports = generateBase("pointvectors", handler); - -/***/ }), -/* 190 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var atan2 = Math.atan2, - sqrt = Math.sqrt, - sin = Math.sin, - cos = Math.cos; - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var w = api.getPanelWidth(), - h = api.getPanelHeight(), - cx = w / 2, - cy = h / 2, - pad = 40, - pts = [ - // first curve: - { x: cx, y: pad }, { x: w - pad, y: pad }, { x: w - pad, y: cy }, - // subsequent curve - { x: w - pad, y: h - pad }, { x: cx, y: h - pad }, - // subsequent curve - { x: pad, y: h - pad }, { x: pad, y: cy }, - // final curve control point - { x: pad, y: pad }]; - api.lpts = pts; - }, - - setupCubic: function setupCubic(api) { - var w = api.getPanelWidth(), - h = api.getPanelHeight(), - cx = w / 2, - cy = h / 2, - pad = 40, - r = (w - 2 * pad) / 2, - k = 0.55228, - kr = k * r, - pts = [ - // first curve: - { x: cx, y: pad }, { x: cx + kr, y: pad }, { x: w - pad, y: cy - kr }, { x: w - pad, y: cy }, - // subsequent curve - { x: w - pad, y: cy + kr }, { x: cx + kr, y: h - pad }, { x: cx, y: h - pad }, - // subsequent curve - { x: cx - kr, y: h - pad }, { x: pad, y: cy + kr }, { x: pad, y: cy }, - // final curve control point - { x: pad, y: cy - kr }, { x: cx - kr, y: pad }]; - api.lpts = pts; - }, - - movePointsQuadraticLD: function movePointsQuadraticLD(api, i) { - // ...we need to move _everything_ - var anchor, fixed, toMove; - for (var p = 1; p < 4; p++) { - anchor = i + (2 * p - 2) + api.lpts.length; - anchor = api.lpts[anchor % api.lpts.length]; - fixed = i + (2 * p - 1); - fixed = api.lpts[fixed % api.lpts.length]; - toMove = i + 2 * p; - toMove = api.lpts[toMove % api.lpts.length]; - - toMove.x = fixed.x + (fixed.x - anchor.x); - toMove.y = fixed.y + (fixed.y - anchor.y); - } - // then, the furthest point cannot be computed properly! - toMove = i + 6; - toMove = api.lpts[toMove % api.lpts.length]; - api.problem = toMove; - }, - - movePointsCubicLD: function movePointsCubicLD(api, i) { - var toMove, fixed; - if (i % 3 === 1) { - fixed = i - 1; - fixed += fixed < 0 ? api.lpts.length : 0; - toMove = i - 2; - toMove += toMove < 0 ? api.lpts.length : 0; - } else { - fixed = (i + 1) % api.lpts.length; - toMove = (i + 2) % api.lpts.length; - } - fixed = api.lpts[fixed]; - toMove = api.lpts[toMove]; - toMove.x = fixed.x + (fixed.x - api.mp.x); - toMove.y = fixed.y + (fixed.y - api.mp.y); - }, - - linkDerivatives: function linkDerivatives(evt, api) { - if (api.mp) { - var quad = api.lpts.length === 8; - var i = api.mp_idx; - if (quad) { - if (i % 2 !== 0) { - this.movePointsQuadraticLD(api, i); - } - } else { - if (i % 3 !== 0) { - this.movePointsCubicLD(api, i); - } - } - } - }, - - movePointsQuadraticDirOnly: function movePointsQuadraticDirOnly(api, i) { - // ...we need to move _everything_ ...again - var anchor, fixed, toMove; - - // move left and right - [-1, 1].forEach(function (v) { - anchor = api.mp; - fixed = i + v + api.lpts.length; - fixed = api.lpts[fixed % api.lpts.length]; - toMove = i + 2 * v + api.lpts.length; - toMove = api.lpts[toMove % api.lpts.length]; - var a = atan2(fixed.y - anchor.y, fixed.x - anchor.x), - dx = toMove.x - fixed.x, - dy = toMove.y - fixed.y, - d = sqrt(dx * dx + dy * dy); - toMove.x = fixed.x + d * cos(a); - toMove.y = fixed.y + d * sin(a); - }); - - // then, the furthest point cannot be computed properly! - toMove = i + 4; - toMove = api.lpts[toMove % api.lpts.length]; - api.problem = toMove; - }, - - movePointsCubicDirOnly: function movePointsCubicDirOnly(api, i) { - var toMove, fixed; - if (i % 3 === 1) { - fixed = i - 1; - fixed += fixed < 0 ? api.lpts.length : 0; - toMove = i - 2; - toMove += toMove < 0 ? api.lpts.length : 0; - } else { - fixed = (i + 1) % api.lpts.length; - toMove = (i + 2) % api.lpts.length; - } - fixed = api.lpts[fixed]; - toMove = api.lpts[toMove]; - var a = atan2(fixed.y - api.mp.y, fixed.x - api.mp.x), - dx = toMove.x - fixed.x, - dy = toMove.y - fixed.y, - d = sqrt(dx * dx + dy * dy); - toMove.x = fixed.x + d * cos(a); - toMove.y = fixed.y + d * sin(a); - }, - - linkDirection: function linkDirection(evt, api) { - if (api.mp) { - var quad = api.lpts.length === 8; - var i = api.mp_idx; - if (quad) { - if (i % 2 !== 0) { - this.movePointsQuadraticDirOnly(api, i); - } - } else { - if (i % 3 !== 0) { - this.movePointsCubicDirOnly(api, i); - } - } - } - }, - - bufferPoints: function bufferPoints(evt, api) { - api.bpts = JSON.parse(JSON.stringify(api.lpts)); - }, - - moveQuadraticPoint: function moveQuadraticPoint(api, i) { - this.moveCubicPoint(api, i); - - // then move the other control points - [-1, 1].forEach(function (v) { - var anchor = i - v + api.lpts.length; - anchor = api.lpts[anchor % api.lpts.length]; - var fixed = i - 2 * v + api.lpts.length; - fixed = api.lpts[fixed % api.lpts.length]; - var toMove = i - 3 * v + api.lpts.length; - toMove = api.lpts[toMove % api.lpts.length]; - var a = atan2(fixed.y - anchor.y, fixed.x - anchor.x), - dx = toMove.x - fixed.x, - dy = toMove.y - fixed.y, - d = sqrt(dx * dx + dy * dy); - toMove.x = fixed.x + d * cos(a); - toMove.y = fixed.y + d * sin(a); - }); - - // then signal a problem - var toMove = i + 4; - toMove = api.lpts[toMove % api.lpts.length]; - api.problem = toMove; - }, - - moveCubicPoint: function moveCubicPoint(api, i) { - var op = api.bpts[i], - np = api.lpts[i], - dx = np.x - op.x, - dy = np.y - op.y, - len = api.lpts.length, - l = i - 1 + len, - r = i + 1, - - // original left and right - ol = api.bpts[l % len], - or = api.bpts[r % len], - - // current left and right - nl = api.lpts[l % len], - nr = api.lpts[r % len]; - // update current left - nl.x = ol.x + dx; - nl.y = ol.y + dy; - // update current right - nr.x = or.x + dx; - nr.y = or.y + dy; - return { x: dx, y: dy }; - }, - - modelCurve: function modelCurve(evt, api) { - if (api.mp) { - var quad = api.lpts.length === 8; - var i = api.mp_idx; - if (quad) { - if (i % 2 !== 0) { - this.movePointsQuadraticDirOnly(api, i); - } else { - this.moveQuadraticPoint(api, i); - } - } else { - if (i % 3 !== 0) { - this.movePointsCubicDirOnly(api, i); - } else { - this.moveCubicPoint(api, i); - } - } - } - }, - - draw: function draw(api, curves) { - api.reset(); - var pts = api.lpts; - var quad = pts.length === 8; - - var c1 = quad ? new api.Bezier(pts[0], pts[1], pts[2]) : new api.Bezier(pts[0], pts[1], pts[2], pts[3]); - api.drawSkeleton(c1, false, true); - api.drawCurve(c1); - - var c2 = quad ? new api.Bezier(pts[2], pts[3], pts[4]) : new api.Bezier(pts[3], pts[4], pts[5], pts[6]); - api.drawSkeleton(c2, false, true); - api.drawCurve(c2); - - var c3 = quad ? new api.Bezier(pts[4], pts[5], pts[6]) : new api.Bezier(pts[6], pts[7], pts[8], pts[9]); - api.drawSkeleton(c3, false, true); - api.drawCurve(c3); - - var c4 = quad ? new api.Bezier(pts[6], pts[7], pts[0]) : new api.Bezier(pts[9], pts[10], pts[11], pts[0]); - api.drawSkeleton(c4, false, true); - api.drawCurve(c4); - - if (api.problem) { - api.setColor("red"); - api.drawCircle(api.problem, 5); - } - } -}; - -/***/ }), -/* 191 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(190); -var generateBase = __webpack_require__(1); -module.exports = generateBase("polybezier", handler); - -/***/ }), -/* 192 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var generateBase = __webpack_require__(1); -module.exports = generateBase("preface"); - -/***/ }), -/* 193 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setup: function setup(api) { - api.setSize(320, 320); - var curve = new api.Bezier([{ x: 248, y: 188 }, { x: 218, y: 294 }, { x: 45, y: 290 }, { x: 12, y: 236 }, { x: 14, y: 82 }, { x: 186, y: 177 }, { x: 221, y: 90 }, { x: 18, y: 156 }, { x: 34, y: 57 }, { x: 198, y: 18 }]); - api.setCurve(curve); - api._lut = curve.getLUT(); - }, - - findClosest: function findClosest(LUT, p, dist) { - var i, - end = LUT.length, - d, - dd = dist(LUT[0], p), - f = 0; - for (i = 1; i < end; i++) { - d = dist(LUT[i], p); - if (d < dd) { - f = i;dd = d; - } - } - return f / (end - 1); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - if (api.mousePt) { - api.setColor("red"); - api.setFill("red"); - api.drawCircle(api.mousePt, 3); - // naive t value - var t = this.findClosest(api._lut, api.mousePt, api.utils.dist); - // no real point in refining for illustration purposes - var p = curve.get(t); - api.drawLine(p, api.mousePt); - api.drawCircle(p, 3); - api.text("t = " + api.utils.round(t, 2), p, { x: 10, y: 3 }); - } - }, - - onMouseMove: function onMouseMove(evt, api) { - api.mousePt = { x: evt.offsetX, y: evt.offsetY }; - api._lut = api.curve.getLUT(); - } -}; - -/***/ }), -/* 194 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(193); -var generateBase = __webpack_require__(1); -module.exports = generateBase("projections", handler); - -/***/ }), -/* 195 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var Reordering = { - statics: { - // Improve this based on http://www.sirver.net/blog/2011/08/23/degree-reduction-of-bezier-curves/ - lower: function lower(curve) { - var pts = curve.points, - q = [], - n = pts.length; - pts.forEach(function (p, k) { - if (!k) { - return q[k] = p; - } - var f1 = k / n, - f2 = 1 - f1; - q[k] = { - x: f1 * p.x + f2 * pts[k - 1].x, - y: f1 * p.y + f2 * pts[k - 1].y - }; - }); - q.splice(n - 1, 1); - q[n - 2] = pts[n - 1]; - curve.points = q; - return curve; - }, - - keyHandlingOptions: { - values: { - "38": function _(api) { - api.setCurve(api.curve.raise()); - }, - "40": function _(api) { - api.setCurve(Reordering.lower(api.curve)); - } - } - } - }, - - getInitialState: function getInitialState() { - return { - order: 0 - }; - }, - - setup: function setup(api) { - var points = []; - var w = api.getPanelWidth(), - h = api.getPanelHeight(); - for (var i = 0; i < 10; i++) { - points.push({ - x: w / 2 + Math.random() * 20 + Math.cos(Math.PI * 2 * i / 10) * (w / 2 - 40), - y: h / 2 + Math.random() * 20 + Math.sin(Math.PI * 2 * i / 10) * (h / 2 - 40) - }); - } - var curve = new api.Bezier(points); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.reset(); - var pts = curve.points; - - this.setState({ - order: pts.length - }); - - var p0 = pts[0]; - - // we can't "just draw" this curve, since it'll be an arbitrary order, - // And the canvas only does 2nd and 3rd - we use de Casteljau's algorithm: - for (var t = 0; t <= 1; t += 0.01) { - var q = JSON.parse(JSON.stringify(pts)); - while (q.length > 1) { - for (var i = 0; i < q.length - 1; i++) { - q[i] = { - x: q[i].x + (q[i + 1].x - q[i].x) * t, - y: q[i].y + (q[i + 1].y - q[i].y) * t - }; - } - q.splice(q.length - 1, 1); - } - api.drawLine(p0, q[0]); - p0 = q[0]; - } - - p0 = pts[0]; - api.setColor("black"); - api.drawCircle(p0, 3); - pts.forEach(function (p) { - if (p === p0) return; - api.setColor("#DDD"); - api.drawLine(p0, p); - api.setColor("black"); - api.drawCircle(p, 3); - p0 = p; - }); - }, - - getOrder: function getOrder() { - var order = this.state.order; - if (order % 10 === 1 && order !== 11) { - order += "st"; - } else if (order % 10 === 2 && order !== 12) { - order += "nd"; - } else if (order % 10 === 3 && order !== 13) { - order += "rd"; - } else { - order += "th"; - } - return order; - } -}; - -module.exports = Reordering; - -/***/ }), -/* 196 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(195); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("reordering", handler)); - -/***/ }), -/* 197 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var modes; - -module.exports = { - getInitialState: function getInitialState() { - modes = this.modes = ["unite", "intersect", "exclude", "subtract"]; - return { - mode: modes[0] - }; - }, - - setMode: function setMode(mode) { - this.setState({ mode: mode }); - }, - - formPath: function formPath(api, mx, my, w, h) { - mx = mx || 0; - my = my || 0; - var unit = 30; - var unit2 = unit / 2; - w = w || 8 * unit; - h = h || 4 * unit; - var w2 = w / 2; - var h2 = h / 2; - var ow3 = w2 / 3; - var oh3 = h2 / 3; - - var Paper = api.Paper; - var Path = Paper.Path; - var Point = Paper.Point; - var path = new Path(); - - path.moveTo(new Point(mx - w2 + unit * 2, my - h2)); - path.cubicCurveTo(new Point(mx - w2 + unit2, my - h2 + unit2), new Point(mx - w2 + unit2, my + h2 - unit2), new Point(mx - w2 + unit * 2, my + h2)); - path.cubicCurveTo(new Point(mx - ow3, my + oh3), new Point(mx + ow3, my + oh3), new Point(mx + w2 - unit * 2, my + h2)); - path.cubicCurveTo(new Point(mx + w2 - unit2, my + h2 - unit2), new Point(mx + w2 - unit2, my - h2 + unit2), new Point(mx + w2 - unit * 2, my - h2)); - path.cubicCurveTo(new Point(mx + ow3, my - oh3), new Point(mx - ow3, my - oh3), new Point(mx - w2 + unit * 2, my - h2)); - path.closePath(true); - path.strokeColor = "rgb(100,100,255)"; - return path; - }, - - setup: function setup(api) { - var dim = api.getPanelWidth(); - var pad = 40; - var cx = dim / 2; - var cy = dim / 2; - api.c1 = this.formPath(api, cx, cy); - cx += pad; - cy += pad; - api.c2 = this.formPath(api, cx, cy); - this.state.mode = modes[0]; - }, - - onMouseMove: function onMouseMove(evt, api) { - var cx = evt.offsetX; - var cy = evt.offsetY; - api.c2.position = { x: cx, y: cy }; - }, - - draw: function draw(api) { - if (api.c3) { - api.c3.remove(); - } - var c1 = api.c1, - c2 = api.c2, - fn = c1[this.state.mode].bind(c1), - c3 = api.c3 = fn(c2); - - c3.strokeColor = "red"; - c3.fillColor = "rgba(255,100,100,0.4)"; - api.Paper.view.draw(); - } -}; - -/***/ }), -/* 198 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(197); -var generateBase = __webpack_require__(1); -module.exports = generateBase("shapes", handler); - -/***/ }), -/* 199 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - api.forward = true; - }, - - drawSplit: function drawSplit(api, curve) { - api.setPanelCount(2); - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var offset = { x: 0, y: 0 }; - var t = 0.5; - var pt = curve.get(0.5); - var split = curve.split(t); - api.drawCurve(split.left); - api.drawCurve(split.right); - api.setColor("red"); - api.drawCircle(pt, 3); - - api.setColor("black"); - offset.x = api.getPanelWidth(); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: api.getPanelHeight() }, offset); - - api.setColor("lightgrey"); - api.drawCurve(curve, offset); - api.drawCircle(pt, 4); - - offset.x -= 20; - offset.y -= 20; - api.drawSkeleton(split.left, offset, true); - api.drawCurve(split.left, offset); - - offset.x += 40; - offset.y += 40; - api.drawSkeleton(split.right, offset, true); - api.drawCurve(split.right, offset); - }, - - drawAnimated: function drawAnimated(api, curve) { - api.setPanelCount(3); - api.reset(); - - var frame = api.getFrame(); - var interval = 5 * api.getPlayInterval(); - var t = frame % interval / interval; - var forward = frame % (2 * interval) < interval; - if (forward) { - t = t % 1; - } else { - t = 1 - t % 1; - } - var offset = { x: 0, y: 0 }; - - api.setColor("lightblue"); - api.drawHull(curve, t); - api.drawSkeleton(curve); - api.drawCurve(curve); - var pt = curve.get(t); - api.drawCircle(pt, 4); - - api.setColor("black"); - offset.x += api.getPanelWidth(); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: api.getPanelHeight() }, offset); - - var split = curve.split(t); - - api.setColor("lightgrey"); - api.drawCurve(curve, offset); - api.drawHull(curve, t, offset); - api.setColor("black"); - api.drawCurve(split.left, offset); - api.drawPoints(split.left.points, offset); - api.setFill("black"); - api.text("Left side of curve split at t = " + (100 * t | 0) / 100, { x: 10 + offset.x, y: 15 + offset.y }); - - offset.x += api.getPanelWidth(); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: api.getPanelHeight() }, offset); - - api.setColor("lightgrey"); - api.drawCurve(curve, offset); - api.drawHull(curve, t, offset); - api.setColor("black"); - api.drawCurve(split.right, offset); - api.drawPoints(split.right.points, offset); - api.setFill("black"); - api.text("Right side of curve split at t = " + (100 * t | 0) / 100, { x: 10 + offset.x, y: 15 + offset.y }); - }, - - togglePlay: function togglePlay(evt, api) { - if (api.playing) { - api.pause(); - } else { - api.play(); - } - } -}; - -/***/ }), -/* 200 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(199); -var generateBase = __webpack_require__(1); -module.exports = generateBase("splitting", handler); - -/***/ }), -/* 201 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - align: function align(points, line) { - var tx = line.p1.x, - ty = line.p1.y, - a = -Math.atan2(line.p2.y - ty, line.p2.x - tx), - cos = Math.cos, - sin = Math.sin, - d = function d(v) { - return { - x: (v.x - tx) * cos(a) - (v.y - ty) * sin(a), - y: (v.x - tx) * sin(a) + (v.y - ty) * cos(a), - a: a - }; - }; - return points.map(d); - }, - - // FIXME: I'm not satisfied with needing to turn a bbox[] into a point[], - // this needs a bezier.js solution, really, with a call curve.tightbbox() - transpose: function transpose(points, angle, offset) { - var tx = offset.x, - ty = offset.y, - cos = Math.cos, - sin = Math.sin, - v = [points.x.min, points.y.min, points.x.max, points.y.max]; - return [{ x: v[0], y: v[1] }, { x: v[2], y: v[1] }, { x: v[2], y: v[3] }, { x: v[0], y: v[3] }].map(function (p) { - var x = p.x, - y = p.y; - return { - x: x * cos(angle) - y * sin(angle) + tx, - y: x * sin(angle) + y * cos(angle) + ty - }; - }); - }, - - draw: function draw(api, curve) { - api.reset(); - - var pts = curve.points; - var line = { p1: pts[0], p2: pts[pts.length - 1] }; - var apts = this.align(pts, line); - var angle = -apts[0].a; - var aligned = new api.Bezier(apts); - var bbox = aligned.bbox(); - var tpts = this.transpose(bbox, angle, pts[0]); - - api.setColor("#00FF00"); - api.drawLine(tpts[0], tpts[1]); - api.drawLine(tpts[1], tpts[2]); - api.drawLine(tpts[2], tpts[3]); - api.drawLine(tpts[3], tpts[0]); - - api.setColor("black"); - api.drawSkeleton(curve); - api.drawCurve(curve); - } -}; - -/***/ }), -/* 202 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(201); -var generateBase = __webpack_require__(1); -module.exports = generateBase("tightbounds", handler); - -/***/ }), -/* 203 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "steps", - values: { - "38": 1, // up arrow - "40": -1 // down arrow - }, - controller: function controller(api) { - if (api.steps < 1) { - api.steps = 1; - } - } - } - }, - - setup: function setup(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - api.steps = 8; - }, - - generate: function generate(api, curve, offset, pad, fwh) { - offset.x += pad; - offset.y += pad; - var len = curve.length(); - var pts = [{ x: 0, y: 0, d: 0 }]; - for (var v = 1, t, d; v <= 100; v++) { - t = v / 100; - d = curve.split(t).left.length(); - pts.push({ - x: api.utils.map(t, 0, 1, 0, fwh), - y: api.utils.map(d, 0, len, 0, fwh), - d: d, - t: t - }); - } - return pts; - }, - - draw: function draw(api, curve, offset) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var len = curve.length(); - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - var pad = 20; - var fwh = w - 2 * pad; - - offset.x += w; - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - api.drawAxes(pad, "t", 0, 1, "d", 0, len, offset); - - return this.generate(api, curve, offset, pad, fwh); - }, - - plotOnly: function plotOnly(api, curve) { - api.setPanelCount(2); - var offset = { x: 0, y: 0 }; - var pts = this.draw(api, curve, offset); - for (var i = 0; i < pts.length - 1; i++) { - api.drawLine(pts[i], pts[i + 1], offset); - } - }, - - drawColoured: function drawColoured(api, curve) { - api.setPanelCount(3); - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - var pad = 20; - var fwh = w - 2 * pad; - - var offset = { x: 0, y: 0 }; - var len = curve.length(); - var pts = this.draw(api, curve, offset); - var s = api.steps, - i, - p, - ts = []; - for (i = 0; i <= s; i++) { - var target = i * len / s; - // find the t nearest our target distance - for (p = 0; p < pts.length; p++) { - if (pts[p].d > target) { - p--; - break; - } - } - if (p < 0) p = 0; - if (p === pts.length) p = pts.length - 1; - ts.push(pts[p]); - } - - for (i = 0; i < pts.length - 1; i++) { - api.drawLine(pts[i], pts[i + 1], offset); - } - - ts.forEach(function (p) { - var pt = { x: api.utils.map(p.t, 0, 1, 0, fwh), y: 0 }; - var pd = { x: 0, y: api.utils.map(p.d, 0, len, 0, fwh) }; - api.setColor("black"); - api.drawCircle(pt, 3, offset); - api.drawCircle(pd, 3, offset); - api.setColor("lightgrey"); - api.drawLine(pt, { x: pt.x, y: pd.y }, offset); - api.drawLine(pd, { x: pt.x, y: pd.y }, offset); - }); - - offset = { x: 2 * w, y: 0 }; - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - - var idx = 0, - colors = ["rgb(240,0,200)", "rgb(0,40,200)"]; - api.setColor(colors[idx]); - var p0 = curve.get(pts[0].t), - p1; - api.drawCircle(curve.get(0), 4, offset); - - for (i = 1, p1; i < pts.length; i++) { - p1 = curve.get(pts[i].t); - api.drawLine(p0, p1, offset); - if (ts.indexOf(pts[i]) !== -1) { - api.setColor(colors[++idx % colors.length]); - api.drawCircle(p1, 4, offset); - } - p0 = p1; - } - } -}; - -/***/ }), -/* 204 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(203); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("tracing", handler)); - -/***/ }), -/* 205 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setup: function setup(api) { - api.setPanelCount(3); - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - api.step = 25; - }, - - draw: function draw(api, curve) { - var dim = api.getPanelWidth(), - pts = curve.points, - p1 = pts[0], - p2 = pts[1], - p3 = pts[2], - p1e, - p2e, - m, - t, - i, - offset = { x: 0, y: 0 }, - d, - v, - tvp; - - api.reset(); - - api.setColor("black"); - api.setFill("black"); - api.drawSkeleton(curve, offset); - api.text("First linear interpolation at " + api.step + "% steps", { x: 5, y: 15 }, offset); - - offset.x += dim; - api.drawLine({ x: 0, y: 0 }, { x: 0, y: this.dim }, offset); - api.drawSkeleton(curve, offset); - api.text("Second interpolation at " + api.step + "% steps", { x: 5, y: 15 }, offset); - - offset.x += dim; - api.drawLine({ x: 0, y: 0 }, { x: 0, y: this.dim }, offset); - api.drawSkeleton(curve, offset); - api.text("Curve points generated this way", { x: 5, y: 15 }, offset); - - api.setColor("lightgrey"); - for (t = 1, d = 20, v, tvp; t < d; t++) { - v = t / d; - tvp = curve.get(v); - api.drawCircle(tvp, 2, offset); - } - - for (i = 3 * api.step; i > 0; i -= api.step) { - t = i / 100; - if (t > 1) continue; - api.setRandomColor(); - - p1e = { - x: p1.x + t * (p2.x - p1.x), - y: p1.y + t * (p2.y - p1.y) - }; - - p2e = { - x: p2.x + t * (p3.x - p2.x), - y: p2.y + t * (p3.y - p2.y) - }; - - m = { - x: p1e.x + t * (p2e.x - p1e.x), - y: p1e.y + t * (p2e.y - p1e.y) - }; - - offset = { x: 0, y: 0 }; - api.drawCircle(p1e, 3, offset); - api.drawCircle(p2e, 3, offset); - api.setWeight(0.5); - api.drawLine(p1e, p2e, offset); - api.setWeight(1.5); - api.drawLine(p1, p1e, offset); - api.drawLine(p2, p2e, offset); - api.setWeight(1); - - offset.x += dim; - api.drawCircle(p1e, 3, offset); - api.drawCircle(p2e, 3, offset); - api.setWeight(0.5); - api.drawLine(p1e, p2e, offset); - api.setWeight(1.5); - api.drawLine(p1e, m, offset); - api.setWeight(1); - api.drawCircle(m, 3, offset); - - offset.x += dim; - api.drawCircle(m, 3, offset); - - api.text(i + "%, or t = " + api.utils.round(t, 2), { x: m.x + 10 + offset.x, y: m.y + 10 + offset.y }); - } - }, - - values: { - "38": 1, // up arrow - "40": -1 // down arrow - }, - - onKeyDown: function onKeyDown(e, api) { - var v = this.values[e.keyCode]; - if (v) { - e.preventDefault(); - api.step += v; - if (api.step < 1) { - api.step = 1; - } - } - } -}; - -/***/ }), -/* 206 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(205); -var generateBase = __webpack_require__(1); -module.exports = generateBase("whatis", handler); - -/***/ }), -/* 207 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -var React=__webpack_require__(5);var Graphic=__webpack_require__(113);var SectionHeader=__webpack_require__(69);var BSplineGraphic=__webpack_require__(110);var KnotController=__webpack_require__(115);var WeightController=__webpack_require__(120);SectionHeader.locale="en-GB";module.exports={"locale":"en-GB","preface":{"locale":"en-GB","title":"Preface","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"preface",title:"Preface"}),React.createElement("p",null,"In order to draw things in 2D, we usually rely on lines, which typically get classified into two categories: straight lines, and curves. The first of these are as easy to draw as they are easy to make a computer draw. Give a computer the first and last point in the line, and BAM! straight line. No questions asked."),React.createElement("p",null,"Curves, however, are a much bigger problem. While we can draw curves with ridiculous ease freehand, computers are a bit handicapped in that they can't draw curves unless there is a mathematical function that describes how it should be drawn. In fact, they even need this for straight lines, but the function is ridiculously easy, so we tend to ignore that as far as computers are concerned, all lines are \"functions\", regardless of whether they're straight or curves. However, that does mean that we need to come up with fast-to-compute functions that lead to nice looking curves on a computer. There's a number of these, and in this article we'll focus on a particular function that has received quite a bit of attention, and is used in pretty much anything that can draw curves: \"Bézier\" curves"),React.createElement("p",null,"They're named after ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Pierre_B%C3%A9zier"},"Pierre Bézier"),", who is principally responsible for getting them known to the world as a curve well-suited for design work (working for Renault and publishing his investigations in 1962), although he was not the first, or only one, to \"invent\" these type of curves. One might be tempted to say that the mathematician ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Paul_de_Casteljau"},"Paul de Casteljau")," was first, investigating the nature of these curves in 1959 while working at Citroën, coming up with a really elegant way of figuring out how to draw them. However, de Casteljau did not publish his work, making the question \"who was first\" hard to answer in any absolute sense. Or is it? Bézier curves are, at their core, \"Bernstein polynomials\", a family of mathematical functions investigated by ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Sergei_Natanovich_Bernstein"},"Sergei Natanovich Bernstein"),", with publications on them at least as far back as 1912. Anyway, that's mostly trivia, what you are more likely to care about is that these curves are handy: you can link up multiple Bézier curves so that the combination looks like a single curve. If you've ever drawn Photoshop \"paths\" or worked with vector drawing programs like Flash, Illustrator or nkscape, those curves you've been drawing are Bézier curves."),React.createElement("p",null,"So, what if you need to program them yourself? What are the pitfalls? How do you draw them? What are the bounding boxes, how do you determine intersections, how can you extrude a curve, in short: how do you do everything that you might want when you do with these curves? That's what this page is for. Prepare to be mathed!"),React.createElement("p",null,"—Pomax (or in the tweetworld, ",React.createElement("a",{href:"https://twitter.com/TheRealPomax"},"@TheRealPomax"),")"),React.createElement("div",{className:"note"},React.createElement("h2",{id:"note-virtually-all-b-zier-graphics-are-interactive-"},"Note: virtually all Bézier graphics are interactive."),React.createElement("p",null,"This page uses interactive examples, relying heavily on ",React.createElement("a",{href:"http://pomax.github.io/bezierjs"},"Bezier.js"),", as well as \"real\" maths (in LaTeX form) which is typeset using the most excellent ",React.createElement("a",{href:"http://MathJax.org"},"MathJax")," library. The page is generated offline as a React application, using Webpack, which has made adding \"view source\" options considerably more challenging. I'm still trying to figure out how to add them back in, but it didn't feel like it should hold up deploying this update compared to the previous years' version."),React.createElement("h2",{id:"this-book-is-open-source-"},"This book is open source."),React.createElement("p",null,"This book is an open source software project, and lives on two github repositorites. The first is ",React.createElement("a",{href:"https://github.com/pomax/bezierinfo"},"https://github.com/pomax/bezierinfo")," and is the purely-for-presentation version you are viewing right now. The other repository is ",React.createElement("a",{href:"https://github.com/pomax/BezierInfo-2"},"https://github.com/pomax/BezierInfo-2"),", which is the development version, housing all the html, javascript, and css. You can fork either of these, and pretty much do with them as you please, except for passing it off as your own work wholesale, of course =)"),React.createElement("h2",{id:"how-complicated-is-the-maths-going-to-be-"},"How complicated is the maths going to be?"),React.createElement("p",null,"Most of the mathematics in this Primer are early high school maths. If you understand basic arithmetic, and you know how to read English, you should be able to get by just fine. There will at times be ",React.createElement("em",null,"far")," more complicated maths, but if you don't feel like digesting them, you can safely skip over them by either skipping over the \"detail boxes\" in section or by just jumping to the end of a section with maths that looks too involving. The end of sections typically simply list the conclusions so you can just work with those values directly."),React.createElement("h2",{id:"questions-comments-"},"Questions, comments:"),React.createElement("p",null,"If you have suggestions for new sections, hit up the ",React.createElement("a",{href:"https://github.com/pomax/BezierInfo-2/issues"},"Github issue tracker")," (also reachable from the repo linked to in the upper right). If you have questions about the material, there's currently no comment section while I'm doing the rewrite, but you can use the issue tracker for that as well. Once the rewrite is done, I'll add a general comment section back in, and maybe a more topical \"select this section of text and hit the 'question' button to ask a question about it\" system. We'll see."),React.createElement("h2",{id:"buy-me-a-coffee-"},"Buy me a coffee?"),React.createElement("p",null,"If you enjoyed this book, or you simply found it useful for something you were trying to get done, and you were wondering how to let me know you appreciated this book, you can always ",React.createElement("a",{href:"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QPRDLNGDANJSW"},"buy me a coffee"),", however-much a coffee is where you live. This work has grown over the years, from a small primer to a 70ish print-page-equivalent reader on the subject of Bézier curves, and a lot of coffee went into the making of it. I don't regret a minute I spent on writing it, but I can always do with some more coffee to keep on writing!")));}},"introduction":{"locale":"en-GB","title":"A lightning introduction","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"introduction",title:"A lightning introduction",number:"1"}),React.createElement("p",null,"Let's start with the good stuff: when we're talking about Bézier curves, we're talking about the things that you can see in the following graphics. They run from some start point to some end point, with their curvature influenced by one or more \"intermediate\" control points. Now, because all the graphics on this page are interactive, go manipulate those curves a bit: click-drag the points, and see how their shape changes based on what you do."),React.createElement("div",{className:"figure"},React.createElement(Graphic,{inline:true,title:"Quadratic Bézier curves",setup:handler.drawQuadratic,draw:handler.drawCurve}),React.createElement(Graphic,{inline:true,title:"Cubic Bézier curves",setup:handler.drawCubic,draw:handler.drawCurve})),React.createElement("p",null,"These curves are used a lot in computer aided design and computer aided manufacturing (CAD/CAM) applications, as well as in graphic design programs like Adobe Illustrator and Photoshop, Inkscape, the Gimp, etc. and in graphic technologies like scalable vector graphics (SVG) and OpenType fonts (ttf/otf). A lot of things use Bézier curves, so if you want to learn more about them... prepare to get your learn on!"));}},"whatis":{"locale":"en-GB","title":"So what makes a Bézier Curve?","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"whatis",title:"So what makes a Bézier Curve?",number:"2"}),React.createElement("p",null,"Playing with the points for curves may have given you a feel for how Bézier curves behave, but what ",React.createElement("em",null,"are")," Bézier curves, really? There are two ways to explain what a Bézier curve is, and they turn out to be the entirely equivalent, but one of them uses complicated maths, and the other uses really simple maths. So... let's start with the simple explanation:"),React.createElement("p",null,"Bezier curves are the result of ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Linear_interpolation"},"linear interpolations"),". That sounds complicated but you've been doing linear interpolation since you were very young: any time you had to point at something between two other things, you've been applying linear interpolation. It's simply \"picking a point between two points\"."),React.createElement("p",null,"If we know the distance between those two points, and we want a new point that is, say, 20% the distance away from the first point (and thus 80% the distance away from the second point) then we can compute that really easily:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/8090904d6448ed0c8e6151aecf62f361d51ead96.svg",width:"526.4rem",height:"107.8rem"}),React.createElement("p",null,"So let's look at that in action: the following graphic is interactive in that you can use your up and down arrow keys to increase or decrease the interpolation ratio, to see what happens. We start with three points, which gives us two lines. Linear interpolation over those lines gives use two points, between which we can again perform linear interpolation, yielding a single point. And that point —and all points we can form in this way for all ratios taken together— form our Bézier curve:"),React.createElement(Graphic,{title:"Linear Interpolation leading to Bézier curves",setup:handler.setup,draw:handler.draw,onKeyDown:handler.onKeyDown}),React.createElement("p",null,"And that brings us to the complicated maths: calculus."),React.createElement("p",null,"While it doesn't look like that's what we've just done, we actually just drew a quadratic curve, in steps, rather than in a single go. One of the fascinating parts about Bézier curves is that they can both be described in terms of polynomial functions, as well as in terms of very simple interpolations of interpolations of [...]. That, in turn, means we can look at what these curves can do based on both \"real maths\" (by examining the functions, their derivatives, and all that stuff), as well as by looking at the \"mechanical\" composition (which tells us that a curve will never extend beyond the points we used to construct it, for instance)"),React.createElement("p",null,"So let's start looking at Bézier curves a bit more in depth. Their mathematical expressions, the properties we can derive from those, and the various things we can do to, and with, Bézier curves."));}},"explanation":{"locale":"en-GB","title":"The mathematics of Bézier curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"explanation",title:"The mathematics of Bézier curves",number:"3"}),React.createElement("p",null,"Bézier curves are a form of \"parametric\" function. Mathematically speaking, parametric functions are cheats: a \"function\" is actually a well defined term representing a mapping from any number of inputs to a ",React.createElement("strong",null,"single")," output. Numbers go in, a single number comes out. Change the numbers that go in, and the number that comes out is still a single number. Parametric functions cheat. They basically say \"alright, well, we want multiple values coming out, so we'll just use more than one function\". An illustration: Let's say we have a function that maps some value, let's call it ",React.createElement("i",null,"x"),", to some other value, using some kind of number manipulation:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/785e792c343b71d4e674ac94d8800940b30917ac.svg",width:"100.8rem",height:"18.2rem"}),React.createElement("p",null,"The notation ",React.createElement("i",null,"f(x)")," is the standard way to show that it's a function (by convention called ",React.createElement("i",null,"f")," if we're only listing one) and its output changes based on one variable (in this case, ",React.createElement("i",null,"x"),"). Change ",React.createElement("i",null,"x"),", and the output for ",React.createElement("i",null,"f(x)")," changes."),React.createElement("p",null,"So far so good. Now, let's look at parametric functions, and how they cheat. Let's take the following two functions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0dfe7562b43441e72201ff4cdd2e8b6e2e3ecb2d.svg",width:"98rem",height:"37.8rem"}),React.createElement("p",null,"There's nothing really remarkable about them, they're just a sine and cosine function, but you'll notice the inputs have different names. If we change the value for ",React.createElement("i",null,"a"),", we're not going to change the output value for ",React.createElement("i",null,"f(b)"),", since ",React.createElement("i",null,"a")," isn't used in that function. Parametric functions cheat by changing that. In a parametric function all the different functions share a variable, like this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ed6f533530199d1e99b3319ba137c1327b0459c0.svg",width:"105rem",height:"42rem"}),React.createElement("p",null,"Multiple functions, but only one variable. If we change the value for ",React.createElement("i",null,"t"),", we change the outcome of both ",React.createElement("i",null,"f",React.createElement("sub",null,"a"),"(t)")," and ",React.createElement("i",null,"f",React.createElement("sub",null,"b"),"(t)"),". You might wonder how that's useful, and the answer is actually pretty simple: if we change the labels ",React.createElement("i",null,"f",React.createElement("sub",null,"a"),"(t)")," and ",React.createElement("i",null,"f",React.createElement("sub",null,"b"),"(t)")," with what we usually mean with them for parametric curves, things might be a lot more obvious:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ea632ea75d6a2aeb6fe69c07feb6e76f81884746.svg",width:"81.19999999999999rem",height:"42rem"}),React.createElement("p",null,"There we go. ",React.createElement("i",null,"x"),"/",React.createElement("i",null,"y")," coordinates, linked through some mystery value ",React.createElement("i",null,"t"),"."),React.createElement("p",null,"So, parametric curves don't define a ",React.createElement("i",null,"y")," coordinate in terms of an ",React.createElement("i",null,"x")," coordinate, like normal functions do, but they instead link the values to a \"control\" variable. If we vary the value of ",React.createElement("i",null,"t"),", then with every change we get ",React.createElement("strong",null,"two")," values, which we can use as (",React.createElement("i",null,"x"),",",React.createElement("i",null,"y"),") coordinates in a graph. The above set of functions, for instance, generates points on a circle: We can range ",React.createElement("i",null,"t")," from negative to positive infinity, and the resulting (",React.createElement("i",null,"x"),",",React.createElement("i",null,"y"),") coordinates will always lie on a circle with radius 1 around the origin (0,0). If we plot it for ",React.createElement("i",null,"t")," from 0 to 5, we get this (use your up and down arrow keys to change the plot end value):"),React.createElement(Graphic,{preset:"empty",title:"A (partial) circle: x=sin(t), y=cos(t)","static":true,setup:handler.setup,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"Bézier curves are (one in many classes of) parametric functions, and are characterised by using the same base function for all its dimensions. Unlike the above example, where the ",React.createElement("i",null,"x")," and ",React.createElement("i",null,"y")," values use different functions (one uses a sine, the other a cosine), Bézier curves use the \"binomial polynomial\" for both ",React.createElement("i",null,"x")," and ",React.createElement("i",null,"y"),". So what are binomial polynomials?"),React.createElement("p",null,"You may remember polynomials from high school, where they're those sums that look like:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3e8b26cf8833db7089d65e9c6b3953a3140bb19f.svg",width:"224rem",height:"21rem"}),React.createElement("p",null,"If they have a highest order term ",React.createElement("i",null,"x³")," they're called \"cubic\" polynomials, if it's ",React.createElement("i",null,"x²")," it's a \"square\" polynomial, if it's just ",React.createElement("i",null,"x")," it's a line (and if there aren't even any terms with ",React.createElement("i",null,"x")," it's not a polynomial!)"),React.createElement("p",null,"Bézier curves are polynomials of ",React.createElement("i",null,"t"),", rather than ",React.createElement("i",null,"x"),", with the value for ",React.createElement("i",null,"t")," fixed being between 0 and 1, with coefficients ",React.createElement("i",null,"a"),", ",React.createElement("i",null,"b")," etc. taking the \"binomial\" form, which sounds fancy but is actually a pretty simple description for mixing values:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/565d935cab46bc995f53190102dadfdd1afc08f6.svg",width:"385rem",height:"68.6rem"}),React.createElement("p",null,"I know what you're thinking: that doesn't look too simple, but if we remove ",React.createElement("i",null,"t")," and add in \"times one\", things suddenly look pretty easy. Check out these binomial terms:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/8c618738924e53a313a31fa407b3d91155525ee1.svg",width:"219.79999999999998rem",height:"91rem"}),React.createElement("p",null,"Notice that 2 is the same as 1+1, and 3 is 2+1 and 1+2, and 6 is 3+3... As you can see, each time we go up a dimension, we simply start and end with 1, and everything in between is just \"the two numbers above it, added together\". Now ",React.createElement("i",null,"that's")," easy to remember."),React.createElement("p",null,"There's an equally simple way to figure out how the polynomial terms work: if we rename ",React.createElement("i",null,"(1-t)")," to ",React.createElement("i",null,"a")," and ",React.createElement("i",null,"t")," to ",React.createElement("i",null,"b"),", and remove the weights for a moment, we get this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c8740a3a9a63b592e1480883a54024ebdaffaf05.svg",width:"316.4rem",height:"62.99999999999999rem"}),React.createElement("p",null,"It's basically just a sum of \"every combination of ",React.createElement("i",null,"a")," and ",React.createElement("i",null,"b"),"\", progressively replacing ",React.createElement("i",null,"a"),"'s with ",React.createElement("i",null,"b"),"'s after every + sign. So that's actually pretty simple too. So now you know binomial polynomials, and just for completeness I'm going to show you the generic function for this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/444a01611e5709f702c36f6ca17aa2761c0877a9.svg",width:"315rem",height:"57.4rem"}),React.createElement("p",null,"And that's the full description for Bézier curves. Σ in this function indicates that this is a series of additions (using the variable listed below the Σ, starting at ...=<value> and ending at the value listed on top of the Σ)."),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"how-to-implement-the-basis-function"},"How to implement the basis function"),React.createElement("p",null,"We could naively implement the basis function as a mathematical construct, using the function as our guide, like this:"),React.createElement("pre",null,"function Bezier(n,t):\n sum = 0\n for(k=0; k<n; k++):\n sum += n!/(k!*(n-k)!) * (1-t)^(n-k) * t^(k)\n return sum\n"),React.createElement("p",null,"I say we could, because we're not going to: the factorial function is ",React.createElement("em",null,"incredibly")," expensive. And, as we can see from the above explanation, we can actually create Pascal's triangle quite easily without it: just start at [1], then [1,1], then [1,2,1], then [1,3,3,1], and so on, with each next row fitting 1 more number than the previous row, starting and ending with \"1\", with all the numbers in between being the sum of the previous row's elements on either side \"above\" the one we're computing."),React.createElement("p",null,"We can generate this as a list of lists lightning fast, and then never have to compute the binomial terms because we have a lookup table:"),React.createElement("pre",null,"lut = [ [1], // n=0\n [1,1], // n=1\n [1,2,1], // n=2\n [1,3,3,1], // n=3\n [1,4,6,4,1], // n=4\n [1,5,10,10,5,1], // n=5\n [1,6,15,20,15,6,1]] // n=6\n\nbinomial(n,k):\n while(n >= lut.length):\n s = lut.length\n nextRow = new array(size=s+1)\n nextRow[0] = 1\n for(i=1, prev=s-1; i<prev; i++):\n nextRow[i] = lut[prev][i-1] + lut[prev][i]\n nextRow[s] = 1\n lut.add(nextRow)\n return lut[n][k]\n"),React.createElement("p",null,"So what's going on here? First, we declare a lookup table with a size that's reasonably large enough to accommodate most lookups. Then, we declare a function to get us the values we need, and we make sure that if an n/k pair is requested that isn't in the LUT yet, we expand it first. Our basis function now looks like this:"),React.createElement("pre",null,"function Bezier(n,t):\n sum = 0\n for(k=0; k<=n; k++):\n sum += binomial(n,k) * (1-t)^(n-k) * t^(k)\n return sum\n"),React.createElement("p",null,"Perfect. Of course, we can optimize further. For most computer graphics purposes, we don't need arbitrary curves. We need quadratic and cubic curves (this primer actually does do arbitrary curves, so you'll find code similar to shown here), which means we can drastically simplify the code:"),React.createElement("pre",null,"function Bezier(2,t):\n t2 = t * t\n mt = 1-t\n mt2 = mt * mt\n return mt2 + 2*mt*t + t2\n\nfunction Bezier(3,t):\n t2 = t * t\n t3 = t2 * t\n mt = 1-t\n mt2 = mt * mt\n mt3 = mt2 * mt\n return mt3 + 3*mt2*t + 3*mt*t2 + t3\n"),React.createElement("p",null,"And now we know how to program the basis function. Exellent.")),React.createElement("p",null,"So, now we know what the base function(s) look(s) like, time to add in the magic that makes Bézier curves so special: control points."));}},"control":{"locale":"en-GB","title":"Controlling Bézier curvatures","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"control",title:"Controlling Bézier curvatures",number:"4"}),React.createElement("p",null,"Bézier curves are (like all \"splines\") interpolation functions, meaning they take a set of points, and generate values somewhere \"between\" those points. (One of the consequences of this is that you'll never be able to generate a point that lies outside the outline for the control points, commonly called the \"hull\" for the curve. Useful information!). In fact, we can visualize how each point contributes to the value generated by the function, so we can see which points are important, where, in the curve."),React.createElement("p",null,"The following graphs show the interpolation functions for quadratic and cubic curves, with \"S\" being the strength of a point's contribution to the total sum of the Bézier function. Click or click-drag to see the interpolation percentages for each curve-defining point at a specific ",React.createElement("i",null,"t")," value."),React.createElement("div",{className:"figure"},React.createElement(Graphic,{inline:true,preset:"simple",title:"Quadratic interpolations",draw:handler.drawQuadraticLerp}),React.createElement(Graphic,{inline:true,preset:"simple",title:"Cubic interpolations",draw:handler.drawCubicLerp}),React.createElement(Graphic,{inline:true,preset:"simple",title:"15th order interpolations",draw:handler.draw15thLerp})),React.createElement("p",null,"Also shown is the interpolation function for a 15",React.createElement("sup",null,"th")," order Bézier function. As you can see, the start and end point contribute considerably more to the curve's shape than any other point in the control point set."),React.createElement("p",null,"If we want to change the curve, we need to change the weights of each point, effectively changing the interpolations. The way to do this is about as straight forward as possible: just multiply each point with a value that changes its strength. These values are conventionally called \"Weights\", and we can add them to our original Bézier function:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/cc82da74955e71db3f5f0ab77dcc4664c0387bec.svg",width:"369.59999999999997rem",height:"57.4rem"}),React.createElement("p",null,"That looks complicated, but as it so happens, the \"weights\" are actually just the coordinate values we want our curve to have: for an ",React.createElement("i",null,"n",React.createElement("sup",null,"th"))," order curve, w",React.createElement("sub",null,"0")," is our start coordinate, w",React.createElement("sub",null,"n")," is our last coordinate, and everything in between is a controlling coordinate. Say we want a cubic curve that starts at (120,160), is controlled by (35,200) and (220,260) and ends at (220,40), we use this Bézier curve:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/853858526831a7ef3eb170efe49de397bb4913a1.svg",width:"496.99999999999994rem",height:"42rem"}),React.createElement("p",null,"Which gives us the curve we saw at the top of the article:"),React.createElement(Graphic,{preset:"simple",title:"Our cubic Bézier curve",setup:handler.drawCubic,draw:handler.drawCurve}),React.createElement("p",null,"What else can we do with Bézier curves? Quite a lot, actually. The rest of this article covers a multitude of possible operations and algorithms that we can apply, and the tasks they achieve."),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"how-to-implement-the-weighted-basis-function"},"How to implement the weighted basis function"),React.createElement("p",null,"Given that we already know how to implement basis function, adding in the control points is remarkably easy:"),React.createElement("pre",null,"function Bezier(n,t,w[]):\n sum = 0\n for(k=0; k<n; k++):\n sum += w[k] * binomial(n,k) * (1-t)^(n-k) * t^(k)\n return sum\n"),React.createElement("p",null,"And for the extremely optimized versions:"),React.createElement("pre",null,"function Bezier(2,t,w[]):\n t2 = t * t\n mt = 1-t\n mt2 = mt * mt\n return w[0]*mt2 + w[1]*2*mt*t + w[2]*t2\n\nfunction Bezier(3,t,w[]):\n t2 = t * t\n t3 = t2 * t\n mt = 1-t\n mt2 = mt * mt\n mt3 = mt2 * mt\n return w[0]*mt3 + 3*w[1]*mt2*t + 3*w[2]*mt*t2 + w[3]*t3\n"),React.createElement("p",null,"And now we know how to program the weighted basis function.")));}},"extended":{"locale":"en-GB","title":"The Bézier interval [0,1]","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"extended",title:"The Bézier interval [0,1]",number:"5"}),React.createElement("p",null,"Now that we know the mathematics behind Bézier curves, there's one curious thing that you may have noticed: they always run from ",React.createElement("code",null,"t=0")," to ",React.createElement("code",null,"t=1"),". Why that particular interval?"),React.createElement("p",null,"It all has to do with how we run from \"the start\" of our curve to \"the end\" of our curve. If we have a value that is a mixture of two other values, then the general formula for this is:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7f5ebb8489a8d04beb28f47c8aac2632b78ae764.svg",width:"225.39999999999998rem",height:"16.799999999999997rem"}),React.createElement("p",null,"The obvious start and end values here need to be ",React.createElement("code",null,"a=1, b=0"),", so that the mixed value is 100% value 1, and 0% value 2, and ",React.createElement("code",null,"a=0, b=1"),", so that the mixed value is 0% value 1 and 100% value 2. Additionally, we don't want \"a\" and \"b\" to be independent: if they are, then we could just pick whatever values we like, and end up with a mixed value that is, for example, 100% value 1 ",React.createElement("strong",null,"and")," 100% value 2. In principle that's fine, but for Bézier curves we always want mixed values ",React.createElement("em",null,"between")," the start and end point, so we need to make sure we can never set \"a\" and \"b\" to some values that lead to a mix value that sums to more than 100%. And that's easy:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d326c8f323ccd2da00d998b533ac26a1c04fcfba.svg",width:"225.39999999999998rem",height:"16.799999999999997rem"}),React.createElement("p",null,"With this we can guarantee that we never sum above 100%. By restricting ",React.createElement("code",null,"a")," to values in the interval [0,1], we will always be somewhere between our two values (inclusively), and we will always sum to a 100% mix."),React.createElement("p",null,"But... what if we use this form, used in the assumption that we will only ever use values between 0 and 1, and instead use values outside of that interval? Do things go horribly wrong? Well... not really, but we get to \"see more\"."),React.createElement("p",null,"In the case of Bézier curves, extending the interval simply makes our curve \"keep going\". Bézier curves are simply segments on some polynomial curve, so if we pick a wider interval we simply get to see more of the curve. So what do they look like?"),React.createElement("p",null,"The following two graphics show you Bézier curves rendered \"the usual way\", as well as the curves they \"lie on\" if we were to extend the ",React.createElement("code",null,"t")," values much further. As you can see, there's a lot more \"shape\" hidden in the rest of the curve, and we can model those parts by moving the curve points around."),React.createElement(Graphic,{preset:"simple",title:"Quadratic infinite interval Bézier curve",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"simple",title:"Cubic infinite interval Bézier curve",setup:handler.setupCubic,draw:handler.draw}),React.createElement("p",null,"In fact, there are curves used in graphics design and computer modelling that do the opposite of Bézier curves, where rather than fixing the interval, and giving you free coordinates, they fix the coordinates, but give you freedom over the interval. A great example of this is the ",React.createElement("a",{href:"http://levien.com/phd/phd.html"},"\"Spiro\" curve"),", which is a curve based on part of a ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Euler_spiral"},"Cornu Spiral, also known as Euler's Spiral"),". It's a very aesthetically pleasing curve and you'll find it in quite a few graphics packages like ",React.createElement("a",{href:"https://fontforge.github.io"},"FontForge")," and ",React.createElement("a",{href:"https://inkscape.org"},"Inkscape"),", having even been used in font design (such as for the Inconsolata font)."));}},"matrix":{"locale":"en-GB","title":"Bézier curvatures as matrix operations","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"matrix",title:"Bézier curvatures as matrix operations",number:"6"}),React.createElement("p",null,"We can also represent Bézier as matrix operations, by expressing the Bézier formula as a polynomial basis function and a coefficients matrix, and the actual coordinates as matrix. Let's look at what this means for the cubic curve:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d961171d6d1dfc22bb1756901e79102147914360.svg",width:"491.4rem",height:"21rem"}),React.createElement("p",null,"Disregarding our actual coordinates for a moment, we have:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/f925c339011e6c38e47b9c3a571e02fca80eb5c3.svg",width:"371rem",height:"19.599999999999998rem"}),React.createElement("p",null,"We can write this as a sum of four expressions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/30d76165668bf15f62986503bea100f39c5b9fec.svg",width:"147rem",height:"78.39999999999999rem"}),React.createElement("p",null,"And we can expand these expressions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7ca5abe1124ba1e51b7f12e0469cb4b1407593b8.svg",width:"417.2rem",height:"78.39999999999999rem"}),React.createElement("p",null,"Furthermore, we can make all the 1 and 0 factors explicit:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/bccbb94942e3ff79579e4719106f4701c157727e.svg",width:"228.2rem",height:"78.39999999999999rem"}),React.createElement("p",null,"And ",React.createElement("em",null,"that"),", we can view as a series of four matrix operations:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d5f85d80fbbc62e1e8d58621b76f3d0224876b62.svg",width:"637rem",height:"75.6rem"}),React.createElement("p",null,"If we compact this into a single matrix operation, we get:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7140be48f45b2e7190fa8dffef5c05c47c038ab0.svg",width:"237.99999999999997rem",height:"75.6rem"}),React.createElement("p",null,"This kind of polynomial basis representation is generally written with the bases in increasing order, which means we need to flip our ",React.createElement("code",null,"t")," matrix horizontally, and our big \"mixing\" matrix upside down:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/4e1849950a5c13f5135aa3412e0ee634cdc67301.svg",width:"237.99999999999997rem",height:"75.6rem"}),React.createElement("p",null,"And then finally, we can add in our original coordinates as a single third matrix:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5910e25a46d9e86ab34513017f1274628a40e5a7.svg",width:"338.79999999999995rem",height:"77rem"}),React.createElement("p",null,"We can perform the same trick for the quadratic curve, in which case we end up with:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e56e78e406d625c2a5ec584216f79a5fee00d8ea.svg",width:"275.79999999999995rem",height:"57.4rem"}),React.createElement("p",null,"If we plug in a ",React.createElement("code",null,"t")," value, and then multiply the matrices, we will get exactly the same values as when we evaluate the original polynomial function, or as when we evaluate the curve using progessive linear interpolation."),React.createElement("p",null,React.createElement("strong",null,"So: why would we bother with matrices?")," Matrix representations allow us to discover things about functions that would otherwise be hard to tell. It turns out that the curves form ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Triangular_matrix"},"triangular matrices"),", and they have a determinant equal to the product of the actual coordinates we use for our curve. It's also invertible, which means there's ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Invertible_matrix#The_invertible_matrix_theorem"},"a ton of properties")," that are all satisfied. Of course, the main question is: \"Why is this useful to us, now?\", and the answer to that is that it's not immediately useful, but you'll be seeing some instances where certain curve properties can be either computed via function manipulation, or via clever use of matrices, and sometimes the matrix approach can be (drastically) faster."),React.createElement("p",null,"So for now, just remember that we can represent curves this way, and let's move on."));}},"decasteljau":{"locale":"en-GB","title":"de Casteljau's algorithm","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"decasteljau",title:"de Casteljau's algorithm",number:"7"}),React.createElement("p",null,"If we want to draw Bézier curves we can run through all values of ",React.createElement("code",null,"t")," from 0 to 1 and then compute the weighted basis function, getting the ",React.createElement("code",null,"x/y")," values we need to plot, but the more complex the curve gets, the more expensive this becomes. Instead, we can use \"de Casteljau's algorithm\" to draw curves, which is a geometric approach to drawing curves, and really easy to implement. So easy, in fact, you can do it by hand with a pencil and ruler."),React.createElement("p",null,"Rather than using our calculus function to find ",React.createElement("code",null,"x/y")," values for ",React.createElement("code",null,"t"),", let's do this instead:"),React.createElement("ul",null,React.createElement("li",null,"treat ",React.createElement("code",null,"t")," as a ratio (which it is). t=0 is 0% along a line, t=1 is 100% along a line."),React.createElement("li",null,"Take all lines between the curve's defining points. For an order ",React.createElement("code",null,"n")," curve, that's ",React.createElement("code",null,"n")," lines."),React.createElement("li",null,"Place markers along each of these line, at distance ",React.createElement("code",null,"t"),". So if ",React.createElement("code",null,"t")," is 0.2, place the mark at 20% from the start, 80% from the end."),React.createElement("li",null,"Now form lines between ",React.createElement("code",null,"those")," points. This gives ",React.createElement("code",null,"n-1")," lines."),React.createElement("li",null,"Place markers along each of these line at distance ",React.createElement("code",null,"t"),"."),React.createElement("li",null,"Form lines between ",React.createElement("code",null,"those")," points. This'll be ",React.createElement("code",null,"n-2")," lines."),React.createElement("li",null,"place markers, form lines, place markers, etc."),React.createElement("li",null,"repeat this until you have only one line left. The point ",React.createElement("code",null,"t")," on that line coincides with the original curve point at ",React.createElement("code",null,"t"),".")),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"how-to-implement-de-casteljau-s-algorithm"},"How to implement de Casteljau's algorithm"),React.createElement("p",null,"Let's just use the algorithm we just specified, and implement that:"),React.createElement("pre",null,"function drawCurve(points[], t):\n if(points.length==1):\n draw(points[0])\n else:\n newpoints=array(points.size-1)\n for(i=0; i<newpoints.length; i++):\n newpoints[i] = (1-t) * points[i] + t * points[i+1]\n drawCurve(newpoints, t)\n"),React.createElement("p",null,"And done, that's the algorithm implemented. Except usually you don't get the luxury of overloading the \"+\" operator, so let's also give the code for when you need to work with ",React.createElement("code",null,"x")," and ",React.createElement("code",null,"y")," values:"),React.createElement("pre",null,"function drawCurve(points[], t):\n if(points.length==1):\n draw(points[0])\n else:\n newpoints=array(points.size-1)\n for(i=0; i<newpoints.length; i++):\n x = (1-t) * points[i].x + t * points[i+1].x\n y = (1-t) * points[i].y + t * points[i+1].y\n newpoints[i] = new point(x,y)\n drawCurve(newpoints, t)\n"),React.createElement("p",null,"So what does this do? This draws a point, if the passed list of points is only 1 point long. Otherwise it will create a new list of points that sit at the ",React.createElement("i",null,"t")," ratios (i.e. the \"markers\" outlined in the above algorithm), and then call the draw function for this new list.")),React.createElement("p",null,"To see this in action, mouse-over the following sketch. Moving the mouse changes which curve point is explicitly evaluated using de Casteljau's algorithm, moving the cursor left-to-right (or, of course, right-to-left), shows you how a curve is generated using this approach."),React.createElement(Graphic,{preset:"simple",title:"Traversing a curve using de Casteljau's algorithm",setup:handler.setup,draw:handler.draw}));}},"flattening":{"locale":"en-GB","title":"Simplified drawing","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"flattening",title:"Simplified drawing",number:"8"}),React.createElement("p",null,"We can also simplify the drawing process by \"sampling\" the curve at certain points, and then joining those points up with straight lines, a process known as \"flattening\", as we are reducing a curve to a simple sequence of straight, \"flat\" lines."),React.createElement("p",null,"We can do this is by saying \"we want X segments\", and then sampling the curve at intervals that are spaced such that we end up with the number of segments we wanted. The advantage of this method is that it's fast: instead of evaluating 100 or even 1000 curve coordinates, we can sample a much lower number and still end up with a curve that sort-of-kind-of looks good enough. The disadvantage of course is that we lose the precision of working with \"the real curve\", so we usually can't use the flattened for for doing true intersection detection, or curvature alignment."),React.createElement(Graphic,{preset:"twopanel",title:"Flattening a quadratic curve",setup:handler.setupQuadratic,draw:handler.drawFlattened,onKeyDown:handler.onKeyDown}),React.createElement(Graphic,{preset:"twopanel",title:"Flattening a cubic curve",setup:handler.setupCubic,draw:handler.drawFlattened,onKeyDown:handler.onKeyDown}),React.createElement("p",null,"Try clicking on the sketch and using your up and down arrow keys to lower the number of segments for both the quadratic and cubic curve. You'll notice that for certain curvatures, a low number of segments works quite well, but for more complex curvatures (try this for the cubic curve), a higher number is required to capture the curvature changes properly."),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"how-to-implement-curve-flattening"},"How to implement curve flattening"),React.createElement("p",null,"Let's just use the algorithm we just specified, and implement that:"),React.createElement("pre",null,"function flattenCurve(curve, segmentCount):\n step = 1/segmentCount;\n coordinates = [curve.getXValue(0), curve.getYValue(0)]\n for(i=1; i <= segmentCount; i++):\n t = i*step;\n coordinates.push[curve.getXValue(t), curve.getYValue(t)]\n return coordinates;\n"),React.createElement("p",null,"And done, that's the algorithm implemented. That just leaves drawing the resulting \"curve\" as a sequence of lines:"),React.createElement("pre",null,"function drawFlattenedCurve(curve, segmentCount):\n coordinates = flattenCurve(curve, segmentCount)\n coord = coordinates[0], _coords;\n for(i=1; i < coordinates.length; i++):\n _coords = coordinates[i]\n line(coords, _coords)\n coords = _coords\n"),React.createElement("p",null,"We start with the first coordinate as reference point, and then just draw lines between each point and its next point.")));}},"splitting":{"locale":"en-GB","title":"Splitting curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"splitting",title:"Splitting curves",number:"9"}),React.createElement("p",null,"With de Casteljau's algorithm we also find all the points we need to split up a Bézier curve into two, smaller curves, which taken together form the original curve. When we construct de Casteljau's skeleton for some value ",React.createElement("code",null,"t"),", the procedure gives us all the points we need to split a curve at that ",React.createElement("code",null,"t")," value: one curve is defined by all the inside skeleton points found prior to our on-curve point, with the other curve being defined by all the inside skeleton points after our on-curve point."),React.createElement(Graphic,{title:"Splitting a curve",setup:handler.setupCubic,draw:handler.drawSplit}),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"implementing-curve-splitting"},"implementing curve splitting"),React.createElement("p",null,"We can implement curve splitting by bolting some extra logging onto the de Casteljau function:"),React.createElement("pre",null,"left=[]\nright=[]\nfunction drawCurve(points[], t):\n if(points.length==1):\n left.add(points[0])\n right.add(points[0])\n draw(points[0])\n else:\n newpoints=array(points.size-1)\n for(i=0; i<newpoints.length; i++):\n if(i==0):\n left.add(points[i])\n if(i==newpoints.length-1):\n right.add(points[i+1])\n newpoints[i] = (1-t) * points[i] + t * points[i+1]\n drawCurve(newpoints, t)\n"),React.createElement("p",null,"After running this function for some value ",React.createElement("code",null,"t"),", the ",React.createElement("code",null,"left")," and ",React.createElement("code",null,"right")," arrays will contain all the coordinates for two new curves - one to the \"left\" of our ",React.createElement("code",null,"t")," value, the other on the \"right\", of the same order as the original curve, and overlayed exactly on the original curve.")),React.createElement("p",null,"This is best illustrated with an animated graphic (click to play/pause):"),React.createElement(Graphic,{preset:"threepanel",title:"Bézier curve splitting",setup:handler.setupCubic,draw:handler.drawAnimated,onClick:handler.togglePlay}));}},"matrixsplit":{"locale":"en-GB","title":"Splitting curves using matrices","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"matrixsplit",title:"Splitting curves using matrices",number:"10"}),React.createElement("p",null,"Another way to split curves is to exploit the matrix representation of a Bézier curve. In ",React.createElement("a",{href:"#matrix"},"the section on matrices")," we saw that we can represent curves as matrix multiplications. Specifically, we saw these two forms for the quadratic, and cubic curves, respectively (using the reversed Bézier coefficients vector for legibility):"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e56e78e406d625c2a5ec584216f79a5fee00d8ea.svg",width:"275.79999999999995rem",height:"57.4rem"}),React.createElement("p",null,"and"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/01ea4f74c4785a19bedf18034b51510c5ce2ad8f.svg",width:"338.79999999999995rem",height:"77rem"}),React.createElement("p",null,"Let's say we want to split the curve at some point ",React.createElement("code",null,"t = z"),", forming two new (obviously smaller) Bézier curves. To find the coordinates for these two Bézier curves, we can use the matrix representation and some linear algebra. First, we split out the the actual \"point on the curve\" information as a new matrix multiplication:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d6fa091a86782480968c232ef86513c578030004.svg",width:"680.4rem",height:"57.4rem"}),React.createElement("p",null,"and"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d487e1e0181420995be49b25bc6595c9d0360435.svg",width:"845.5999999999999rem",height:"78.39999999999999rem"}),React.createElement("p",null,"If we could compact these matrices back to a form ",React.createElement("strong",null,"[t values] · [bezier matrix] · [column matrix]"),", with the first two staying the same, then that column matrix on the right would be the coordinates of a new Bézier curve that describes the first segment, from ",React.createElement("code",null,"t = 0")," to ",React.createElement("code",null,"t = z"),". As it turns out, we can do this quite easily, by exploiting some simple rules of linear algebra (and if you don't care about the derivations, just skip to the end of the box for the results!)."),React.createElement("div",{className:"note"},React.createElement("h2",{id:"deriving-new-hull-coordinates"},"Deriving new hull coordinates"),React.createElement("p",null,"Deriving the two segments upon splitting a curve takes a few steps, and the higher the curve order, the more work it is, so let's look at the quadratic curve first:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d4b8355c3f1f80aacfc2766423a30151c5180a02.svg",width:"365.4rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/fe5f623585a9bbb836f54164aecaadd3fc4ec953.svg",width:"259rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1eb9833685c9189c64d9cbdfdbb24a94e70e493f.svg",width:"259rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/55f9d31b32a3e8855f2d28c3253201c8963eefd1.svg",width:"257.59999999999997rem",height:"57.4rem"}),React.createElement("p",null,"We do this, because [",React.createElement("em",null,"M · M",React.createElement("sup",null,"-1")),"] is the identity matrix (a bit like multiplying something by x/x in calculus. It doesn't do anything to the function, but it does allow you to rewrite it to something that may be easier to work with, or can be broken up differently). Adding that as matrix multiplication has no effect on the total formula, but it does allow us to change the matrix sequence [",React.createElement("em",null,"something · M"),"] to a sequence [",React.createElement("em",null,"M · something"),"], and that makes a world of difference: if we know what [",React.createElement("em",null,"M",React.createElement("sup",null,"-1")," · Z · M"),"] is, we can apply that to our coordinates, and be left with a proper matrix representation of a quadratic Bézier curve (which is [",React.createElement("em",null,"T · M · P"),"]), with a new set of coordinates that represent the curve from ",React.createElement("em",null,"t = 0")," to ",React.createElement("em",null,"t = z"),". So let's get computing:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1dbabc115128a85389cbbcc75fbced48e5a2ca25.svg",width:"658rem",height:"58.8rem"}),React.createElement("p",null,"Excellent! Now we can form our new quadratic curve:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/2972cd74dab6560ea68189c2e53f247287cbefae.svg",width:"438.2rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/39b64e07c41ef6d734064f017036f6391321e924.svg",width:"502.59999999999997rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d615960f862664749c54858520c364efeb4a4c5a.svg",width:"516.6rem",height:"57.4rem"}),React.createElement("p",null,React.createElement("strong",null,React.createElement("em",null,"Brilliant")),": if we want a subcurve from ",React.createElement("code",null,"t = 0")," to ",React.createElement("code",null,"t = z"),", we can keep the first coordinate the same (which makes sense), our control point becomes a z-ratio mixture of the original control point and the start point, and the new end point is a mixture that looks oddly similar to a bernstein polynomial of degree two, except it uses (z-1) rather than (1-z)... These new coordinates are actually really easy to compute directly!"),React.createElement("p",null,"Of course, that's only one of the two curves. Getting the section from ",React.createElement("code",null,"t = z")," to ",React.createElement("code",null,"t = 1")," requires doing this again. We first observe what what we just did is actually evaluate the general interval [0,",React.createElement("code",null,"z"),"], which we wrote down simplified becuase of that zero, but we actually evaluated this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/a51e64df3cb31acf32d0ad5814c8c6cff41ae611.svg",width:"400.4rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b50cdfed6656e681d5885a14a3af3e67efa4ccb.svg",width:"329rem",height:"57.4rem"}),React.createElement("p",null,"If we want the interval [",React.createElement("em",null,"z"),",1], we will be evaluating this instead:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/eca8cfda9b7a3f0819ec38acc53f95af67bb26bb.svg",width:"484.4rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e8c983a3efd47356c971fe46add4d0cdf103cced.svg",width:"432.59999999999997rem",height:"60.199999999999996rem"}),React.createElement("p",null,"We're going to do the same trick, to turn ",React.createElement("code",null,"[something · M]")," into ",React.createElement("code",null,"[M · something]"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/a28b6dcc1335de19a065b6a04d8bb45d86122bb7.svg",width:"765.8rem",height:"60.199999999999996rem"}),React.createElement("p",null,"So, our final second curve looks like:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5851c9191acb59456e3706a8f6f1a0f85e691eda.svg",width:"442.4rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0333e63f50b3d43067dc299280f70e9eb98711bb.svg",width:"496.99999999999994rem",height:"60.199999999999996rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/00a133860115d7a4db4ddf62781b5ae2bffef088.svg",width:"516.6rem",height:"60.199999999999996rem"}),React.createElement("p",null,React.createElement("strong",null,React.createElement("em",null,"Nice")),": we see the same as before; can keep the last coordinate the same (which makes sense), our control point becomes a z-ratio mixture of the original control point and the end point, and the new start point is a mixture that looks oddly similar to a bernstein polynomial of degree two, except it uses (z-1) rather than (1-z). These new coordinates are ",React.createElement("em",null,"also")," really easy to compute directly!")),React.createElement("p",null,"So, using linear algebra rather than de Casteljau's algorithm, we have determined that for any quadratic curve split at some value ",React.createElement("code",null,"t = z"),", we get two subcurves that are described as Bézier curves with simple-to-derive coordinates."),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5769f44aea3344c32c497a3a77d236f524222b95.svg",width:"604.8rem",height:"57.4rem"}),React.createElement("p",null,"and"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1fdde935dc357642358bdf5e632d6539c9d4debd.svg",width:"599.1999999999999rem",height:"60.199999999999996rem"}),React.createElement("p",null,"We can do the same for cubic curves. However, I'll spare you the actual derivation (don't let that stop you from writing that out yourself, though) and simply show you the resulting new coordinate sets:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/44db09290062827525a9b23cbaf91e65063d86d7.svg",width:"883.4rem",height:"78.39999999999999rem"}),React.createElement("p",null,"and"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d6b1abe72bac1b55d184f2c4254769404371d06f.svg",width:"886.1999999999999rem",height:"81.19999999999999rem"}),React.createElement("p",null,"So, looking at our matrices, did we really need to compute the second segment matrix? No, we didn't. Actually having one segment's matrix means we implicitly have the other: push the values of each row in the matrix ",React.createElement("strong",null,React.createElement("em",null,"Q"))," to the right, with zeroes getting pushed off the right edge and appearing back on the left, and then flip the matrix vertically. Presto, you just \"calculated\" ",React.createElement("strong",null,React.createElement("em",null,"Q'")),"."),React.createElement("p",null,"Implementing curve splitting this way requires less recursion, and is just straight arithmetic with cached values, so can be cheaper on systems were recursion is expensive. If you're doing computation with devices that are good at matrix multiplication, chopping up a Bézier curve with this method will be a lot faster than applying de Casteljau."));}},"reordering":{"locale":"en-GB","title":"Lowering and elevating curve order","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"reordering",title:"Lowering and elevating curve order",number:"11"}),React.createElement("p",null,"One interesting property of Bézier curves is that an ",React.createElement("em",null,"n",React.createElement("sup",null,"th"))," order curve can always be perfectly represented by an ",React.createElement("em",null,"(n+1)",React.createElement("sup",null,"th"))," order curve, by giving the higher order curve specific control points."),React.createElement("p",null,"If we have a curve with three points, then we can create a four point curve that exactly reproduce the original curve as long as we give it the same start and end points, and for its two control points we pick \"1/3",React.createElement("sup",null,"rd")," start + 2/3",React.createElement("sup",null,"rd")," control\" and \"2/3",React.createElement("sup",null,"rd")," control + 1/3",React.createElement("sup",null,"rd")," end\", and now we have exactly the same curve as before, except represented as a cubic curve, rather than a quadratic curve."),React.createElement("p",null,"The general rule for raising an ",React.createElement("em",null,"n",React.createElement("sup",null,"th"))," order curve to an ",React.createElement("em",null,"(n+1)",React.createElement("sup",null,"th"))," order curve is as follows (observing that the start and end weights are the same as the start and end weights for the old curve):"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c69c811b7fa790fbc7d082f29855b6f66243b454.svg",width:"803.5999999999999rem",height:"64.39999999999999rem"}),React.createElement("p",null,"However, this rule also has as direct consequence that you ",React.createElement("strong",null,"cannot")," generally safely lower a curve from ",React.createElement("em",null,"n",React.createElement("sup",null,"th"))," order to ",React.createElement("em",null,"(n-1)",React.createElement("sup",null,"th"))," order, because the control points cannot be \"pulled apart\" cleanly. We can try to, but the resulting curve will not be identical to the original, and may in fact look completely different."),React.createElement("p",null,"We can apply this to a (semi) random curve, as is done in the following graphic. Select the sketch and press your up and down arrow keys to elevate or lower the curve order."),React.createElement(Graphic,{preset:"simple",title:"A "+handler.getOrder()+" order Bézier curve",setup:handler.setup,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"There is a good, if mathematical, explanation on the matrices necessary for optimal reduction over on ",React.createElement("a",{href:"http://www.sirver.net/blog/2011/08/23/degree-reduction-of-bezier-curves"},"Sirver's Castle"),", which given time will find its way in a more direct description into this article."));}},"derivatives":{"locale":"en-GB","title":"Derivatives","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"derivatives",title:"Derivatives",number:"12"}),React.createElement("p",null,"There's a number of useful things that you can do with Bézier curves based on their derivative, and one of the more amusing observations about Bézier curves is that their derivatives are, in fact, also Bézier curves. In fact, the derivation of a Bézier curve is relatively straight forward, although we do need a bit of math. First, let's look at the derivative rule for Bézier curves, which is:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/17c8e825e1d2ae198cd7c33427870a3cf8ff31a1.svg",width:"350rem",height:"46.199999999999996rem"}),React.createElement("p",null,"which we can also write (observing that ",React.createElement("i",null,"b")," in this formula is the same as our ",React.createElement("i",null,"w")," weights, and that ",React.createElement("i",null,"n")," times a summation is the same as a summation where each term is multiplied by ",React.createElement("i",null,"n"),") as:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/a3a62e074a592e2c6497046261452ef89d1893d3.svg",width:"359.79999999999995rem",height:"46.199999999999996rem"}),React.createElement("p",null,"Or, in plain text: the derivative of an n",React.createElement("sup",null,"th")," degree Bézier curve is an (n-1)",React.createElement("sup",null,"th")," degree Bézier curve, with one fewer term, and new weights w'",React.createElement("sub",null,"0"),"...w'",React.createElement("sub",null,"n-1")," derived from the original weights as n(w",React.createElement("sub",null,"i+1")," - w",React.createElement("sub",null,"i"),"), so for a 3rd degree curve, with four weights, the derivative has three new weights w'",React.createElement("sub",null,"0")," = 3(w",React.createElement("sub",null,"1"),"-w",React.createElement("sub",null,"0"),"), w'",React.createElement("sub",null,"1")," = 3(w",React.createElement("sub",null,"2"),"-w",React.createElement("sub",null,"1"),") and w'",React.createElement("sub",null,"2")," = 3(w",React.createElement("sub",null,"3"),"-w",React.createElement("sub",null,"2"),")."),React.createElement("div",{className:"note"},React.createElement("h3",{id:"-slow-down-why-is-that-true-"},"\"Slow down, why is that true?\""),React.createElement("p",null,"Sometimes just being told \"this is the derivative\" is nice, but you might want to see why this is indeed the case. As such, let's have a look at the proof for this derivative. First off, the weights are independent of the full Bézier function, so the derivative involves only the derivative of the polynomial basis function. So, let's find that:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1f8148ecaac6af494a8bb96d2f96f7a96f85d9e0.svg",width:"219.79999999999998rem",height:"37.8rem"}),React.createElement("p",null,"Applying the ",React.createElement("a",{href:"http://en.wikipedia.org/wiki/Product_rule"},"product")," and ",React.createElement("a",{href:"http://en.wikipedia.org/wiki/Chain_rule"},"chain")," rules gives us:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5dbfaadcef0cb26159cedb26c9c7c54ac008064d.svg",width:"432.59999999999997rem",height:"29.4rem"}),React.createElement("p",null,"Which is hard to work with, so let's expand that properly:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ebfac729364de2cfd10ba3b8b4a6a6c44e7b4578.svg",width:"361.2rem",height:"28rem"}),React.createElement("p",null,"Now, the trick is to turn this expression into something that has binomial coefficients again, so we want to end up with things that look like \"x! over y!(x-y)!\". If we can do that in a way that involves terms of ",React.createElement("i",null,"n-1")," and ",React.createElement("i",null,"k-1"),", we'll be on the right track."),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b2a6fe8fe85ddf02a05f618b9ab12d65cc60cb3c.svg",width:"574rem",height:"79.8rem"}),React.createElement("p",null,"And that's the first part done: the two components inside the parentheses are actually regular, lower order Bezier expressions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/222b5aafd8b8fca6dcfc04ca7ac4248f652752fd.svg",width:"560rem",height:"50.4rem"}),React.createElement("p",null,"Now to apply this to our weighted Bezier curves. We'll write out the plain curve formula that we saw earlier, and then work our way through to its derivative:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e2f7ff20e5f540af4cb96cae56a241f3ea3f52f0.svg",width:"553rem",height:"117.6rem"}),React.createElement("p",null,"If we expand this (with some color to show how terms line up), and reorder the terms by increasing values for ",React.createElement("i",null,"k")," we see the following:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/2505458c9422a6a1dcc59ad2f5b134c1daf0c860.svg",width:"315rem",height:"114.8rem"}),React.createElement("p",null,"Two of these terms fall way: the first term falls away because there is no -1",React.createElement("sup",null,"st")," term in a summation. As such, it always contributes \"nothing\", so we can safely completely ignore it for the purpose of finding the derivative function. The other term is the very last term in this expansion: one involving ",React.createElement("i",null,"B",React.createElement("sub",null,"n-1,n")),". This term would have a binomial coefficient of [",React.createElement("i",null,"i")," choose ",React.createElement("i",null,"i+1"),"], which is a non-existent binomial coefficient. Again, this term would contribute \"nothing\", so we can ignore it, too. This means we're left with:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/f058419c1a80d98e6f74ceaf385a1c4e1fc3c645.svg",width:"309.4rem",height:"74.19999999999999rem"}),React.createElement("p",null,"And that's just a summation of lower order curves:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/08a399ed22fbf888982020848612ab348e4cbfc3.svg",width:"751.8rem",height:"37.8rem"}),React.createElement("p",null,"We can rewrite this as a normal summation, and we're done:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b66421144e6848bbbe434a23b3a7b311ce9ff770.svg",width:"572.5999999999999rem",height:"53.199999999999996rem"})),React.createElement("p",null,"Let's rewrite that in a form similar to our original formula, so we can see the difference. We will first list our original formula for Bézier curves, and then the derivative:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/cc82da74955e71db3f5f0ab77dcc4664c0387bec.svg",width:"369.59999999999997rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/6c95e389e593152cd24eb52e891db7c7b37c4e97.svg",width:"560rem",height:"61.599999999999994rem"}),React.createElement("p",null,"What are the differences? In terms of the actual Bézier curve, virtually nothing! We lowered the order (rather than ",React.createElement("i",null,"n"),", it's now ",React.createElement("i",null,"n-1"),"), but it's still the same Bézier function. The only real difference is in how the weights change when we derive the curve's function. If we have four points A, B, C, and D, then the derivative will have three points, the second derivative two, and the third derivative one:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/34e8aadefa9d0ee443efe27a1fc76210eedb373c.svg",width:"548.8rem",height:"77rem"}),React.createElement("p",null,"We can keep performing this trick for as long as we have more than one weight. Once we have one weight left, the next step will see ",React.createElement("i",null,"k = 0"),", and the result of our \"Bézier function\" summation is zero, because we're not adding anything at all. As such, a quadratic curve has no second derivative, a cubic curve has no third derivative, and generalized: an ",React.createElement("i",null,"n",React.createElement("sup",null,"th"))," order curve has ",React.createElement("i",null,"n-1")," (meaningful) derivatives, with any further derivative being zero."));}},"pointvectors":{"locale":"en-GB","title":"Tangents and normals","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"pointvectors",title:"Tangents and normals",number:"13"}),React.createElement("p",null,"If you want to move objects along a curve, or \"away from\" a curve, the two vectors you're most interested in are the tangent vector and normal vector for curve points. These are actually really easy to find. For moving, and orienting, along a curve we use the tangent, which indicates the direction travel at specific points, and is literally just the first derivative of our curve:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/2271ae26977a681a1695d14ea8255564e716916e.svg",width:"148.39999999999998rem",height:"42rem"}),React.createElement("p",null,"This gives us the directional vector we want. We can normalize it to give us uniform directional vectors (having a length of 1.0) at each point, and then do whatever it is we want to do based on those directions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3cb2c4f5806142e83c66e1312520d0783d15201c.svg",width:"263.2rem",height:"26.599999999999998rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/72826b8f5053c299dbb2082678191e3564bb50a6.svg",width:"303.79999999999995rem",height:"60.199999999999996rem"}),React.createElement("p",null,"The tangent is very useful for moving along a line, but what if we want to move away from the curve instead, perpendicular to the curve at some point ",React.createElement("i",null,"t"),"? In that case we want the \"normal\" vector. This vector runs at a right angle to the direction of the curve, and is typically of length 1.0, so all we have to do is rotate the normalized directional vector and we're done:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/6cb29c325e059e236343bdd448c149ecc6d8795f.svg",width:"355.59999999999997rem",height:"62.99999999999999rem"}),React.createElement("div",{className:"note"},React.createElement("p",null,"Rotating coordinates is actually very easy, if you know the rule for it. You might find it explained as \"applying a ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Rotation_matrix"},"rotation matrix"),", which is what we'll look at here, too. Essentially, the idea is to take the circles over which we can rotate, and simply \"sliding the coordinates\" over these circles by the desired angle. If we want a quarter circle turn, we take the coordinate, slide it along the cirle by a quarter turn, and done."),React.createElement("p",null,"To turn any point ",React.createElement("i",null,"(x,y)")," into a rotated point ",React.createElement("i",null,"(x',y')")," (over 0,0) by some angle φ, we apply this nicely easy computation:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d3932ac925ad9f238029d888dc5432f6678f6491.svg",width:"191.79999999999998rem",height:"39.199999999999996rem"}),React.createElement("p",null,"Which is the \"long\" version of the following matrix transformation:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7297632eb150a8f5f37178612f71e5d0f2c367b1.svg",width:"221.2rem",height:"42rem"}),React.createElement("p",null,"And that's all we need to rotate any coordinate. Note that for quarter, half and three quarter turns these functions become even easier, since ",React.createElement("em",null,"sin")," and ",React.createElement("em",null,"cos")," for these angles are, respectively: 0 and 1, -1 and 0, and 0 and -1."),React.createElement("p",null,"But ",React.createElement("strong",null,React.createElement("em",null,"why"))," does this work? Why this matrix multiplication? ",React.createElement("a",{href:"http://en.wikipedia.org/wiki/Rotation_matrix#Decomposition_into_shears"},"Wikipedia")," (Technically, Thomas Herter and Klaus Lott) tells us that a rotation matrix can be treated as a sequence of three (elementary) shear operations. When we combine this into a single matrix operation (because all matrix multiplications can be collapsed), we get the matrix that you see above. ",React.createElement("a",{href:"http://datagenetics.com/blog/august32013/index.html"},"DataGenetics")," have an excellent article about this very thing: it's really quite cool, and I strongly recommend taking a quick break from this primer to read that article.")),React.createElement("p",null,"The following two graphics show the tangent and normal along a quadratic and cubic curve, with the direction vector coloured blue, and the normal vector coloured red (the markers are spaced out evenly as ",React.createElement("em",null,"t"),"-intervals, not spaced equidistant)."),React.createElement("div",{className:"figure"},React.createElement(Graphic,{preset:"simple",title:"Quadratic Bézier tangents and normals",inline:true,setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"simple",title:"Cubic Bézier tangents and normals",inline:true,setup:handler.setupCubic,draw:handler.draw})));}},"components":{"locale":"en-GB","title":"Component functions","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"components",title:"Component functions",number:"14"}),React.createElement("p",null,"One of the first things people run into when they start using Bézier curves in their own programs is \"I know how to draw the curve, but how do I determine the bounding box?\". It's actually reasonably straight forward to do so, but it requires having some knowledge on exploiting math to get the values we need. For bounding boxes, we aren't actually interested in the curve itself, but only in its \"extremities\": the minimum and maximum values the curve has for its x- and y-axis values. If you remember your calculus (provided you ever took calculus, otherwise it's going to be hard to remember) we can determine function extremities using the first derivative of that function, but this poses a problem, since our function is parametric: every axis has its own function."),React.createElement("p",null,"The solution: compute the derivative for each axis separately, and then fit them back together in the same way we do for the original."),React.createElement("p",null,"Let's look at how a parametric Bézier curve \"splits up\" into two normal functions, one for the x-axis and one for the y-axis. Note the left-most figure is again an interactive curve, without labeled axes (you get coordinates in the graph instead). The center and right-most figures are the component functions for computing the x-axis value, given a value for ",React.createElement("i",null,"t")," (between 0 and 1 inclusive), and the y-axis value, respectively."),React.createElement("p",null,"If you move points in a curve sideways, you should only see the middle graph change; likely, moving points vertically should only show a change in the right graph."),React.createElement(Graphic,{preset:"simple",title:"Quadratic Bézier curve components",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"simple",title:"Cubic Bézier curve components",setup:handler.setupCubic,draw:handler.draw}));}},"extremities":{"locale":"en-GB","title":"Finding extremities: root finding","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"extremities",title:"Finding extremities: root finding",number:"15"}),React.createElement("p",null,"Now that we understand (well, superficially anyway) the component functions, we can find the extremities of our Bézier curve by finding maxima and minima on the component functions, by solving the equations B'(t) = 0 and B''(t) = 0. Although, in the case of quadratic curves there is no B''(t), so we only need to compute B'(t) = 0. So, how do we compute the first and second derivatives? Fairly easily, actually, until our derivatives are 4th order or higher... then things get really hard. But let's start simple:"),React.createElement("h3",{id:"quadratic-curves-linear-derivatives-"},"Quadratic curves: linear derivatives."),React.createElement("p",null,"Finding the solution for \"where is this line 0\" should be trivial:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/baa66be2d93813bf9ef4aef1dbfac3db772e30e2.svg",width:"138.6rem",height:"109.19999999999999rem"}),React.createElement("p",null,"Done. And quadratic curves have no meaningful second derivative, so we're ",React.createElement("em",null,"really")," done."),React.createElement("h3",{id:"cubic-curves-the-quadratic-formula-"},"Cubic curves: the quadratic formula."),React.createElement("p",null,"The derivative of a cubic curve is a quadratic curve, and finding the roots for a quadratic Bézier curve means we can apply the ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Quadratic_formula"},"Quadratic formula"),". If you've seen it before, you'll remember it, and if you haven't, it looks like this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d5882cc83b002196c8e701ad273ced103e2b4484.svg",width:"431.2rem",height:"42rem"}),React.createElement("p",null,"So, if we can express a Bézier component function as a plain polynomial, we're done: we just plug in the values into the quadratic formula, check if that square root is negative or not (if it is, there are no roots) and then just compute the two values that come out (because of that plus/minus sign we get two). Any value between 0 and 1 is a root that matters for Bézier curves, anything below or above that is irrelevant (because Bézier curves are only defined over the interval [0,1]). So, how do we convert?"),React.createElement("p",null,"First we turn our cubic Bézier function into a quadratic one, by following the rule mentioned at the end of the ",React.createElement("a",{href:"#derivatives"},"derivatives section"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d38fc2ce8c5af65b94b56897b8ae8d304c84a4b7.svg",width:"561.4rem",height:"37.8rem"}),React.createElement("p",null,"And then, using these ",React.createElement("em",null,"v")," values, we can find out what our ",React.createElement("em",null,"a"),", ",React.createElement("em",null,"b"),", and ",React.createElement("em",null,"c")," should be:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/292b2b9178aca5486da7e1a596e66091ba2ed282.svg",width:"330.4rem",height:"124.6rem"}),React.createElement("p",null,"This gives us thee coefficients ",React.createElement("em",null,"a"),", ",React.createElement("em",null,"b"),", and ",React.createElement("em",null,"c")," that are expressed in terms of ",React.createElement("em",null,"v")," values, where the ",React.createElement("em",null,"v")," values are just convenient expressions of our original ",React.createElement("em",null,"p")," values, so we can do some trivial substitution to get:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/2de779b7b9c6aa130b9aeadbb8c46878b94920a1.svg",width:"323.4rem",height:"65.8rem"}),React.createElement("p",null,"Easy peasy. We can now almost trivially find the roots by plugging those values into the quadratic formula. We also note that the second derivative of a cubic curve means computing the first derivative of a quadratic curve, and we just saw how to do that in the section above."),React.createElement("h3",{id:"quartic-curves-cardano-s-algorithm-"},"Quartic curves: Cardano's algorithm."),React.createElement("p",null,"Quartic—fourth degree—curves have a cubic function as derivative. Now, cubic functions are a bit of a problem because they're really hard to solve. But, way back in the 16",React.createElement("sup",null,"th")," century, ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Gerolamo_Cardano"},"Gerolamo Cardano")," figured out that even if the general cubic function is really hard to solve, it can be rewritten to a form for which finding the roots is \"easy\", and then the only hard part is figuring out how to go from that form to the generic form. So:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/a16a0da87e138b1307973397275c296eb475b1b1.svg",width:"478.79999999999995rem",height:"21rem"}),React.createElement("p",null,"This is easier because for the \"easier formula\" we can use ",React.createElement("a",{href:"http://www.wolframalpha.com/input/?i=t^3+%2B+pt+%2B+q"},"regular calculus")," to find the roots (as a cubic function, however, it can have up to three roots, but two of those can be complex. For the purpose of Bézier curve extremities, we can completely ignore those complex roots, since our ",React.createElement("em",null,"t")," is a plain real number from 0 to 1)."),React.createElement("p",null,"So, the trick is to figure out how to turn the first formula into the second formula, and to then work out the maths that gives us the roots. This is explained in detail over at ",React.createElement("a",{href:"http://www.trans4mind.com/personal_development/mathematics/polynomials/cubicAlgebra.htm"},"Ken J. Ward's page")," for solving the cubic equation, so instead of showing the maths, I'm simply going to show the programming code for solving the cubic equation, with the complex roots getting totally ignored."),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"implementing-cardano-s-algorithm-for-finding-all-real-roots"},"Implementing Cardano's algorithm for finding all real roots"),React.createElement("p",null,"The \"real roots\" part is fairly important, because while you cannot take a square, cube, etc. root of a negative number in the \"real\" number space (denoted with ℝ), this is perfectly fine in the ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Complex_number"},"\"complex\" number")," space (denoted with ℂ). And, as it so happens, Cardano is also attributed as the first mathematician in history to have made use of complex numbers in his calculations. For this very algorithm!"),React.createElement("pre",null,"// A helper function to filter for values in the [0,1] interval:\nfunction accept(t) {\n return 0<=t && t <=1;\n}\n\n// A real-cuberoots-only function:\nfunction crt(v) {\n if(v<0) return -Math.pow(-v,1/3);\n return Math.pow(v,1/3);\n}\n\n// Now then: given cubic coordinates {pa, pb, pc, pd} find all roots.\nfunction getCubicRoots(pa, pb, pc, pd) {\n var d = (-pa + 3*pb - 3*pc + pd),\n a = (3*pa - 6*pb + 3*pc) / d,\n b = (-3*pa + 3*pb) / d,\n c = pa / d;\n\n var p = (3*b - a*a)/3,\n p3 = p/3,\n q = (2*a*a*a - 9*a*b + 27*c)/27,\n q2 = q/2,\n discriminant = q2*q2 + p3*p3*p3;\n\n // and some variables we're going to use later on:\n var u1,v1,root1,root2,root3;\n\n // three possible real roots:\n if (discriminant < 0) {\n var mp3 = -p/3,\n mp33 = mp3*mp3*mp3,\n r = sqrt( mp33 ),\n t = -q / (2*r),\n cosphi = t<-1 ? -1 : t>1 ? 1 : t,\n phi = acos(cosphi),\n crtr = cuberoot(r),\n t1 = 2*crtr;\n root1 = t1 * cos(phi/3) - a/3;\n root2 = t1 * cos((phi+2*pi)/3) - a/3;\n root3 = t1 * cos((phi+4*pi)/3) - a/3;\n return [root1, root2, root3].filter(accept);\n }\n\n // three real roots, but two of them are equal:\n if(discriminant === 0) {\n u1 = q2 < 0 ? cuberoot(-q2) : -cuberoot(q2);\n root1 = 2*u1 - a/3;\n root2 = -u1 - a/3;\n return [root1, root2].filter(accept);\n }\n\n // one real root, two complex roots\n var sd = sqrt(discriminant);\n u1 = cuberoot(sd - q2);\n v1 = cuberoot(sd + q2);\n root1 = u1 - v1 - a/3;\n return [root1].filter(accept);\n}\n")),React.createElement("p",null,"And that's it. The maths is complicated, but the code is pretty much just \"follow the maths, while caching as many values as we can to reduce recomputing things as much as possible\" and now we have a way to find all roots for a cubic function and can just move on with using that to find extremities of our curves."),React.createElement("h3",{id:"quintic-and-higher-order-curves-finding-numerical-solutions"},"Quintic and higher order curves: finding numerical solutions"),React.createElement("p",null,"The problem with this is that as the order of the curve goes up, we can't actually solve those equations the normal way. We can't take the function, and then work out what the solutions are. Not to mention that even solving a third order derivative (for a fourth order curve) is already a royal pain in the backside. We need a better solution. We need numerical approaches."),React.createElement("p",null,"That's a fancy word for saying \"rather than solve the function, treat the problem as a sequence of identical operations, the performing of which gets us closer and closer to the real answer\". As it turns out, there is a really nice numerical root finding algorithm, called the ",React.createElement("a",{href:"http://en.wikipedia.org/wiki/Newton-Raphson"},"Newton-Raphson")," root finding method (yes, after ",React.createElement("em",null,React.createElement("a",{href:"https://en.wikipedia.org/wiki/Isaac_Newton"},"that"))," Newton), which we can make use of."),React.createElement("p",null,"The Newton-Raphson approach consists of picking a value ",React.createElement("em",null,"t")," (any will do), and getting the corresponding value at that ",React.createElement("em",null,"t")," value. For normal functions, we can treat that value as a height. If the height is zero, we're done, we have found a root. If it's not, we take the tangent of the curve at that point, and extend it until it passes the x-axis, which will be at some new point ",React.createElement("em",null,"t"),". We then repeat the procedure with this new value, and we keep doing this until we find our root."),React.createElement("p",null,"Mathematically, this means that for some ",React.createElement("em",null,"t"),", at step ",React.createElement("em",null,"n=1"),", we perform the following calculation until ",React.createElement("em",null,"f",React.createElement("sub",null,"y")),"(",React.createElement("em",null,"t"),") is zero, so that the next ",React.createElement("em",null,"t")," is the same as the one we already have:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b563256be7016370365935944308cf878cdbc29c.svg",width:"130.2rem",height:"47.599999999999994rem"}),React.createElement("p",null,"(The wikipedia article has a decent animation for this process, so I'm not adding a sketch for that here unless there are requests for it)"),React.createElement("p",null,"Now, this works well only if we can pick good starting points, and our curve is continuously differentiable and doesn't have oscillations. Glossing over the exact meaning of those terms, the curves we're dealing with conform to those constraints, so as long as we pick good starting points, this will work. So the question is: which starting points do we pick?"),React.createElement("p",null,"As it turns out, Newton-Raphson is so blindingly fast, so we could get away with just not picking: we simply run the algorithm from ",React.createElement("em",null,"t=0")," to ",React.createElement("em",null,"t=1")," at small steps (say, 1/200",React.createElement("sup",null,"th"),") and the result will be all the roots we want. Of course, this may pose problems for high order Bézier curves: 200 steps for a 200",React.createElement("sup",null,"th")," order Bézier curve is going to go wrong, but that's okay: there is no reason, ever, to use Bézier curves of crazy high orders. You might use a fifth order curve to get the \"nicest still remotely workable\" approximation of a full circle with a single Bézier curve, that's pretty much as high as you'll ever need to go."),React.createElement("h3",{id:"in-conclusion-"},"In conclusion:"),React.createElement("p",null,"So now that we know how to do root finding, we can determine the first and second derivative roots for our Bézier curves, and show those roots overlaid on the previous graphics:"),React.createElement(Graphic,{preset:"simple",title:"Quadratic Bézier curve extremities",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"simple",title:"Cubic Bézier curve extremities",setup:handler.setupCubic,draw:handler.draw}));}},"boundingbox":{"locale":"en-GB","title":"Bounding boxes","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"boundingbox",title:"Bounding boxes",number:"16"}),React.createElement("p",null,"If we have the extremities, and the start/end points, a simple for loop that tests for min/max values for x and y means we have the four values we need to box in our curve:"),React.createElement("p",null,React.createElement("em",null,"Computing the bounding box for a Bézier curve"),":"),React.createElement("ol",null,React.createElement("li",null,"Find all ",React.createElement("em",null,"t")," value(s) for the curve derivative's x- and y-roots."),React.createElement("li",null,"Discard any ",React.createElement("em",null,"t")," value that's lower than 0 or higher than 1, because Bézier curves only use the interval [0,1]."),React.createElement("li",null,"Determine the lowest and highest value when plugging the values ",React.createElement("em",null,"t=0"),", ",React.createElement("em",null,"t=1")," and each of the found roots into the original functions: the lowest value is the lower bound, and the highest value is the upper bound for the bounding box we want to construct.")),React.createElement("p",null,"Applying this approach to our previous root finding, we get the following bounding boxes (with all curve extremity points shown on the curve):"),React.createElement(Graphic,{preset:"simple",title:"Quadratic Bézier bounding box",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"simple",title:"Cubic Bézier bounding box",setup:handler.setupCubic,draw:handler.draw}),React.createElement("p",null,"We can construct even nicer boxes by aligning them along our curve, rather than along the x- and y-axis, but in order to do so we first need to look at how aligning works."));}},"aligning":{"locale":"en-GB","title":"Aligning curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"aligning",title:"Aligning curves",number:"17"}),React.createElement("p",null,"While there are an incredible number of curves we can define by varying the x- and y-coordinates for the control points, not all curves are actually distinct. For instance, if we define a curve, and then rotate it 90 degrees, it's still the same curve, and we'll find its extremities in the same spots, just at different draw coordinates. As such, one way to make sure we're working with a \"unique\" curve is to \"axis-align\" it."),React.createElement("p",null,"Aligning also simplifies a curve's functions. We can translate (move) the curve so that the first point lies on (0,0), which turns our ",React.createElement("em",null,"n")," term polynomial functions into ",React.createElement("em",null,"n-1")," term functions. The order stays the same, but we have less terms. Then, we can rotate the curves so that the last point always lies on the x-axis, too, making its coordinate (...,0). This further simplifies the function for the y-component to an ",React.createElement("em",null,"n-2")," term function. For instance, if we have a cubic curve such as this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d253dc7ff011a8ae46f3351975f1d4beedd7a794.svg",width:"499.79999999999995rem",height:"42rem"}),React.createElement("p",null,"Then translating it so that the first coordinate lies on (0,0), moving all ",React.createElement("em",null,"x")," coordinates by -120, and all ",React.createElement("em",null,"y")," coordinates by -160, gives us:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b3ec747086a146c1b2c682afea6b1eae016c9a7a.svg",width:"482.99999999999994rem",height:"42rem"}),React.createElement("p",null,"If we then rotate the curve so that its end point lies on the x-axis, the coordinates (integer-rounded for illustrative purposes here) become:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/fd82fad845da25b074dff33bbc4aa563d5f367a7.svg",width:"474.59999999999997rem",height:"42rem"}),React.createElement("p",null,"If we drop all the zero-terms, this gives us:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b4d6e220358b2d00f0cf516f433fbe5ecb58f25d.svg",width:"386.4rem",height:"42rem"}),React.createElement("p",null,"We can see that our original curve definition has been simplified considerably. The following graphics illustrate the result of aligning our example curves to the x-axis, with the cubic case using the coordinates that were just used in the example formulae:"),React.createElement(Graphic,{preset:"twopanel",title:"Aligning a quadratic curve",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"twopanel",title:"Aligning a cubic curve",setup:handler.setupCubic,draw:handler.draw}));}},"tightbounds":{"locale":"en-GB","title":"Tight boxes","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"tightbounds",title:"Tight boxes",number:"18"}),React.createElement("p",null,"With our knowledge of bounding boxes, and curve alignment, We can now form the \"tight\" bounding box for curves. We first align our curve, recording the translation we performed, \"T\", and the rotation angle we used, \"R\". We then determine the aligned curve's normal bounding box. Once we have that, we can map that bounding box back to our original curve by rotating it by -R, and then translating it by -T. We now have nice tight bounding boxes for our curves:"),React.createElement(Graphic,{preset:"twopanel",title:"Aligning a quadratic curve",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"twopanel",title:"Aligning a cubic curve",setup:handler.setupCubic,draw:handler.draw}),React.createElement("p",null,"These are, strictly speaking, not necessarily the tightest possible bounding boxes. It is possible to compute the optimal bounding box by determining which spanning lines we need to effect a minimal box area, but because of the parametric nature of Bézier curves this is actually a rather costly operation, and the gain in bounding precision is often not worth it. If there is high demand for it, I'll add a section on how to precisely compute the best fit bounding box, but the maths is fairly gruelling and just not really worth spending time on."));}},"inflections":{"locale":"en-GB","title":"Curve inflections","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"inflections",title:"Curve inflections",number:"19"}),React.createElement("p",null,"Now that we know how to align a curve, there's one more thing we can calculate: inflection points. Imagine we have a variable size circle that we can slide up against our curve. We place it against the curve and adjust its radius so that where it touches the curve, the curvatures of the curve and the circle are the same, and then we start to slide the circle along the curve - for quadratic curves, we can always do this without the circle behaving oddly: we might have to change the radius of the circle as we slide it along, but it'll always sit against the same side of the curve."),React.createElement("p",null,"But what happens with cubic curves? Imagine we have an S curve and we place our circle at the start of the curve, and start sliding it along. For a while we can simply adjust the radius and things will be fine, but once we get to the midpoint of that S, something odd happens: the circle \"flips\" from one side of the curve to the other side, in order for the curvatures to keep matching. This is called an inflection, and we can find out where those happen relatively easily."),React.createElement("p",null,"What we need to do is solve a simple equation:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b039194e01b6081628efaf4aa169a4c50fa4aae4.svg",width:"61.599999999999994rem",height:"16.799999999999997rem"}),React.createElement("p",null,"What we're saying here is that given the curvature function ",React.createElement("em",null,"C(t)"),", we want to know for which values of ",React.createElement("em",null,"t")," this function is zero, meaning there is no \"curvature\", which will be exactly at the point between our circle being on one side of the curve, and our circle being on the other side of the curve. So what does ",React.createElement("em",null,"C(t)")," look like? Actually something that seems not too hard:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/297d1e13000b19d351e5884a40909652a2ee83e2.svg",width:"404.59999999999997rem",height:"22.4rem"}),React.createElement("p",null,"So the function ",React.createElement("em",null,"C(t)")," is wholly defined by the first and second derivative functions for the parametric dimensions of our curve. And as already shown, derivatives of Bézier curves are just simpler Bézier curves, with very easy to compute new coefficients, so this should be pretty easy."),React.createElement("p",null,"However as we've seen in the section on aligning, aligning lets us simplify things ",React.createElement("em",null,"a lot"),", by completely removing the contributions of the first coordinate from most mathematical evaluations, and removing the last ",React.createElement("em",null,"y")," coordinate as well by virtue of the last point lying on the x-axis. So, while we can evaluate ",React.createElement("em",null,"C(t) = 0")," for our curve, it'll be much easier to first axis-align the curve and ",React.createElement("em",null,"then")," evalutating the curvature function."),React.createElement("div",{className:"note"},React.createElement("h3",{id:"let-s-derive-the-full-formula-anyway"},"Let's derive the full formula anyway"),React.createElement("p",null,"Of course, before we do our aligned check, let's see what happens if we compute the curvature function without axis-aligning. We start with the first and second derivatives, given our basis functions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e522d174844a5a31f585cc04cab944a3c4593781.svg",width:"631.4rem",height:"74.19999999999999rem"}),React.createElement("p",null,"And of course the same functions for ",React.createElement("em",null,"y"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/57d857282b8c91da5caf94dcfbe85145dbd760a8.svg",width:"418.59999999999997rem",height:"72.8rem"}),React.createElement("p",null,"Asking a computer to now compose the ",React.createElement("em",null,"C(t)")," function for us (and to expand it to a readable form of simple terms) gives us this rather overly complicated set of arithmetic expressions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e69d797dc67f0bd2d826fcf8c48c22ff5decf23.svg",width:"579.5999999999999rem",height:"102.19999999999999rem"}),React.createElement("p",null,"That is... unwieldy. So, we note that there are a lot of terms that involve multiplications involving x1, y1, and y4, which would all disappear if we axis-align our curve, which is why aligning is a great idea.")),React.createElement("p",null,"Aligning our curve so that three of the eight coefficients become zero, we end up with the following simple term function for ",React.createElement("em",null,"C(t)"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/f61c01094f0de8ca4c7f26a229f0206d54b13930.svg",width:"589.4rem",height:"22.4rem"}),React.createElement("p",null,"That's a lot easier to work with: we see a fair number of terms that we can compute and then cache, giving us the following simplification:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c1e427616a8a2502abf3cf46415971d0df9a273c.svg",width:"534.8rem",height:"77rem"}),React.createElement("p",null,"This is a plain quadratic curve, and we know how to solve ",React.createElement("em",null,"C(t) = 0"),"; we use the quadratic formula:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/368099657b735b0d17becbbe7be915e88e8c04c5.svg",width:"456.4rem",height:"57.4rem"}),React.createElement("p",null,"We can easily compute this value ",React.createElement("em",null,"if")," the descriminator isn't a negative number (because we only want real roots, not complex roots), and ",React.createElement("em",null,"if")," ",React.createElement("em",null,"x")," is not zero, because divisions by zero are rather useless."),React.createElement("p",null,"Taking that into account, we compute ",React.createElement("em",null,"t"),", we disregard any ",React.createElement("em",null,"t")," value that isn't in the Bézier interval [0,1], and we now know at which ",React.createElement("em",null,"t")," value(s) our curve will inflect."),React.createElement(Graphic,{title:"Finding cubic Bézier curve inflections",setup:handler.setupCubic,draw:handler.draw}));}},"canonical":{"locale":"en-GB","title":"Canonical form (for cubic curves)","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"canonical",title:"Canonical form (for cubic curves)",number:"20"}),React.createElement("p",null,"While quadratic curves are relatively simple curves to analyze, the same cannot be said of the cubic curve. As a curvature controlled by more than one control points, it exhibits all kinds of features like loops, cusps, odd colinear features, and up to two inflection points because the curvature can change direction up to three times. Now, knowing what kind of curve we're dealing with means that some algorithms can be run more efficiently than if we have to implement them as generic solvers, so is there a way to determine the curve type without lots of work?"),React.createElement("p",null,"As it so happens, the answer is yes and the solution we're going to look at was presented by Maureen C. Stone from Xerox PARC and Tony D. deRose from the University of Washington in their joint paper ",React.createElement("a",{href:"http://graphics.pixar.com/people/derose/publications/CubicClassification/paper.pdf"},"\"A Geometric Characterization of Parametric Cubic curves\""),". It was published in 1989, and defines curves as having a \"canonical\" form (i.e. a form that all curves can be reduced to) from which we can immediately tell which features a curve will have. So how does it work?"),React.createElement("p",null,"The first observation that makes things work is that if we have a cubic curve with four points, we can apply a linear transformation to these points such that three of the points end up on (0,0), (0,1) and (1,1), with the last point then being \"somewhere\". After applying that transformation, the location of that last point can then tell us what kind of curve we're dealing with. Specifically, we see the following breakdown:"),React.createElement(Graphic,{"static":true,preset:"simple",title:"The canonical curve map",setup:handler.setup,draw:handler.drawBase}),React.createElement("p",null,"This is a fairly funky image, so let's see how it breaks down. We see the three fixed points at (0,0), (0,1) and (1,1), and then the fourth point is somewhere. Depending on where it is, our curve will have certain features. Namely, if the fourth point is..."),React.createElement("ol",null,React.createElement("li",null,"anywhere on and in the red zone, the curve will be self-intersecting, yielding either a cusp or a loop. Anywhere inside the the red zone, this will be a loop. We won't know ",React.createElement("i",null,"where")," that loop is (in terms of ",React.createElement("i",null,"t")," values), but we are guaranteed that there is one."),React.createElement("li",null,"on the left (red) edge, the curve will have a cusp. We again don't know ",React.createElement("em",null,"where"),", just that it has one. This edge is described by the function:")),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ae5a63e86bb367e6266a394962387344d0a92b10.svg",width:"189rem",height:"39.199999999999996rem"}),React.createElement("ol",null,React.createElement("li",null,"on the lower right (pink) edge, the curve will have a loop at t=1, so we know the end coordinate of the curve also lies ",React.createElement("em",null,"on")," the curve. This edge is described by the function:")),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d389fcde05a773be99f84db5fc9ed7ef043bf406.svg",width:"242.2rem",height:"40.599999999999994rem"}),React.createElement("ol",null,React.createElement("li",null,"on the top (blue) edge, the curve will have a loop at t=0, so we know the start coordinate of the curve also lies ",React.createElement("em",null,"on")," the curve. This edge is described by the function:")),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d97181a9d0ada19862a0ff2cebb08bdee00868d7.svg",width:"161rem",height:"39.199999999999996rem"}),React.createElement("ol",null,React.createElement("li",null,"inside the green zone, the curve will have a single inflection, switching concave/convex once."),React.createElement("li",null,"between the red and green zones, the curve has two inflections, meaning its curvature switches between concave/convex form twice."),React.createElement("li",null,"anywhere on the right of the red zone, the curve will have no inflections. It'll just be a well-behaved arch.")),React.createElement("p",null,"Of course, this map is fairly small, but the regions extend to infinity, with well defined boundaries."),React.createElement("div",{className:"note"},React.createElement("h3",{id:"wait-where-do-those-lines-come-from-"},"Wait, where do those lines come from?"),React.createElement("p",null,"Without repeating the paper mentioned at the top of this section, the loop-boundaries come from rewriting the curve into canonical form, and then solving the formulae for which constraints must hold for which possible curve properties. In the paper these functions yield formulae for where you will find cusp points, or loops where we know t=0 or t=1, but those functions are derived for the full cubic expression, meaning they apply to t=-∞ to t=∞... For Bézier curves we only care about the \"clipped interval\" t=0 to t=1, so some of the properties that apply when you look at the curve over an infinite interval simply don't apply to the Bézier curve interval."),React.createElement("p",null,"The right bound for the loop region, indicating where the curve switches from \"having inflections\" to \"having a loop\", for the general cubic curve, is actually mirrored over x=1, but for Bézier curves this right half doesn't apply, so we don't need to pay attention to it. Similarly, the boundaries for t=0 and t=1 loops are also nice clean curves but get \"cut off\" when we only look at what the general curve does over the interval t=0 to t=1."),React.createElement("p",null,"For the full details, head over to the paper and read through sections 3 and 4. If you still remember your high school precalculus, you can probably follow along with this paper, although you might have to read it a few times before all the bits \"click\".")),React.createElement("p",null,"So now the question becomes: how do we manipulate our curve so that it fits this canonical form, with three fixed points, and one \"free\" point? Enter linear algerba. Don't worry, I'll be doing all the math for you, as well as show you what the effect is on our curves, but basically we're going to be using linear algebra, rather than calculus, because \"it's way easier\". Sometimes a calculus approach is very hard to work with, when the equivalent geometrical solution is super obvious."),React.createElement("p",null,"The approach is going to start with a curve that doesn't have all-colinear points (so we need to make sure the points don't all fall on a straight line), and then applying four graphics operations that you will probably have heard of: translation (moving all points by some fixed x- and y-distance), scaling (multiplying all points by some x and y scale factor), and shearing (an operation that turns rectangles into parallelograms)."),React.createElement("p",null,"Step 1: we translate any curve by -p1.x and -p1.y, so that the curve starts at (0,0). We're going to make use of an interesting trick here, by pretending our 2D coordinates are 3D, with the ",React.createElement("i",null,"z")," coordinate simply always being 1. This is an old trick in graphics to overcome the limitations of 2D transformations: without it, we can only turn (x,y) coordinates into new coordinates of the form (ax + by, cx + dy), which means we can't do translation, since that requires we end up with some kind of (x + a, y + b). If we add a bogus ",React.createElement("i",null,"z")," coordinate that is always 1, then we can suddenly add arbitrary values. For example:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/00ca2970fccea8f0883af6db4fbc3a60efd2539d.svg",width:"495.59999999999997rem",height:"57.4rem"}),React.createElement("p",null,"Sweet! ",React.createElement("i",null,"z")," stays 1, so we can effectively ignore it entirely, but we added some plain values to our x and y coordinates. So, if we want to subtract p1.x and p1.y, we use:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1a48a27661f19f066ddd591fb4fc0d553b34c944.svg",width:"477.4rem",height:"60.199999999999996rem"}),React.createElement("p",null,"Running all our coordinates through this transformation gives a new set of coordinates, let's call those ",React.createElement("b",null,"U"),", where the first coordinate lies on (0,0), and the rest is still somewhat free. Our next job is to make sure point 2 ends up lying on the ",React.createElement("i",null,"x=0")," line, so what we want is a transformation matrix that, when we run it, subtracts ",React.createElement("i",null,"x")," from whatever ",React.createElement("i",null,"x")," we currently have. This is called ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Shear_matrix"},"shearing"),", and the typical x-shear matrix and its transformation looks like this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/8e98c870c9d5b60bccf196d29e290f9de6657ce7.svg",width:"204.39999999999998rem",height:"56rem"}),React.createElement("p",null,"So we want some shearing value that, when multiplied by ",React.createElement("i",null,"y"),", yields ",React.createElement("i",null,"-x"),", so our x coordinate becomes zero. That value is simpy ",React.createElement("i",null,"-x/y"),", because ",React.createElement("i",null,"-x/y * y = -x"),". Done:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/585fa88864a98008c15225bdbeb0eb26a4653dab.svg",width:"140rem",height:"70rem"}),React.createElement("p",null,"Now, running this on all our points generates a new set of coordinates, let's call those V, which now have point 1 on (0,0) and point 2 on (0, some-value), and we wanted it at (0,1), so we need to ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Scaling_%28geometry%29"},"do some scaling")," to make sure it ends up at (0,1). Additionally, we want point 3 to end up on (1,1), so we can also scale x to make sure its x-coordinate will be 1 after we run the transform. That means we'll be x-scaling by 1/point3",React.createElement("sub",null,"x"),", and y-scaling by point2",React.createElement("sub",null,"y"),". This is really easy:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/bf9c60b59e6247de3fece63638a8333bdcd068a4.svg",width:"144.2rem",height:"74.19999999999999rem"}),React.createElement("p",null,"Then, finally, this generates a new set of coordinates, let's call those W, of which point 1 lies on (0,0), point 2 lies on (0,1), and point three lies on (1, ...) so all that's left is to make sure point 3 ends up at (1,1) - but we can't scale! Point 2 is already in the right place, and y-scaling would move it out of (0,1) again, so our only option is to y-shear point three, just like how we x-sheared point 2 earlier. In this case, we do the same trick, but with ",React.createElement("code",null,"y/x")," rather than ",React.createElement("code",null,"x/y")," because we're not x-shearing but y-shearing. Additionally, we don't actually want to end up at zero (which is what we did before) so we need to shear towards an offset, in this case 1:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/af412fd7df7faf35973314095ec6bf1cb28a8e34.svg",width:"147rem",height:"68.6rem"}),React.createElement("p",null,"And this generates our final set of four coordinates. Of these, we already know that points 1 through 3 are (0,0), (0,1) and (1,1), and only the last coordinate is \"free\". In fact, given any four starting coordinates, the resulting \"transformation mapped\" coordinate will be:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/66e084e9ee396b8cc40de3d0df9c4658dcd10e14.svg",width:"477.4rem",height:"95.19999999999999rem"}),React.createElement("p",null,"That looks very complex, but notice that every coordinate value is being offset by the initial translation, and a lot of terms in there repeat: it's pretty easy to calculate this fast, since there's so much we can cache and reuse while we compute this mapped coordinate!"),React.createElement("p",null,"First, let's just do that translation step as a \"preprocessing\" operation so we don't have to subtract the values all the time. What does that leave?"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d2dc58a4a6951ff27e5b83fb9be239e2fbe0f7ce.svg",width:"371rem",height:"61.599999999999994rem"}),React.createElement("p",null,"Suddenly things look a lot simpler: the mapped x is fairly straight forward to compute, and we see that the mapped y actually contains the mapped x in its entirety, so we'll have that part already available when we need to evaluate it. In fact, let's pull out all those common factors to see just how simple this is:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ebaea590e50dfce555e8ad2c63682fe9e6285f06.svg",width:"428.4rem",height:"42rem"}),React.createElement("p",null,"That's kind of super-simple to write out in code, I think you'll agree. Coding math tends to be easier than the formulae initially make it look!"),React.createElement("div",{className:"note"},React.createElement("h3",{id:"how-do-you-track-all-that-"},"How do you track all that?"),React.createElement("p",null,"Doing maths can be a pain, so whenever possible, I like to make computers do the work for me. Especially for things like this, I simply use ",React.createElement("a",{href:"http://www.wolfram.com/mathematica"},"Mathematica"),". Tracking all this math by hand is insane, and we invented computers, literally, to do this for us. I have no reason to use pen and paper when I can write out what I want to do in a program, and have the program do the math for me. And real math, too, with symbols, not with numbers. In fact, ",React.createElement("a",{href:"http://pomax.github.io/gh-weblog/downloads/canonical-curve.nb"},"here's")," the Mathematica notebook if you want to see how this works for yourself."),React.createElement("p",null,"Now, I know, you're thinking \"but Mathematica is super expensive!\" and that's true, it's ",React.createElement("a",{href:"http://www.wolfram.com/mathematica-home-edition"},"$295 for home use"),", but it's ",React.createElement("strong",null,"also")," ",React.createElement("a",{href:"http://www.wolfram.com/raspberry-pi"},"free when you buy a $35 raspberry pi"),". Obviously, I bought a raspberry pi, and I encourage you to do the same. With that, as long as you know what you want to ",React.createElement("em",null,"do"),", Mathematica can just do it for you. And we don't have to be geniusses to work out what the maths looks like. That's what we have computers for.")),React.createElement("p",null,"So, let's write up a sketch that'll show us the canonical form for any curve drawn in blue, overlaid on our canonical map, so that we can immediately tell which features our curve must have, based on where the fourth coordinate is located on the map:"),React.createElement(Graphic,{preset:"simple",title:"A cubic curve mapped to canonical form",setup:handler.setup,draw:handler.draw}));}},"arclength":{"locale":"en-GB","title":"Arc length","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"arclength",title:"Arc length",number:"21"}),React.createElement("p",null,"How long is a Bézier curve? As it turns out, that's not actually an easy question, because the answer requires maths that —much like root finding— cannot generally be solved the traditional way. If we have a parametric curve with ",React.createElement("em",null,"f",React.createElement("sub",null,"x"),"(t)")," and ",React.createElement("em",null,"f",React.createElement("sub",null,"y"),"(t)"),", then the length of the curve, measured from start point to some point ",React.createElement("em",null,"t = z"),", is computed using the following seemingly straight forward (if a bit overwhelming) formula:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/16e3f81dfc12c526ca53b477b2aa67ef7b56bfe2.svg",width:"147rem",height:"35rem"}),React.createElement("p",null,"or, more commonly written using Leibnitz notation as:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/8e2857c32b23969bca67b0ead318493a3e61dc4a.svg",width:"257.59999999999997rem",height:"36.4rem"}),React.createElement("p",null,"This formula says that the length of a parametric curve is in fact equal to the ",React.createElement("strong",null,"area")," underneath a function that looks a remarkable amount like Pythagoras' rule for computing the diagonal of a straight angled triangle. This sounds pretty simple, right? Sadly, it's far from simple... cutting straight to after the chase is over: for quadratic curves, this formula generates an ",React.createElement("a",{href:"http://www.wolframalpha.com/input/?i=antiderivative+for+sqrt%28%282*%281-t%29*t*B+%2B+t%5E2*C%29%27%5E2+%2B+%282*%281-t%29*t*E%29%27%5E2%29&incParTime=true"},"unwieldy computation"),", and we're simply not going to implement things that way. For cubic Bézier curves, things get even more fun, because there is no \"closed form\" solution, meaning that due to the way calculus works, there is no generic formula that allows you to calculate the arc length. Let me just repeat this, because it's fairly crucial: ",React.createElement("strong",null,React.createElement("em",null,"for cubic and higher Bézier curves, there is no way to solve this function if you want to use it \"for all possible coordinates\"")),"."),React.createElement("p",null,"Seriously: ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Abel%E2%80%93Ruffini_theorem"},"It cannot be done"),"."),React.createElement("p",null,"So we turn to numerical approaches again. The method we'll look at here is the ",React.createElement("a",{href:"http://www.youtube.com/watch?v=unWguclP-Ds&feature=BFa&list=PLC8FC40C714F5E60F&index=1"},"Gauss quadrature"),". This approximation is a really neat trick, because for any ",React.createElement("em",null,"n",React.createElement("sup",null,"th"))," degree polynomial it finds approximated values for an integral really efficiently. Explaining this procedure in length is way beyond the scope of this page, so if you're interested in finding out why it works, I can recommend the University of South Florida video lecture on the procedure, linked in this very paragraph. The general solution we're looking for is the following:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e6a8d7d5f1742bb926c0c992d2b89c71090edbf4.svg",width:"576.8rem",height:"74.19999999999999rem"}),React.createElement("p",null,"In plain text: an integral function can always be treated as the sum of an (infinite) number of (infinitely thin) rectangular strips sitting \"under\" the function's plotted graph. To illustrate this idea, the following graph shows the integral for a sinoid function. The more strips we use (and of course the more we use, the thinner they get) the closer we get to the true area under the curve, and thus the better the approximation:"),React.createElement("div",{className:"figure"},React.createElement(Graphic,{inline:true,"static":true,preset:"empty",title:"A function's approximated integral",setup:handler.setup,draw:handler.drawCoarseIntegral}),React.createElement(Graphic,{inline:true,"static":true,preset:"empty",title:"A better approximation",setup:handler.setup,draw:handler.drawFineIntegral}),React.createElement(Graphic,{inline:true,"static":true,preset:"empty",title:"An even better approximation",setup:handler.setup,draw:handler.drawSuperFineIntegral})),React.createElement("p",null,"Now, infinitely many terms to sum and infinitely thin rectangles are not something that computers can work with, so instead we're going to approximate the infinite summation by using a sum of a finite number of \"just thin\" rectangular strips. As long as we use a high enough number of thin enough rectangular strips, this will give us an approximation that is pretty close to what the real value is."),React.createElement("p",null,"So, the trick is to come up with useful rectangular strips. A naive way is to simply create ",React.createElement("em",null,"n")," strips, all with the same width, but there is a far better way using special values for ",React.createElement("em",null,"C")," and ",React.createElement("em",null,"f(t)")," depending on the value of ",React.createElement("em",null,"n"),", which indicates how many strips we'll use, and it's called the Legendre-Gauss quadrature."),React.createElement("p",null,"This approach uses strips that are ",React.createElement("em",null,"not")," spaced evenly, but instead spaces them in a special way that works remarkably well. If you look at the earlier sinoid graphic, you could imagine that we could probably get a result similar to the one with 99 strips if we used fewer strips, but spaced them so that the steeper the curve is, the thinner we make the strip, and conversely, the flatter the curve is (especially near the tops of the function), the wider we make the strip. That's akin to how the Legendre values work."),React.createElement("div",{className:"note"},React.createElement("p",null,"Note that one requirement for the approach we'll use is that the integral must run from -1 to 1. That's no good, because we're dealing with Bézier curves, and the length of a section of curve applies to values which run from 0 to \"some value smaller than or equal to 1\" (let's call that value ",React.createElement("em",null,"z"),"). Thankfully, we can quite easily transform any integral interval to any other integral interval, by shifting and scaling the inputs. Doing so, we get the following:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/631e6396082d9621472546b87c2e27065990d568.svg",width:"358.4rem",height:"75.6rem"}),React.createElement("p",null,"That may look a bit more complicated, but the fraction involving ",React.createElement("em",null,"z")," is a fixed number, so the summation, and the evaluation of the ",React.createElement("em",null,"f(t)")," values are still pretty simple."),React.createElement("p",null,"So, what do we need to perform this calculation? For one, we'll need an explicit formula for ",React.createElement("em",null,"f(t)"),", because that derivative notation is handy on paper, but not when we have to implement it. We'll also need to know what these ",React.createElement("em",null,"C",React.createElement("sub",null,"i"))," and ",React.createElement("em",null,"t",React.createElement("sub",null,"i"))," values should be. Luckily, that's less work because there are actually many tables available that give these values, for any ",React.createElement("em",null,"n"),", so if we want to approximate our integral with only two terms (which is a bit low, really) then ",React.createElement("a",{href:"legendre-gauss.html"},"these tables")," would tell us that for ",React.createElement("em",null,"n=2")," we must use the following values:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/6dc4299695f03c27c362e7faf47ae4474794809e.svg",width:"65.8rem",height:"98rem"}),React.createElement("p",null,"Which means that in order for us to approximate the integral, we must plug these values into the approximate function, which gives us:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/fe54606651e308caf83a65e53bc4d6104f8a4ee1.svg",width:"499.79999999999995rem",height:"46.199999999999996rem"}),React.createElement("p",null,"We can program that pretty easily, provided we have that ",React.createElement("em",null,"f(t)")," available, which we do, as we know the full description for the Bézier curve functions B",React.createElement("sub",null,"x"),"(t) and B",React.createElement("sub",null,"y"),"(t).")),React.createElement("p",null,"If we use the Legendre-Gauss values for our ",React.createElement("em",null,"C")," values (thickness for each strip) and ",React.createElement("em",null,"t")," values (location of each strip), we can determine the approximate length of a Bézier curve by computing the Legendre-Gauss sum. The following graphic shows a cubic curve, with its computed lengths; Go ahead and change the curve, to see how its length changes. One thing worth trying is to see if you can make a straight line, and see if the length matches what you'd expect. What if you form a line with the control points on the outside, and the start/end points on the inside?"),React.createElement(Graphic,{preset:"simple",title:"Arc length for a Bézier curve",setup:handler.setupCurve,draw:handler.drawCurve}));}},"arclengthapprox":{"locale":"en-GB","title":"Approximated arc length","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"arclengthapprox",title:"Approximated arc length",number:"22"}),React.createElement("p",null,"Sometimes, we don't actually need the precision of a true arc length, and we can get away with simply computing the approximate arc length instead. The by far fastest way to do this is to flatten the curve and then simply calculate the linear distance from point to point. This will come with an error, but this can be made arbitrarily small by increasing the segment count."),React.createElement("p",null,"If we combine the work done in the previous sections on curve flattening and arc length computation, we can implement these with minimal effort:"),React.createElement(Graphic,{preset:"twopanel",title:"Approximate quadratic curve arc length",setup:handler.setupQuadratic,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement(Graphic,{preset:"twopanel",title:"Approximate cubic curve arc length",setup:handler.setupCubic,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"Try clicking on the sketch and using your up and down arrow keys to lower the number of segments for both the quadratic and cubic curve. You may notice that the error in length is actually pretty significant, even if the percentage is fairly low: if the number of segments used yields an error of 0.1% or higher, the flattened curve already looks fairly obviously flattened. And of course, the longer the curve, the more significant the error will be."));}},"tracing":{"locale":"en-GB","title":"Tracing a curve at fixed distance intervals","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"tracing",title:"Tracing a curve at fixed distance intervals",number:"23"}),React.createElement("p",null,"Say you want to draw a curve with a dashed line, rather than a solid line, or you want to move something along the curve at fixed distance intervals over time, like a train along a track, and you want to use Bézier curves."),React.createElement("p",null,"Now you have a problem."),React.createElement("p",null,"The reason you have a problem is that Bézier curves are parametric functions with non-linear behaviour, whereas moving a train along a track is about as close to a practical example of linear behaviour as you can get. The problem we're faced with is that we can't just pick ",React.createElement("em",null,"t")," values at some fixed interval and expect the Bézier functions to generate points that are spaced a fixed distance apart. In fact, let's look at the relation between \"distance long a curve\" and \"",React.createElement("em",null,"t")," value\", by plotting them against one another."),React.createElement("p",null,"The following graphic shows a particularly illustrative curve, and it's length-to-t plot. For linear traversal, this line needs to be straight, running from (0,0) to (length,1). This is, it's safe to say, not what we'll see, we'll see something wobbly instead. To make matters even worse, the length-to-",React.createElement("em",null,"t")," function is also of a much higher order than our curve is: while the curve we're using for this exercise is a cubic curve, which can switch concave/convex form once at best, the plot shows that the distance function along the curve is able to switch forms three times (to see this, try creating an S curve with the start/end close together, but the control points far apart)."),React.createElement(Graphic,{preset:"twopanel",title:"The t-for-distance function",setup:handler.setup,draw:handler.plotOnly}),React.createElement("p",null,"We see a function that might be invertible, but we won't be able to do so, symbolically. You may remember from the section on arc length that we cannot actually compute the true arc length function as an expression of ",React.createElement("em",null,"t"),", which means we also can't compute the true inverted function that gives ",React.createElement("em",null,"t")," as an expression of length. So how do we fix this?"),React.createElement("p",null,"One way is to do what the graphic does: simply run through the curve, determine its ",React.createElement("em",null,"t"),"-for-length values as a set of discrete values at some high resolution (the graphic uses 100 discrete points), and then use those as a basis for finding an appropriate ",React.createElement("em",null,"t")," value, given a distance along the curve. This works quite well, actually, and is fairly fast."),React.createElement("p",null,"We can use some colour to show the difference between distance-based and time based intervals: the following graph is similar to the previous one, except it segments the curve in terms of equal-distance intervals. This shows as regular colour intervals going down the graph, but the mapping to ",React.createElement("em",null,"t")," values is not linear, so there will be (highly) irregular intervals along the horizontal axis. It also shows the curve in an alternating colouring based on the t-for-distance values we find our LUT:"),React.createElement(Graphic,{preset:"threepanel",title:"Fixed-interval coloring a curve",setup:handler.setup,draw:handler.drawColoured,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"Use your up and down arrow keys to increase or decrease the number of equidistant segments used to colour the curve."),React.createElement("p",null,"However, are there better ways? One such way is discussed in \"",React.createElement("a",{href:"http://www.geometrictools.com/Documentation/MovingAlongCurveSpecifiedSpeed.pdf"},"Moving Along a Curve with Specified Speed"),"\" by David Eberly of Geometric Tools, LLC, but basically because we have no explicit length function (or rather, one we don't have to constantly compute for different intervals), you may simply be better off with a traditional lookup table (LUT)."));}},"intersections":{"locale":"en-GB","title":"Intersections","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"intersections",title:"Intersections",number:"24"}),React.createElement("p",null,"Let's look at some more things we will want to do with Bézier curves. Almost immediately after figuring out how to get bounding boxes to work, people tend to run into the problem that even though the minimal bounding box (based on rotation) is tight, it's not sufficient to perform true collision detection. It's a good first step to make sure there ",React.createElement("em",null,"might")," be a collision (if there is no bounding box overlap, there can't be one), but in order to do real collision detection we need to know whether or not there's an intersection on the actual curve."),React.createElement("p",null,"We'll do this in steps, because it's a bit of a journey to get to curve/curve intersection checking. First, let's start simple, by implementing a line-line intersection checker. While we can solve this the traditional calculus way (determine the functions for both lines, then compute the intersection by equating them and solving for two unknowns), linear algebra actually offers a nicer solution."),React.createElement("h3",{id:"line-line-intersections"},"Line-line intersections"),React.createElement("p",null,"if we have two line segments with two coordinates each, segments A-B and C-D, we can find the intersection of the lines these segments are an intervals on by linear algebra, using the procedure outlined in this ",React.createElement("a",{href:"http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=geometry2#line_line_intersection"},"top coder")," article. Of course, we need to make sure that the intersection isn't just on the lines our line segments lie on, but also on our line segments themselves, so after we find the intersection we need to verify it lies without the bounds of our original line segments."),React.createElement("p",null,"The following graphic implements this intersection detection, showing a red point for an intersection on the lines our segments lie on (thus being a virtual intersection point), and a green point for an intersection that lies on both segments (being a real intersection point)."),React.createElement(Graphic,{preset:"simple",title:"Line/line intersections",setup:handler.setupLines,draw:handler.drawLineIntersection}),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"implementing-line-line-intersections"},"Implementing line-line intersections"),React.createElement("p",null,"Let's have a look at how to implement a line-line intersection checking function. The basics are covered in the article mentioned above, but sometimes you need more function signatures, because you might not want to call your function with eight distinct parameters. Maybe you're using point structs or the line. Let's get coding:"),React.createElement("pre",null,"lli8 = function(x1,y1,x2,y2,x3,y3,x4,y4):\n var nx=(x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4),\n ny=(x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4),\n d=(x1-x2)*(y3-y4)-(y1-y2)*(x3-x4);\n if d=0:\n return false\n return point(nx/d, ny/d)\n\nlli4 = function(p1, p2, p3, p4):\n var x1 = p1.x, y1 = p1.y,\n x2 = p2.x, y2 = p2.y,\n x3 = p3.x, y3 = p3.y,\n x4 = p4.x, y4 = p4.y;\n return lli8(x1,y1,x2,y2,x3,y3,x4,y4)\n\nlli = function(line1, line2):\n return lli4(line1.p1, line1.p2, line2.p1, line2.p2)\n")),React.createElement("h3",{id:"what-about-curve-line-intersections-"},"What about curve-line intersections?"),React.createElement("p",null,"Curve/line intersection is more work, but we've already seen the techniques we need to use in order to perform it: first we translate/rotate both the line and curve together, in such a way that the line coincides with the x-axis. This will position the curve in a way that makes it cross the line at points where its y-function is zero. By doing this, the problem of finding intersections between a curve and a line has now become the problem of performing root finding on our translated/rotated curve, as we already covered in the section on finding extremities."),React.createElement(Graphic,{preset:"simple",title:"Quadratic curve/line intersections",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"simple",title:"Cubic curve/line intersections",setup:handler.setupCubic,draw:handler.draw}),React.createElement("p",null,"Curve/curve intersection, however, is more complicated. Since we have no straight line to align to, we can't simply align one of the curves and be left with a simple procedure. Instead, we'll need to apply two techniques we've not covered yet: de Casteljau's algorithm, and curve splitting."));}},"curveintersection":{"locale":"en-GB","title":"Curve/curve intersection","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"curveintersection",title:"Curve/curve intersection",number:"25"}),React.createElement("p",null,"Using de Casteljau's algorithm to split the curve we can now implement curve/curve intersection finding using a \"divide and conquer\" technique:"),React.createElement("ul",null,React.createElement("li",null,"Take two curves ",React.createElement("em",null,"C",React.createElement("sub",null,"1"))," and ",React.createElement("em",null,"C",React.createElement("sub",null,"2")),", and treat them as a pair."),React.createElement("li",null,"If their bounding boxes overlap, split up each curve into two sub-curves"),React.createElement("li",null,"With ",React.createElement("em",null,"C",React.createElement("sub",null,"1.1")),", ",React.createElement("em",null,"C",React.createElement("sub",null,"1.2")),", ",React.createElement("em",null,"C",React.createElement("sub",null,"2.1"))," and ",React.createElement("em",null,"C",React.createElement("sub",null,"2.2")),", form four new pairs (",React.createElement("em",null,"C",React.createElement("sub",null,"1.1")),",",React.createElement("em",null,"C",React.createElement("sub",null,"2.1")),"), (",React.createElement("em",null,"C",React.createElement("sub",null,"1.1")),", ",React.createElement("em",null,"C",React.createElement("sub",null,"2.2")),"), (",React.createElement("em",null,"C",React.createElement("sub",null,"1.2")),",",React.createElement("em",null,"C",React.createElement("sub",null,"2.1")),"), and (",React.createElement("em",null,"C",React.createElement("sub",null,"1.2")),",",React.createElement("em",null,"C",React.createElement("sub",null,"2.2")),")."),React.createElement("li",null,"For each pair, check whether their bounding boxes overlap.",React.createElement("ul",null,React.createElement("li",null,"If their bounding boxes do not overlap, discard the pair, as there is no intersection between this pair of curves."),React.createElement("li",null,"If there ",React.createElement("em",null,"is")," overlap, rerun all steps for this pair."))),React.createElement("li",null,"Once the sub-curves we form are so small that they effectively occupy sub-pixel areas, we consider an intersection found.")),React.createElement("p",null,"This algorithm will start with a single pair, \"balloon\" until it runs in parallel for a large number of potential sub-pairs, and then taper back down as it homes in on intersection coordinates, ending up with as many pairs as there are intersections."),React.createElement("p",null,"The following graphic applies this algorithm to a pair of cubic curves, one step at a time, so you can see the algorithm in action. Click the button to run a single step in the algorithm, after setting up your curves in some creative arrangement. The algorithm resets once it's found a solution, so you can try this with lots of different curves (can you find the configuration that yields the maximum number of intersections between two cubic curves? Nine intersections!)"),React.createElement(Graphic,{preset:"clipping",title:"Curve/curve intersections",setup:handler.setup,draw:handler.draw},"\\t",React.createElement("button",{onClick:handler.stepUp},"advance one step")),React.createElement("p",null,"Self-intersection is dealt with in the same way, except we turn a curve into two or more curves first based on the inflection points. We then form all possible curve pairs with the resultant segments, and run exactly the same algorithm. All non-overlapping curve pairs will be removed after the first iteration, and the remaining steps home in on the curve's self-intersection points."));}},"abc":{"locale":"en-GB","title":"The projection identity","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"abc",title:"The projection identity",number:"26"}),React.createElement("p",null,"De Casteljau's algorithm is the pivotal algorithm when it comes to Bézier curves. You can use it not just to split curves, but also to draw them efficiently (especially for high-order Bézier curves), as well as to come up with curves based on three points and a tangent. Particularly this last thing is really useful because it lets us \"mould\" a curve, by picking it up at some point, and dragging that point around to change the curve's shape."),React.createElement("p",null,"How does that work? Succinctly: we run de Casteljau's algorithm in reverse!"),React.createElement("p",null,"In order to run de Casteljau's algorithm in reverse, we need a few basic things: a start and end point, a point on the curve that want to be moving around, which has an associated ",React.createElement("em",null,"t")," value, and a point we've not explicitly talked about before, and as far as I know has no explicit name, but lives one iteration higher in the de Casteljau process then our on-curve point does. I like to call it \"A\" for reasons that will become obvious."),React.createElement("p",null,"So let's use graphics instead of text to see where this \"A\" is, because text only gets us so far: in the following graphic, click anywhere on the curves to see the identity information that we'll be using to run de Casteljau in reverse (you can manipulate the curve even after picking a point. Note the \"ratio\" value when you do so: does it change?):"),React.createElement("div",{className:"figure"},React.createElement(Graphic,{inline:true,preset:"abc",title:"Projections in a quadratic Bézier curve",setup:handler.setupQuadratic,draw:handler.draw,onClick:handler.onClick}),React.createElement(Graphic,{inline:true,preset:"abc",title:"Projections in a cubic Bézier curve",setup:handler.setupCubic,draw:handler.draw,onClick:handler.onClick})),React.createElement("p",null,"Clicking anywhere on the curves shows us three things:"),React.createElement("ol",null,React.createElement("li",null,"our on-curve point; let's call that ",React.createElement("b",null,"B"),","),React.createElement("li",null,"a point at the tip of B's \"hat\", on de Casteljau step up; let's call that ",React.createElement("b",null,"A"),", and"),React.createElement("li",null,"a point that we get by projecting B onto the start--end baseline; let's call that ",React.createElement("b",null,"C"),".")),React.createElement("p",null,"These three values ABC hide an important identity formula for quadratic and cubic Bézier curves: for any point on the curve with some ",React.createElement("em",null,"t")," value, the ratio distance of C along baseline is fixed: if some ",React.createElement("em",null,"t")," value sets up a C that is 20% away from the start and 80% away from the end, then it doesn't matter where the start, end, or control points are: for that ",React.createElement("em",null,"t")," value, C will ",React.createElement("em",null,"always")," lie at 20% from the start and 80% from the end point. Go ahead, pick an on-curve point in either graphic and then move all the other points around: if you only move the control points, start and end won't move, and so neither will C, and if you move either start or end point, C will move but its relative position will not change. The following function stays true:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/f48f095d9c37c079ff6a5f71b3047397aa7dfc6b.svg",width:"207.2rem",height:"16.799999999999997rem"}),React.createElement("p",null,"So that just leaves finding A."),React.createElement("div",{className:"note"},React.createElement("p",null,"While that relation is fixed, the function ",React.createElement("em",null,"u(t)")," differs depending on whether we're working with quadratic or cubic curves:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/cb35e42bf53bfc2b96f959e78256da01f8b91dbc.svg",width:"207.2rem",height:"91rem"}),React.createElement("p",null,"So, if we know the start and end coordinates, and we know the ",React.createElement("em",null,"t")," value, we know C:"),React.createElement("div",{className:"figure"},React.createElement(Graphic,{inline:true,preset:"abc",title:"Quadratic value of C for t",draw:handler.drawQCT,onMouseMove:handler.setCT}),React.createElement(Graphic,{inline:true,preset:"abc",title:"Cubic value of C for t",draw:handler.drawCCT,onMouseMove:handler.setCT})),React.createElement("p",null,"Mouse-over the graphs to see the expression for C, given the ",React.createElement("em",null,"t")," value at the mouse pointer.")),React.createElement("p",null,"There's also another important bit of information that is inherent to the ABC values: while the distances between A and B, and B and C, are dynamic (based on where we put B), the ",React.createElement("em",null,"ratio")," between the two distances is stable: given some ",React.createElement("em",null,"t")," value, the following always holds:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/6cb3e94fe9164128a25570a32abed15baa726f17.svg",width:"263.2rem",height:"40.599999999999994rem"}),React.createElement("p",null,"This leads to a pretty powerful bit of knowledge: merely by knowing the ",React.createElement("em",null,"t")," value of some on curve point, we know where C has to be (as per the above note), and because we know B and C, and thus have the distance between them, we know where A has to be:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1dffb79b42799c95c899e689b074361f662ec807.svg",width:"228.2rem",height:"39.199999999999996rem"}),React.createElement("p",null,"And that's it, all values found."),React.createElement("div",{className:"note"},React.createElement("p",null,"Much like the ",React.createElement("em",null,"u(t)")," function in the above note, the ",React.createElement("em",null,"ratio(t)")," function depends on whether we're looking at quadratic or cubic curves. Their form is intrinsically related to the ",React.createElement("em",null,"u(t)")," function in that they both come rolling out of the same function evalution, explained over on ",React.createElement("a",{href:"http://mathoverflow.net/questions/122257/finding-the-formula-for-Bézier-curve-ratios-hull-point-point-baseline"},"MathOverflow")," by Boris Zbarsky and myself. The ratio functions are the \"s(t)\" functions from the answers there, while the \"u(t)\" functions have the same name both here and on MathOverflow."),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7ef64890f95db9e48258edb46a3d52d5ed143155.svg",width:"257.59999999999997rem",height:"43.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5f2bb71795c615637d632da70b722938cb103b03.svg",width:"233.79999999999998rem",height:"43.4rem"}),React.createElement("p",null,"Unfortunately, this trick only works for quadratic and cubic curves. Once we hit higher order curves, things become a lot less predictable; the \"fixed point ",React.createElement("em",null,"C"),"\" is no longer fixed, moving around as we move the control points, and projections of ",React.createElement("em",null,"B")," onto the line between start and end may actually lie on that line before the start, or after the end, and there are no simple ratios that we can exploit.")),React.createElement("p",null,"So: if we know B and its corresponding ",React.createElement("em",null,"t")," value, then we know all the ABC values, which —together with a start and end coordinate— gives us the necessary information to reconstruct a curve's \"de Casteljau skeleton\", which means that two points and a value between 0 and 1, we can come up with a curve. And that opens up possibilities: curve manipulation by dragging an on-curve point, curve fitting of \"a bunch of coordinates\", these are useful things, and we'll look at both in the next sections."));}},"moulding":{"locale":"en-GB","title":"Manipulating a curve","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"moulding",title:"Manipulating a curve",number:"27"}),React.createElement("p",null,"Armed with knowledge of the \"ABC\" relation, we can now update a curve interactively, by letting people click anywhere on the curve, find the ",React.createElement("em",null,"t"),"-value matching that coordinate, and then letting them drag that point around. With every drag update we'll have a new point \"B\", which we can combine with the fixed point \"C\" to find our new point A. Once we have those, we can reconstruct the de Casteljau skeleton and thus construct a new curve with the same start/end points as the original curve, passing through the user-selected point B, with correct new control points."),React.createElement(Graphic,{preset:"moulding",title:"Moulding a quadratic Bézier curve",setup:handler.setupQuadratic,draw:handler.drawMould,onClick:handler.placeMouldPoint,onMouseDown:handler.markQB,onMouseDrag:handler.dragQB,onMouseUp:handler.saveCurve}),React.createElement("p",null,React.createElement("strong",null,"Click-dragging the curve itself")," shows what we're using to compute the new coordinates: while dragging you will see the original points B and its corresponding ",React.createElement("i",null,"t"),"-value, the original point C for that ",React.createElement("i",null,"t"),"-value, as well as the new point B' based on the mouse cursor. Since we know the ",React.createElement("i",null,"t"),"-value for this configuration, we can compute the ABC ratio for this configuration, and we know that our new point A' should like at a distance:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e361e1235c94bbe87e95834c7fcfb6ab96e028b9.svg",width:"226.79999999999998rem",height:"37.8rem"}),React.createElement("p",null,"For quadratic curves, this means we're done, since the new point A' is equivalent to the new quadratic control point. For cubic curves, we need to do a little more work:"),React.createElement(Graphic,{preset:"moulding",title:"Moulding a cubic Bézier curve",setup:handler.setupCubic,draw:handler.drawMould,onClick:handler.placeMouldPoint,onMouseDown:handler.markCB,onMouseDrag:handler.dragCB,onMouseUp:handler.saveCurve}),React.createElement("p",null,"To help understand what's going on, the cubic graphic shows the full de Casteljau construction \"hull\" when repositioning point B. We compute A` in exactly the same way as before, but we also record the final strut line that forms B in the original curve. Given A', B', and the endpoints e1 and e2 of the strut line relative to B', we can now compute where the new control points should be. Remember that B' lies on line e1--e2 at a distance ",React.createElement("i",null,"t"),", because that's how Bézier curves work. In the same manner, we know the distance A--e1 is only line-interval [0,t] of the full segment, and A--e2 is only line-interval [t,1], so constructing the new control points is fairly easy."),React.createElement("p",null,"First, we construct the one-level-of-de-Casteljau-up points:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1833383a4800c495451abcacc2ada34e5601995d.svg",width:"140rem",height:"78.39999999999999rem"}),React.createElement("p",null,"And then we can compute the new control points:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d53cad094fddaacbb047c9d7c465a5011e3bfbfd.svg",width:"163.79999999999998rem",height:"78.39999999999999rem"}),React.createElement("p",null,"And that's cubic curve manipulation."));}},"pointcurves":{"locale":"en-GB","title":"Creating a curve from three points","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"pointcurves",title:"Creating a curve from three points",number:"28"}),React.createElement("p",null,"Given the preceding section on curve manipulation, we can also generate quadratic and cubic curves from any three points. However, unlike circle-fitting, which requires just three points, Bézier curve fitting requires three points, as well as a ",React.createElement("em",null,"t")," value, so we can figure out where point 'C' needs to be."),React.createElement("p",null,"The following graphic lets you place three points, and will use the preceding sections on the ABC ratio and curve construction to form a quadratic curve through them. You can move the points you've placed around by click-dragging, or try a new curve by drawing new points with pure clicks. (There's some freedom here, so for illustrative purposes we clamped ",React.createElement("em",null,"t")," to simply be 0.5, lets us bypass some maths, since a ",React.createElement("em",null,"t")," value of 0.5 always puts C in the middle of the start--end line segment)"),React.createElement(Graphic,{preset:"generate",title:"Fitting a quadratic Bézier curve",setup:handler.setup,draw:handler.drawQuadratic,onClick:handler.onClick}),React.createElement("p",null,"For cubic curves we also need some values to construct the \"de Casteljau line through B\" with, and that gives us quite a bit of choice. Since we've clamped ",React.createElement("em",null,"t")," to 0.5, we'll set up a line through B parallel to the line start--end, with a length that is proportional to the length of the line B--C: the further away from the baseline B is, the wider its construction line will be, and so the more \"bulby\" the curve will look. This still gives us some freedom in terms of exactly how to scale the length of the construction line as we move B closer or further away from the baseline, so I simply picked some values that sort-of-kind-of look right in that if a circle through (start,B,end) forms a perfect hemisphere, the cubic curve constructed forms something close to a hemisphere, too, and if the points lie on a line, then the curve constructed has the control points very close to B, while still lying between B and the correct curve end point:"),React.createElement(Graphic,{preset:"generate",title:"Fitting a cubic Bézier curve",setup:handler.setup,draw:handler.drawCubic,onClick:handler.onClick}),React.createElement("p",null,"In each graphic, the blue parts are the values that we \"just have\" simply by setting up our three points, combined with our decision on which ",React.createElement("em",null,"t")," value to use (and construction line orientation and length for cubic curves). There are of course many ways to determine a combination of ",React.createElement("em",null,"t")," and tangent values that lead to a more \"æsthetic\" curve, but this will be left as an exercise to the reader, since there are many, and æsthetics are often quite personal."));}},"catmullconv":{"locale":"en-GB","title":"Bézier curves and Catmull-Rom curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"catmullconv",title:"Bézier curves and Catmull-Rom curves",number:"29"}),React.createElement("p",null,"Taking an excursion to different splines, the other common design curve is the ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull.E2.80.93Rom_spline"},"Catmull-Rom spline"),". Now, a Catmull-Rom spline is a form of cubic Hermite spline, and as it so happens the cubic Bézier curve is also a cubic Hermite spline, so maybe... maybe we can convert one into the other, and back, with some simple substitutions?"),React.createElement("p",null,"Unlike Bézier curves, Catmull-Rom splines pass through each point used to define the curve, except the first and last, which makes sense if you read the \"natural language\" descriptionfor how a Catmull-Rom spline works: a Catmull-Rom spline is a curve that, at each point P",React.createElement("sub",null,"x"),", has a tangent along the line P",React.createElement("sub",null,"x-1")," to P",React.createElement("sub",null,"x+1"),". The curve runs from points P",React.createElement("sub",null,"2")," to P",React.createElement("sub",null,"n-1"),", and has a \"tension\" that determines how fast the curve passes through each point. The lower the tension, the faster the curve goes through each point, and the bigger its local tangent is."),React.createElement("p",null,"I'll be showing the conversion to and from Catmull-Rom curves for the tension that the Processing language uses for its Catmull-Rom algorithm."),React.createElement("p",null,"We start with showing the Catmull-Rom matrix form:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5fc1c44e623f2a9fbeefdaa204557479e3debf5a.svg",width:"429.79999999999995rem",height:"78.39999999999999rem"}),React.createElement("p",null,"However, there's something funny going on here: the coordinate column matrix looks weird. The reason is that Catmull-Rom curves are actually curve segments that are described by two points, and two tangents; the curve leaves a point V1 (if we have four coordinates instead, this is coordinate 2), arriving at a point V2 (coordinate 3), with the curve departing V1 with a tangent vector V'1 (equal to the tangent from coordinate 1 to coordinate 3) and arriving at V2 with tangent vector V'2 (equal to the tangent from coordinate 2 to coordinate 4). So if we want to express this as a matrix form based on four coordinates, we get this representation instead:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/40b9ca9b5755a4be49517ddfa630fef7b8e23067.svg",width:"406rem",height:"86.8rem"}),React.createElement("div",{className:"note"},React.createElement("h2",{id:"where-did-that-2-come-from-"},"Where did that 2 come from?"),React.createElement("p",null,"Catmull-Rom splines are based on the concept of tension: the higher the tensions, the shorter the tangents at the departure and arrival points. The basic Catmull-Rom curve arrives and departs with tangents equal to half the distance between the two adjacent points, so that's where that 2 came from."),React.createElement("p",null,"However, the \"real\" matrix is this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7bf9b5e971866babedd991ccdde5c4ab104297e5.svg",width:"351.4rem",height:"88.19999999999999rem"}),React.createElement("p",null,"This bakes in the tension factor τ explicitly.")),React.createElement("p",null,"Plugging this into the \"two coordinates and two tangent vectors\" matrix form, we get:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/4818f8797c35f23c2b9883aa986b1129b2fa151a.svg",width:"299.59999999999997rem",height:"78.39999999999999rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/08f77989369f664cbc0fb7526791efd4c5299d70.svg",width:"499.79999999999995rem",height:"77rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c7ae769c5370469b16523bab6f34abf0dd6749be.svg",width:"414.4rem",height:"77rem"}),React.createElement("p",null,"So let's find out which transformation matrix we need in order to convert from Catmull-Rom to Bézier:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7250f1c57e2bd66ec4349e4e88db4d5d74401a06.svg",width:"730.8rem",height:"77rem"}),React.createElement("p",null,"The difference is somewhere in the actual hermite matrix, since the ",React.createElement("em",null,"t")," and coordinate values are identical, so let's solve that matrix equasion:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/8a42b24fca3aaf6b8ec08e84b7e91c43e26e8acf.svg",width:"418.59999999999997rem",height:"75.6rem"}),React.createElement("p",null,"We left-multiply both sides by the inverse of the Bézier matrix, to get rid of the Bézier matrix on the right side of the equals sign:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e111d6e846f4d7204dec484005f74993e66c6c9.svg",width:"841.4rem",height:"84rem"}),React.createElement("p",null,"Which gives us:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/f94b80113772d90a4fbc93d4495cb5767e5c8123.svg",width:"183.39999999999998rem",height:"75.6rem"}),React.createElement("p",null,"Multiplying this ",React.createElement("strong",null,React.createElement("em",null,"A"))," with our coordinates will give us a proper Bézier matrix expression again:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d088274e440ceeac2916a0f32176682d776c1c57.svg",width:"448rem",height:"77rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/9e68f80b270d3445d9f9cb28ff2c5aed219aa9d2.svg",width:"365.4rem",height:"85.39999999999999rem"}),React.createElement("p",null,"So a Catmull-Rom to Bézier conversion, based on coordinates, requires turning the Catmull-Rom coordinates on the left into the Bézier coordinates on the right (with τ being our tension factor):"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/92a34d777899da97f1907e6b093db28872f02c3a.svg",width:"261.8rem",height:"89.6rem"}),React.createElement("p",null,"And the other way around, a Bézier to Catmull-Rom conversion requires turning the Bézier coordinates on the left this time into the Catmull-Rom coordinates on the right. Note that there is no tension this time, because Bézier curves don't have any. Converting from Bézier to Catmull-Rom is simply a default-tension Catmull-Rom curve:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ee3d3d219a18596dc403c0392d44bc585d738e6c.svg",width:"309.4rem",height:"81.19999999999999rem"}),React.createElement("p",null,"Done. We can now draw the curves we want using either Bézier curves or Catmull-Rom splines, the choice mostly being which drawing algorithms we have natively available."));}},"catmullmoulding":{"locale":"en-GB","title":"Creating a Catmull-Rom curve from three points","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"catmullmoulding",title:"Creating a Catmull-Rom curve from three points",number:"30"}),React.createElement("p",null,"Now, we saw how to fit a Bézier curve to three points, but if Catmull-Rom curves go through points, why can't we just use those to do curve fitting, instead?"),React.createElement("p",null,"As a matter of fact, we can, but there's a difference between the kind of curve fitting we did in the previous section, and the kind of curve fitting that we can do with Catmull-Rom curves. In the previous section we came up with a single curve that goes through three points. There was a decent amount of maths and computation involved, and the end result was three or four coordinates that described a single curve, depending on whether we were fitting a quadratic or cubic curve."),React.createElement("p",null,"Using Catmull-Rom curves, we need virtually no computation, but even though we end up with one Catmull-Rom curve of ",React.createElement("i",null,"n")," points, in order to draw the equivalent curve using cubic Bézier curves we need a massive ",React.createElement("i",null,"3n-2")," points (and that's without double-counting points that are shared by consecutive cubic curves)."),React.createElement("p",null,"In the following graphic, on the left we see three points that we want to draw a Catmull-Rom curve through (which we can move around freely, by the way), with in the second panel some of the \"interesting\" Catmull-Rom information: in black there's the baseline start--end, which will act as tangent orientation for the curve at point p2. We also see a virtual point p0 and p4, which are initially just point p2 reflected over the baseline. However, by using the up and down cursor key we can offset these points parallel to the baseline. Why would we want to do this? Because the line p0--p2 acts as departure tangent at p1, and the line p2--p4 acts as arrival tangent at p3. Play around with the graphic a bit to get an idea of what all of that meant:"),React.createElement(Graphic,{preset:"threepanel",title:"Catmull-Rom curve fitting",setup:handler.setup,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"As should be obvious by now, Catmull-Rom curves are great for \"fitting a curvature to some points\", but if we want to convert that curve to Bézier form we're going to end up with a lot of separate (but visually joined) Bézier curves. Depending on what we want to do, that'll be either unnecessary work, or exactly what we want: which it is depends entirely on you."));}},"polybezier":{"locale":"en-GB","title":"Forming poly-Bézier curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"polybezier",title:"Forming poly-Bézier curves",number:"31"}),React.createElement("p",null,"Much like lines can be chained together to form polygons, Bézier curves can be chained together to form poly-Béziers, and the only trick required is to make sure that:"),React.createElement("ol",null,React.createElement("li",null,"the end point of each section is the starting point of the following section, and"),React.createElement("li",null,"the derivatives across that dual point line up.")),React.createElement("p",null,"Unless, of course, you want discontinuities; then you don't even need 2."),React.createElement("p",null,"We'll cover three forms of poly-Bézier curves in this section. First, we'll look at the kind that just follows point 1. where the end point of a segment is the same point as the start point of the next segment. This leads to poly-Béziers that are pretty hard to work with, but they're the easiest to implement:"),React.createElement(Graphic,{preset:"poly",title:"Unlinked quadratic poly-Bézier",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"poly",title:"Unlinked cubic poly-Bézier",setup:handler.setupCubic,draw:handler.draw}),React.createElement("p",null,"Dragging the control points around only affects the curve segments that the control point belongs to, and moving an on-curve point leaves the control points where they are, which is not the most useful for practical modelling purposes. So, let's add in the logic we need to make things a little better. We'll start by linking up control points by ensuring that the \"incoming\" derivative at an on-curve point is the same as it's \"outgoing\" derivative:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/37740bb1a0b7b1ff48bf3454e52295fc717cacbb.svg",width:"130.2rem",height:"18.2rem"}),React.createElement("p",null,"We can effect this quite easily, because we know that the vector from a curve's last control point to its last on-curve point is equal to the derivative vector. If we want to ensure that the first control point of the next curve matches that, all we have to do is mirror that last control point through the last on-curve point. And mirroring any point A through any point B is really simple:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ce6e3939608c4ed0598107b06543c2301b91bb7f.svg",width:"319.2rem",height:"42rem"}),React.createElement("p",null,"So let's implement that and see what it gets us. The following two graphics show a quadratic and a cubic poly-Bézier curve again, but this time moving the control points around moves others, too. However, you might see something unexpected going on for quadratic curves..."),React.createElement(Graphic,{preset:"poly",title:"Loosely connected quadratic poly-Bézier",setup:handler.setupQuadratic,draw:handler.draw,onMouseMove:handler.linkDerivatives}),React.createElement(Graphic,{preset:"poly",title:"Loosely connected cubic poly-Bézier",setup:handler.setupCubic,draw:handler.draw,onMouseMove:handler.linkDerivatives}),React.createElement("p",null,"As you can see, quadratic curves are particularly ill-suited for poly-Bézier curves, as all the control points are effectively linked. Move one of them, and you move all of them. Not only that, but if we move the on-curve points, it's possible to get a situation where a control point's positions is different depending on whether it's the reflection of its left or right neighbouring control point: we can't even form a proper rule-conforming curve! This means that we cannot use quadratic poly-Béziers for anything other than really, really simple shapes. And even then, they're probably the wrong choice. Cubic curves are pretty decent, but the fact that the derivatives are linked means we can't manipulate curves as well as we might if we relaxed the constraints a little."),React.createElement("p",null,"So: let's relax the requirement a little."),React.createElement("p",null,"We can change the constraint so that we still preserve the ",React.createElement("em",null,"angle")," of the derivatives across sections (so transitions from one section to the next will still look natural), but give up the requirement that they should also have the same ",React.createElement("em",null,"vector length"),". Doing so will give us a much more useful kind of poly-Bézier curve:"),React.createElement(Graphic,{preset:"poly",title:"Loosely connected quadratic poly-Bézier",setup:handler.setupQuadratic,draw:handler.draw,onMouseMove:handler.linkDirection}),React.createElement(Graphic,{preset:"poly",title:"Loosely connected cubic poly-Bézier",setup:handler.setupCubic,draw:handler.draw,onMouseMove:handler.linkDirection}),React.createElement("p",null,"Cubic curves are now better behaved when it comes to dragging control points around, but the quadratic poly-Bézier still has the problem that moving one control points will move the control points and may ending up defining \"the next\" control point in a way that doesn't work. Quadratic curves really aren't very useful to work with..."),React.createElement("p",null,"Finally, we also want to make sure that moving the on-curve coordinates preserves the relative positions of the associated control points. With that, we get to the kind of curve control that you might be familiar with from applications like Photoshop, Inkscape, Blender, etc."),React.createElement(Graphic,{preset:"poly",title:"Loosely connected quadratic poly-Bézier",setup:handler.setupQuadratic,draw:handler.draw,onMouseDown:handler.bufferPoints,onMouseMove:handler.modelCurve}),React.createElement(Graphic,{preset:"poly",title:"Loosely connected cubic poly-Bézier",setup:handler.setupCubic,draw:handler.draw,onMouseDown:handler.bufferPoints,onMouseMove:handler.modelCurve}),React.createElement("p",null,"Again, we see that cubic curves are now rather nice to work with, but quadratic curves have a new, very serious problem: we can move an on-curve point in such a way that we can't compute what needs to \"happen next\". Move the top point down, below the left and right points, for instance. There is no way to preserve correct control points without a kink at the bottom point. Quadratic curves: just not that good..."),React.createElement("p",null,"A final improvement is to offer fine-level control over which points behave which, so that you can have \"kinks\" or individually controlled segments when you need them, with nicely well-behaved curves for the rest of the path. Implementing that, is left as an excercise for the reader."));}},"shapes":{"locale":"en-GB","title":"Boolean shape operations","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"shapes",title:"Boolean shape operations",number:"32"}),React.createElement("p",null,"We can apply the topics covered so far in this primer to effect boolean shape operations: getting the union, intersection, or exclusion, between two or more shapes that involve Bézier curves. For simplicity (well.. sort of, more homogeneity), we'll be looking at Poly-Bézier shapes only, but a shape that consists of a mix of lines and Bézier curves is technically a simplification (although it does mean we need to write a definition for the class of shapes that mix lines and Bézier curves. Since poly-Bézier curves are a superset, we'll be using those in the following examples)"),React.createElement("p",null,"The procedure for performing boolean operations consists, broadly, of four steps:"),React.createElement("ol",null,React.createElement("li",null,"Find the intersection points between both shapes,"),React.createElement("li",null,"cut up the shapes into multiple sections between these intersections,"),React.createElement("li",null,"discard any section that isn't part of the desired operation's resultant shape, and"),React.createElement("li",null,"link up the remaining sections to form the new shape.")),React.createElement("p",null,"Finding all intersections between two poly-Bézier curves, or any poly-line-section shape, is similar to the iterative algorithm discussed in the section on curve/curve intersection. For each segment in the poly-Bézier curve we check whether its bounding box overlaps with any of the segment bounding boxes in the other poly-Bézier curve. If so, we run normal intersection detection."),React.createElement("p",null,"After we found all intersection points, we split up our poly-Bézier curves, making sure to record which of the newly formed poly-Bézier curves might potentially link up at the points we split the originals up at. This will let us quickly glue poly-Bézier curves back together after the next step."),React.createElement("p",null,"Once we have all the new poly-Bézier curves, we run the first step of the desired boolean operation."),React.createElement("ul",null,React.createElement("li",null,"Union: discard all poly-Bézier curves that lie \"inside\" our union of our shapes. E.g. if we want the union of two overlapping circles, the resulting shape is the outline."),React.createElement("li",null,"Intersection: discard all poly-Bézier curves that lie \"outside\" the intersection of the two shapes. E.g. if we want the intersection of two overlapping circles, the resulting shape is the tapered ellipse where they overlap."),React.createElement("li",null,"Exclusion: none of the sections are discarded, but we will need to link the shapes back up in a special way. Flip any section that would qualify for removal under UNION rules.")),React.createElement("table",{className:"sketch"},React.createElement("tbody",null,React.createElement("tr",null,React.createElement("td",{className:"labeled-image"},React.createElement("img",{src:"images/op_base.gif",height:"169px"}),"Two overlapping shapes."),React.createElement("td",{className:"labeled-image"},React.createElement("img",{src:"images/op_union.gif",height:"169px"}),"The unified region."),React.createElement("td",{className:"labeled-image"},React.createElement("img",{src:"images/op_intersection.gif",height:"169px"}),"Their intersection."),React.createElement("td",{className:"labeled-image"},React.createElement("img",{src:"images/op_exclusion.gif",height:"169px"}),"Their exclusion regions.")))),React.createElement("p",null,"The main complication in the outlined procedure here is determining how sections qualify in terms of being \"inside\" and \"outside\" of our shapes. For this, we need to be able to perform point-in-shape detection, for which we'll use a classic algorithm: getting the \"crossing number\" by using ray casting, and then testing for \"insidedness\" by applying the ",React.createElement("a",{href:"http://folk.uio.no/bjornw/doc/bifrost-ref/bifrost-ref-12.html"},"even-odd rule"),": For any point and any shape, we can cast a ray from our point, to some point that we know lies outside of the shape (such as a corner of our drawing surface). We then count how many times that line crosses our shape (remember that we can perform line/curve intersection detection quite easily). If the number of times it crosses the shape's outline is even, the point did not actually lie inside our shape. If the number of intersections is odd, our point did lie inside out shape. With that knowledge, we can decide whether to treat a section that such a point lies on \"needs removal\" (under union rules), \"needs preserving\" (under intersection rules), or \"needs flipping\" (under exclusion rules)."),React.createElement("p",null,"These operations are expensive, and implementing your own code for this is generally a bad idea if there is already a geometry package available for your language of choice. In this case, for JavaScript the most excellent ",React.createElement("a",{href:"http://paperjs.org"},"Paper.js")," already comes with all the code in place to perform efficient boolean shape operations, so rather that implement an inferior version here, I can strongly recommend the Paper.js library if you intend to do any boolean shape work."),React.createElement("p",null,"The following graphic shows Paper.js doing its thing for two shapes: one static, and one that is linked to your mouse pointer. If you move the mouse around, you'll see how the shape intersections are resolved. The base shapes are outlined in blue, and the boolean result is coloured red."),React.createElement(Graphic,{preset:"simple",title:"Boolean shape operations with Paper.js",paperjs:true,setup:handler.setup,draw:handler.draw,onMouseMove:handler.onMouseMove},React.createElement("br",null),handler.modes.map(function(mode){var className=handler.state.mode===mode?"selected":null;return React.createElement("button",{className:className,key:mode,onClick:function onClick(){return handler.setMode(mode);}},mode);})));}},"projections":{"locale":"en-GB","title":"Projecting a point onto a Bézier curve","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"projections",title:"Projecting a point onto a Bézier curve",number:"33"}),React.createElement("p",null,"Say we have a Bézier curve and some point, not on the curve, of which we want to know which ",React.createElement("code",null,"t")," value on the curve gives us an on-curve point closest to our off-curve point. Or: say we want to find the projection of a random point onto a curve. How do we do that?"),React.createElement("p",null,"If the Bézier curve is of low enough order, we might be able to ",React.createElement("a",{href:"http://jazzros.blogspot.ca/2011/03/projecting-point-on-bezier-curve.html"},"work out the maths for how to do this"),", and get a perfect ",React.createElement("code",null,"t")," value back, but in general this is an incredibly hard problem and the easiest solution is, really, a numerical approach again. We'll be finding our ideal ",React.createElement("code",null,"t")," value using a ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Binary_search_algorithm"},"binary search"),". First, we do a coarse distance-check based on ",React.createElement("code",null,"t")," values associated with the curve's \"to draw\" coordinates (using a lookup table, or LUT). This is pretty fast. Then we run this algorithm:"),React.createElement("ol",null,React.createElement("li",null,"with the ",React.createElement("code",null,"t")," value we found, start with some small interval around ",React.createElement("code",null,"t")," (1/length_of_LUT on either side is a reasonable start),"),React.createElement("li",null,"if the distance to ",React.createElement("code",null,"t ± interval/2")," is larger than the distance to ",React.createElement("code",null,"t"),", try again with the interval reduced to half its original length."),React.createElement("li",null,"if the distance to ",React.createElement("code",null,"t ± interval/2")," is smaller than the distance to ",React.createElement("code",null,"t"),", replace ",React.createElement("code",null,"t")," with the smaller-distance value."),React.createElement("li",null,"after reducing the interval, or changing ",React.createElement("code",null,"t"),", go back to step 1.")),React.createElement("p",null,"We keep repeating this process until the interval is small enough to claim the difference in precision found is irrelevant for the purpose we're trying to find ",React.createElement("code",null,"t")," for. In this case, I'm arbitrarily fixing it at 0.0001."),React.createElement("p",null,"The following graphic demonstrates the result of this procedure.Simply move the cursor around, and if it does not lie on top of the curve, you will see a line that projects the cursor onto the curve based on an iteratively found \"ideal\" ",React.createElement("code",null,"t")," value."),React.createElement(Graphic,{preset:"simple",title:"Projecting a point onto a Bézier curve",setup:handler.setup,draw:handler.draw,onMouseMove:handler.onMouseMove}));}},"offsetting":{"locale":"en-GB","title":"Curve offsetting","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"offsetting",title:"Curve offsetting",number:"34"}),React.createElement("p",null,"Perhaps you are like me, and you've been writing various small programs that use Bézier curves in some way or another, and at some point you make the step to implementing path extrusion. But you don't want to do it pixel based, you want to stay in the vector world. You find that extruding lines is relatively easy, and tracing outlines is coming along nicely (although junction caps and fillets are a bit of a hassle), and then decide to do things properly and add Bézier curves to the mix. Now you have a problem."),React.createElement("p",null,"Unlike lines, you can't simply extrude a Bézier curve by taking a copy and moving it around, because of the curvatures; rather than a uniform thickness you get an extrusion that looks too thin in places, if you're lucky, but more likely will self-intersect. The trick, then, is to scale the curve, rather than simply copying it. But how do you scale a Bézier curve?"),React.createElement("p",null,"Bottom line: ",React.createElement("strong",null,"you can't"),". So you cheat. We're not going to do true curve scaling, or rather curve offsetting, because that's impossible. Instead we're going to try to generate 'looks good enough' offset curves."),React.createElement("div",{className:"note"},React.createElement("h3",{id:"-what-do-you-mean-you-can-t-prove-it-"},"\"What do you mean, you can't. Prove it.\""),React.createElement("p",null,"First off, when I say \"you can't\" what I really mean is \"you can't offset a Bézier curve with another Bézier curve\". not even by using a really high order curve. You can find the function that describes the offset curve, but it won't be a polynomial, and as such it cannot be represented as a Bézier curve, which ",React.createElement("strong",null,"has")," to be a polynomial. Let's look at why this is:"),React.createElement("p",null,"From a mathematical point of view, an offset curve ",React.createElement("code",null,"O(t)")," is a curve such that, given our original curve ",React.createElement("code",null,"B(t)"),", any point on ",React.createElement("code",null,"O(t)")," is a fixed distance ",React.createElement("code",null,"d")," away from coordinate ",React.createElement("code",null,"B(t)"),". So let's math that:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3aff5cef0028337bbb48ae64ad30000c4d5e238f.svg",width:"113.39999999999999rem",height:"16.799999999999997rem"}),React.createElement("p",null,"However, we're working in 2D, and ",React.createElement("code",null,"d")," is a single value, so we want to turn it into a vector. If we want a point distance ",React.createElement("code",null,"d")," \"away\" from the curve ",React.createElement("code",null,"B(t)")," then what we really mean is that we want a point at ",React.createElement("code",null,"d")," times the \"normal vector\" from point ",React.createElement("code",null,"B(t)"),", where the \"normal\" is a vector that runs perpendicular (\"at a right angle\") to the tangent at ",React.createElement("code",null,"B(t)"),". Easy enough:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/2cf48e2f8525258a3fa0fe4f10ec2acef67104b3.svg",width:"158.2rem",height:"16.799999999999997rem"}),React.createElement("p",null,"Now this still isn't very useful unless we know what the formula for ",React.createElement("code",null,"N(t)")," is, so let's find out. ",React.createElement("code",null,"N(t)")," runs perpendicular to the original curve tangent, and we know that the tangent is simply ",React.createElement("code",null,"B'(t)"),", so we could just rotate that 90 degrees and be done with it. However, we need to ensure that ",React.createElement("code",null,"N(t)")," has the same magnitude for every ",React.createElement("code",null,"t"),", or the offset curve won't be at a uniform distance, thus not being an offset curve at all. The easiest way to guarantee this is to make sure ",React.createElement("code",null,"N(t)")," always has length 1, which we can achieve by dividing ",React.createElement("code",null,"B'(t)")," by its magnitude:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/4941ecbff4c50732ba66fec53307456fc605f032.svg",width:"125.99999999999999rem",height:"42rem"}),React.createElement("p",null,"Determining the length requires computing an arc length, and this is where things get Tricky with a capital T. First off, to compute arc length from some start ",React.createElement("code",null,"a")," to end ",React.createElement("code",null,"b"),", we must use the formula we saw earlier. Noting that \"length\" is usually denoted with double vertical bars:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/f6d8c2965b02363e092acb00bbc1398cfbb170a4.svg",width:"177.79999999999998rem",height:"37.8rem"}),React.createElement("p",null,"So if we want the length of the tangent, we plug in ",React.createElement("code",null,"B'(t)"),", with ",React.createElement("code",null,"t = 0")," as start and",React.createElement("code",null,"t = 1")," as end:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1f024282044316a9e4b3de2c855d2ceb96aff056.svg",width:"219.79999999999998rem",height:"37.8rem"}),React.createElement("p",null,"And that's where things go wrong. It doesn't even really matter what the second derivative for ",React.createElement("code",null,"B(t)")," is, that square root is screwing everything up, because it turns our nice polynomials into things that are no longer polynomials."),React.createElement("p",null,"There is a small class of polynomials where the square root is also a polynomial, but they're utterly useless to us: any polynomial with unweighted binomial coefficients has a square root that is also a polynomial. Now, you might think that Bézier curves are just fine because they do, but they don't; remember that only the ",React.createElement("strong",null,"base")," function has binomial coefficients. That's before we factor in our coordinates, which turn it into a non-binomial polygon. The only way to make sure the functions stay binomial is to make all our coordinates have the same value. And that's not a curve, that's a point. We can already create offset curves for points, we call them circles, and they have much simpler functions than Bézier curves."),React.createElement("p",null,"So, since the tangent length isn't a polynomial, the normalised tangent won't be a polynomial either, which means ",React.createElement("code",null,"N(t)")," won't be a polynomial, which means that ",React.createElement("code",null,"d")," times ",React.createElement("code",null,"N(t)")," won't be a polynomial, which means that, ultimately, ",React.createElement("code",null,"O(t)")," won't be a polynomial, which means that even if we can determine the function for ",React.createElement("code",null,"O(t)")," just fine (and that's far from trivial!), it simply cannot be represented as a Bézier curve."),React.createElement("p",null,"And that's one reason why Bézier curves are tricky: there are actually a ",React.createElement("code",null,"lot")," of curves that cannot be represent as a Bézier curve at all. They can't even model their own offset curves. They're weird that way. So how do all those other programs do it? Well, much like we're about to do, they cheat. We're going to approximate an offset curve in a way that will look relatively close to what the real offset curve would look like, if we could compute it.")),React.createElement("p",null,"So, you cannot offset a Bézier curve perfectly with another Bézier curve, no matter how high-order you make that other Bézier curve. However, we can chop up a curve into \"safe\" sub-curves (where safe means that all the control points are always on a single side of the baseline, and the midpoint of the curve at ",React.createElement("code",null,"t=0.5")," is roughly in the centre of the polygon defined by the curve coordinates) and then point-scale each sub-curve with respect to its scaling origin (which is the intersection of the point normals at the start and end points)."),React.createElement("p",null,"A good way to do this reduction is to first find the curve's extreme points, as explained in the earlier section on curve extremities, and use these as initial splitting points. After this initial split, we can check each individual segment to see if it's \"safe enough\" based on where the center of the curve is. If the on-curve point for ",React.createElement("code",null,"t=0.5")," is too far off from the center, we simply split the segment down the middle. Generally this is more than enough to end up with safe segments."),React.createElement("p",null,"The following graphics show off curve offsetting, and you can use your up and down arrow keys to control the distance at which the curve gets offset. The curve first gets reduced to safe segments, each of which is then offset at the desired distance. Especially for simple curves, particularly easily set up for quadratic curves, no reduction is necessary, but the more twisty the curve gets, the more the curve needs to be reduced in order to get segments that can safely be scaled."),React.createElement(Graphic,{preset:"simple",title:"Offsetting a quadratic Bézier curve",setup:handler.setupQuadratic,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement(Graphic,{preset:"simple",title:"Offsetting a cubic Bézier curve",setup:handler.setupCubic,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"You may notice that this may still lead to small 'jumps' in the sub-curves when moving the curve around. This is caused by the fact that we're still performing a naive form of offsetting, moving the control points the same distance as the start and end points. If the curve is large enough, this may still lead to incorrect offsets."));}},"graduatedoffset":{"locale":"en-GB","title":"Graduated curve offsetting","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"graduatedoffset",title:"Graduated curve offsetting",number:"35"}),React.createElement("p",null,"What if we want to do graduated offsetting, starting at some distance ",React.createElement("code",null,"s")," but ending at some other distance ",React.createElement("code",null,"e"),"? well, if we can compute the length of a curve (which we can if we use the Legendre-Gauss quadrature approach) then we can also determine how far \"along the line\" any point on the curve is. With that knowledge, we can offset a curve so that its offset curve is not uniformly wide, but graduated between with two different offset widths at the start and end."),React.createElement("p",null,"Like normal offsetting we cut up our curve in sub-curves, and then check at which distance along the original curve each sub-curve starts and ends, as well as to which point on the curve each of the control points map. This gives us the distance-along-the-curve for each interesting point in the sub-curve. If we call the total length of all sub-curves seen prior to seeing \"the current\" sub-curve ",React.createElement("code",null,"S")," (and if the current sub-curve is the first one, ",React.createElement("code",null,"S")," is zero), and we call the full length of our original curve ",React.createElement("code",null,"L"),", then we get the following graduation values:"),React.createElement("ul",null,React.createElement("li",null,"start: map ",React.createElement("code",null,"S")," from interval (",React.createElement("code",null,"0,L"),") to interval ",React.createElement("code",null,"(s,e)")),React.createElement("li",null,"c1: ",React.createElement("code",null,"map(<strong>S+d1</strong>, 0,L, s,e)"),", d1 = distance along curve to projection of c1"),React.createElement("li",null,"c2: ",React.createElement("code",null,"map(<strong>S+d2</strong>, 0,L, s,e)"),", d2 = distance along curve to projection of c2"),React.createElement("li",null,"..."),React.createElement("li",null,"end: ",React.createElement("code",null,"map(<strong>S+length(subcurve)</strong>, 0,L, s,e)"))),React.createElement("p",null,"At each of the relevant points (start, end, and the projections of the control points onto the curve) we know the curve's normal, so offsetting is simply a matter of taking our original point, and moving it along the normal vector by the offset distance for each point. Doing so will give us the following result (these have with a starting width of 0, and an end width of 40 pixels, but can be controlled with your up and down arrow keys):"),React.createElement(Graphic,{preset:"simple",title:"Offsetting a quadratic Bézier curve",setup:handler.setupQuadratic,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement(Graphic,{preset:"simple",title:"Offsetting a cubic Bézier curve",setup:handler.setupCubic,draw:handler.draw,onKeyDown:handler.props.onKeyDown}));}},"circles":{"locale":"en-GB","title":"Circles and quadratic Bézier curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"circles",title:"Circles and quadratic Bézier curves",number:"36"}),React.createElement("p",null,"Circles and Bézier curves are very different beasts, and circles are infinitely easier to work with than Bézier curves. Their formula is much simpler, and they can be drawn more efficiently. But, sometimes you don't have the luxury of using circles, or ellipses, or arcs. Sometimes, all you have are Bézier curves. For instance, if you're doing font design, fonts have no concept of geometric shapes, they only know straight lines, and Bézier curves. OpenType fonts with TrueType outlines only know quadratic Bézier curves, and OpenType fonts with Type 2 outlines only know cubic Bézier curves. So how do you draw a circle, or an ellipse, or an arc?"),React.createElement("p",null,"You approximate."),React.createElement("p",null,"We already know that Bézier curves cannot model all curves that we can think of, and this includes perfect circles, as well as ellipses, and their arc counterparts. However, we can certainly approximate them to a degree that is visually acceptable. Quadratic and cubic curves offer us different curvature control, so in order to approximate a circle we will first need to figure out what the error is if we try to approximate arcs of increasing degree with quadratic and cubic curves, and where the coordinates even lie."),React.createElement("p",null,"Since arcs are mid-point-symmetrical, we need the control points to set up a symmetrical curve. For quadratic curves this means that the control point will be somewhere on a line that intersects the baseline at a right angle. And we don't get any choice on where that will be, since the derivatives at the start and end point have to line up, so our control point will lie at the intersection of the tangents at the start and end point."),React.createElement("p",null,"First, let's try to fit the quadratic curve onto a circular arc. In the following sketch you can move the mouse around over a unit circle, to see how well, or poorly, a quadratic curve can approximate the arc from (1,0) to where your mouse cursor is:"),React.createElement(Graphic,{preset:"arcfitting",title:"Quadratic Bézier arc approximation",setup:handler.setup,draw:handler.draw,onMouseMove:handler.onMouseMove}),React.createElement("p",null,"As you can see, things go horribly wrong quite quickly; even trying to approximate a quarter circle using a quadratic curve is a bad idea. An eighth of a turns might look okay, but how okay is okay? Let's apply some maths and find out. What we're interested in is how far off our on-curve coordinates are with respect to a circular arc, given a specific start and end angle. We'll be looking at how much space there is between the circular arc, and the quadratic curve's midpoint."),React.createElement("p",null,"We start out with our start and end point, and for convenience we will place them on a unit circle (a circle around 0,0 with radius 1), at some angle ",React.createElement("em",null,"φ"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ef34ab8f466ed3294895135a346b55ada05d779d.svg",width:"183.39999999999998rem",height:"42rem"}),React.createElement("p",null,"What we want to find is the intersection of the tangents, so we want a point C such that:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5660e8512b07dbac7fcf04633de8002fa25aa962.svg",width:"298.2rem",height:"42rem"}),React.createElement("p",null,"i.e. we want a point that lies on the vertical line through S (at some distance ",React.createElement("em",null,"a")," from S) and also lies on the tangent line through E (at some distance ",React.createElement("em",null,"b")," from E). Solving this gives us:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d16e7a1c1e9686e1afb82f4ffcec07078d264565.svg",width:"229.6rem",height:"42rem"}),React.createElement("p",null,"First we solve for ",React.createElement("em",null,"b"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3128b31a874166ebe4479d3002d70f280de375a1.svg",width:"588rem",height:"18.2rem"}),React.createElement("p",null,"which yields:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/02b158f9ef2191b970dc2fe69c0903eba2b1f8b5.svg",width:"106.39999999999999rem",height:"40.599999999999994rem"}),React.createElement("p",null,"which we can then substitute in the expression for ",React.createElement("em",null,"a"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3bd9c2d6740ff530aabcbe60252742032af816e9.svg",width:"242.2rem",height:"204.39999999999998rem"}),React.createElement("p",null,"A quick check shows that plugging these values for ",React.createElement("em",null,"a")," and ",React.createElement("em",null,"b")," into the expressions for C",React.createElement("sub",null,"x")," and C",React.createElement("sub",null,"y")," give the same x/y coordinates for both \"",React.createElement("em",null,"a")," away from A\" and \"",React.createElement("em",null,"b")," away from B\", so let's continue: now that we know the coordinate values for C, we know where our on-curve point T for ",React.createElement("em",null,"t=0.5")," (or angle φ/2) is, because we can just evaluate the Bézier polynomial, and we know where the circle arc's actual point P is for angle φ/2:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b80423188012451e0400f473c19729eb2bad654.svg",width:"197.39999999999998rem",height:"33.599999999999994rem"}),React.createElement("p",null,"We compute T, observing that if ",React.createElement("em",null,"t=0.5"),", the polynomial values (1-t)², 2(1-t)t, and t² are 0.25, 0.5, and 0.25 respectively:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/bc50559ff8bd9062694a449aae5f6f85f91de909.svg",width:"264.59999999999997rem",height:"36.4rem"}),React.createElement("p",null,"Which, worked out for the x and y components, gives:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c7fca7664a3acb855eeaaf412aa2331202f41097.svg",width:"428.4rem",height:"81.19999999999999rem"}),React.createElement("p",null,"And the distance between these two is the standard Euclidean distance:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3251cd91a1cffc27a1695ece4c13cc651d7007fb.svg",width:"418.59999999999997rem",height:"161rem"}),React.createElement("p",null,"So, what does this distance function look like when we plot it for a number of ranges for the angle φ, such as a half circle, quarter circle and eighth circle?"),React.createElement("table",null,React.createElement("tbody",null,React.createElement("tr",null,React.createElement("td",null,React.createElement("img",{src:"images/arc-q-pi.gif",height:"190px"}),"plotted for 0 ≤ φ ≤ π:"),React.createElement("td",null,React.createElement("img",{src:"images/arc-q-pi2.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ ½π:"),React.createElement("td",null,handler.props.showhref?"http://www.wolframalpha.com/input/?i=plot+sqrt%28%281%2F4+*+%28sin%28x%29+%2B+2tan%28x%2F2%29%29+-+sin%28x%2F2%29%29%5E2+%2B+%282sin%5E4%28x%2F4%29%29%5E2%29+for+0+%3C%3D+x+%3C%3D+pi%2F4":null,React.createElement("img",{src:"images/arc-q-pi4.gif",height:"174px"}),"plotted for 0 ≤ φ ≤ ¼π:")))),React.createElement("p",null,"We now see why the eighth circle arc looks decent, but the quarter circle arc doesn't: an error of roughly 0.06 at ",React.createElement("em",null,"t=0.5")," means we're 6% off the mark... we will already be off by one pixel on a circle with pixel radius 17. Any decent sized quarter circle arc, say with radius 100px, will be way off if approximated by a quadratic curve! For the eighth circle arc, however, the error is only roughly 0.003, or 0.3%, which explains why it looks so close to the actual eighth circle arc. In fact, if we want a truly tiny error, like 0.001, we'll have to contend with an angle of (rounded) 0.593667, which equates to roughly 34 degrees. We'd need 11 quadratic curves to form a full circle with that precision! (technically, 10 and ten seventeenth, but we can't do partial curves, so we have to round up). That's a whole lot of curves just to get a shape that can be drawn using a simple function!"),React.createElement("p",null,"In fact, let's flip the function around, so that if we plug in the precision error, labelled ε, we get back the maximum angle for that precision:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/61a938fa10b77e8c41c3c064ed39bd1145d6bbcc.svg",width:"259rem",height:"56rem"}),React.createElement("p",null,"And frankly, things are starting to look a bit ridiculous at this point, we're doing way more maths than we've ever done, but thankfully this is as far as we need the maths to take us: If we plug in the precisions 0.1, 0.01, 0.001 and 0.0001 we get the radians values 1.748, 1.038, 0.594 and 0.3356; in degrees, that means we can cover roughly 100 degrees (requiring four curves), 59.5 degrees (requiring six curves), 34 degrees (requiring 11 curves), and 19.2 degrees (requiring a whopping nineteen curves)."),React.createElement("p",null,"The bottom line? ",React.createElement("strong",null,"Quadratic curves are kind of lousy")," if you want circular (or elliptical, which are circles that have been squashed in one dimension) curves. We can do better, even if it's just by raising the order of our curve once. So let's try the same thing for cubic curves."));}},"circles_cubic":{"locale":"en-GB","title":"Circles and cubic Bézier curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"circles_cubic",title:"Circles and cubic Bézier curves",number:"37"}),React.createElement("p",null,"In the previous section we tried to approximate a circular arc with a quadratic curve, and it mostly made us unhappy. Cubic curves are much better suited to this task, so what do we need to do?"),React.createElement("p",null,"For cubic curves, we basically want the curve to pass through three points on the circle: the start point, the mid point at \"angle/2\", and the end point at \"angle\". We then also need to make sure the control points are such that the start and end tangent lines line up with the circle's tangent lines at the start and end point."),React.createElement("p",null,"The first thing we can do is \"guess\" what the curve should look like, based on the previously outlined curve-through-three-points procedure. This will give use a curve with correct start, mid and end points, but possibly incorrect derivatives at the start and end, because the control points might not be in the right spot. We can then slide the control points along the lines that connect them to their respective end point, until they effect the corrected derivative at the start and end points. However, if you look back at the section on fitting curves through three points, the rules used were such that they optimized for a near perfect hemisphere, so using the same guess won't be all that useful: guessing the solution based on knowing the solution is not really guessing."),React.createElement("p",null,"So have a graphical look at a \"bad\" guess versus the true fit, where we'll be using the bad guess and the description in the second paragraph to derive the maths for the true fit:"),React.createElement(Graphic,{preset:"arcfitting",title:"Cubic Bézier arc approximation",setup:handler.setup,draw:handler.draw,onMouseMove:handler.onMouseMove}),React.createElement("p",null,"We see two curves here; in blue, our \"guessed\" curve and its control points, and in grey/black, the true curve fit, with proper control points that were shifted in, along line between our guessed control points, such that the derivatives at the start and end points are correct."),React.createElement("p",null,"We can already seethat cubic curves are a lot better than quadratic curves, and don't look all that wrong until we go well past a quarter circle; ⅜th starts to hint at problems, and half a circle has an obvious \"gap\" between the real circle and the cubic approximation. Anything past that just looks plain ridiculous... but quarter curves actually look pretty okay!"),React.createElement("p",null,"So, maths time again: how okay is \"okay\"? Let's apply some more maths to find out."),React.createElement("p",null,"Unlike for the quadratic curve, we can't use ",React.createElement("i",null,"t=0.5")," as our reference point because by its very nature it's one of the three points that are actually guaranteed to lie on the circular curve. Instead, we need a different ",React.createElement("i",null,"t")," value. If we run some analysis on the curve we find that the actual ",React.createElement("i",null,"t")," value at which the curve is furthest from what it should be is 0.211325 (rounded), but we don't know \"why\", since finding this value involves root-finding, and is nearly impossible to do symbolically without pages and pages of math just to express one of the possible solutions."),React.createElement("p",null,"So instead of walking you through the derivation for that value, let's simply take that ",React.createElement("i",null,"t")," value and see what the error is for circular arcs with an angle ranging from 0 to 2π:"),React.createElement("table",null,React.createElement("tbody",null,React.createElement("tr",null,React.createElement("td",null,React.createElement("img",{src:"images/arc-c-2pi.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ 2π:"),React.createElement("td",null,React.createElement("img",{src:"images/arc-c-pi.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ π:"),React.createElement("td",null,React.createElement("img",{src:"images/arc-c-pi2.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ ½π:")))),React.createElement("p",null,"We see that cubic Bézier curves are much better when it comes to approximating circular arcs, with an error of less than 0.027 at the two \"bulge\" points for a quarter circle (which had an error of 0.06 for quadratic curves at the mid point), and an error near 0.001 for an eighth of a circle, so we're getting less than half the error for a quarter circle, or: at a slightly lower error, we're getting twice the arc. This makes cubic curves quite useful!"),React.createElement("p",null,"In fact, the precision of a cubic curve at a quarter circle is considered \"good enough\" by so many people that it's generally considered \"just fine\" to use four cubic Bézier curves to fake a full circle when no circle primitives are available; generally, people won't notice that it's not a real circle unless you also happen to overlay an actual circle, so that the difference becomes obvious."),React.createElement("p",null,"So with the error analysis out of the way, how do we actually compute the coordinates needed to get that \"true fit\" cubic curve? The first observation is that we already know the start and end points, because they're the same as for the quadratic attempt:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ef34ab8f466ed3294895135a346b55ada05d779d.svg",width:"183.39999999999998rem",height:"42rem"}),React.createElement("p",null,"But we now need to find two control points, rather than one. If we want the derivatives at the start and end point to match the circle, then the first control point can only lie somewhere on the vertical line through S, and the second control point can only lie somewhere on the line tangent to point E, which means:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/4df65dae78bc5a0e6c5f23a2faae9a9d7a8b39b3.svg",width:"118.99999999999999rem",height:"42rem"}),React.createElement("p",null,"where \"a\" is some scaling factor, and:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/cb32f8f9c3ae2b264a48003c237a798d02dc8935.svg",width:"170.79999999999998rem",height:"42rem"}),React.createElement("p",null,"where \"b\" is also some scaling factor."),React.createElement("p",null,"Starting with this information, we slowly maths our way to success, but I won't lie: the maths for this is pretty trig-heavy, and it's easy to get lost if you remember (or know!) some of the core trigonoetric identities, so if you just want to see the final result just skip past the next section!"),React.createElement("div",{className:"note"},React.createElement("h2",{id:"let-s-do-this-thing-"},"Let's do this thing."),React.createElement("p",null,"Unlike for the quadratic case, we need some more information in order to compute ",React.createElement("i",null,"a")," and ",React.createElement("i",null,"b"),", since they're no longer dependent variables. First, we observe that the curve is symmetrical, so whatever values we end up finding for C",React.createElement("sub",null,"1")," will apply to C",React.createElement("sub",null,"2")," as well (rotated along its tangent), so we'll focus on finding the location of C",React.createElement("sub",null,"1")," only. So here's where we do something that you might not expect: we're going to ignore for a moment, because we're going to have a much easier time if we just solve this problem with geometry first, then move to calculus to solve a much simpler problem."),React.createElement("p",null,"If we look at the triangle that is formed between our starting point, or initial guess C",React.createElement("sub",null,"1")," and our real C",React.createElement("sub",null,"1"),", there's something funny going on: if we treat the line ",'{',"start,guess",'}'," as our opposite side, the line ",'{',"guess,real",'}'," as our adjacent side, with ",'{',"start,real",'}'," our hypothenuse, then the angle for the corner hypothenuse/adjacent is half that of the arc we're covering. Try it: if you place the end point at a quarter circle (pi/2, or 90 degrees), the angle in our triangle is half a quarter (pi/4, or 45 degrees). With that knowledge, and a knowledge of what the length of any of our lines segments are (as a function), we can determine where our control points are, and thus have everything we need to find the error distance function. Of the three lines, the one we can easiest determine is ",'{',"start,guess",'}',", so let's find out what the guessed control point is. Again geometrically, because we have the benefit of an on-curve ",React.createElement("i",null,"t=0.5")," value."),React.createElement("p",null,"The distance from our guessed point to the start point is exactly the same as the projection distance we looked at earlier. Using ",React.createElement("i",null,"t=0.5")," as our point \"B\" in the \"A,B,C\" projection, then we know the length of the line segment ",'{',"C,A",'}',", since it's d",React.createElement("sub",null,"1")," = ",'{',"A,B",'}'," + d",React.createElement("sub",null,"2")," = ",'{',"B,C",'}',":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b15a274c1e0a6aeeaf517b5d2c8ee0a7997dd617.svg",width:"417.2rem",height:"42rem"}),React.createElement("p",null,"So that just leaves us to find the distance from ",React.createElement("i",null,"t=0.5")," to the baseline for an arbitrary angle φ, which is the distance from the centre of the circle to our ",React.createElement("i",null,"t=0.5")," point, minus the distance from the centre to the line that runs from start point to end point. The first is the same as the point P we found for the quadratic curve:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b80423188012451e0400f473c19729eb2bad654.svg",width:"197.39999999999998rem",height:"33.599999999999994rem"}),React.createElement("p",null,"And the distance from the origin to the line start/end is another application of angles, since the triangle ",'{',"origin,start,C",'}'," has known angles, and two known sides. We can find the length of the line ",'{',"origin,C",'}',", which lets us trivially compute the coordinate for C:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/9be55fb38d5d30bbc6c7140afb1c7bc097bc044e.svg",width:"274.4rem",height:"70rem"}),React.createElement("p",null,"With the coordinate C, and knowledge of coordinate B, we can determine coordinate A, and get a vector that is identical to the vector ",'{',"start,guess",'}',":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/262f2eca63105779f30a0a5445cf76f60786039a.svg",width:"417.2rem",height:"50.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e83ebbac13a84ef6036bf4be57b3d1b6cb316f8.svg",width:"221.2rem",height:"49rem"}),React.createElement("p",null,"Which means we can now determine the distance ",'{',"start,guessed",'}',", which is the same as the distance ",'{',"C,A",'}',", and use that to determine the vertical distance from our start point to our C",React.createElement("sub",null,"1"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c87e454fb11ef7f15c7386e83ca1ce41a004d8a7.svg",width:"264.59999999999997rem",height:"58.8rem"}),React.createElement("p",null,"And after this tedious detour to find the coordinate for C",React.createElement("sub",null,"1"),", we can find C",React.createElement("sub",null,"2")," fairly simply, since it's lies at distance -C",React.createElement("sub",null,"1y")," along the end point's tangent:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/25f027074b6af8ca7b640e27636e3bf89c28afdb.svg",width:"550.1999999999999rem",height:"82.6rem"}),React.createElement("p",null,"And that's it, we have all four points now for an approximation of an arbitrary circular arc with angle φ.")),React.createElement("p",null,"So, to recap, given an angle φ, the new control coordinates are:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c4d82e44d1c67dda8ba26aa6da0f406d05eba618.svg",width:"215.6rem",height:"42rem"}),React.createElement("p",null,"and"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3a4b1ee00eebb7697e5513ef9df673928913252e.svg",width:"337.4rem",height:"42rem"}),React.createElement("p",null,"And, because the \"quarter curve\" special case comes up so incredibly often, let's look at what these new control points mean for the curve coordinates of a quarter curve, by simply filling in φ = π/2:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/63e0936b4849d4cdbb9a2e0909181259be951e4d.svg",width:"432.59999999999997rem",height:"35rem"}),React.createElement("p",null,"Which, in decimal values, rounded to six significant digits, is:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/fd12e65204a31319b66355c6ff99e6b3d9603b05.svg",width:"432.59999999999997rem",height:"16.799999999999997rem"}),React.createElement("p",null,"Of course, this is for a circle with radius 1, so if you have a different radius circle, simply multiply the coordinate by the radius you need. And then finally, forming a full curve is now a simple a matter of mirroring these coordinates about the origin:"),React.createElement(Graphic,{preset:"simple",title:"Cubic Bézier circle approximation",draw:handler.drawCircle,"static":true}));}},"arcapproximation":{"locale":"en-GB","title":"Approximating Bézier curves with circular arcs","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"arcapproximation",title:"Approximating Bézier curves with circular arcs",number:"38"}),React.createElement("p",null,"Let's look at doing the exact opposite of the previous section: rather than approximating circular arc using Bézier curves, let's approximate Bézier curves using circular arcs."),React.createElement("p",null,"We already saw in the section on circle approximation that this will never yield a perfect equivalent, but sometimes you need circular arcs, such as when you're working with fabrication machinery, or simple vector languages that understand lines and circles, but not much else."),React.createElement("p",null,"The approach is fairly simple: pick a starting point on the curve, and pick two points that are further along the curve. Determine the circle that goes through those three points, and see if it fits the part of the curve we're trying to approximate. Decent fit? Try spacing the points further apart. Bad fit? Try spacing the points closer together. Keep doing this until you've found the \"good approximation/bad approximation\" boundary, record the \"good\" arc, and then move the starting point up to overlap the end point we previously found. Rinse and repeat until we've covered the entire curve."),React.createElement("p",null,"So: step 1, how do we find a circle through three points? That part is actually really simple. You may remember (if you ever learned it!) that a line between two points on a circle is called a ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Chord_%28geometry%29"},"chord"),", and one property of chords is that the line from the center of any chord, perpendicular to that chord, passes through the center of the circle."),React.createElement("p",null,"So: if we have have three points, we have three (different) chords, and consequently, three (different) lines that go from those chords through the center of the circle. So we find the centers of the chords, find the perpendicular lines, find the intersection of those lines, and thus find the center of the circle."),React.createElement("p",null,"The following graphic shows this procedure with a different colour for each chord and its associated perpendicular through the center. You can move the points around as much as you like, those lines will always meet!"),React.createElement(Graphic,{preset:"simple",title:"Finding a circle through three points",setup:handler.setupCircle,draw:handler.drawCircle}),React.createElement("p",null,"So, with the procedure on how to find a circle through three points, finding the arc through those points is straight-forward: pick one of the three points as start point, pick another as an end point, and the arc has to necessarily go from the start point, over the remaining point, to the end point."),React.createElement("p",null,"So how can we convert a Bezier curve into a (sequence of) circular arc(s)?"),React.createElement("ul",null,React.createElement("li",null,"Start at ",React.createElement("em",null,"t=0")),React.createElement("li",null,"Pick two points further down the curve at some value ",React.createElement("em",null,"m = t + n")," and ",React.createElement("em",null,"e = t + 2n")),React.createElement("li",null,"Find the arc that these points define"),React.createElement("li",null,"Determine how close the found arc is to the curve:",React.createElement("ul",null,React.createElement("li",null,"Pick two additional points ",React.createElement("em",null,"e1 = t + n/2")," and ",React.createElement("em",null,"e2 = t + n + n/2"),"."),React.createElement("li",null,"These points, if the arc is a good approximation of the curve interval chosen, should lie ",React.createElement("em",null,"on")," the circle, so their distance to the center of the circle should be the same as the distance from any of the three other points to the center."),React.createElement("li",null,"For point points, determine the (absolute) error between the radius of the circle, and the",React.createElement("em",null,"actual")," distance from the center of the circle to the point on the curve."),React.createElement("li",null,"If this error is too high, we consider the arc bad, and try a smaller interval.")))),React.createElement("p",null,"The result of this is shown in the next graphic: we start at a guaranteed failure: s=0, e=1. That's the entire curve. The midpoint is simply at ",React.createElement("em",null,"t=0.5"),", and then we start performing a ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Binary_search_algorithm"},"Binary Search"),"."),React.createElement("ol",null,React.createElement("li",null,"We start with ",(0,0.5,1)),React.createElement("li",null,"That'll fail, so we retry with the interval halved: ",(0,0.25,0.5),React.createElement("ul",null,React.createElement("li",null,"If that arc's good, we move back up by half distance: ",(0,0.375,0.75),"."),React.createElement("li",null,"However, if the arc was still bad, we move ",React.createElement("em",null,"down")," by half the distance: ",(0,0.125,0.25),"."))),React.createElement("li",null,"We keep doing this over and over until we have two arcs found in sequence of which the first arc is good, and the second arc is bad. When we find that pair, we've found the boundary between a good approximation and a bad approximation, and we pick the former.")),React.createElement("p",null,"The following graphic shows the result of this approach, with a default error threshold of 0.5, meaning that if an arc is off by a ",React.createElement("em",null,"combined")," half pixel over both verification points, then we treat the arc as bad. This is an extremely simple error policy, but already works really well. Note that the graphic is still interactive, and you can use your up and down arrow keys keys to increase or decrease the error threshold, to see what the effect of a smaller or larger error threshold is."),React.createElement(Graphic,{preset:"simple",title:"Arc approximation of a Bézier curve",setup:handler.setupCubic,draw:handler.drawSingleArc,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"With that in place, all that's left now is to \"restart\" the procedure by treating the found arc's end point as the new to-be-determined arc's starting point, and using points further down the curve. We keep trying this until the found end point is for ",React.createElement("em",null,"t=1"),", at which point we are done. Again, the following graphic allows for up and down arrow key input to increase or decrease the error threshold, so you can see how picking a different threshold changes the number of arcs that are necessary to reasonably approximate a curve:"),React.createElement(Graphic,{preset:"simple",title:"Arc approximation of a Bézier curve",setup:handler.setupCubic,draw:handler.drawArcs,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"So... what is this good for? Obviously, If you're working with technologies that can't do curves, but can do lines and circles, then the answer is pretty straight-forward, but what else? There are some reasons why you might need this technique: using circular arcs means you can determine whether a coordinate lies \"on\" your curve really easily: simply compute the distance to each circular arc center, and if any of those are close to the arc radii, at an angle betwee the arc start and end: bingo, this point can be treated as lying \"on the curve\". Another benefit is that this approximation is \"linear\": you can almost trivially travel along the arcs at fixed speed. You can also trivially compute the arc length of the approximated curve (it's a bit like curve flattening). The only thing to bear in mind is that this is a lossy equivalence: things that you compute based on the approximation are guaranteed \"off\" by some small value, and depending on how much precision you need, arc approximation is either going to be super useful, or completely useless. It's up to you to decide which, based on your application!"));}},"bsplines":{"locale":"en-GB","title":"B-Splines","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"bsplines",title:"B-Splines",number:"39"}),React.createElement("p",null,"No discussion on Bézier curves is complete without also giving mention of that other beast in the curve design space: B-Splines. Easily confused to mean Bézier splines, that's not actually what they are; they are \"basis function\" splines, which makes a lot of difference, which we'll be looking at in this section. We're not going to dive as deep into B-Splines as we have for Bézier curves (that would be an entire primer on its own) but we'll be looking at how B-Splines work, what kind of maths is involved in computing them, and how to draw them based on a number of parameters that you can pick for individual B-Splines."),React.createElement("p",null,"First off: B-Splines are ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Piecewise"},"piecewise polynomial interpolation curves"),", where the \"single curve\" is built by performing polynomial interpolation over a set of points, using a sliding window of a fixed number of points. For instance, a \"cubic\" B-Spline defined by twelve points will have its curve built by evaluating the polynomial interpolation of four points, and the curve can be treated as a lot of different sections, each controlled by four points at a time, such that the full curve consists of smoothly connected sections defined by points ",'{',"1,2,3,4",'}',", ",'{',"2,3,4,5",'}',", ..., ",'{',"8,9,10,11",'}',", and finally ",'{',"9,10,11,12",'}',", for eight sections."),React.createElement("p",null,"What do they look like? They look like this! .. okay that's an empty graph, but simply click to place some point, with the stipulation that you need at least four point to see any curve. More than four points simply draws a longer B-Spline curve:"),React.createElement(BSplineGraphic,{sketch:handler.basicSketch}),React.createElement("p",null,"The important part to notice here is that we are ",React.createElement("strong",null,"not")," doing the same thing with B-Splines that we do for poly-Béziers or Catmull-Rom curves: both of the latter simply define new sections as literally \"new sections based on new points\", so a 12 point cubic poly-Bézier curve is actually impossible, because we start with a four point curve, and then add three more points for each section that follows, so we can only have 4, 7, 10, 13, 16, etc point Poly-Béziers. Similarly, while Catmull-Rom curves can grow by adding single points, this addition of a single point introduces three implicit Bézier points. Cubic B-Splines, on the other hand, are smooth interpolations of ",React.createElement("em",null,"each possible curve involving four consecutive points"),", such that at any point along the curve except for our start and end points, our on-curve coordinate is defined by four control points."),React.createElement("p",null,"Consider the difference to be this:"),React.createElement("ul",null,React.createElement("li",null,"for Bézier curves, the curve is defined as an interpolation of points, but:"),React.createElement("li",null,"for B-Splines, the curve is defined as an interpolation of ",React.createElement("em",null,"curves"),".")),React.createElement("p",null,"In order to make this interpolation of curves work, the maths is necessarily more complex than the maths for Bézier curves, so let's have a look at how things work."),React.createElement("h2",{id:"how-to-compute-a-b-spline-curve-some-maths"},"How to compute a B-Spline curve: some maths"),React.createElement("p",null,"Given a B-Spline of degree ",React.createElement("code",null,"d")," and thus order ",React.createElement("code",null,"k=d+1")," (so a quadratic B-Spline is degree 2 and order 3, a cubic B-Spline is degree 3 and order 4, etc) and ",React.createElement("code",null,"n")," control points ",React.createElement("code",null,"P<sub>0</sub>")," through ",React.createElement("code",null,"P<sub>n-1</sub>"),", we can compute a point on the curve for some value ",React.createElement("code",null,"t")," in the interval [0,1] (where 0 is the start of the curve, and 1 the end, just like for Bézier curves), by evaluting the following function:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/329da80e737b0005f4dbe4c84ff868bde5dfaee0.svg",width:"177.79999999999998rem",height:"43.4rem"}),React.createElement("p",null,"Which, honestly, doesn't tell us all that much. All we can see is that a point on a B-Spline curve is defined as \"a mix of all the control points, weighted somehow\", where the weighting is achieved through the ",React.createElement("em",null,"N(...)")," function, subscipted with an obvious parameter ",React.createElement("code",null,"i"),", which comes from our summation, and some magical parameter ",React.createElement("code",null,"k"),". So we need to know two things: 1. what does N(t) do, and 2. what is that ",React.createElement("code",null,"k"),"? Let's cover both, in reverse order."),React.createElement("p",null,"The parameter ",React.createElement("code",null,"k")," represents the \"knot interval\" over which a section of curve is defined. As we learned earlier, a B-Spline curve is itself an interpoliation of curves, and we can treat each transition where a control point starts or tops influencing the total curvature as a \"knot on the curve\". Doing so for a degree ",React.createElement("code",null,"d")," B-Spline with ",React.createElement("code",null,"n")," control point gives us ",React.createElement("code",null,"d + n + 1")," knots, defining ",React.createElement("code",null,"d + n")," intervals along the curve, and it is these intervals that the above ",React.createElement("code",null,"k")," subscript to the N() function applies to."),React.createElement("p",null,"Then the N() function itself. What does it look like?"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c10575fb591062784484357356796a4c0be4f83e.svg",width:"588rem",height:"44.8rem"}),React.createElement("p",null,"So this is where we see the interpolation: N(t) for an (i,k) pair (that is, for a step in the above summation, on a specific knot interval) is a mix between N(t) for (i,k-1) and N(t) for (i+1,k-1), so we see that this is a recursive iteration where ",React.createElement("code",null,"i")," goes up, and ",React.createElement("code",null,"k")," goes down, so it seem reasonable to expect that this recursion has to stop at some point; obviously, it does, and specifically it does so for the following ",React.createElement("code",null,"i"),"/",React.createElement("code",null,"k")," values:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/6664a4fc5832059bbc68eaa8068a4b2577e1d96a.svg",width:"251.99999999999997rem",height:"42rem"}),React.createElement("p",null,"And this function finally has a straight up evaluation: if a ",React.createElement("code",null,"t")," value lies within a knot-specific interval once we reach a ",React.createElement("code",null,"k=1")," value, it \"counts\", otherwise it doesn't. We did cheat a little, though, because for all these values we need to scale our ",React.createElement("code",null,"t")," value first, so that it lies in the interval bounded by ",React.createElement("code",null,"knots[d]")," and ",React.createElement("code",null,"knots[n]"),", which are the start point and end point where curvature is controlled by exactly ",React.createElement("code",null,"order")," control points. For instance, for degree 3 (=order 4) and 7 control points, with knot vector [1,2,3,4,5,6,7,8,9,10,11], we map ",React.createElement("code",null,"t")," from [the interval 0,1] to the interval [4,8], and then use that value in the functions above, instead."),React.createElement("h2",{id:"can-we-simplify-that-"},"Can we simplify that?"),React.createElement("p",null,"We can, yes."),React.createElement("p",null,"People far smarter than us have looked at this work, and two in particular — ",React.createElement("a",{href:"http://www.npl.co.uk/people/maurice-cox"},"Maurice Cox")," and ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Carl_R._de_Boor"},"Carl de Boor")," — came to a mathematically pleasing solution: to compute a point P(t), we can compute this point by evaluating ",React.createElement("em",null,"d(t)")," on a curve section between knots ",React.createElement("em",null,"i")," and ",React.createElement("em",null,"i+1"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3780a420cd9b1bc59bec2c49bbd29f5e58497a3c.svg",width:"295.4rem",height:"22.4rem"}),React.createElement("p",null,"This is another recursive function, with ",React.createElement("em",null,"k")," values decreasing from the curve order to 1, and the value ",React.createElement("em",null,"α")," (alpha) defined by:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ba3b25cd54993b4601d8f415bc4cde73af4fc460.svg",width:"267.4rem",height:"40.599999999999994rem"}),React.createElement("p",null,"That looks complicated, but it's not. Computing alpha is just a fraction involving known, plain numbers and once we have our alpha value, computing (1-alpha) is literally just \"computing one minus alpha\". Computing this d() function is thus simply a matter of \"computing simple arithmetics but with recursion\", which might be computationally expensive because we're doing \"a lot of\" steps, but is also computationally cheap because each step only involves very simple maths. Of course as before the recursion has to stop:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1405067abebab73574934e3e69d7a7158106c744.svg",width:"387.79999999999995rem",height:"42rem"}),React.createElement("p",null,"So, we see two stopping conditions: either ",React.createElement("code",null,"i")," becomes 0, in which case d() is zero, or ",React.createElement("code",null,"k")," becomes zero, in which case we get the same \"either 1 or 0\" that we saw in the N() function above."),React.createElement("p",null,"Thanks to Cox and de Boor, we can compute points on a B-Spline pretty easily: we just need to compute a triangle of interconnected values. For instance, d() for i=3, k=3 yields the following triangle:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/a0a1069b001c75a1fab7f40ffa8bc403e1408f0d.svg",width:"438.2rem",height:"242.2rem"}),React.createElement("p",null,"That is, we compute d(3,3) as a mixture of d(2,3) and d(2,2): d(3,3) = a(3,3) x d(2,3) + (1-a(3,3)) x d(2,2)... and we simply keep expanding our triangle until we reach the terminating function parameters. Done deal!"),React.createElement("p",null,"One thing we need to keep in mind is that we're working with a spline that is contrained by its control points, so even though the ",React.createElement("code",null,"d(..., k)")," values are zero or one at the lowest level, they are really \"zero or one, times their respective control point\", so in the next section you'll see the algorithm for running through the computation in a way that starts with a copy of the control point vector and then works its way up to that single point: that's pretty essential!"),React.createElement("p",null,"If we run this computation \"down\", starting at d(3,3), then without special code in place we would be computing quite a few terms multiple times at each step. On the other hand, we can also start with that last \"column\", we can generate the terminating d() values first, then compute the a() constants, perform our multiplcations, generate the previous step's d() values, compute their a() constants, do the multiplications, etc. until we end up all the way back at the top. If we run our computation this way, we don't need any explicit caching, we can just \"recycle\" the list of numbers we start with and simply update them as we move up the triangle. So, let's implement that!"),React.createElement("h2",{id:"cool-cool-but-i-don-t-know-what-to-do-with-that-information"},"Cool, cool... but I don't know what to do with that information"),React.createElement("p",null,"I know, this is pretty mathy, so let's have a look at what happens when we change parameters here. We can't change the maths for the interpolation functions, so that gives us only one way to control what happens here: the knot vector itself. As such, let's look at the graph that shows the interpolation functions for a cubic B-Spline with seven points with a uniform knot vector (so we see seven identical functions), representing how much each point (represented by one function each) influences the total curvature, given our knot values. And, because exploration is the key to discovery, let's make the knot vector a thing we can actually manipulate. Normally a proper knot vector has a constraint that any value is strictly equal to, or larger than the previous ones, but screw it this is programming, let's ignore that hard restriction and just mess with the knots however we like."),React.createElement("div",{className:"two-column"},React.createElement(KnotController,{ref:"interpolation-graph"}),React.createElement(BSplineGraphic,{sketch:handler.interpolationGraph,controller:function controller(owner,knots){return handler.bindKnots(owner,knots,"interpolation-graph");}})),React.createElement("p",null,"Changing the values in the knot vector changes how much each point influences the total curvature (with some clever knot value manipulation, we can even make the influence of certain points disappear entirely!), so we can see that while the control points define the hull inside of which we're going to be drawing a curve, it is actually the knot vector that determines the actual ",React.createElement("em",null,"shape")," of the curve inside that hull."),React.createElement("p",null,"After reading the rest of this section you may want to come back here to try some specific knot vectors, and see if the resulting interpolation landscape makes sense given what you will now think should happen!"),React.createElement("h2",{id:"running-the-computation"},"Running the computation"),React.createElement("p",null,"Unlike the de Casteljau algorithm, where the ",React.createElement("code",null,"t")," value stays the same at every iteration, for B-Splines that is not the case, and so we end having to (for each point we evaluate) run a fairly involving bit of recursive computation. The algorithm is discussed on ",React.createElement("a",{href:"http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/de-Boor.html"},"this Michigan Tech")," page, but an easier to read version is implemented by ",React.createElement("a",{href:"https://github.com/thibauts/b-spline/blob/master/index.js#L59-L71"},"b-spline.js"),", so we'll look at its code."),React.createElement("p",null,"Given an input value ",React.createElement("code",null,"t"),", we first map the input to a value from the domain [0,1] to the domain [knots[degree], knots[knots.length - 1 - degree]. Then, we find the section number ",React.createElement("code",null,"s")," that this mapped ",React.createElement("code",null,"t")," value lies on:"),React.createElement("pre",null,"for(s=domain[0]; s < domain[1]; s++) {\n if(knots[s] <= t && t <= knots[s+1]) break;\n}\n"),React.createElement("p",null,"after running this code, ",React.createElement("code",null,"s")," is the index for the section the point will lie on. We then run the algorithm mentioned on the MU page (updated to use this description's variable names):"),React.createElement("pre",null,"let v = copy of control points\n\nfor(let L = 1; L <= order; L++) {\n for(let i=s; i > s + L - order; i--) {\n let numerator = t - knots[i]\n let denominator = knots[i - L + order] - knots[i]\n let alpha = numerator / denominator\n let v[i] = alpha * v[i] + (1-alpha) * v[i-1]\n }\n}\n"),React.createElement("p",null,"(A nice bit of behaviour in this code is that we work the interpolation \"backwards\", starting at ",React.createElement("code",null,"i=s")," at each level of the interpolation, and we stop when ",React.createElement("code",null,"i = s - order + level"),", so we always end up with a value for ",React.createElement("code",null,"i")," such that those ",React.createElement("code",null,"v[i-1]")," don't try to use an array index that doesn't exist)"),React.createElement("h2",{id:"open-vs-closed-paths"},"Open vs. closed paths"),React.createElement("p",null,"Much like poly-Béziers, B-Splines can be either open, running from the first point to the last point, or closed, where the first and last point are ",React.createElement("em",null,"the same point"),". However, because B-Splines are an interpolation of curves, not just point, we can't simply make the first and last point the same, we need to link a few point point: for an order ",React.createElement("code",null,"d")," B-Spline, we need to make the last ",React.createElement("code",null,"d")," point the same as the first ",React.createElement("code",null,"d")," points. And the easiest way to do this is to simply append ",React.createElement("code",null,"points.splice(0,d)")," to ",React.createElement("code",null,"points"),". Done!"),React.createElement("p",null,"Of course if we want to manipulate these kind of curves we need to make sure to mark them as \"closed\" so that we know the coordinate for ",React.createElement("code",null,"points[0]")," and ",React.createElement("code",null,"points[n-k]")," etc. are the same coordinate, and manipulating one will equally manipulate the other, but programming generally makes this really easy by storing references to coordinates (or other linked values such as coordinate weights, discussed in the NURBS section) rather than separate coordinate objects."),React.createElement("h2",{id:"manipulating-the-curve-through-the-knot-vector"},"Manipulating the curve through the knot vector"),React.createElement("p",null,"The most important thing to understand when it comes to B-Splines is that they work ",React.createElement("em",null,"because")," of the concept of a knot vector. As mentioned above, knots represent \"where individual control points start/stop influencing the curve\", but we never looked at the ",React.createElement("em",null,"values")," that go in the knot vector. If you look back at the N() and a() functions, you see that interpolations are based on intervals in the knot vector, rather than the actual values in the knot vector, and we can exploit this to do some pretty interesting things with clever manipulation of the knot vector. Specifically there are four things we can do that are worth looking at:"),React.createElement("ol",null,React.createElement("li",null,"we can use a uniform knot vector, with equally spaced intervals,"),React.createElement("li",null,"we can use a non-uniform knot vector, without enforcing equally spaced internvals,"),React.createElement("li",null,"we can collapse sequential knots to the same value, locally lowering curve complexity using \"null\" intervals, and"),React.createElement("li",null,"we can form a special case non-uniform vector, by combining (1) and (3) to for a vector with collapsed start and end knots, with a uniform vector in between.")),React.createElement("h3",{id:"uniform-b-splines"},"Uniform B-Splines"),React.createElement("p",null,"The most straightforward type of B-Spline is the uniform spline. In a uniform spline, the knots are distributed uniformly over the entire curve interval. For instance, if we have a knot vector of length twelve, then a uniform knot vector would be [0,1,2,3,...,9,10,11]. Or [4,5,6,...,13,14,15], which defines ",React.createElement("em",null,"the same intervals"),", or even [0,2,3,...,18,20,22], which also defines ",React.createElement("em",null,"the same intervals"),", just scaled by a constant factor, which becomes normalised during interpolation and so does not contribute to the curvature."),React.createElement("div",{className:"two-column"},React.createElement(KnotController,{ref:"uniform-spline"}),React.createElement(BSplineGraphic,{sketch:handler.uniformBSpline,controller:function controller(owner,knots){return handler.bindKnots(owner,knots,"uniform-spline");}})),React.createElement("p",null,"This is an important point: the intervals that the knot vector defines are ",React.createElement("em",null,"relative")," intervals, so it doesn't matter if every interval is size 1, or size 100 - the relative differences between the intervals is what shapes any particular curve."),React.createElement("p",null,"The problem with uniform knot vectors is that, as we need ",React.createElement("code",null,"order")," control points before we have any curve with which we can perform interpolation, the curve does not \"start\" at the first point, nor \"ends\" at the last point. Instead there are \"gaps\". We can get rid of these, by being clever about how we apply the following uniformity-breaking approach instead..."),React.createElement("h3",{id:"reducing-local-curve-complexity-by-collapsing-intervals"},"Reducing local curve complexity by collapsing intervals"),React.createElement("p",null,"By collapsing knot intervals by making two or more consecutive knots have the same value, we can reduce the curve complexity in the sections that are affected by the knots involved. This can have drastic effects: for ever interval collapse, the curve order goes down, and curve continuity goes down, to the point where collapsing ",React.createElement("code",null,"order")," knots creates a situation where all continuity is lost and the curve \"kinks\"."),React.createElement("div",{className:"two-column"},React.createElement(KnotController,{ref:"center-cut-bspline"}),React.createElement(BSplineGraphic,{sketch:handler.centerCutBSpline,controller:function controller(owner,knots){return handler.bindKnots(owner,knots,"center-cut-bspline");}})),React.createElement("h3",{id:"open-uniform-b-splines"},"Open-Uniform B-Splines"),React.createElement("p",null,"By combining knot interval collapsing at the start and end of the curve, with uniform knots in between, we can overcome the problem of the curve not starting and ending where we'd kind of like it to:"),React.createElement("p",null,"For any curve of degree ",React.createElement("code",null,"D")," with control points ",React.createElement("code",null,"N"),", we can define a knot vector of length ",React.createElement("code",null,"N+D+1")," in which the values ",React.createElement("code",null,"0 ... D+1")," are the same, the values ",React.createElement("code",null,"D+1 ... N+1")," follow the \"uniform\" pattern, and the values ",React.createElement("code",null,"N+1 ... N+D+1")," are the same again. For example, a cubic B-Spline with 7 control points can have a knot vector [0,0,0,0,1,2,3,4,4,4,4], or it might have the \"identical\" knot vector [0,0,0,0,2,4,6,8,8,8,8], etc. Again, it is the relative differences that determine the curve shape."),React.createElement("div",{className:"two-column"},React.createElement(KnotController,{ref:"open-uniform-bspline"}),React.createElement(BSplineGraphic,{sketch:handler.openUniformBSpline,controller:function controller(owner,knots){return handler.bindKnots(owner,knots,"open-uniform-bspline");}})),React.createElement("h3",{id:"non-uniform-b-splines"},"Non-uniform B-Splines"),React.createElement("p",null,"This is essentialy the \"free form\" version of a B-Spline, and also the least interesting to look at, as without any specific reason to pick specific knot intervals, there is nothing particularly interesting going on. There is one constraint to the knot vector, and that is that any value ",React.createElement("code",null,"knots[k+1]")," should be equal to, or greater than ",React.createElement("code",null,"knots[k]"),"."),React.createElement("h2",{id:"one-last-thing-rational-b-splines"},"One last thing: Rational B-Splines"),React.createElement("p",null,"While it is true that this section on B-Splines is running quite long already, there is one more thing we need to talk about, and that's \"Rational\" splines, where the rationality applies to the \"ratio\", or relative weights, of the control points themselves. By introducing a ratio vector with weights to apply to each control point, we greatly increase our influence over the final curve shape: the more weight a control point carries, the close to that point the spline curve will lie, a bit like turning up the gravity of a control point."),React.createElement("div",{className:"two-column"},React.createElement(WeightController,{ref:"rational-uniform-bspline-weights"}),React.createElement(BSplineGraphic,{scrolling:true,sketch:handler.rationalUniformBSpline,controller:function controller(owner,knots,weights,closed){// handler.bindKnots(owner, knots, "rational-uniform-bspline"); -handler.bindWeights(owner,weights,closed,"rational-uniform-bspline-weights");}})),React.createElement("p",null,"Of course this brings us to the final topic that any text on B-Splines must touch on before calling it a day: the NURBS, or Non-Uniform Rational B-Spline (NURBS is not a plural, the capital S actually just stands for \"spline\", but a lot of people mistakenly treat it as if it is, so now you know better). NURBS are an important type of curve in computer-facilitated design, used a lot in 3D modelling (as NURBS surfaces) as well as in arbitrary-precision 2D design due to the level of control a NURBS curve offers designers."),React.createElement("p",null,"While a true non-uniform rational B-Spline would be hard to work with, when we talk about NURBS we typically mean the Open-Uniform Rational B-Spline, or OURBS, but that doesn't roll off the tongue nearly as nicely, and so remember that when people talk about NURBS, they typically mean open-uniform, which has the useful property of starting the curve at the first control point, and ending it at the last."),React.createElement("h2",{id:"extending-our-implementation-to-cover-rational-splines"},"Extending our implementation to cover rational splines"),React.createElement("p",null,"The algorithm for working with Rational B-Splines is virtually identical to the regular algorithm, and the extension to work in the control point weights is fairly simple: we extend each control point from a point in its original number of dimensions (2D, 3D, etc) to one dimension higher, scaling the original dimensions by the control point's weight, and then assigning that weight as its value for the extended dimension."),React.createElement("p",null,"For example, a 2D point ",React.createElement("code",null,"(x,y)")," with weight ",React.createElement("code",null,"w")," becomes a 3D point ",React.createElement("code",null,"(w * x, w * y, w)"),"."),React.createElement("p",null,"We then run the same algorithm as before, which will automatically perform weight interpolation in addition to regular coordinate interpolation, because all we've done is pretended we have coordinates in a higher dimension. The algorithm doesn't really care about how many dimensions it needs to interpolate."),React.createElement("p",null,"In order to recover our \"real\" curve point, we take the final result of the point generation algorithm, and \"unweigh\" it: we take the final point's derived weight ",React.createElement("code",null,"w'")," and divide all the regular coordinate dimensions by it, then throw away the weight information."),React.createElement("p",null,"Based on our previous example, we take the final 3D point ",React.createElement("code",null,"(x', y', w')"),", which we then turn back into a 2D point by computing ",React.createElement("code",null,"(x'/w', y'/w')"),". And that's it, we're done!"));}},"comments":{"locale":"en-GB","title":"Comments and questions","getContent":function getContent(handler){return React.createElement("section",null,React.createElement("script",null,"/* ----------------------------------------------------------------------------- * * * PLEASE DO NOT LOCALISE THIS FILE * * I can't respond to questions that aren't asked in English, so this is one of * the few cases where there is a content.en-GB.md but you shouldn't change it. * * ----------------------------------------------------------------------------- */"),React.createElement("style",null,"#comments ",'{',"width: calc(960px + 2em), marginTop: 0, borderTop: 1px solid rgba(255, 0, 0, 0.5), paddingTop: 3em",'}'),React.createElement(SectionHeader,{name:"comments",title:"Comments and questions",number:"40"}),React.createElement("p",null,"If you enjoyed this book, or you simply found it useful for something you were trying to get done, and you were wondering how to let me know you appreciated this book, you can always ",React.createElement("a",{href:"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QPRDLNGDANJSW"},"buy me a coffee"),", however much a coffee is where you live. This work has grown over the years, from a small primer to a 70ish print-page-equivalent reader on the subject of Bézier curves, and a lot of coffee went into the making of it. I don't regret a minute I spent on writing it, but I can always do with some more coffee to keep on writing!"),React.createElement("div",{id:"disqus_thread"}),React.createElement("script",{src:"lib/site/disqus.js",async:true}));}},"locale-switcher":{"locale":"en-GB","title":"locale-switcher","getContent":function getContent(handler){return React.createElement("section",null,React.createElement("p",null,"Read this in your own language:"),React.createElement("ul",null,React.createElement("li",null,React.createElement("a",{href:"./en-GB"},"English")),React.createElement("li",null,React.createElement("a",{href:"./ja-JP"},"日本語")),React.createElement("li",null,React.createElement("a",{href:"./zh-CN"},"中文"))),React.createElement("p",null,"Don't see your language listed? ",React.createElement("a",{href:"https://github.com/Pomax/BezierInfo-2/wiki/localize"},"Help translate this content!")));}}}; - -/***/ }), -/* 208 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(70); - - -/***/ }), -/* 209 */ -/***/ (function(module, exports, __webpack_require__) { - -(function() { - "use strict"; - - var utils = __webpack_require__(71); - - /** - * Poly Bezier - * @param {[type]} curves [description] - */ - var PolyBezier = function(curves) { - this.curves = []; - this._3d = false; - if(!!curves) { - this.curves = curves; - this._3d = this.curves[0]._3d; - } - } - - PolyBezier.prototype = { - valueOf: function() { - return this.toString(); - }, - toString: function() { - return utils.pointsToString(this.points); - }, - addCurve: function(curve) { - this.curves.push(curve); - this._3d = this._3d || curve._3d; - }, - length: function() { - return this.curves.map(function(v) { return v.length(); }).reduce(function(a,b) { return a+b; }); - }, - curve: function(idx) { - return this.curves[idx]; - }, - bbox: function() { - var c = this.curves; - var bbox = c[0].bbox(); - for(var i=1; i<c.length; i++) { - utils.expandbox(bbox, c[i].bbox()); - } - return bbox; - }, - offset: function(d) { - var offset = []; - this.curves.forEach(function(v) { - offset = offset.concat(v.offset(d)); - }); - return new PolyBezier(offset); - } - }; - - module.exports = PolyBezier; -}()); - - -/***/ }), -/* 210 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(module) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; -/** +function r(e,t){if(!a.canUseDOM||t&&!("addEventListener"in document))return!1;var n="on"+e,r=n in document;if(!r){var o=document.createElement("div");o.setAttribute(n,"return;"),r="function"==typeof o[n]}return!r&&i&&"wheel"===e&&(r=document.implementation.hasFeature("Events.wheel","3.0")),r}var i,a=n(7);a.canUseDOM&&(i=document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0),e.exports=r},function(e,t,n){"use strict";function r(e,t){var n=null===e||e===!1,r=null===t||t===!1;if(n||r)return n===r;var i=typeof e,a=typeof t;return"string"===i||"number"===i?"string"===a||"number"===a:"object"===a&&e.type===t.type&&e.key===t.key}e.exports=r},function(e,t,n){"use strict";var r=(n(5),n(9)),i=(n(2),r);e.exports=i},function(e,t,n){"use strict";function r(e,t,n){function r(){o=!0,n.apply(this,arguments)}function i(){o||(a<e?t.call(this,a++,i,r):r.apply(this,arguments))}var a=0,o=!1;i()}function i(e,t,n){function r(e,t,r){o||(t?(o=!0,n(t)):(a[e]=r,o=++s===i,o&&n(null,a)))}var i=e.length,a=[];if(0===i)return n(null,a);var o=!1,s=0;e.forEach(function(e,n){t(e,n,function(e,t){r(n,e,t)})})}t.__esModule=!0,t.loopAsync=r,t.mapAsync=i},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e){for(var t in e)if(e.hasOwnProperty(t))return!0;return!1}function o(e){return function(){function t(e,t){var n=!(arguments.length<=2||void 0===arguments[2])&&arguments[2];return g.default(e,t,n,k.location,k.routes,k.params)}function n(e){var t=e.pathname,n=e.query,r=e.state;return C.createLocation(C.createPath(t,n),r,c.REPLACE)}function r(e,t){S&&S.location===e?o(S,t):b.default(x,e,function(n,r){n?t(n):r?o(s({},r,{location:e}),t):t()})}function o(e,t){var r=f.default(k,e),i=r.leaveRoutes,a=r.enterRoutes;p.runLeaveHooks(i),p.runEnterHooks(a,e,function(r,i){r?t(r):i?t(null,n(i)):w.default(e,function(n,r){n?t(n):t(null,null,k=s({},e,{components:r}))})})}function l(e){return e.__id__||(e.__id__=P++)}function u(e){return e.reduce(function(e,t){return e.push.apply(e,T[l(t)]),e},[])}function d(e,t){b.default(x,e,function(n,r){if(null==r)return void t();S=s({},r,{location:e});for(var i=u(f.default(k,S).leaveRoutes),a=void 0,o=0,l=i.length;null==a&&o<l;++o)a=i[o](e);t(a)})}function m(){if(k.routes){for(var e=u(k.routes),t=void 0,n=0,r=e.length;"string"!=typeof t&&n<r;++n)t=e[n]();return t}}function v(e,t){var n=l(e),r=T[n];if(null==r){var i=!a(T);r=T[n]=[t],i&&(M=C.listenBefore(d),C.listenBeforeUnload&&(N=C.listenBeforeUnload(m)))}else r.indexOf(t)===-1&&r.push(t);return function(){var e=T[n];if(null!=e){var r=e.filter(function(e){return e!==t});0===r.length?(delete T[n],a(T)||(M&&(M(),M=null),N&&(N(),N=null))):T[n]=r}}}function y(e){return C.listen(function(t){k.location===t?e(null,k):r(t,function(t,n,r){t?e(t):n?C.transitionTo(n):r&&e(null,r)})})}var _=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],x=_.routes,E=i(_,["routes"]),C=h.default(e)(E),k={},S=void 0,P=1,T={},M=void 0,N=void 0;return s({},C,{isActive:t,match:r,listenBeforeLeavingRoute:v,listen:y})}}t.__esModule=!0;var s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l=n(8),c=(r(l),n(27)),u=n(230),h=r(u),d=n(306),f=r(d),p=n(305),m=n(309),g=r(m),v=n(307),w=r(v),y=n(311),b=r(y);t.default=o,e.exports=t.default},function(e,t,n){"use strict";function r(e,t,n){this.props=e,this.context=t,this.refs=o,this.updater=n||a}var i=n(25),a=n(62),o=(n(101),n(26));n(1),n(2);r.prototype.isReactComponent={},r.prototype.setState=function(e,t){"object"!=typeof e&&"function"!=typeof e&&null!=e?i("85"):void 0,this.updater.enqueueSetState(this,e),t&&this.updater.enqueueCallback(this,t,"setState")},r.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this),e&&this.updater.enqueueCallback(this,e,"forceUpdate")};e.exports=r},function(e,t,n){"use strict";function r(e,t){}var i=(n(2),{isMounted:function(e){return!1},enqueueCallback:function(e,t){},enqueueForceUpdate:function(e){r(e,"forceUpdate")},enqueueReplaceState:function(e,t){r(e,"replaceState")},enqueueSetState:function(e,t){r(e,"setState")}});e.exports=i},function(e,t,n){var r=n(204),i=function(){this.data={},this.data=r};i.prototype={getSectionLocale:function(e){return this.data[e].locale},getContent:function(e,t){return this.data[e].getContent(t)},getTitle:function(e){return this.data[e].title}},e.exports=i},function(e,t,n){"use strict";var r=n(4),i=r.createClass({displayName:"SectionHeader",statics:{locale:""},render:function(){var e=i.locale;"undefined"!=typeof window&&window.location.toString().indexOf(e)===-1&&(e="");var t=(e?"./"+e+"/":".")+"#"+this.props.name;return r.createElement("h2",{id:this.props.name,"data-num":this.props.number},r.createElement("a",{href:t},this.props.title))},componentDidMount:function(){if("undefined"!=typeof window&&window.location){var e=window.location.hash;e&&(window.location=window.location.hash)}}});e.exports=i},function(e,t,n){!function(){"use strict";function t(e,t,n,r,i){"undefined"==typeof i&&(i=.5);var a=u.projectionratio(i,e),o=1-a,s={x:a*t.x+o*r.x,y:a*t.y+o*r.y},l=u.abcratio(i,e),c={x:n.x+(n.x-s.x)/l,y:n.y+(n.y-s.y)/l};return{A:c,B:n,C:s}}var r=Math.abs,i=Math.min,a=Math.max,o=Math.acos,s=Math.sqrt,l=Math.PI,c={x:0,y:0,z:0},u=n(66),h=n(206),d=function(e){var t=e&&e.forEach?e:[].slice.call(arguments),n=!1;if("object"==typeof t[0]){n=t.length;var i=[];t.forEach(function(e){["x","y","z"].forEach(function(t){"undefined"!=typeof e[t]&&i.push(e[t])})}),t=i}var a=!1,o=t.length;if(n){if(n>4){if(1!==arguments.length)throw new Error("Only new Bezier(point[]) is accepted for 4th and higher order curves");a=!0}}else if(6!==o&&8!==o&&9!==o&&12!==o&&1!==arguments.length)throw new Error("Only new Bezier(point[]) is accepted for 4th and higher order curves");var s=!a&&(9===o||12===o)||e&&e[0]&&"undefined"!=typeof e[0].z;this._3d=s;for(var l=[],c=0,h=s?3:2;c<o;c+=h){var d={x:t[c],y:t[c+1]};s&&(d.z=t[c+2]),l.push(d)}this.order=l.length-1,this.points=l;var f=["x","y"];s&&f.push("z"),this.dims=f,this.dimlen=f.length,function(e){for(var t=e.order,n=e.points,i=u.align(n,{p1:n[0],p2:n[t]}),a=0;a<i.length;a++)if(r(i[a].y)>1e-4)return void(e._linear=!1);e._linear=!0}(this),this._t1=0,this._t2=1,this.update()};d.fromSVG=function(e){var t=e.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/g).map(parseFloat),n=/[cq]/.test(e);return n?(t=t.map(function(e,n){return n<2?e:e+t[n%2]}),new d(t)):new d(t)},d.quadraticFromPoints=function(e,n,r,i){if("undefined"==typeof i&&(i=.5),0===i)return new d(n,n,r);if(1===i)return new d(e,n,n);var a=t(2,e,n,r,i);return new d(e,a.A,r)},d.cubicFromPoints=function(e,n,r,i,a){"undefined"==typeof i&&(i=.5);var o=t(3,e,n,r,i);"undefined"==typeof a&&(a=u.dist(n,o.C));var s=a*(1-i)/i,l=u.dist(e,r),c=(r.x-e.x)/l,h=(r.y-e.y)/l,f=a*c,p=a*h,m=s*c,g=s*h,v={x:n.x-f,y:n.y-p},w={x:n.x+m,y:n.y+g},y=o.A,b={x:y.x+(v.x-y.x)/(1-i),y:y.y+(v.y-y.y)/(1-i)},_={x:y.x+(w.x-y.x)/i,y:y.y+(w.y-y.y)/i},x={x:e.x+(b.x-e.x)/i,y:e.y+(b.y-e.y)/i},E={x:r.x+(_.x-r.x)/(1-i),y:r.y+(_.y-r.y)/(1-i)};return new d(e,x,E,r)};var f=function(){return u};d.getUtils=f,d.prototype={getUtils:f,valueOf:function(){return this.toString()},toString:function(){return u.pointsToString(this.points)},toSVG:function(e){if(this._3d)return!1;for(var t=this.points,n=t[0].x,r=t[0].y,i=["M",n,r,2===this.order?"Q":"C"],a=1,o=t.length;a<o;a++)i.push(t[a].x),i.push(t[a].y);return i.join(" ")},update:function(){this.dpoints=[];for(var e=this.points,t=e.length,n=t-1;t>1;t--,n--){for(var r,i=[],a=0;a<n;a++)r={x:n*(e[a+1].x-e[a].x),y:n*(e[a+1].y-e[a].y)},this._3d&&(r.z=n*(e[a+1].z-e[a].z)),i.push(r);this.dpoints.push(i),e=i}this.computedirection()},computedirection:function(){var e=this.points,t=u.angle(e[0],e[this.order],e[1]);this.clockwise=t>0},length:function(){return u.length(this.derivative.bind(this))},_lut:[],getLUT:function(e){if(e=e||100,this._lut.length===e)return this._lut;this._lut=[];for(var t=0;t<=e;t++)this._lut.push(this.compute(t/e));return this._lut},on:function(e,t){t=t||5;for(var n,r=this.getLUT(),i=[],a=0,o=0;o<r.length;o++)n=r[o],u.dist(n,e)<t&&(i.push(n),a+=o/r.length);return!!i.length&&(a/=i.length)},project:function(e){var t=this.getLUT(),n=t.length-1,r=u.closest(t,e),i=r.mdist,a=r.mpos;if(0===a||a===n){var o=a/n,s=this.compute(o);return s.t=o,s.d=i,s}var l,o,c,h,d=(a-1)/n,f=(a+1)/n,p=.1/n;for(i+=1,o=d,l=o;o<f+p;o+=p)c=this.compute(o),h=u.dist(e,c),h<i&&(i=h,l=o);return c=this.compute(l),c.t=l,c.d=i,c},get:function(e){return this.compute(e)},point:function(e){return this.points[e]},compute:function(e){if(0===e)return this.points[0];if(1===e)return this.points[this.order];var t=this.points,n=1-e;if(1===this.order)return u={x:n*t[0].x+e*t[1].x,y:n*t[0].y+e*t[1].y},this._3d&&(u.z=n*t[0].z+e*t[1].z),u;if(this.order<4){var r,i,a,o=n*n,s=e*e,l=0;2===this.order?(t=[t[0],t[1],t[2],c],r=o,i=n*e*2,a=s):3===this.order&&(r=o*n,i=o*e*3,a=n*s*3,l=e*s);var u={x:r*t[0].x+i*t[1].x+a*t[2].x+l*t[3].x,y:r*t[0].y+i*t[1].y+a*t[2].y+l*t[3].y};return this._3d&&(u.z=r*t[0].z+i*t[1].z+a*t[2].z+l*t[3].z),u}for(var h=JSON.parse(JSON.stringify(this.points));h.length>1;){for(var d=0;d<h.length-1;d++)h[d]={x:h[d].x+(h[d+1].x-h[d].x)*e,y:h[d].y+(h[d+1].y-h[d].y)*e},"undefined"!=typeof h[d].z&&(h[d]=h[d].z+(h[d+1].z-h[d].z)*e);h.splice(h.length-1,1)}return h[0]},raise:function(){for(var e,t,n,r=this.points,i=[r[0]],a=r.length,e=1;e<a;e++)t=r[e],n=r[e-1],i[e]={x:(a-e)/a*t.x+e/a*n.x,y:(a-e)/a*t.y+e/a*n.y};return i[a]=r[a-1],new d(i)},derivative:function(e){var t,n,r=1-e,i=0,a=this.dpoints[0];2===this.order&&(a=[a[0],a[1],c],t=r,n=e),3===this.order&&(t=r*r,n=r*e*2,i=e*e);var o={x:t*a[0].x+n*a[1].x+i*a[2].x,y:t*a[0].y+n*a[1].y+i*a[2].y};return this._3d&&(o.z=t*a[0].z+n*a[1].z+i*a[2].z),o},inflections:function(){return u.inflections(this.points)},normal:function(e){return this._3d?this.__normal3(e):this.__normal2(e)},__normal2:function(e){var t=this.derivative(e),n=s(t.x*t.x+t.y*t.y);return{x:-t.y/n,y:t.x/n}},__normal3:function(e){var t=this.derivative(e),n=this.derivative(e+.01),r=s(t.x*t.x+t.y*t.y+t.z*t.z),i=s(n.x*n.x+n.y*n.y+n.z*n.z);t.x/=r,t.y/=r,t.z/=r,n.x/=i,n.y/=i,n.z/=i;var a={x:n.y*t.z-n.z*t.y,y:n.z*t.x-n.x*t.z,z:n.x*t.y-n.y*t.x},o=s(a.x*a.x+a.y*a.y+a.z*a.z);a.x/=o,a.y/=o,a.z/=o;var l=[a.x*a.x,a.x*a.y-a.z,a.x*a.z+a.y,a.x*a.y+a.z,a.y*a.y,a.y*a.z-a.x,a.x*a.z-a.y,a.y*a.z+a.x,a.z*a.z],c={x:l[0]*t.x+l[1]*t.y+l[2]*t.z,y:l[3]*t.x+l[4]*t.y+l[5]*t.z,z:l[6]*t.x+l[7]*t.y+l[8]*t.z};return c},hull:function(e){var t,n=this.points,r=[],i=[],a=0,o=0,s=0;for(i[a++]=n[0],i[a++]=n[1],i[a++]=n[2],3===this.order&&(i[a++]=n[3]);n.length>1;){for(r=[],o=0,s=n.length-1;o<s;o++)t=u.lerp(e,n[o],n[o+1]),i[a++]=t,r.push(t);n=r}return i},split:function(e,t){if(0===e&&t)return this.split(t).left;if(1===t)return this.split(e).right;var n=this.hull(e),r={left:new d(2===this.order?[n[0],n[3],n[5]]:[n[0],n[4],n[7],n[9]]),right:new d(2===this.order?[n[5],n[4],n[2]]:[n[9],n[8],n[6],n[3]]),span:n};if(r.left._t1=u.map(0,0,1,this._t1,this._t2),r.left._t2=u.map(e,0,1,this._t1,this._t2),r.right._t1=u.map(e,0,1,this._t1,this._t2),r.right._t2=u.map(1,0,1,this._t1,this._t2),!t)return r;t=u.map(t,e,1,0,1);var i=r.right.split(t);return i.left},extrema:function(){var e,t,n=this.dims,r={},i=[];return n.forEach(function(n){t=function(e){return e[n]},e=this.dpoints[0].map(t),r[n]=u.droots(e),3===this.order&&(e=this.dpoints[1].map(t),r[n]=r[n].concat(u.droots(e))),r[n]=r[n].filter(function(e){return e>=0&&e<=1}),i=i.concat(r[n].sort())}.bind(this)),i=i.sort().filter(function(e,t){return i.indexOf(e)===t}),r.values=i,r},bbox:function(){var e=this.extrema(),t={};return this.dims.forEach(function(n){t[n]=u.getminmax(this,n,e[n])}.bind(this)),t},overlaps:function(e){var t=this.bbox(),n=e.bbox();return u.bboxoverlap(t,n)},offset:function(e,t){if("undefined"!=typeof t){var n=this.get(e),r=this.normal(e),i={c:n,n:r,x:n.x+r.x*t,y:n.y+r.y*t};return this._3d&&(i.z=n.z+r.z*t),i}if(this._linear){var a=this.normal(0),o=this.points.map(function(t){var n={x:t.x+e*a.x,y:t.y+e*a.y};return t.z&&r.z&&(n.z=t.z+e*a.z),n});return[new d(o)]}var s=this.reduce();return s.map(function(t){return t.scale(e)})},simple:function(){if(3===this.order){var e=u.angle(this.points[0],this.points[3],this.points[1]),t=u.angle(this.points[0],this.points[3],this.points[2]);if(e>0&&t<0||e<0&&t>0)return!1}var n=this.normal(0),i=this.normal(1),a=n.x*i.x+n.y*i.y;this._3d&&(a+=n.z*i.z);var s=r(o(a));return s<l/3},reduce:function(){var e,t,n=0,i=0,a=.01,o=[],s=[],l=this.extrema().values;for(l.indexOf(0)===-1&&(l=[0].concat(l)),l.indexOf(1)===-1&&l.push(1),n=l[0],e=1;e<l.length;e++)i=l[e],t=this.split(n,i),t._t1=n,t._t2=i,o.push(t),n=i;return o.forEach(function(e){for(n=0,i=0;i<=1;)for(i=n+a;i<=1+a;i+=a)if(t=e.split(n,i),!t.simple()){if(i-=a,r(n-i)<a)return[];t=e.split(n,i),t._t1=u.map(n,0,1,e._t1,e._t2),t._t2=u.map(i,0,1,e._t1,e._t2),s.push(t),n=i;break}n<1&&(t=e.split(n,1),t._t1=u.map(n,0,1,e._t1,e._t2),t._t2=e._t2,s.push(t))}),s},scale:function(e){var t=this.order,n=!1;if("function"==typeof e&&(n=e),n&&2===t)return this.raise().scale(n);var r=this.clockwise,i=n?n(0):e,a=n?n(1):e,o=[this.offset(0,10),this.offset(1,10)],l=u.lli4(o[0],o[0].c,o[1],o[1].c);if(!l)throw new Error("cannot scale this curve. Try reducing it first.");var c=this.points,h=[];return[0,1].forEach(function(e){var n=h[e*t]=u.copy(c[e*t]);n.x+=(e?a:i)*o[e].n.x,n.y+=(e?a:i)*o[e].n.y}.bind(this)),n?([0,1].forEach(function(i){if(2!==this.order||!i){var a=c[i+1],o={x:a.x-l.x,y:a.y-l.y},u=n?n((i+1)/t):e;n&&!r&&(u=-u);var d=s(o.x*o.x+o.y*o.y);o.x/=d,o.y/=d,h[i+1]={x:a.x+u*o.x,y:a.y+u*o.y}}}.bind(this)),new d(h)):([0,1].forEach(function(e){if(2!==this.order||!e){var n=h[e*t],r=this.derivative(e),i={x:n.x+r.x,y:n.y+r.y};h[e+1]=u.lli4(n,i,l,c[e+1])}}.bind(this)),new d(h))},outline:function(e,t,n,r){function i(e,t,n,r,i){return function(a){var o=r/n,s=(r+i)/n,l=t-e;return u.map(a,0,1,e+o*l,e+s*l)}}t="undefined"==typeof t?e:t;var a,o=this.reduce(),s=o.length,l=[],c=[],d=0,f=this.length(),p="undefined"!=typeof n&&"undefined"!=typeof r;o.forEach(function(a){x=a.length(),p?(l.push(a.scale(i(e,n,f,d,x))),c.push(a.scale(i(-t,-r,f,d,x)))):(l.push(a.scale(e)),c.push(a.scale(-t))),d+=x}),c=c.map(function(e){return a=e.points,a[3]?e.points=[a[3],a[2],a[1],a[0]]:e.points=[a[2],a[1],a[0]],e}).reverse();var m=l[0].points[0],g=l[s-1].points[l[s-1].points.length-1],v=c[s-1].points[c[s-1].points.length-1],w=c[0].points[0],y=u.makeline(v,m),b=u.makeline(g,w),_=[y].concat(l).concat([b]).concat(c),x=_.length;return new h(_)},outlineshapes:function(e,t,n){t=t||e;for(var r=this.outline(e,t).curves,i=[],a=1,o=r.length;a<o/2;a++){var s=u.makeshape(r[a],r[o-a],n);s.startcap.virtual=a>1,s.endcap.virtual=a<o/2-1,i.push(s)}return i},intersects:function(e,t){return e?e.p1&&e.p2?this.lineIntersects(e):(e instanceof d&&(e=e.reduce()),this.curveintersects(this.reduce(),e,t)):this.selfintersects(t)},lineIntersects:function(e){var t=i(e.p1.x,e.p2.x),n=i(e.p1.y,e.p2.y),r=a(e.p1.x,e.p2.x),o=a(e.p1.y,e.p2.y),s=this;return u.roots(this.points,e).filter(function(e){var i=s.get(e);return u.between(i.x,t,r)&&u.between(i.y,n,o)})},selfintersects:function(e){var t,n,r,i,a=this.reduce(),o=a.length-2,s=[];for(t=0;t<o;t++)r=a.slice(t,t+1),i=a.slice(t+2),n=this.curveintersects(r,i,e),s=s.concat(n);return s},curveintersects:function(e,t,n){var r=[];e.forEach(function(e){t.forEach(function(t){e.overlaps(t)&&r.push({left:e,right:t})})});var i=[];return r.forEach(function(e){var t=u.pairiteration(e.left,e.right,n);t.length>0&&(i=i.concat(t))}),i},arcs:function(e){e=e||.5;var t=[];return this._iterate(e,t)},_error:function(e,t,n,i){var a=(i-n)/4,o=this.get(n+a),s=this.get(i-a),l=u.dist(e,t),c=u.dist(e,o),h=u.dist(e,s);return r(c-l)+r(h-l)},_iterate:function(e,t){var n,r=0,i=1;do{n=0,i=1;var a,o,s,l,c,h=this.get(r),d=!1,f=!1,p=i,m=1,g=0;do{f=d,l=s,p=(r+i)/2,g++,a=this.get(p),o=this.get(i),s=u.getccenter(h,a,o),s.interval={start:r,end:i};var v=this._error(s,h,r,i);if(d=v<=e,c=f&&!d,c||(m=i),d){if(i>=1){m=1,l=s;break}i+=(i-r)/2}else i=p}while(!c&&n++<100);if(n>=100){console.error("arc abstraction somehow failed...");break}l=l?l:s,t.push(l),r=m}while(i<1);return t}},e.exports=d}()},function(e,t,n){!function(){"use strict";var t=Math.abs,r=Math.cos,i=Math.sin,a=Math.acos,o=Math.atan2,s=Math.sqrt,l=Math.pow,c=function(e){return e<0?-l(-e,1/3):l(e,1/3)},u=Math.PI,h=2*u,d=u/2,f=1e-6,p={Tvalues:[-.06405689286260563,.06405689286260563,-.1911188674736163,.1911188674736163,-.3150426796961634,.3150426796961634,-.4337935076260451,.4337935076260451,-.5454214713888396,.5454214713888396,-.6480936519369755,.6480936519369755,-.7401241915785544,.7401241915785544,-.820001985973903,.820001985973903,-.8864155270044011,.8864155270044011,-.9382745520027328,.9382745520027328,-.9747285559713095,.9747285559713095,-.9951872199970213,.9951872199970213],Cvalues:[.12793819534675216,.12793819534675216,.1258374563468283,.1258374563468283,.12167047292780339,.12167047292780339,.1155056680537256,.1155056680537256,.10744427011596563,.10744427011596563,.09761865210411388,.09761865210411388,.08619016153195327,.08619016153195327,.0733464814110803,.0733464814110803,.05929858491543678,.05929858491543678,.04427743881741981,.04427743881741981,.028531388628933663,.028531388628933663,.0123412297999872,.0123412297999872],arcfn:function(e,t){var n=t(e),r=n.x*n.x+n.y*n.y;return"undefined"!=typeof n.z&&(r+=n.z*n.z),s(r)},between:function(e,t,n){return t<=e&&e<=n||p.approximately(e,t)||p.approximately(e,n)},approximately:function(e,n,r){return t(e-n)<=(r||f)},length:function(e){var t,n,r=.5,i=0,a=p.Tvalues.length;for(t=0;t<a;t++)n=r*p.Tvalues[t]+r,i+=p.Cvalues[t]*p.arcfn(n,e);return r*i},map:function(e,t,n,r,i){var a=n-t,o=i-r,s=e-t,l=s/a;return r+o*l},lerp:function(e,t,n){var r={x:t.x+e*(n.x-t.x),y:t.y+e*(n.y-t.y)};return t.z&&n.z&&(r.z=t.z+e*(n.z-t.z)),r},pointToString:function(e){var t=e.x+"/"+e.y;return"undefined"!=typeof e.z&&(t+="/"+e.z),t},pointsToString:function(e){return"["+e.map(p.pointToString).join(", ")+"]"},copy:function(e){return JSON.parse(JSON.stringify(e))},angle:function(e,t,n){var r,i=t.x-e.x,a=t.y-e.y,l=n.x-e.x,c=n.y-e.y,u=i*c-a*l,h=s(i*i+a*a),d=s(l*l+c*c);return i/=h,a/=h,l/=d,c/=d,r=i*l+a*c,o(u,r)},round:function(e,t){var n=""+e,r=n.indexOf(".");return parseFloat(n.substring(0,r+1+t))},dist:function(e,t){var n=e.x-t.x,r=e.y-t.y;return s(n*n+r*r)},closest:function(e,t){var n,r,i=l(2,63);return e.forEach(function(e,a){r=p.dist(t,e),r<i&&(i=r,n=a)}),{mdist:i,mpos:n}},abcratio:function(e,n){if(2!==n&&3!==n)return!1;if("undefined"==typeof e)e=.5;else if(0===e||1===e)return e;var r=l(e,n)+l(1-e,n),i=r-1;return t(i/r)},projectionratio:function(e,t){if(2!==t&&3!==t)return!1;if("undefined"==typeof e)e=.5;else if(0===e||1===e)return e;var n=l(1-e,t),r=l(e,t)+n;return n/r},lli8:function(e,t,n,r,i,a,o,s){var l=(e*r-t*n)*(i-o)-(e-n)*(i*s-a*o),c=(e*r-t*n)*(a-s)-(t-r)*(i*s-a*o),u=(e-n)*(a-s)-(t-r)*(i-o);return 0!=u&&{x:l/u,y:c/u}},lli4:function(e,t,n,r){var i=e.x,a=e.y,o=t.x,s=t.y,l=n.x,c=n.y,u=r.x,h=r.y;return p.lli8(i,a,o,s,l,c,u,h)},lli:function(e,t){return p.lli4(e,e.c,t,t.c)},makeline:function(e,t){var r=n(65),i=e.x,a=e.y,o=t.x,s=t.y,l=(o-i)/3,c=(s-a)/3;return new r(i,a,i+l,a+c,i+2*l,a+2*c,o,s)},findbbox:function(e){var t=99999999,n=t,r=-t,i=r;return e.forEach(function(e){var a=e.bbox();t>a.x.min&&(t=a.x.min),n>a.y.min&&(n=a.y.min),r<a.x.max&&(r=a.x.max),i<a.y.max&&(i=a.y.max)}),{x:{min:t,mid:(t+r)/2,max:r,size:r-t},y:{min:n,mid:(n+i)/2,max:i,size:i-n}}},shapeintersections:function(e,t,n,r,i){if(!p.bboxoverlap(t,r))return[];var a=[],o=[e.startcap,e.forward,e.back,e.endcap],s=[n.startcap,n.forward,n.back,n.endcap];return o.forEach(function(t){t.virtual||s.forEach(function(r){if(!r.virtual){var o=t.intersects(r,i);o.length>0&&(o.c1=t,o.c2=r,o.s1=e,o.s2=n,a.push(o))}})}),a},makeshape:function(e,t,n){var r=t.points.length,i=e.points.length,a=p.makeline(t.points[r-1],e.points[0]),o=p.makeline(e.points[i-1],t.points[0]),s={startcap:a,forward:e,back:t,endcap:o,bbox:p.findbbox([a,e,t,o])},l=p;return s.intersections=function(e){return l.shapeintersections(s,s.bbox,e,e.bbox,n)},s},getminmax:function(e,t,n){if(!n)return{min:0,max:0};var r,i,a=0x10000000000000000,o=-a;n.indexOf(0)===-1&&(n=[0].concat(n)),n.indexOf(1)===-1&&n.push(1);for(var s=0,l=n.length;s<l;s++)r=n[s],i=e.get(r),i[t]<a&&(a=i[t]),i[t]>o&&(o=i[t]);return{min:a,mid:(a+o)/2,max:o,size:o-a}},align:function(e,t){var n=t.p1.x,a=t.p1.y,s=-o(t.p2.y-a,t.p2.x-n),l=function(e){return{x:(e.x-n)*r(s)-(e.y-a)*i(s),y:(e.x-n)*i(s)+(e.y-a)*r(s)}};return e.map(l)},roots:function(e,t){t=t||{p1:{x:0,y:0},p2:{x:1,y:0}};var n=e.length-1,i=p.align(e,t),o=function(e){return 0<=e&&e<=1};if(2===n){var l=i[0].y,u=i[1].y,d=i[2].y,f=l-2*u+d;if(0!==f){var m=-s(u*u-l*d),g=-l+u,v=-(m+g)/f,w=-(-m+g)/f;return[v,w].filter(o)}return u!==d&&0===f?[(2*u-d)/2*(u-d)].filter(o):[]}var y,v,b,_,x,E=i[0].y,C=i[1].y,k=i[2].y,S=i[3].y,f=-E+3*C-3*k+S,l=(3*E-6*C+3*k)/f,u=(-3*E+3*C)/f,d=E/f,i=(3*u-l*l)/3,P=i/3,T=(2*l*l*l-9*l*u+27*d)/27,M=T/2,N=M*M+P*P*P;if(N<0){var I=-i/3,L=I*I*I,A=s(L),O=-T/(2*A),B=O<-1?-1:O>1?1:O,z=a(B),R=c(A),D=2*R;return b=D*r(z/3)-l/3,_=D*r((z+h)/3)-l/3,x=D*r((z+2*h)/3)-l/3,[b,_,x].filter(o)}if(0===N)return y=M<0?c(-M):-c(M),b=2*y-l/3,_=-y-l/3,[b,_].filter(o);var j=s(N);return y=c(-M+j),v=c(M+j),[y-v-l/3].filter(o)},droots:function(e){if(3===e.length){var t=e[0],n=e[1],r=e[2],i=t-2*n+r;if(0!==i){var a=-s(n*n-t*r),o=-t+n,l=-(a+o)/i,c=-(-a+o)/i;return[l,c]}return n!==r&&0===i?[(2*n-r)/(2*(n-r))]:[]}if(2===e.length){var t=e[0],n=e[1];return t!==n?[t/(t-n)]:[]}},inflections:function(e){if(e.length<4)return[];var t=p.align(e,{p1:e[0],p2:e.slice(-1)[0]}),n=t[2].x*t[1].y,r=t[3].x*t[1].y,i=t[1].x*t[2].y,a=t[3].x*t[2].y,o=18*(-3*n+2*r+3*i-a),s=18*(3*n-r-3*i),l=18*(i-n);if(p.approximately(o,0))return[];var c=s*s-4*o*l,u=Math.sqrt(c),a=2*o;return p.approximately(a,0)?[]:[(u-s)/a,-(s+u)/a].filter(function(e){return 0<=e&&e<=1})},bboxoverlap:function(e,n){var r,i,a,o,s,l=["x","y"],c=l.length;for(r=0;r<c;r++)if(i=l[r],a=e[i].mid,o=n[i].mid,s=(e[i].size+n[i].size)/2,t(a-o)>=s)return!1;return!0},expandbox:function(e,t){t.x.min<e.x.min&&(e.x.min=t.x.min),t.y.min<e.y.min&&(e.y.min=t.y.min),t.z&&t.z.min<e.z.min&&(e.z.min=t.z.min),t.x.max>e.x.max&&(e.x.max=t.x.max),t.y.max>e.y.max&&(e.y.max=t.y.max),t.z&&t.z.max>e.z.max&&(e.z.max=t.z.max),e.x.mid=(e.x.min+e.x.max)/2,e.y.mid=(e.y.min+e.y.max)/2,e.z&&(e.z.mid=(e.z.min+e.z.max)/2),e.x.size=e.x.max-e.x.min,e.y.size=e.y.max-e.y.min,e.z&&(e.z.size=e.z.max-e.z.min)},pairiteration:function(e,t,n){var r=e.bbox(),i=t.bbox(),a=1e5,o=n||.5;if(r.x.size+r.y.size<o&&i.x.size+i.y.size<o)return[(a*(e._t1+e._t2)/2|0)/a+"/"+(a*(t._t1+t._t2)/2|0)/a];var s=e.split(.5),l=t.split(.5),c=[{left:s.left,right:l.left},{left:s.left,right:l.right},{left:s.right,right:l.right},{left:s.right,right:l.left}];c=c.filter(function(e){return p.bboxoverlap(e.left.bbox(),e.right.bbox())});var u=[];return 0===c.length?u:(c.forEach(function(e){u=u.concat(p.pairiteration(e.left,e.right,o))}),u=u.filter(function(e,t){return u.indexOf(e)===t}))},getccenter:function(e,t,n){var a,s=t.x-e.x,l=t.y-e.y,c=n.x-t.x,u=n.y-t.y,f=s*r(d)-l*i(d),m=s*i(d)+l*r(d),g=c*r(d)-u*i(d),v=c*i(d)+u*r(d),w=(e.x+t.x)/2,y=(e.y+t.y)/2,b=(t.x+n.x)/2,_=(t.y+n.y)/2,x=w+f,E=y+m,C=b+g,k=_+v,S=p.lli8(w,y,x,E,b,_,C,k),P=p.dist(S,e),T=o(e.y-S.y,e.x-S.x),M=o(t.y-S.y,t.x-S.x),N=o(n.y-S.y,n.x-S.x);return T<N?((T>M||M>N)&&(T+=h),T>N&&(a=N,N=T,T=a)):N<M&&M<T?(a=N,N=T,T=a):N+=h,S.s=T,S.e=N,S.r=P,S}};e.exports=p}()},function(e,t,n){"use strict";var r=n(9),i={listen:function(e,t,n){return e.addEventListener?(e.addEventListener(t,n,!1),{remove:function(){e.removeEventListener(t,n,!1)}}):e.attachEvent?(e.attachEvent("on"+t,n),{remove:function(){e.detachEvent("on"+t,n)}}):void 0},capture:function(e,t,n){return e.addEventListener?(e.addEventListener(t,n,!0),{remove:function(){e.removeEventListener(t,n,!0)}}):{remove:r}},registerDefault:function(){}};e.exports=i},function(e,t,n){"use strict";function r(e){try{e.focus()}catch(e){}}e.exports=r},function(e,t,n){"use strict";function r(){if("undefined"==typeof document)return null;try{return document.activeElement||document.body}catch(e){return document.body}}e.exports=r},function(e,t,n){"use strict";function r(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent("on"+t,n)}function i(e,t,n){e.removeEventListener?e.removeEventListener(t,n,!1):e.detachEvent("on"+t,n)}function a(){return window.location.href.split("#")[1]||""}function o(e){window.location.replace(window.location.pathname+window.location.search+"#"+e)}function s(){return window.location.pathname+window.location.search+window.location.hash}function l(e){e&&window.history.go(e)}function c(e,t){t(window.confirm(e))}function u(){var e=navigator.userAgent;return(e.indexOf("Android 2.")===-1&&e.indexOf("Android 4.0")===-1||e.indexOf("Mobile Safari")===-1||e.indexOf("Chrome")!==-1||e.indexOf("Windows Phone")!==-1)&&(e.indexOf("CriOS")===-1&&(window.history&&"pushState"in window.history))}function h(){var e=navigator.userAgent;return e.indexOf("Firefox")===-1}t.__esModule=!0,t.addEventListener=r,t.removeEventListener=i,t.getHashPath=a,t.replaceHashPath=o,t.getWindowPath=s,t.go=l,t.getUserConfirmation=c,t.supportsHistory=u,t.supportsGoWithoutReloadUsingHash=h},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){return Math.random().toString(36).substr(2,e)}function a(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.key===t.key&&c.default(e.state,t.state)}function o(){function e(e){return R.push(e),function(){R=R.filter(function(t){return t!==e})}}function t(){return q&&q.action===h.POP?D.indexOf(q.key):F?D.indexOf(F.key):-1}function n(e){var n=t();F=e,F.action===h.PUSH?D=[].concat(D.slice(0,n+1),[F.key]):F.action===h.REPLACE&&(D[n]=F.key),j.forEach(function(e){e(F)})}function r(e){if(j.push(e),F)e(F);else{var t=I();D=[t.key],n(t)}return function(){j=j.filter(function(t){return t!==e})}}function o(e,t){u.loopAsync(R.length,function(t,n,r){m.default(R[t],e,function(e){null!=e?r(e):n()})},function(e){z&&"string"==typeof e?z(e,function(e){t(e!==!1)}):t(e!==!1)})}function l(e){F&&a(F,e)||(q=e,o(e,function(t){if(q===e)if(t){if(e.action===h.PUSH){var r=_(F),i=_(e);i===r&&(e.action=h.REPLACE)}L(e)!==!1&&n(e)}else if(F&&e.action===h.POP){var a=D.indexOf(F.key),o=D.indexOf(e.key);a!==-1&&o!==-1&&O(a-o)}}))}function c(e){l(E(e,h.PUSH,w()))}function d(e){l(E(e,h.REPLACE,w()))}function p(){O(-1)}function g(){O(1)}function w(){return i(B)}function _(e){if(null==e||"string"==typeof e)return e;var t=e.pathname,n=e.search,r=e.hash,i=t;return n&&(i+=n),r&&(i+=r),i}function x(e){return _(e)}function E(e,t){var n=arguments.length<=2||void 0===arguments[2]?w():arguments[2];return"object"==typeof t&&("string"==typeof e&&(e=v.default(e)),e=s({},e,{state:t}),t=n,n=arguments[3]||w()),f.default(e,t,n)}function C(e){F?(k(F,e),n(F)):k(I(),e)}function k(e,t){e.state=s({},e.state,t),A(e.key,e.state)}function S(e){R.indexOf(e)===-1&&R.push(e)}function P(e){R=R.filter(function(t){return t!==e})}function T(e,t){"string"==typeof t&&(t=v.default(t)),c(s({state:e},t))}function M(e,t){"string"==typeof t&&(t=v.default(t)),d(s({state:e},t))}var N=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],I=N.getCurrentLocation,L=N.finishTransition,A=N.saveState,O=N.go,B=N.keyLength,z=N.getUserConfirmation;"number"!=typeof B&&(B=b);var R=[],D=[],j=[],F=void 0,q=void 0;return{listenBefore:e,listen:r,transitionTo:l,push:c,replace:d,go:O,goBack:p,goForward:g,createKey:w,createPath:_,createHref:x,createLocation:E,setState:y.default(C,"setState is deprecated; use location.key to save state instead"),registerTransitionHook:y.default(S,"registerTransitionHook is deprecated; use listenBefore instead"),unregisterTransitionHook:y.default(P,"unregisterTransitionHook is deprecated; use the callback returned from listenBefore instead"),pushState:y.default(T,"pushState is deprecated; use push instead"),replaceState:y.default(M,"replaceState is deprecated; use replace instead")}}t.__esModule=!0;var s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l=n(208),c=r(l),u=n(223),h=n(27),d=n(227),f=r(d),p=n(42),m=r(p),g=n(19),v=r(g),w=n(41),y=r(w),b=6;t.default=o,e.exports=t.default},function(e,t,n){"use strict";function r(e){var t=e.match(/^https?:\/\/[^\/]*/);return null==t?e:e.substring(t[0].length)}t.__esModule=!0,t.default=r,e.exports=t.default},function(e,t){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function i(e){if(u===setTimeout)return setTimeout(e,0);if((u===n||!u)&&setTimeout)return u=setTimeout,setTimeout(e,0);try{return u(e,0)}catch(t){try{return u.call(null,e,0)}catch(t){return u.call(this,e,0)}}}function a(e){if(h===clearTimeout)return clearTimeout(e);if((h===r||!h)&&clearTimeout)return h=clearTimeout,clearTimeout(e);try{return h(e)}catch(t){try{return h.call(null,e)}catch(t){return h.call(this,e)}}}function o(){m&&f&&(m=!1,f.length?p=f.concat(p):g=-1,p.length&&s())}function s(){if(!m){var e=i(o);m=!0;for(var t=p.length;t;){for(f=p,p=[];++g<t;)f&&f[g].run();g=-1,t=p.length}f=null,m=!1,a(e)}}function l(e,t){this.fun=e,this.array=t}function c(){}var u,h,d=e.exports={};!function(){try{u="function"==typeof setTimeout?setTimeout:n}catch(e){u=n}try{h="function"==typeof clearTimeout?clearTimeout:r}catch(e){h=r}}();var f,p=[],m=!1,g=-1;d.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];p.push(new l(e,t)),1!==p.length||m||i(s)},l.prototype.run=function(){this.fun.apply(null,this.array)},d.title="browser",d.browser=!0,d.env={},d.argv=[],d.version="",d.versions={},d.on=c,d.addListener=c,d.once=c,d.off=c,d.removeListener=c,d.removeAllListeners=c,d.emit=c,d.binding=function(e){throw new Error("process.binding is not supported")},d.cwd=function(){return"/"},d.chdir=function(e){throw new Error("process.chdir is not supported")},d.umask=function(){return 0}},function(e,t,n){"use strict";function r(e,t){return e+t.charAt(0).toUpperCase()+t.substring(1)}var i={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridColumn:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},a=["Webkit","ms","Moz","O"];Object.keys(i).forEach(function(e){a.forEach(function(t){i[r(t,e)]=i[e]})});var o={background:{backgroundAttachment:!0,backgroundColor:!0,backgroundImage:!0,backgroundPositionX:!0,backgroundPositionY:!0,backgroundRepeat:!0},backgroundPosition:{backgroundPositionX:!0,backgroundPositionY:!0},border:{borderWidth:!0,borderStyle:!0,borderColor:!0},borderBottom:{borderBottomWidth:!0,borderBottomStyle:!0,borderBottomColor:!0},borderLeft:{borderLeftWidth:!0,borderLeftStyle:!0,borderLeftColor:!0},borderRight:{borderRightWidth:!0,borderRightStyle:!0,borderRightColor:!0},borderTop:{borderTopWidth:!0,borderTopStyle:!0,borderTopColor:!0},font:{fontStyle:!0,fontVariant:!0,fontWeight:!0,fontSize:!0,lineHeight:!0,fontFamily:!0},outline:{outlineWidth:!0,outlineStyle:!0,outlineColor:!0}},s={isUnitlessNumber:i,shorthandPropertyExpansions:o};e.exports=s},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(3),a=n(17),o=(n(1),function(){function e(t){r(this,e),this._callbacks=null, +this._contexts=null,this._arg=t}return e.prototype.enqueue=function(e,t){this._callbacks=this._callbacks||[],this._callbacks.push(e),this._contexts=this._contexts||[],this._contexts.push(t)},e.prototype.notifyAll=function(){var e=this._callbacks,t=this._contexts,n=this._arg;if(e&&t){e.length!==t.length?i("24"):void 0,this._callbacks=null,this._contexts=null;for(var r=0;r<e.length;r++)e[r].call(t[r],n);e.length=0,t.length=0}},e.prototype.checkpoint=function(){return this._callbacks?this._callbacks.length:0},e.prototype.rollback=function(e){this._callbacks&&this._contexts&&(this._callbacks.length=e,this._contexts.length=e)},e.prototype.reset=function(){this._callbacks=null,this._contexts=null},e.prototype.destructor=function(){this.reset()},e}());e.exports=a.addPoolingTo(o)},function(e,t,n){"use strict";function r(e){return!!c.hasOwnProperty(e)||!l.hasOwnProperty(e)&&(s.test(e)?(c[e]=!0,!0):(l[e]=!0,!1))}function i(e,t){return null==t||e.hasBooleanValue&&!t||e.hasNumericValue&&isNaN(t)||e.hasPositiveNumericValue&&t<1||e.hasOverloadedBooleanValue&&t===!1}var a=n(21),o=(n(6),n(11),n(295)),s=(n(2),new RegExp("^["+a.ATTRIBUTE_NAME_START_CHAR+"]["+a.ATTRIBUTE_NAME_CHAR+"]*$")),l={},c={},u={createMarkupForID:function(e){return a.ID_ATTRIBUTE_NAME+"="+o(e)},setAttributeForID:function(e,t){e.setAttribute(a.ID_ATTRIBUTE_NAME,t)},createMarkupForRoot:function(){return a.ROOT_ATTRIBUTE_NAME+'=""'},setAttributeForRoot:function(e){e.setAttribute(a.ROOT_ATTRIBUTE_NAME,"")},createMarkupForProperty:function(e,t){var n=a.properties.hasOwnProperty(e)?a.properties[e]:null;if(n){if(i(n,t))return"";var r=n.attributeName;return n.hasBooleanValue||n.hasOverloadedBooleanValue&&t===!0?r+'=""':r+"="+o(t)}return a.isCustomAttribute(e)?null==t?"":e+"="+o(t):null},createMarkupForCustomAttribute:function(e,t){return r(e)&&null!=t?e+"="+o(t):""},setValueForProperty:function(e,t,n){var r=a.properties.hasOwnProperty(t)?a.properties[t]:null;if(r){var o=r.mutationMethod;if(o)o(e,n);else{if(i(r,n))return void this.deleteValueForProperty(e,t);if(r.mustUseProperty)e[r.propertyName]=n;else{var s=r.attributeName,l=r.attributeNamespace;l?e.setAttributeNS(l,s,""+n):r.hasBooleanValue||r.hasOverloadedBooleanValue&&n===!0?e.setAttribute(s,""):e.setAttribute(s,""+n)}}}else if(a.isCustomAttribute(t))return void u.setValueForAttribute(e,t,n)},setValueForAttribute:function(e,t,n){if(r(t)){null==n?e.removeAttribute(t):e.setAttribute(t,""+n)}},deleteValueForAttribute:function(e,t){e.removeAttribute(t)},deleteValueForProperty:function(e,t){var n=a.properties.hasOwnProperty(t)?a.properties[t]:null;if(n){var r=n.mutationMethod;if(r)r(e,void 0);else if(n.mustUseProperty){var i=n.propertyName;n.hasBooleanValue?e[i]=!1:e[i]=""}else e.removeAttribute(n.attributeName)}else a.isCustomAttribute(t)&&e.removeAttribute(t)}};e.exports=u},function(e,t,n){"use strict";var r={hasCachedChildNodes:1};e.exports=r},function(e,t,n){"use strict";function r(){if(this._rootNodeID&&this._wrapperState.pendingUpdate){this._wrapperState.pendingUpdate=!1;var e=this._currentElement.props,t=s.getValue(e);null!=t&&i(this,Boolean(e.multiple),t)}}function i(e,t,n){var r,i,a=l.getNodeFromInstance(e).options;if(t){for(r={},i=0;i<n.length;i++)r[""+n[i]]=!0;for(i=0;i<a.length;i++){var o=r.hasOwnProperty(a[i].value);a[i].selected!==o&&(a[i].selected=o)}}else{for(r=""+n,i=0;i<a.length;i++)if(a[i].value===r)return void(a[i].selected=!0);a.length&&(a[0].selected=!0)}}function a(e){var t=this._currentElement.props,n=s.executeOnChange(t,e);return this._rootNodeID&&(this._wrapperState.pendingUpdate=!0),c.asap(r,this),n}var o=n(5),s=n(48),l=n(6),c=n(12),u=(n(2),!1),h={getHostProps:function(e,t){return o({},t,{onChange:e._wrapperState.onChange,value:void 0})},mountWrapper:function(e,t){var n=s.getValue(t);e._wrapperState={pendingUpdate:!1,initialValue:null!=n?n:t.defaultValue,listeners:null,onChange:a.bind(e),wasMultiple:Boolean(t.multiple)},void 0===t.value||void 0===t.defaultValue||u||(u=!0)},getSelectValueContext:function(e){return e._wrapperState.initialValue},postUpdateWrapper:function(e){var t=e._currentElement.props;e._wrapperState.initialValue=void 0;var n=e._wrapperState.wasMultiple;e._wrapperState.wasMultiple=Boolean(t.multiple);var r=s.getValue(t);null!=r?(e._wrapperState.pendingUpdate=!1,i(e,Boolean(t.multiple),r)):n!==Boolean(t.multiple)&&(null!=t.defaultValue?i(e,Boolean(t.multiple),t.defaultValue):i(e,Boolean(t.multiple),t.multiple?[]:""))}};e.exports=h},function(e,t,n){"use strict";var r,i={injectEmptyComponentFactory:function(e){r=e}},a={create:function(e){return r(e)}};a.injection=i,e.exports=a},function(e,t,n){"use strict";var r={logTopLevelRenders:!1};e.exports=r},function(e,t,n){"use strict";function r(e){return s?void 0:o("111",e.type),new s(e)}function i(e){return new l(e)}function a(e){return e instanceof l}var o=n(3),s=(n(1),null),l=null,c={injectGenericComponentClass:function(e){s=e},injectTextComponentClass:function(e){l=e}},u={createInternalComponent:r,createInstanceForText:i,isTextComponent:a,injection:c};e.exports=u},function(e,t,n){"use strict";function r(e){return a(document.documentElement,e)}var i=n(254),a=n(213),o=n(68),s=n(69),l={hasSelectionCapabilities:function(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&"text"===e.type||"textarea"===t||"true"===e.contentEditable)},getSelectionInformation:function(){var e=s();return{focusedElem:e,selectionRange:l.hasSelectionCapabilities(e)?l.getSelection(e):null}},restoreSelection:function(e){var t=s(),n=e.focusedElem,i=e.selectionRange;t!==n&&r(n)&&(l.hasSelectionCapabilities(n)&&l.setSelection(n,i),o(n))},getSelection:function(e){var t;if("selectionStart"in e)t={start:e.selectionStart,end:e.selectionEnd};else if(document.selection&&e.nodeName&&"input"===e.nodeName.toLowerCase()){var n=document.selection.createRange();n.parentElement()===e&&(t={start:-n.moveStart("character",-e.value.length),end:-n.moveEnd("character",-e.value.length)})}else t=i.getOffsets(e);return t||{start:0,end:0}},setSelection:function(e,t){var n=t.start,r=t.end;if(void 0===r&&(r=n),"selectionStart"in e)e.selectionStart=n,e.selectionEnd=Math.min(r,e.value.length);else if(document.selection&&e.nodeName&&"input"===e.nodeName.toLowerCase()){var a=e.createTextRange();a.collapse(!0),a.moveStart("character",n),a.moveEnd("character",r-n),a.select()}else i.setOffsets(e,t)}};e.exports=l},function(e,t,n){"use strict";function r(e,t){for(var n=Math.min(e.length,t.length),r=0;r<n;r++)if(e.charAt(r)!==t.charAt(r))return r;return e.length===t.length?-1:n}function i(e){return e?e.nodeType===O?e.documentElement:e.firstChild:null}function a(e){return e.getAttribute&&e.getAttribute(I)||""}function o(e,t,n,r,i){var a;if(_.logTopLevelRenders){var o=e._currentElement.props.child,s=o.type;a="React mount: "+("string"==typeof s?s:s.displayName||s.name),console.time(a)}var l=C.mountComponent(e,n,null,y(e,t),i,0);a&&console.timeEnd(a),e._renderedComponent._topLevelWrapper=e,j._mountImageIntoNode(l,t,e,r,n)}function s(e,t,n,r){var i=S.ReactReconcileTransaction.getPooled(!n&&b.useCreateElement);i.perform(o,null,e,t,i,n,r),S.ReactReconcileTransaction.release(i)}function l(e,t,n){for(C.unmountComponent(e,n),t.nodeType===O&&(t=t.documentElement);t.lastChild;)t.removeChild(t.lastChild)}function c(e){var t=i(e);if(t){var n=w.getInstanceFromNode(t);return!(!n||!n._hostParent)}}function u(e){return!(!e||e.nodeType!==A&&e.nodeType!==O&&e.nodeType!==B)}function h(e){var t=i(e),n=t&&w.getInstanceFromNode(t);return n&&!n._hostParent?n:null}function d(e){var t=h(e);return t?t._hostContainerInfo._topLevelWrapper:null}var f=n(3),p=n(20),m=n(21),g=n(23),v=n(33),w=(n(15),n(6)),y=n(248),b=n(250),_=n(80),x=n(30),E=(n(11),n(264)),C=n(22),k=n(51),S=n(12),P=n(26),T=n(90),M=(n(1),n(37)),N=n(57),I=(n(2),m.ID_ATTRIBUTE_NAME),L=m.ROOT_ATTRIBUTE_NAME,A=1,O=9,B=11,z={},R=1,D=function(){this.rootID=R++};D.prototype.isReactComponent={},D.prototype.render=function(){return this.props.child},D.isReactTopLevelWrapper=!0;var j={TopLevelWrapper:D,_instancesByReactRootID:z,scrollMonitor:function(e,t){t()},_updateRootComponent:function(e,t,n,r,i){return j.scrollMonitor(r,function(){k.enqueueElementInternal(e,t,n),i&&k.enqueueCallbackInternal(e,i)}),e},_renderNewRootComponent:function(e,t,n,r){u(t)?void 0:f("37"),v.ensureScrollValueMonitoring();var i=T(e,!1);S.batchedUpdates(s,i,t,n,r);var a=i._instance.rootID;return z[a]=i,i},renderSubtreeIntoContainer:function(e,t,n,r){return null!=e&&x.has(e)?void 0:f("38"),j._renderSubtreeIntoContainer(e,t,n,r)},_renderSubtreeIntoContainer:function(e,t,n,r){k.validateCallback(r,"ReactDOM.render"),g.isValidElement(t)?void 0:f("39","string"==typeof t?" Instead of passing a string like 'div', pass React.createElement('div') or <div />.":"function"==typeof t?" Instead of passing a class like Foo, pass React.createElement(Foo) or <Foo />.":null!=t&&void 0!==t.props?" This may be caused by unintentionally loading two independent copies of React.":"");var o,s=g.createElement(D,{child:t});if(e){var l=x.get(e);o=l._processChildContext(l._context)}else o=P;var u=d(n);if(u){var h=u._currentElement,p=h.props.child;if(N(p,t)){var m=u._renderedComponent.getPublicInstance(),v=r&&function(){r.call(m)};return j._updateRootComponent(u,s,o,n,v),m}j.unmountComponentAtNode(n)}var w=i(n),y=w&&!!a(w),b=c(n),_=y&&!u&&!b,E=j._renderNewRootComponent(s,n,_,o)._renderedComponent.getPublicInstance();return r&&r.call(E),E},render:function(e,t,n){return j._renderSubtreeIntoContainer(null,e,t,n)},unmountComponentAtNode:function(e){u(e)?void 0:f("40");var t=d(e);if(!t){c(e),1===e.nodeType&&e.hasAttribute(L);return!1}return delete z[t._instance.rootID],S.batchedUpdates(l,t,e,!1),!0},_mountImageIntoNode:function(e,t,n,a,o){if(u(t)?void 0:f("41"),a){var s=i(t);if(E.canReuseMarkup(e,s))return void w.precacheNode(n,s);var l=s.getAttribute(E.CHECKSUM_ATTR_NAME);s.removeAttribute(E.CHECKSUM_ATTR_NAME);var c=s.outerHTML;s.setAttribute(E.CHECKSUM_ATTR_NAME,l);var h=e,d=r(h,c),m=" (client) "+h.substring(d-20,d+20)+"\n (server) "+c.substring(d-20,d+20);t.nodeType===O?f("42",m):void 0}if(t.nodeType===O?f("43"):void 0,o.useCreateElement){for(;t.lastChild;)t.removeChild(t.lastChild);p.insertTreeBefore(t,e,null)}else M(t,e),w.precacheNode(n,t.firstChild)}};e.exports=j},function(e,t,n){"use strict";var r=n(3),i=n(23),a=(n(1),{HOST:0,COMPOSITE:1,EMPTY:2,getType:function(e){return null===e||e===!1?a.EMPTY:i.isValidElement(e)?"function"==typeof e.type?a.COMPOSITE:a.HOST:void r("26",e)}});e.exports=a},function(e,t,n){"use strict";var r={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(e){r.currentScrollLeft=e.x,r.currentScrollTop=e.y}};e.exports=r},function(e,t,n){"use strict";function r(e,t){return null==t?i("30"):void 0,null==e?t:Array.isArray(e)?Array.isArray(t)?(e.push.apply(e,t),e):(e.push(t),e):Array.isArray(t)?[e].concat(t):[e,t]}var i=n(3);n(1);e.exports=r},function(e,t,n){"use strict";function r(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)}e.exports=r},function(e,t,n){"use strict";function r(e){for(var t;(t=e._renderedNodeType)===i.COMPOSITE;)e=e._renderedComponent;return t===i.HOST?e._renderedComponent:t===i.EMPTY?null:void 0}var i=n(84);e.exports=r},function(e,t,n){"use strict";function r(){return!a&&i.canUseDOM&&(a="textContent"in document.documentElement?"textContent":"innerText"),a}var i=n(7),a=null;e.exports=r},function(e,t,n){"use strict";function r(e){if(e){var t=e.getName();if(t)return" Check the render method of `"+t+"`."}return""}function i(e){return"function"==typeof e&&"undefined"!=typeof e.prototype&&"function"==typeof e.prototype.mountComponent&&"function"==typeof e.prototype.receiveComponent}function a(e,t){var n;if(null===e||e===!1)n=c.create(a);else if("object"==typeof e){var s=e,l=s.type;if("function"!=typeof l&&"string"!=typeof l){var d="";d+=r(s._owner),o("130",null==l?l:typeof l,d)}"string"==typeof s.type?n=u.createInternalComponent(s):i(s.type)?(n=new s.type(s),n.getHostNode||(n.getHostNode=n.getNativeNode)):n=new h(s)}else"string"==typeof e||"number"==typeof e?n=u.createInstanceForText(e):o("131",typeof e);return n._mountIndex=0,n._mountImage=null,n}var o=n(3),s=n(5),l=n(245),c=n(79),u=n(81),h=(n(292),n(1),n(2),function(e){this.construct(e)});s(h.prototype,l,{_instantiateReactComponent:a}),e.exports=a},function(e,t,n){"use strict";function r(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!i[e.type]:"textarea"===t}var i={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};e.exports=r},function(e,t,n){"use strict";var r=n(7),i=n(36),a=n(37),o=function(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t};r.canUseDOM&&("textContent"in document.documentElement||(o=function(e,t){return 3===e.nodeType?void(e.nodeValue=t):void a(e,i(t))})),e.exports=o},function(e,t,n){"use strict";function r(e,t){return e&&"object"==typeof e&&null!=e.key?c.escape(e.key):t.toString(36)}function i(e,t,n,a){var d=typeof e;if("undefined"!==d&&"boolean"!==d||(e=null),null===e||"string"===d||"number"===d||"object"===d&&e.$$typeof===s)return n(a,e,""===t?u+r(e,0):t),1;var f,p,m=0,g=""===t?u:t+h;if(Array.isArray(e))for(var v=0;v<e.length;v++)f=e[v],p=g+r(f,v),m+=i(f,p,n,a);else{var w=l(e);if(w){var y,b=w.call(e);if(w!==e.entries)for(var _=0;!(y=b.next()).done;)f=y.value,p=g+r(f,_++),m+=i(f,p,n,a);else for(;!(y=b.next()).done;){var x=y.value;x&&(f=x[1],p=g+c.escape(x[0])+h+r(f,0),m+=i(f,p,n,a))}}else if("object"===d){var E="",C=String(e);o("31","[object Object]"===C?"object with keys {"+Object.keys(e).join(", ")+"}":C,E)}}return m}function a(e,t,n){return null==e?0:i(e,"",t,n)}var o=n(3),s=(n(15),n(260)),l=n(291),c=(n(1),n(47)),u=(n(2),"."),h=":";e.exports=a},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function s(e){return 0===e.button}function l(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function c(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0}t.__esModule=!0;var u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},h=n(4),d=r(h),f=d.default.PropTypes,p=f.bool,m=f.object,g=f.string,v=f.func,w=function(e){function t(){a(this,t),e.apply(this,arguments)}return o(t,e),t.prototype.handleClick=function(e){var t=!0;if(this.props.onClick&&this.props.onClick(e),!l(e)&&s(e)){if(e.defaultPrevented===!0&&(t=!1),this.props.target)return void(t||e.preventDefault());if(e.preventDefault(),t){var n=this.props,r=n.state,i=n.to,a=n.query,o=n.hash;o&&(i+=o),this.context.history.pushState(r,i,a)}}},t.prototype.render=function(){var e=this,t=this.props,n=t.to,r=t.query,a=t.hash,o=(t.state,t.activeClassName),s=t.activeStyle,l=t.onlyActiveOnIndex,h=i(t,["to","query","hash","state","activeClassName","activeStyle","onlyActiveOnIndex"]);h.onClick=function(t){return e.handleClick(t)};var f=this.context.history;return f&&(h.href=f.createHref(n,r),a&&(h.href+=a),(o||null!=s&&!c(s))&&f.isActive(n,r,l)&&(o&&(h.className+=""===h.className?o:" "+o),s&&(h.style=u({},h.style,s)))),d.default.createElement("a",h)},t}(h.Component);w.contextTypes={history:m},w.propTypes={to:g.isRequired,query:m,hash:g,state:m,activeStyle:m,activeClassName:g,onlyActiveOnIndex:p.isRequired,onClick:v},w.defaultProps={onlyActiveOnIndex:!1,className:"",style:{}},t.default=w,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var o=n(10),s=r(o),l=n(4),c=r(l),u=n(16),h=n(32),d=n(18),f=c.default.PropTypes,p=f.string,m=f.object,g=function(e){function t(){i(this,t),e.apply(this,arguments)}return a(t,e),t.prototype.render=function(){s.default(!1)},t}(l.Component);g.createRouteFromReactElement=function(e){var t=u.createRouteFromReactElement(e);return t.from&&(t.path=t.from),t.onEnter=function(e,n){var r=e.location,i=e.params,a=void 0;if("/"===t.to.charAt(0))a=h.formatPattern(t.to,i);else if(t.to){var o=e.routes.indexOf(t),s=g.getRoutePattern(e.routes,o-1),l=s.replace(/\/*$/,"/")+t.to;a=h.formatPattern(l,i)}else a=r.pathname;n(t.state||r.state,a,t.query||r.query)},t},g.getRoutePattern=function(e,t){for(var n="",r=t;r>=0;r--){var i=e[r],a=i.path||"";if(n=a.replace(/\/*$/,"/")+n,0===a.indexOf("/"))break}return"/"+n},g.propTypes={path:p,from:p,to:p.isRequired,query:m,state:m,onEnter:d.falsy,children:d.falsy},t.default=g,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s=n(10),l=r(s),c=n(4),u=r(c),h=n(16),d=n(308),f=r(d),p=u.default.PropTypes,m=p.array,g=p.func,v=p.object,w=function(e){function t(){i(this,t),e.apply(this,arguments)}return a(t,e),t.prototype.getChildContext=function(){var e=this.props,t=e.history,n=e.location;return{history:t,location:n}},t.prototype.createElement=function(e,t){return null==e?null:this.props.createElement(e,t)},t.prototype.render=function(){var e=this,t=this.props,n=t.history,r=t.location,i=t.routes,a=t.params,s=t.components,c=null;return s&&(c=s.reduceRight(function(t,s,l){if(null==s)return t;var c=i[l],u=f.default(c,a),d={history:n,location:r,params:a,route:c,routeParams:u,routes:i};if(h.isReactChildren(t))d.children=t;else if(t)for(var p in t)t.hasOwnProperty(p)&&(d[p]=t[p]);if("object"==typeof s){var m={};for(var g in s)s.hasOwnProperty(g)&&(m[g]=e.createElement(s[g],o({key:g},d)));return m}return e.createElement(s,d)},c)),null===c||c===!1||u.default.isValidElement(c)?void 0:l.default(!1),c},t}(c.Component);w.propTypes={history:v.isRequired,createElement:g.isRequired,location:v.isRequired,routes:m.isRequired,params:v.isRequired,components:m.isRequired},w.defaultProps={createElement:u.default.createElement},w.childContextTypes={history:v.isRequired,location:v.isRequired},t.default=w,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(304),a=r(i);t.Router=a.default;var o=n(94),s=r(o);t.Link=s.default;var l=n(298),c=r(l);t.IndexLink=c.default;var u=n(299),h=r(u);t.IndexRedirect=h.default;var d=n(300),f=r(d);t.IndexRoute=f.default;var p=n(95),m=r(p);t.Redirect=m.default;var g=n(302),v=r(g);t.Route=v.default;var w=n(297),y=r(w);t.History=y.default;var b=n(301),_=r(b);t.Lifecycle=_.default;var x=n(303),E=r(x);t.RouteContext=E.default;var C=n(60),k=r(C);t.useRoutes=k.default;var S=n(16);t.createRoutes=S.createRoutes;var P=n(96),T=r(P);t.RoutingContext=T.default;var M=n(18),N=r(M);t.PropTypes=N.default;var I=n(310),L=r(I);t.match=L.default;var A=r(i);t.default=A.default},function(e,t,n){"use strict";function r(e){var t=Function.prototype.toString,n=Object.prototype.hasOwnProperty,r=RegExp("^"+t.call(n).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");try{var i=t.call(e);return r.test(i)}catch(e){return!1}}function i(e){var t=c(e);if(t){var n=t.childIDs;u(e),n.forEach(i)}}function a(e,t,n){return"\n in "+(e||"Unknown")+(t?" (at "+t.fileName.replace(/^.*[\\\/]/,"")+":"+t.lineNumber+")":n?" (created by "+n+")":"")}function o(e){return null==e?"#empty":"string"==typeof e||"number"==typeof e?"#text":"string"==typeof e.type?e.type:e.type.displayName||e.type.name||"Unknown"}function s(e){var t,n=k.getDisplayName(e),r=k.getElement(e),i=k.getOwnerID(e);return i&&(t=k.getDisplayName(i)),a(n,r&&r._source,t)}var l,c,u,h,d,f,p,m=n(25),g=n(15),v=(n(1),n(2),"function"==typeof Array.from&&"function"==typeof Map&&r(Map)&&null!=Map.prototype&&"function"==typeof Map.prototype.keys&&r(Map.prototype.keys)&&"function"==typeof Set&&r(Set)&&null!=Set.prototype&&"function"==typeof Set.prototype.keys&&r(Set.prototype.keys));if(v){var w=new Map,y=new Set;l=function(e,t){w.set(e,t)},c=function(e){return w.get(e)},u=function(e){w.delete(e)},h=function(){return Array.from(w.keys())},d=function(e){y.add(e)},f=function(e){y.delete(e)},p=function(){return Array.from(y.keys())}}else{var b={},_={},x=function(e){return"."+e},E=function(e){return parseInt(e.substr(1),10)};l=function(e,t){var n=x(e);b[n]=t},c=function(e){var t=x(e);return b[t]},u=function(e){var t=x(e);delete b[t]},h=function(){return Object.keys(b).map(E)},d=function(e){var t=x(e);_[t]=!0},f=function(e){var t=x(e);delete _[t]},p=function(){return Object.keys(_).map(E)}}var C=[],k={onSetChildren:function(e,t){var n=c(e);n?void 0:m("144"),n.childIDs=t;for(var r=0;r<t.length;r++){var i=t[r],a=c(i);a?void 0:m("140"),null==a.childIDs&&"object"==typeof a.element&&null!=a.element?m("141"):void 0,a.isMounted?void 0:m("71"),null==a.parentID&&(a.parentID=e),a.parentID!==e?m("142",i,a.parentID,e):void 0}},onBeforeMountComponent:function(e,t,n){var r={element:t,parentID:n,text:null,childIDs:[],isMounted:!1,updateCount:0};l(e,r)},onBeforeUpdateComponent:function(e,t){var n=c(e);n&&n.isMounted&&(n.element=t)},onMountComponent:function(e){var t=c(e);t?void 0:m("144"),t.isMounted=!0;var n=0===t.parentID;n&&d(e)},onUpdateComponent:function(e){var t=c(e);t&&t.isMounted&&t.updateCount++},onUnmountComponent:function(e){var t=c(e);if(t){t.isMounted=!1;var n=0===t.parentID;n&&f(e)}C.push(e)},purgeUnmountedComponents:function(){if(!k._preventPurging){for(var e=0;e<C.length;e++){var t=C[e];i(t)}C.length=0}},isMounted:function(e){var t=c(e);return!!t&&t.isMounted},getCurrentStackAddendum:function(e){var t="";if(e){var n=o(e),r=e._owner;t+=a(n,e._source,r&&r.getName())}var i=g.current,s=i&&i._debugID;return t+=k.getStackAddendumByID(s)},getStackAddendumByID:function(e){for(var t="";e;)t+=s(e),e=k.getParentID(e);return t},getChildIDs:function(e){var t=c(e);return t?t.childIDs:[]},getDisplayName:function(e){var t=k.getElement(e);return t?o(t):null},getElement:function(e){var t=c(e);return t?t.element:null},getOwnerID:function(e){var t=k.getElement(e);return t&&t._owner?t._owner._debugID:null},getParentID:function(e){var t=c(e);return t?t.parentID:null},getSource:function(e){var t=c(e),n=t?t.element:null,r=null!=n?n._source:null;return r},getText:function(e){var t=k.getElement(e);return"string"==typeof t?t:"number"==typeof t?""+t:null},getUpdateCount:function(e){var t=c(e);return t?t.updateCount:0},getRootIDs:p,getRegisteredIDs:h};e.exports=k},function(e,t,n){"use strict";var r="function"==typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103;e.exports=r},function(e,t,n){"use strict";var r={};e.exports=r},function(e,t,n){"use strict";var r=!1;e.exports=r},function(e,t,n){"use strict";function r(e){var t=e&&(i&&e[i]||e[a]);if("function"==typeof t)return t}var i="function"==typeof Symbol&&Symbol.iterator,a="@@iterator";e.exports=r},function(e,t,n){"use strict";var r=n(4),i=n(232),a=n(109);"undefined"!=typeof document&&i.render(r.createElement(a,null),document.getElementById("article")),e.exports={FullArticle:a}},function(e,t){e.exports=function(){}},function(e,t){e.exports=function(e,t,n,r,i,a,o){var s,l,c,u,h=n.length,d=n[0].length;if(t<1)throw new Error("degree must be at least 1 (linear)");if(t>h-1)throw new Error("degree must be less than or equal to point count - 1");if(!i)for(i=[],s=0;s<h;s++)i[s]=1;if(r){if(r.length!==h+t+1)throw new Error("bad knot vector length")}else{var r=[];for(s=0;s<h+t+1;s++)r[s]=s}var f=[t,r.length-1-t],p=r[f[0]],m=r[f[1]];if(o||(e=e*(m-p)+p),e<p||e>m)throw new Error("out of bounds");for(c=f[0];c<f[1]&&!(e>=r[c]&&e<=r[c+1]);c++);var g=[];for(s=0;s<h;s++){for(g[s]=[],l=0;l<d;l++)g[s][l]=n[s][l]*i[s];g[s][d]=i[s]}var v;for(u=1;u<=t+1;u++)for(s=c;s>c-t-1+u;s--)for(v=(e-r[s])/(r[s+t+1-u]-r[s]),l=0;l<d+1;l++)g[s][l]=(1-v)*g[s-1][l]+v*g[s][l];var a=a||[];for(s=0;s<d;s++)a[s]=g[c][s]/g[c][d];return a}},function(e,t,n){var r,i,a=new function(o){var s=new function(){function e(e,t,n,i,a){function o(r,o){o=o||(o=c(t,r))&&(o.get?o:o.value),"string"==typeof o&&"#"===o[0]&&(o=e[o.substring(1)]||o);var u,d="function"==typeof o,f=o,p=a||d&&!o.base?o&&o.get?r in e:e[r]:null;a&&p||(d&&p&&(o.base=p),d&&i!==!1&&(u=r.match(/^([gs]et|is)(([A-Z])(.*))$/))&&(l[u[3].toLowerCase()+u[4]]=u[2]),f&&!d&&f.get&&"function"==typeof f.get&&s.isPlainObject(f)||(f={value:f,writable:!0}),(c(e,r)||{configurable:!0}).configurable&&(f.configurable=!0,f.enumerable=n),h(e,r,f))}var l={};if(t){for(var u in t)t.hasOwnProperty(u)&&!r.test(u)&&o(u);for(var u in l){var d=l[u],f=e["set"+d],p=e["get"+d]||f&&e["is"+d];!p||i!==!0&&0!==p.length||o(u,{get:p,set:f})}}return e}function t(e,t,n){return e&&("length"in e&&!e.getLength&&"number"==typeof e.length?i:a).call(e,t,n=n||e),n}function n(e,t,n){for(var r in t)!t.hasOwnProperty(r)||n&&n[r]||(e[r]=t[r]);return e}var r=/^(statics|enumerable|beans|preserve)$/,i=[].forEach||function(e,t){for(var n=0,r=this.length;n<r;n++)e.call(t,this[n],n,this)},a=function(e,t){for(var n in this)this.hasOwnProperty(n)&&e.call(t,this[n],n,this)},l=Object.create||function(e){return{__proto__:e}},c=Object.getOwnPropertyDescriptor||function(e,t){var n=e.__lookupGetter__&&e.__lookupGetter__(t);return n?{get:n,set:e.__lookupSetter__(t),enumerable:!0,configurable:!0}:e.hasOwnProperty(t)?{value:e[t],enumerable:!0,configurable:!0,writable:!0}:null},u=Object.defineProperty||function(e,t,n){return(n.get||n.set)&&e.__defineGetter__?(n.get&&e.__defineGetter__(t,n.get),n.set&&e.__defineSetter__(t,n.set)):e[t]=n.value,e},h=function(e,t,n){return delete e[t],u(e,t,n)};return e(function(){for(var e=0,t=arguments.length;e<t;e++)n(this,arguments[e])},{inject:function(t){if(t){var n=t.statics===!0?t:t.statics,r=t.beans,i=t.preserve;n!==t&&e(this.prototype,t,t.enumerable,r,i),e(this,n,!0,r,i)}for(var a=1,o=arguments.length;a<o;a++)this.inject(arguments[a]);return this},extend:function(){for(var t,n,r=this,i=0,a=arguments.length;i<a&&!(t=arguments[i].initialize);i++);return t=t||function(){r.apply(this,arguments)},n=t.prototype=l(this.prototype),h(n,"constructor",{value:t,writable:!0,configurable:!0}),e(t,this,!0),arguments.length&&this.inject.apply(t,arguments),t.base=r,t}},!0).inject({inject:function(){for(var t=0,n=arguments.length;t<n;t++){var r=arguments[t];r&&e(this,r,r.enumerable,r.beans,r.preserve)}return this},extend:function(){var e=l(this);return e.inject.apply(e,arguments)},each:function(e,n){return t(this,e,n)},set:function(e){return n(this,e)},clone:function(){return new this.constructor(this)},statics:{each:t,create:l,define:h,describe:c,set:n,clone:function(e){return n(new e.constructor,e)},isPlainObject:function(e){var t=null!=e&&e.constructor;return t&&(t===Object||t===s||"Object"===t.name)},pick:function(e,t){return e!==o?e:t}}})};e.exports=s,s.inject({toString:function(){return null!=this._id?(this._class||"Object")+(this._name?" '"+this._name+"'":" @"+this._id):"{ "+s.each(this,function(e,t){if(!/^_/.test(t)){var n=typeof e;this.push(t+": "+("number"===n?h.instance.number(e):"string"===n?"'"+e+"'":e))}},[]).join(", ")+" }"},getClassName:function(){return this._class||""},exportJSON:function(e){return s.exportJSON(this,e)},toJSON:function(){return s.serialize(this)},_set:function(e,t,n){if(e&&(n||s.isPlainObject(e))){for(var r=Object.keys(e._filtering||e),i=0,a=r.length;i<a;i++){var l=r[i];if(!t||!t[l]){var c=e[l];c!==o&&(this[l]=c)}}return!0}},statics:{exports:{enumerable:!0},extend:function e(){var t=e.base.apply(this,arguments),n=t.prototype._class;return n&&!s.exports[n]&&(s.exports[n]=t),t},equals:function(e,t){if(e===t)return!0;if(e&&e.equals)return e.equals(t);if(t&&t.equals)return t.equals(e);if(e&&t&&"object"==typeof e&&"object"==typeof t){if(Array.isArray(e)&&Array.isArray(t)){var n=e.length;if(n!==t.length)return!1;for(;n--;)if(!s.equals(e[n],t[n]))return!1}else{var r=Object.keys(e),n=r.length;if(n!==Object.keys(t).length)return!1;for(;n--;){var i=r[n];if(!t.hasOwnProperty(i)||!s.equals(e[i],t[i]))return!1}}return!0}return!1},read:function(e,t,n,r){if(this===s){var i=this.peek(e,t);return e.__index++,i}var a=this.prototype,l=a._readIndex,c=t||l&&e.__index||0;r||(r=e.length-c);var u=e[c];return u instanceof this||n&&n.readNull&&null==u&&r<=1?(l&&(e.__index=c+1),u&&n&&n.clone?u.clone():u):(u=s.create(this.prototype),l&&(u.__read=!0),u=u.initialize.apply(u,c>0||r<e.length?Array.prototype.slice.call(e,c,c+r):e)||u,l&&(e.__index=c+u.__read,u.__read=o),u)},peek:function(e,t){return e[e.__index=t||e.__index||0]},remain:function(e){return e.length-(e.__index||0)},readAll:function(e,t,n){for(var r,i=[],a=t||0,o=e.length;a<o;a++)i.push(Array.isArray(r=e[a])?this.read(r,0,n):this.read(e,a,n,1));return i},readNamed:function(e,t,n,r,i){var a=this.getNamed(e,t),l=a!==o;if(l){var c=e._filtered;c||(c=e._filtered=s.create(e[0]),c._filtering=e[0]),c[t]=o}return this.read(l?[a]:e,n,r,i)},getNamed:function(e,t){var n=e[0];if(e._hasObject===o&&(e._hasObject=1===e.length&&s.isPlainObject(n)),e._hasObject)return t?n[t]:e._filtered||n},hasNamed:function(e,t){return!!this.getNamed(e,t)},isPlainValue:function(e,t){return this.isPlainObject(e)||Array.isArray(e)||t&&"string"==typeof e},serialize:function(e,t,n,r){t=t||{};var i,a=!r;if(a&&(t.formatter=new h(t.precision),r={length:0,definitions:{},references:{},add:function(e,t){var n="#"+e._id,r=this.references[n];if(!r){this.length++;var i=t.call(e),a=e._class;a&&i[0]!==a&&i.unshift(a),this.definitions[n]=i,r=this.references[n]=[n]}return r}}),e&&e._serialize){i=e._serialize(t,r);var o=e._class;!o||n||i._compact||i[0]===o||i.unshift(o)}else if(Array.isArray(e)){i=[];for(var l=0,c=e.length;l<c;l++)i[l]=s.serialize(e[l],t,n,r);n&&(i._compact=!0)}else if(s.isPlainObject(e)){i={};for(var u=Object.keys(e),l=0,c=u.length;l<c;l++){var d=u[l];i[d]=s.serialize(e[d],t,n,r)}}else i="number"==typeof e?t.formatter.number(e,t.precision):e;return a&&r.length>0?[["dictionary",r.definitions],i]:i},deserialize:function(e,t,n,r){var i=e,a=!n;if(n=n||{},Array.isArray(e)){var o=e[0],l="dictionary"===o;if(1==e.length&&/^#/.test(o))return n.dictionary[o];o=s.exports[o],i=[],r&&(n.dictionary=i);for(var c=o?1:0,u=e.length;c<u;c++)i.push(s.deserialize(e[c],t,n,l));if(o){var h=i;t?i=t(o,h):(i=s.create(o.prototype),o.apply(i,h))}}else if(s.isPlainObject(e)){i={},r&&(n.dictionary=i);for(var d in e)i[d]=s.deserialize(e[d],t,n)}return a&&e&&e.length&&"dictionary"===e[0][0]?i[1]:i},exportJSON:function(e,t){var n=s.serialize(e,t);return t&&t.asString===!1?n:JSON.stringify(n)},importJSON:function(e,t){return s.deserialize("string"==typeof e?JSON.parse(e):e,function(e,n){var r=t&&t.constructor===e?t:s.create(e.prototype),i=r===t;if(1===n.length&&r instanceof C&&(i||!(r instanceof S))){ +var a=n[0];s.isPlainObject(a)&&(a.insert=!1)}return e.apply(r,n),i&&(t=null),r})},splice:function(e,t,n,r){var i=t&&t.length,a=n===o;n=a?e.length:n,n>e.length&&(n=e.length);for(var s=0;s<i;s++)t[s]._index=n+s;if(a)return e.push.apply(e,t),[];var l=[n,r];t&&l.push.apply(l,t);for(var c=e.splice.apply(e,l),s=0,u=c.length;s<u;s++)c[s]._index=o;for(var s=n+i,u=e.length;s<u;s++)e[s]._index=s;return c},capitalize:function(e){return e.replace(/\b[a-z]/g,function(e){return e.toUpperCase()})},camelize:function(e){return e.replace(/-(.)/g,function(e,t){return t.toUpperCase()})},hyphenate:function(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}}});var l={on:function(e,t){if("string"!=typeof e)s.each(e,function(e,t){this.on(t,e)},this);else{var n=this._eventTypes,r=n&&n[e],i=this._callbacks=this._callbacks||{};i=i[e]=i[e]||[],i.indexOf(t)===-1&&(i.push(t),r&&r.install&&1===i.length&&r.install.call(this,e))}return this},off:function(e,t){if("string"!=typeof e)return void s.each(e,function(e,t){this.off(t,e)},this);var n,r=this._eventTypes,i=r&&r[e],a=this._callbacks&&this._callbacks[e];return a&&(!t||(n=a.indexOf(t))!==-1&&1===a.length?(i&&i.uninstall&&i.uninstall.call(this,e),delete this._callbacks[e]):n!==-1&&a.splice(n,1)),this},once:function(e,t){return this.on(e,function(){t.apply(this,arguments),this.off(e,t)})},emit:function(e,t){var n=this._callbacks&&this._callbacks[e];if(!n)return!1;var r=[].slice.call(arguments,1);n=n.slice();for(var i=0,a=n.length;i<a;i++)if(n[i].apply(this,r)===!1){t&&t.stop&&t.stop();break}return!0},responds:function(e){return!(!this._callbacks||!this._callbacks[e])},attach:"#on",detach:"#off",fire:"#emit",_installEvents:function(e){var t=this._callbacks,n=e?"install":"uninstall";for(var r in t)if(t[r].length>0){var i=this._eventTypes,a=i&&i[r],o=a&&a[n];o&&o.call(this,r)}},statics:{inject:function e(t){var n=t._events;if(n){var r={};s.each(n,function(e,n){var i="string"==typeof e,a=i?e:n,o=s.capitalize(a),l=a.substring(2).toLowerCase();r[l]=i?{}:e,a="_"+a,t["get"+o]=function(){return this[a]},t["set"+o]=function(e){var t=this[a];t&&this.off(l,t),e&&this.on(l,e),this[a]=e}}),t._eventTypes=r}return e.base.apply(this,arguments)}}},c=s.extend({_class:"PaperScope",initialize:function e(){a=this,this.settings=new s({applyMatrix:!0,handleSize:4,hitTolerance:0}),this.project=null,this.projects=[],this.tools=[],this.palettes=[],this._id=e._id++,e._scopes[this._id]=this;var t=e.prototype;if(!this.support){var n=ne.getContext(1,1);t.support={nativeDash:"setLineDash"in n||"mozDash"in n,nativeBlendModes:re.nativeModes},ne.release(n)}if(!this.browser){var r=navigator.userAgent.toLowerCase(),i=(/(win)/.exec(r)||/(mac)/.exec(r)||/(linux)/.exec(r)||[])[0],o=t.browser={platform:i};i&&(o[i]=!0),r.replace(/(opera|chrome|safari|webkit|firefox|msie|trident|atom)\/?\s*([.\d]+)(?:.*version\/([.\d]+))?(?:.*rv\:([.\d]+))?/g,function(e,t,n,r,i){if(!o.chrome){var a="opera"===t?r:n;"trident"===t&&(a=i,t="msie"),o.version=a,o.versionNumber=parseFloat(a),o.name=t,o[t]=!0}}),o.chrome&&delete o.webkit,o.atom&&delete o.chrome}},version:"0.9.25",getView:function(){return this.project&&this.project.getView()},getPaper:function(){return this},execute:function(e,t,n){a.PaperScript.execute(e,this,t,n),K.updateFocus()},install:function(e){var t=this;s.each(["project","view","tool"],function(n){s.define(e,n,{configurable:!0,get:function(){return t[n]}})});for(var n in this)!/^_/.test(n)&&this[n]&&(e[n]=this[n])},setup:function(e){return a=this,this.project=new x(e),this},activate:function(){a=this},clear:function(){for(var e=this.projects.length-1;e>=0;e--)this.projects[e].remove();for(var e=this.tools.length-1;e>=0;e--)this.tools[e].remove();for(var e=this.palettes.length-1;e>=0;e--)this.palettes[e].remove()},remove:function(){this.clear(),delete c._scopes[this._id]},statics:new function(){function e(e){return e+="Attribute",function(t,n){return t[e](n)||t[e]("data-paper-"+n)}}return{_scopes:{},_id:0,get:function(e){return this._scopes[e]||null},getAttribute:e("get"),hasAttribute:e("has")}}}),u=s.extend(l,{initialize:function(e){this._scope=a,this._index=this._scope[this._list].push(this)-1,!e&&this._scope[this._reference]||this.activate()},activate:function(){if(!this._scope)return!1;var e=this._scope[this._reference];return e&&e!==this&&e.emit("deactivate"),this._scope[this._reference]=this,this.emit("activate",e),!0},isActive:function(){return this._scope[this._reference]===this},remove:function(){return null!=this._index&&(s.splice(this._scope[this._list],null,this._index,1),this._scope[this._reference]==this&&(this._scope[this._reference]=null),this._scope=null,!0)}}),h=s.extend({initialize:function(e){this.precision=e||5,this.multiplier=Math.pow(10,this.precision)},number:function(e){return Math.round(e*this.multiplier)/this.multiplier},pair:function(e,t,n){return this.number(e)+(n||",")+this.number(t)},point:function(e,t){return this.number(e.x)+(t||",")+this.number(e.y)},size:function(e,t){return this.number(e.width)+(t||",")+this.number(e.height)},rectangle:function(e,t){return this.point(e,t)+(t||",")+this.size(e,t)}});h.instance=new h;var d=new function(){function e(e,t,n){return e<t?t:e>n?n:e}var t=[[.5773502691896257],[0,.7745966692414834],[.33998104358485626,.8611363115940526],[0,.5384693101056831,.906179845938664],[.2386191860831969,.6612093864662645,.932469514203152],[0,.4058451513773972,.7415311855993945,.9491079123427585],[.1834346424956498,.525532409916329,.7966664774136267,.9602898564975363],[0,.3242534234038089,.6133714327005904,.8360311073266358,.9681602395076261],[.14887433898163122,.4333953941292472,.6794095682990244,.8650633666889845,.9739065285171717],[0,.26954315595234496,.5190961292068118,.7301520055740494,.8870625997680953,.978228658146057],[.1252334085114689,.3678314989981802,.5873179542866175,.7699026741943047,.9041172563704749,.9815606342467192],[0,.2304583159551348,.44849275103644687,.6423493394403402,.8015780907333099,.9175983992229779,.9841830547185881],[.10805494870734367,.31911236892788974,.5152486363581541,.6872929048116855,.827201315069765,.9284348836635735,.9862838086968123],[0,.20119409399743451,.3941513470775634,.5709721726085388,.7244177313601701,.8482065834104272,.937273392400706,.9879925180204854],[.09501250983763744,.2816035507792589,.45801677765722737,.6178762444026438,.755404408355003,.8656312023878318,.9445750230732326,.9894009349916499]],n=[[1],[.8888888888888888,.5555555555555556],[.6521451548625461,.34785484513745385],[.5688888888888889,.47862867049936647,.23692688505618908],[.46791393457269104,.3607615730481386,.17132449237917036],[.4179591836734694,.3818300505051189,.27970539148927664,.1294849661688697],[.362683783378362,.31370664587788727,.22238103445337448,.10122853629037626],[.3302393550012598,.31234707704000286,.26061069640293544,.1806481606948574,.08127438836157441],[.29552422471475287,.26926671930999635,.21908636251598204,.1494513491505806,.06667134430868814],[.2729250867779006,.26280454451024665,.23319376459199048,.18629021092773426,.1255803694649046,.05566856711617366],[.24914704581340277,.2334925365383548,.20316742672306592,.16007832854334622,.10693932599531843,.04717533638651183],[.2325515532308739,.22628318026289723,.2078160475368885,.17814598076194574,.13887351021978725,.09212149983772845,.04048400476531588],[.2152638534631578,.2051984637212956,.18553839747793782,.15720316715819355,.12151857068790319,.08015808715976021,.03511946033175186],[.2025782419255613,.19843148532711158,.1861610000155622,.16626920581699392,.13957067792615432,.10715922046717194,.07036604748810812,.03075324199611727],[.1894506104550685,.18260341504492358,.16915651939500254,.14959598881657674,.12462897125553388,.09515851168249279,.062253523938647894,.027152459411754096]],r=Math.abs,i=Math.sqrt,a=Math.pow,o=1e-12,s=1.12e-16;return{TOLERANCE:1e-6,EPSILON:o,MACHINE_EPSILON:s,CURVETIME_EPSILON:4e-7,GEOMETRIC_EPSILON:2e-7,WINDING_EPSILON:2e-7,TRIGONOMETRIC_EPSILON:1e-7,CLIPPING_EPSILON:1e-7,KAPPA:4*(i(2)-1)/3,isZero:function(e){return e>=-o&&e<=o},integrate:function(e,r,i,a){for(var o=t[a-2],s=n[a-2],l=.5*(i-r),c=l+r,u=0,h=a+1>>1,d=1&a?s[u++]*e(c):0;u<h;){var f=l*o[u];d+=s[u++]*(e(c+f)+e(c-f))}return l*d},findRoot:function(e,t,n,i,a,o,s){for(var l=0;l<o;l++){var c=e(n),u=c/t(n),h=n-u;if(r(u)<s)return h;c>0?(a=n,n=h<=i?.5*(i+a):h):(i=n,n=h>=a?.5*(i+a):h)}return n},solveQuadratic:function(t,n,l,c,u,h){var d,f,p=0,m=u-o,g=h+o,v=1/0,w=n;if(n/=-2,f=n*n-t*l,0!==f&&r(f)<s){var y=a(r(t*n*l),1/3);if(y<1e-8){var b=a(10,r(Math.floor(Math.log(y)*Math.LOG10E)));isFinite(b)||(b=0),t*=b,n*=b,l*=b,f=n*n-t*l}}if(r(t)<o){if(r(w)<o)return r(l)<o?-1:0;d=-l/w}else if(f>=-s){var _=f<0?0:i(f),x=n+(n<0?-_:_);0===x?(d=l/t,v=-d):(d=x/t,v=l/x)}return isFinite(d)&&(null==u||d>m&&d<g)&&(c[p++]=null==u?d:e(d,u,h)),v!==d&&isFinite(v)&&(null==u||v>m&&v<g)&&(c[p++]=null==u?v:e(v,u,h)),p},solveCubic:function(t,n,l,c,u,h,f){var p,m,g,v=0;if(r(t)<o)t=n,m=l,g=c,p=1/0;else if(r(c)<o)m=n,g=l,p=0;else{var w,y,b,_,x,E,C,k=1+s;if(p=-(n/t)/3,C=t*p,m=C+n,g=m*p+l,b=(C+m)*p+g,y=g*p+c,_=y/t,x=a(r(_),1/3),E=_<0?-1:1,_=-b/t,x=_>0?1.3247179572*Math.max(x,i(_)):x,w=p-E*x,w!==p){do if(p=w,C=t*p,m=C+n,g=m*p+l,b=(C+m)*p+g,y=g*p+c,w=0===b?p:p-y/b/k,w===p){p=w;break}while(E*w>E*p);r(t)*p*p>r(c/p)&&(g=-c/p,m=(g-l)/p)}}var v=d.solveQuadratic(t,m,g,u,h,f);return isFinite(p)&&(0===v||p!==u[v-1])&&(null==h||p>h-o&&p<f+o)&&(u[v++]=null==h?p:e(p,h,f)),v}}},f={_id:1,_pools:{},get:function(e){if(e){var t=e._class,n=this._pools[t];return n||(n=this._pools[t]={_id:1}),n._id++}return this._id++}},p=s.extend({_class:"Point",_readIndex:!0,initialize:function(e,t){var n=typeof e;if("number"===n){var r="number"==typeof t;this.x=e,this.y=r?t:e,this.__read&&(this.__read=r?2:1)}else"undefined"===n||null===e?(this.x=this.y=0,this.__read&&(this.__read=null===e?1:0)):(Array.isArray(e)?(this.x=e[0],this.y=e.length>1?e[1]:e[0]):null!=e.x?(this.x=e.x,this.y=e.y):null!=e.width?(this.x=e.width,this.y=e.height):null!=e.angle?(this.x=e.length,this.y=0,this.setAngle(e.angle)):(this.x=this.y=0,this.__read&&(this.__read=0)),this.__read&&(this.__read=1))},set:function(e,t){return this.x=e,this.y=t,this},equals:function(e){return this===e||e&&(this.x===e.x&&this.y===e.y||Array.isArray(e)&&this.x===e[0]&&this.y===e[1])||!1},clone:function(){return new p(this.x,this.y)},toString:function(){var e=h.instance;return"{ x: "+e.number(this.x)+", y: "+e.number(this.y)+" }"},_serialize:function(e){var t=e.formatter;return[t.number(this.x),t.number(this.y)]},getLength:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},setLength:function(e){if(this.isZero()){var t=this._angle||0;this.set(Math.cos(t)*e,Math.sin(t)*e)}else{var n=e/this.getLength();d.isZero(n)&&this.getAngle(),this.set(this.x*n,this.y*n)}},getAngle:function(){return 180*this.getAngleInRadians.apply(this,arguments)/Math.PI},setAngle:function(e){this.setAngleInRadians.call(this,e*Math.PI/180)},getAngleInDegrees:"#getAngle",setAngleInDegrees:"#setAngle",getAngleInRadians:function(){if(arguments.length){var e=p.read(arguments),t=this.getLength()*e.getLength();if(d.isZero(t))return NaN;var n=this.dot(e)/t;return Math.acos(n<-1?-1:n>1?1:n)}return this.isZero()?this._angle||0:this._angle=Math.atan2(this.y,this.x)},setAngleInRadians:function(e){if(this._angle=e,!this.isZero()){var t=this.getLength();this.set(Math.cos(e)*t,Math.sin(e)*t)}},getQuadrant:function(){return this.x>=0?this.y>=0?1:4:this.y>=0?2:3}},{beans:!1,getDirectedAngle:function(){var e=p.read(arguments);return 180*Math.atan2(this.cross(e),this.dot(e))/Math.PI},getDistance:function(){var e=p.read(arguments),t=e.x-this.x,n=e.y-this.y,r=t*t+n*n,i=s.read(arguments);return i?r:Math.sqrt(r)},normalize:function(e){e===o&&(e=1);var t=this.getLength(),n=0!==t?e/t:0,r=new p(this.x*n,this.y*n);return n>=0&&(r._angle=this._angle),r},rotate:function(e,t){if(0===e)return this.clone();e=e*Math.PI/180;var n=t?this.subtract(t):this,r=Math.sin(e),i=Math.cos(e);return n=new p(n.x*i-n.y*r,n.x*r+n.y*i),t?n.add(t):n},transform:function(e){return e?e._transformPoint(this):this},add:function(){var e=p.read(arguments);return new p(this.x+e.x,this.y+e.y)},subtract:function(){var e=p.read(arguments);return new p(this.x-e.x,this.y-e.y)},multiply:function(){var e=p.read(arguments);return new p(this.x*e.x,this.y*e.y)},divide:function(){var e=p.read(arguments);return new p(this.x/e.x,this.y/e.y)},modulo:function(){var e=p.read(arguments);return new p(this.x%e.x,this.y%e.y)},negate:function(){return new p(-this.x,-this.y)},isInside:function(){return w.read(arguments).contains(this)},isClose:function(){var e=p.read(arguments),t=s.read(arguments);return this.getDistance(e)<t},isCollinear:function(){var e=p.read(arguments);return p.isCollinear(this.x,this.y,e.x,e.y)},isColinear:"#isCollinear",isOrthogonal:function(){var e=p.read(arguments);return p.isOrthogonal(this.x,this.y,e.x,e.y)},isZero:function(){return d.isZero(this.x)&&d.isZero(this.y)},isNaN:function(){return isNaN(this.x)||isNaN(this.y)},dot:function(){var e=p.read(arguments);return this.x*e.x+this.y*e.y},cross:function(){var e=p.read(arguments);return this.x*e.y-this.y*e.x},project:function(){var e=p.read(arguments),t=e.isZero()?0:this.dot(e)/e.dot(e);return new p(e.x*t,e.y*t)},statics:{min:function(){var e=p.read(arguments),t=p.read(arguments);return new p(Math.min(e.x,t.x),Math.min(e.y,t.y))},max:function(){var e=p.read(arguments),t=p.read(arguments);return new p(Math.max(e.x,t.x),Math.max(e.y,t.y))},random:function(){return new p(Math.random(),Math.random())},isCollinear:function(e,t,n,r){return Math.abs(e*r-t*n)<=1e-7*Math.sqrt((e*e+t*t)*(n*n+r*r))},isOrthogonal:function(e,t,n,r){return Math.abs(e*n+t*r)<=1e-7*Math.sqrt((e*e+t*t)*(n*n+r*r))}}},s.each(["round","ceil","floor","abs"],function(e){var t=Math[e];this[e]=function(){return new p(t(this.x),t(this.y))}},{})),m=p.extend({initialize:function(e,t,n,r){this._x=e,this._y=t,this._owner=n,this._setter=r},set:function(e,t,n){return this._x=e,this._y=t,n||this._owner[this._setter](this),this},getX:function(){return this._x},setX:function(e){this._x=e,this._owner[this._setter](this)},getY:function(){return this._y},setY:function(e){this._y=e,this._owner[this._setter](this)}}),g=s.extend({_class:"Size",_readIndex:!0,initialize:function(e,t){var n=typeof e;if("number"===n){var r="number"==typeof t;this.width=e,this.height=r?t:e,this.__read&&(this.__read=r?2:1)}else"undefined"===n||null===e?(this.width=this.height=0,this.__read&&(this.__read=null===e?1:0)):(Array.isArray(e)?(this.width=e[0],this.height=e.length>1?e[1]:e[0]):null!=e.width?(this.width=e.width,this.height=e.height):null!=e.x?(this.width=e.x,this.height=e.y):(this.width=this.height=0,this.__read&&(this.__read=0)),this.__read&&(this.__read=1))},set:function(e,t){return this.width=e,this.height=t,this},equals:function(e){return e===this||e&&(this.width===e.width&&this.height===e.height||Array.isArray(e)&&this.width===e[0]&&this.height===e[1])||!1},clone:function(){return new g(this.width,this.height)},toString:function(){var e=h.instance;return"{ width: "+e.number(this.width)+", height: "+e.number(this.height)+" }"},_serialize:function(e){var t=e.formatter;return[t.number(this.width),t.number(this.height)]},add:function(){var e=g.read(arguments);return new g(this.width+e.width,this.height+e.height)},subtract:function(){var e=g.read(arguments);return new g(this.width-e.width,this.height-e.height)},multiply:function(){var e=g.read(arguments);return new g(this.width*e.width,this.height*e.height)},divide:function(){var e=g.read(arguments);return new g(this.width/e.width,this.height/e.height)},modulo:function(){var e=g.read(arguments);return new g(this.width%e.width,this.height%e.height)},negate:function(){return new g(-this.width,-this.height)},isZero:function(){return d.isZero(this.width)&&d.isZero(this.height)},isNaN:function(){return isNaN(this.width)||isNaN(this.height)},statics:{min:function(e,t){return new g(Math.min(e.width,t.width),Math.min(e.height,t.height))},max:function(e,t){return new g(Math.max(e.width,t.width),Math.max(e.height,t.height))},random:function(){return new g(Math.random(),Math.random())}}},s.each(["round","ceil","floor","abs"],function(e){var t=Math[e];this[e]=function(){return new g(t(this.width),t(this.height))}},{})),v=g.extend({initialize:function(e,t,n,r){this._width=e,this._height=t,this._owner=n,this._setter=r},set:function(e,t,n){return this._width=e,this._height=t,n||this._owner[this._setter](this),this},getWidth:function(){return this._width},setWidth:function(e){this._width=e,this._owner[this._setter](this)},getHeight:function(){return this._height},setHeight:function(e){this._height=e,this._owner[this._setter](this)}}),w=s.extend({_class:"Rectangle",_readIndex:!0,beans:!0,initialize:function(e,t,n,r){var i=typeof e,a=0;if("number"===i?(this.x=e,this.y=t,this.width=n,this.height=r,a=4):"undefined"===i||null===e?(this.x=this.y=this.width=this.height=0,a=null===e?1:0):1===arguments.length&&(Array.isArray(e)?(this.x=e[0],this.y=e[1],this.width=e[2],this.height=e[3],a=1):e.x!==o||e.width!==o?(this.x=e.x||0,this.y=e.y||0,this.width=e.width||0,this.height=e.height||0,a=1):e.from===o&&e.to===o&&(this.x=this.y=this.width=this.height=0,this._set(e),a=1)),!a){var l=p.readNamed(arguments,"from"),c=s.peek(arguments);if(this.x=l.x,this.y=l.y,c&&c.x!==o||s.hasNamed(arguments,"to")){var u=p.readNamed(arguments,"to");this.width=u.x-l.x,this.height=u.y-l.y,this.width<0&&(this.x=u.x,this.width=-this.width),this.height<0&&(this.y=u.y,this.height=-this.height)}else{var h=g.read(arguments);this.width=h.width,this.height=h.height}a=arguments.__index}this.__read&&(this.__read=a)},set:function(e,t,n,r){return this.x=e,this.y=t,this.width=n,this.height=r,this},clone:function(){return new w(this.x,this.y,this.width,this.height)},equals:function(e){var t=s.isPlainValue(e)?w.read(arguments):e;return t===this||t&&this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height||!1},toString:function(){var e=h.instance;return"{ x: "+e.number(this.x)+", y: "+e.number(this.y)+", width: "+e.number(this.width)+", height: "+e.number(this.height)+" }"},_serialize:function(e){var t=e.formatter;return[t.number(this.x),t.number(this.y),t.number(this.width),t.number(this.height)]},getPoint:function(e){var t=e?p:m;return new t(this.x,this.y,this,"setPoint")},setPoint:function(){var e=p.read(arguments);this.x=e.x,this.y=e.y},getSize:function(e){var t=e?g:v;return new t(this.width,this.height,this,"setSize")},setSize:function(){var e=g.read(arguments);this._fixX&&(this.x+=(this.width-e.width)*this._fixX),this._fixY&&(this.y+=(this.height-e.height)*this._fixY),this.width=e.width,this.height=e.height,this._fixW=1,this._fixH=1},getLeft:function(){return this.x},setLeft:function(e){this._fixW||(this.width-=e-this.x),this.x=e,this._fixX=0},getTop:function(){return this.y},setTop:function(e){this._fixH||(this.height-=e-this.y),this.y=e,this._fixY=0},getRight:function(){return this.x+this.width},setRight:function(e){this._fixX!==o&&1!==this._fixX&&(this._fixW=0),this._fixW?this.x=e-this.width:this.width=e-this.x,this._fixX=1},getBottom:function(){return this.y+this.height},setBottom:function(e){this._fixY!==o&&1!==this._fixY&&(this._fixH=0),this._fixH?this.y=e-this.height:this.height=e-this.y,this._fixY=1},getCenterX:function(){return this.x+.5*this.width},setCenterX:function(e){this.x=e-.5*this.width,this._fixX=.5},getCenterY:function(){return this.y+.5*this.height},setCenterY:function(e){this.y=e-.5*this.height,this._fixY=.5},getCenter:function(e){var t=e?p:m;return new t(this.getCenterX(),this.getCenterY(),this,"setCenter")},setCenter:function(){var e=p.read(arguments);return this.setCenterX(e.x),this.setCenterY(e.y),this},getArea:function(){return this.width*this.height},isEmpty:function(){return 0===this.width||0===this.height},contains:function(e){return e&&e.width!==o||4==(Array.isArray(e)?e:arguments).length?this._containsRectangle(w.read(arguments)):this._containsPoint(p.read(arguments))},_containsPoint:function(e){var t=e.x,n=e.y;return t>=this.x&&n>=this.y&&t<=this.x+this.width&&n<=this.y+this.height},_containsRectangle:function(e){var t=e.x,n=e.y;return t>=this.x&&n>=this.y&&t+e.width<=this.x+this.width&&n+e.height<=this.y+this.height},intersects:function(){var e=w.read(arguments);return e.x+e.width>this.x&&e.y+e.height>this.y&&e.x<this.x+this.width&&e.y<this.y+this.height},touches:function(){var e=w.read(arguments);return e.x+e.width>=this.x&&e.y+e.height>=this.y&&e.x<=this.x+this.width&&e.y<=this.y+this.height},intersect:function(){var e=w.read(arguments),t=Math.max(this.x,e.x),n=Math.max(this.y,e.y),r=Math.min(this.x+this.width,e.x+e.width),i=Math.min(this.y+this.height,e.y+e.height);return new w(t,n,r-t,i-n)},unite:function(){var e=w.read(arguments),t=Math.min(this.x,e.x),n=Math.min(this.y,e.y),r=Math.max(this.x+this.width,e.x+e.width),i=Math.max(this.y+this.height,e.y+e.height);return new w(t,n,r-t,i-n)},include:function(){var e=p.read(arguments),t=Math.min(this.x,e.x),n=Math.min(this.y,e.y),r=Math.max(this.x+this.width,e.x),i=Math.max(this.y+this.height,e.y);return new w(t,n,r-t,i-n)},expand:function(){var e=g.read(arguments),t=e.width,n=e.height;return new w(this.x-t/2,this.y-n/2,this.width+t,this.height+n)},scale:function(e,t){return this.expand(this.width*e-this.width,this.height*(t===o?e:t)-this.height)}},s.each([["Top","Left"],["Top","Right"],["Bottom","Left"],["Bottom","Right"],["Left","Center"],["Top","Center"],["Right","Center"],["Bottom","Center"]],function(e,t){var n=e.join(""),r=/^[RL]/.test(n);t>=4&&(e[1]+=r?"Y":"X");var i=e[r?0:1],a=e[r?1:0],o="get"+i,s="get"+a,l="set"+i,c="set"+a,u="get"+n,h="set"+n;this[u]=function(e){var t=e?p:m;return new t(this[o](),this[s](),this,h)},this[h]=function(){var e=p.read(arguments);this[l](e.x),this[c](e.y)}},{beans:!0})),y=w.extend({initialize:function(e,t,n,r,i,a){this.set(e,t,n,r,!0),this._owner=i,this._setter=a},set:function(e,t,n,r,i){return this._x=e,this._y=t,this._width=n,this._height=r,i||this._owner[this._setter](this),this}},new function(){var e=w.prototype;return s.each(["x","y","width","height"],function(e){var t=s.capitalize(e),n="_"+e;this["get"+t]=function(){return this[n]},this["set"+t]=function(e){this[n]=e,this._dontNotify||this._owner[this._setter](this)}},s.each(["Point","Size","Center","Left","Top","Right","Bottom","CenterX","CenterY","TopLeft","TopRight","BottomLeft","BottomRight","LeftCenter","TopCenter","RightCenter","BottomCenter"],function(t){var n="set"+t;this[n]=function(){this._dontNotify=!0,e[n].apply(this,arguments),this._dontNotify=!1,this._owner[this._setter](this)}},{isSelected:function(){return this._owner._boundsSelected},setSelected:function(e){var t=this._owner;t.setSelected&&(t._boundsSelected=e,t.setSelected(e||t._selectedSegmentState>0))}}))}),b=s.extend({_class:"Matrix",initialize:function e(t){var n=arguments.length,r=!0;if(6===n?this.set.apply(this,arguments):1===n?t instanceof e?this.set(t._a,t._c,t._b,t._d,t._tx,t._ty):Array.isArray(t)?this.set.apply(this,t):r=!1:0===n?this.reset():r=!1,!r)throw new Error("Unsupported matrix parameters")},set:function(e,t,n,r,i,a,o){return this._a=e,this._c=t,this._b=n,this._d=r,this._tx=i,this._ty=a,o||this._changed(),this},_serialize:function(e){return s.serialize(this.getValues(),e)},_changed:function(){var e=this._owner;e&&(e._applyMatrix?e.transform(null,!0):e._changed(9))},clone:function(){return new b(this._a,this._c,this._b,this._d,this._tx,this._ty)},equals:function(e){return e===this||e&&this._a===e._a&&this._b===e._b&&this._c===e._c&&this._d===e._d&&this._tx===e._tx&&this._ty===e._ty||!1},toString:function(){var e=h.instance;return"[["+[e.number(this._a),e.number(this._b),e.number(this._tx)].join(", ")+"], ["+[e.number(this._c),e.number(this._d),e.number(this._ty)].join(", ")+"]]"},reset:function(e){return this._a=this._d=1,this._c=this._b=this._tx=this._ty=0,e||this._changed(),this},apply:function(e,t){var n=this._owner;return!!n&&(n.transform(null,!0,s.pick(e,!0),t),this.isIdentity())},translate:function(){var e=p.read(arguments),t=e.x,n=e.y;return this._tx+=t*this._a+n*this._b,this._ty+=t*this._c+n*this._d,this._changed(),this},scale:function(){var e=p.read(arguments),t=p.read(arguments,0,{readNull:!0});return t&&this.translate(t),this._a*=e.x,this._c*=e.x,this._b*=e.y,this._d*=e.y,t&&this.translate(t.negate()),this._changed(),this},rotate:function(e){e*=Math.PI/180;var t=p.read(arguments,1),n=t.x,r=t.y,i=Math.cos(e),a=Math.sin(e),o=n-n*i+r*a,s=r-n*a-r*i,l=this._a,c=this._b,u=this._c,h=this._d;return this._a=i*l+a*c,this._b=-a*l+i*c,this._c=i*u+a*h,this._d=-a*u+i*h,this._tx+=o*l+s*c,this._ty+=o*u+s*h,this._changed(),this},shear:function(){var e=p.read(arguments),t=p.read(arguments,0,{readNull:!0});t&&this.translate(t);var n=this._a,r=this._c;return this._a+=e.y*this._b,this._c+=e.y*this._d,this._b+=e.x*n,this._d+=e.x*r,t&&this.translate(t.negate()),this._changed(),this},skew:function(){var e=p.read(arguments),t=p.read(arguments,0,{readNull:!0}),n=Math.PI/180,r=new p(Math.tan(e.x*n),Math.tan(e.y*n));return this.shear(r,t)},concatenate:function(e){var t=this._a,n=this._b,r=this._c,i=this._d,a=e._a,o=e._b,s=e._c,l=e._d,c=e._tx,u=e._ty;return this._a=a*t+s*n,this._b=o*t+l*n,this._c=a*r+s*i,this._d=o*r+l*i,this._tx+=c*t+u*n,this._ty+=c*r+u*i,this._changed(),this},preConcatenate:function(e){var t=this._a,n=this._b,r=this._c,i=this._d,a=this._tx,o=this._ty,s=e._a,l=e._b,c=e._c,u=e._d,h=e._tx,d=e._ty;return this._a=s*t+l*r,this._b=s*n+l*i,this._c=c*t+u*r,this._d=c*n+u*i,this._tx=s*a+l*o+h,this._ty=c*a+u*o+d,this._changed(),this},chain:function(e){var t=this._a,n=this._b,r=this._c,i=this._d,a=this._tx,o=this._ty,s=e._a,l=e._b,c=e._c,u=e._d,h=e._tx,d=e._ty;return new b(s*t+c*n,s*r+c*i,l*t+u*n,l*r+u*i,a+h*t+d*n,o+h*r+d*i)},isIdentity:function(){return 1===this._a&&0===this._c&&0===this._b&&1===this._d&&0===this._tx&&0===this._ty},orNullIfIdentity:function(){return this.isIdentity()?null:this},isInvertible:function(){return!!this._getDeterminant()},isSingular:function(){return!this._getDeterminant()},transform:function(e,t,n){return arguments.length<3?this._transformPoint(p.read(arguments)):this._transformCoordinates(e,t,n)},_transformPoint:function(e,t,n){var r=e.x,i=e.y;return t||(t=new p),t.set(r*this._a+i*this._b+this._tx,r*this._c+i*this._d+this._ty,n)},_transformCoordinates:function(e,t,n){for(var r=0,i=0,a=2*n;r<a;){var o=e[r++],s=e[r++];t[i++]=o*this._a+s*this._b+this._tx,t[i++]=o*this._c+s*this._d+this._ty}return t},_transformCorners:function(e){var t=e.x,n=e.y,r=t+e.width,i=n+e.height,a=[t,n,r,n,r,i,t,i];return this._transformCoordinates(a,a,4)},_transformBounds:function(e,t,n){for(var r=this._transformCorners(e),i=r.slice(0,2),a=i.slice(),o=2;o<8;o++){var s=r[o],l=1&o;s<i[l]?i[l]=s:s>a[l]&&(a[l]=s)}return t||(t=new w),t.set(i[0],i[1],a[0]-i[0],a[1]-i[1],n)},inverseTransform:function(){return this._inverseTransform(p.read(arguments))},_getDeterminant:function(){var e=this._a*this._d-this._b*this._c;return isFinite(e)&&!d.isZero(e)&&isFinite(this._tx)&&isFinite(this._ty)?e:null},_inverseTransform:function(e,t,n){var r=this._getDeterminant();if(!r)return null;var i=e.x-this._tx,a=e.y-this._ty;return t||(t=new p),t.set((i*this._d-a*this._b)/r,(a*this._a-i*this._c)/r,n)},decompose:function(){var e=this._a,t=this._b,n=this._c,r=this._d;if(d.isZero(e*r-t*n))return null;var i=Math.sqrt(e*e+t*t);e/=i,t/=i;var a=e*n+t*r;n-=e*a,r-=t*a;var o=Math.sqrt(n*n+r*r);return n/=o,r/=o,a/=o,e*r<t*n&&(e=-e,t=-t,a=-a,i=-i),{scaling:new p(i,o),rotation:180*-Math.atan2(t,e)/Math.PI,shearing:a}},getValues:function(){return[this._a,this._c,this._b,this._d,this._tx,this._ty]},getTranslation:function(){return new p(this._tx,this._ty)},getScaling:function(){return(this.decompose()||{}).scaling},getRotation:function(){return(this.decompose()||{}).rotation},inverted:function(){var e=this._getDeterminant();return e&&new b(this._d/e,-this._c/e,-this._b/e,this._a/e,(this._b*this._ty-this._d*this._tx)/e,(this._c*this._tx-this._a*this._ty)/e)},shiftless:function(){return new b(this._a,this._c,this._b,this._d,0,0)},applyToContext:function(e){e.transform(this._a,this._c,this._b,this._d,this._tx,this._ty)}},s.each(["a","c","b","d","tx","ty"],function(e){var t=s.capitalize(e),n="_"+e;this["get"+t]=function(){return this[n]},this["set"+t]=function(e){this[n]=e,this._changed()}},{})),_=s.extend({_class:"Line",initialize:function(e,t,n,r,i){var a=!1;arguments.length>=4?(this._px=e,this._py=t,this._vx=n,this._vy=r,a=i):(this._px=e.x,this._py=e.y,this._vx=t.x,this._vy=t.y,a=n),a||(this._vx-=this._px,this._vy-=this._py)},getPoint:function(){return new p(this._px,this._py)},getVector:function(){return new p(this._vx,this._vy)},getLength:function(){return this.getVector().getLength()},intersect:function(e,t){return _.intersect(this._px,this._py,this._vx,this._vy,e._px,e._py,e._vx,e._vy,!0,t)},getSide:function(e,t){return _.getSide(this._px,this._py,this._vx,this._vy,e.x,e.y,!0,t)},getDistance:function(e){return Math.abs(_.getSignedDistance(this._px,this._py,this._vx,this._vy,e.x,e.y,!0))},isCollinear:function(e){return p.isCollinear(this._vx,this._vy,e._vx,e._vy)},isOrthogonal:function(e){return p.isOrthogonal(this._vx,this._vy,e._vx,e._vy)},statics:{intersect:function(e,t,n,r,i,a,o,s,l,c){l||(n-=e,r-=t,o-=i,s-=a);var u=n*s-r*o;if(!d.isZero(u)){var h=e-i,f=t-a,m=(o*f-s*h)/u,g=(n*f-r*h)/u,v=1e-12,w=-v,y=1+v;if(c||w<m&&m<y&&w<g&&g<y)return c||(m=m<=0?0:m>=1?1:m),new p(e+m*n,t+m*r)}},getSide:function(e,t,n,r,i,a,o,s){o||(n-=e,r-=t);var l=i-e,c=a-t,u=l*r-c*n;return 0!==u||s||(u=(l*n+l*n)/(n*n+r*r),u>=0&&u<=1&&(u=0)),u<0?-1:u>0?1:0},getSignedDistance:function(e,t,n,r,i,a,o){return o||(n-=e,r-=t),0===n?r>0?i-e:e-i:0===r?n<0?a-t:t-a:((i-e)*r-(a-t)*n)/Math.sqrt(n*n+r*r)}}}),x=u.extend({_class:"Project",_list:"projects",_reference:"project",initialize:function(e){u.call(this,!0),this.layers=[],this._activeLayer=null,this.symbols=[],this._currentStyle=new G(null,null,this),this._view=K.create(this,e||ne.getCanvas(1,1)),this._selectedItems={},this._selectedItemCount=0,this._updateVersion=0},_serialize:function(e,t){return s.serialize(this.layers,e,!0,t)},clear:function(){for(var e=this.layers.length-1;e>=0;e--)this.layers[e].remove();this.symbols=[]},isEmpty:function(){return 0===this.layers.length},remove:function e(){return!!e.base.call(this)&&(this._view&&this._view.remove(),!0)},getView:function(){return this._view},getCurrentStyle:function(){return this._currentStyle},setCurrentStyle:function(e){this._currentStyle.initialize(e)},getIndex:function(){return this._index},getOptions:function(){return this._scope.settings},getActiveLayer:function(){return this._activeLayer||new S({project:this})},getSelectedItems:function(){var e=[];for(var t in this._selectedItems){var n=this._selectedItems[t];n.isInserted()&&e.push(n)}return e},insertChild:function(e,t,n){return t instanceof S?(t._remove(!1,!0),s.splice(this.layers,[t],e,0),t._setProject(this,!0),this._changes&&t._changed(5),this._activeLayer||(this._activeLayer=t)):t instanceof C?(this._activeLayer||this.insertChild(e,new S(C.NO_INSERT))).insertChild(e,t,n):t=null,t},addChild:function(e,t){return this.insertChild(o,e,t)},_updateSelection:function(e){var t=e._id,n=this._selectedItems;e._selected?n[t]!==e&&(this._selectedItemCount++,n[t]=e):n[t]===e&&(this._selectedItemCount--,delete n[t])},selectAll:function(){for(var e=this.layers,t=0,n=e.length;t<n;t++)e[t].setFullySelected(!0)},deselectAll:function(){var e=this._selectedItems;for(var t in e)e[t].setFullySelected(!1)},hitTest:function(){for(var e=p.read(arguments),t=N.getOptions(s.read(arguments)),n=this.layers.length-1;n>=0;n--){var r=this.layers[n]._hitTest(e,t);if(r)return r}return null},getItems:function(e){return C._getItems(this.layers,e)},getItem:function(e){return C._getItems(this.layers,e,null,null,!0)[0]||null},importJSON:function(e){this.activate();var t=this._activeLayer;return s.importJSON(e,t&&t.isEmpty()&&t)},draw:function(e,t,n){this._updateVersion++,e.save(),t.applyToContext(e);for(var r=new s({ +offset:new p(0,0),pixelRatio:n,viewMatrix:t.isIdentity()?null:t,matrices:[new b],updateMatrix:!0}),i=0,a=this.layers,o=a.length;i<o;i++)a[i].draw(e,r);if(e.restore(),this._selectedItemCount>0){e.save(),e.strokeWidth=1;var l=this._selectedItems,c=this._scope.settings.handleSize,u=this._updateVersion;for(var h in l)l[h]._drawSelection(e,t,c,l,u);e.restore()}}}),E=s.extend({_class:"Symbol",initialize:function(e,t){this._id=f.get(),this.project=a.project,this.project.symbols.push(this),e&&this.setDefinition(e,t)},_serialize:function(e,t){return t.add(this,function(){return s.serialize([this._class,this._definition],e,!1,t)})},_changed:function(e){8&e&&C._clearBoundsCache(this),1&e&&(this.project._needsUpdate=!0)},getDefinition:function(){return this._definition},setDefinition:function(e,t){e._parentSymbol&&(e=e.clone()),this._definition&&(this._definition._parentSymbol=null),this._definition=e,e.remove(),e.setSelected(!1),t||e.setPosition(new p),e._parentSymbol=this,this._changed(9)},place:function(e){return new M(this,e)},clone:function(){return new E(this._definition.clone(!1))},equals:function(e){return e===this||e&&this.definition.equals(e.definition)||!1}}),C=s.extend(l,{statics:{extend:function e(t){return t._serializeFields&&(t._serializeFields=new s(this.prototype._serializeFields,t._serializeFields)),e.base.apply(this,arguments)},NO_INSERT:{insert:!1}},_class:"Item",_applyMatrix:!0,_canApplyMatrix:!0,_boundsSelected:!1,_selectChildren:!1,_serializeFields:{name:null,applyMatrix:null,matrix:new b,pivot:null,locked:!1,visible:!0,blendMode:"normal",opacity:1,guide:!1,selected:!1,clipMask:!1,data:{}},initialize:function(){},_initialize:function(e,t){var n=e&&s.isPlainObject(e),r=n&&e.internal===!0,i=this._matrix=new b,o=n&&e.project||a.project;return r||(this._id=f.get()),this._applyMatrix=this._canApplyMatrix&&a.settings.applyMatrix,t&&i.translate(t),i._owner=this,this._style=new G(o._currentStyle,this,o),this._project||(r||n&&e.insert===!1?this._setProject(o):n&&e.parent?this.setParent(e.parent):(o._activeLayer||new S).addChild(this)),n&&e!==C.NO_INSERT&&this._set(e,{insert:!0,project:!0,parent:!0},!0),n},_events:s.each(["onMouseDown","onMouseUp","onMouseDrag","onClick","onDoubleClick","onMouseMove","onMouseEnter","onMouseLeave"],function(e){this[e]={install:function(e){this.getView()._installEvent(e)},uninstall:function(e){this.getView()._uninstallEvent(e)}}},{onFrame:{install:function(){this.getView()._animateItem(this,!0)},uninstall:function(){this.getView()._animateItem(this,!1)}},onLoad:{}}),_serialize:function(e,t){function n(n){for(var a in n){var o=i[a];s.equals(o,"leading"===a?1.2*n.fontSize:n[a])||(r[a]=s.serialize(o,e,"data"!==a,t))}}var r={},i=this;return n(this._serializeFields),this instanceof k||n(this._style._defaults),[this._class,r]},_changed:function(e){var t=this._parentSymbol,n=this._parent||t,r=this._project;if(8&e&&(this._bounds=this._position=this._decomposed=this._globalMatrix=this._currentPath=o),n&&40&e&&C._clearBoundsCache(n),2&e&&C._clearBoundsCache(this),r&&(1&e&&(r._needsUpdate=!0),r._changes)){var i=r._changesById[this._id];i?i.flags|=e:(i={item:this,flags:e},r._changesById[this._id]=i,r._changes.push(i))}t&&t._changed(e)},set:function(e){return e&&this._set(e),this},getId:function(){return this._id},getName:function(){return this._name},setName:function(e,t){if(this._name&&this._removeNamed(),e===+e+"")throw new Error("Names consisting only of numbers are not supported.");var n=this._parent;if(e&&n){for(var r=n._children,i=n._namedChildren,a=e,s=1;t&&r[e];)e=a+" "+s++;(i[e]=i[e]||[]).push(this),r[e]=this}this._name=e||o,this._changed(128)},getStyle:function(){return this._style},setStyle:function(e){this.getStyle().set(e)}},s.each(["locked","visible","blendMode","opacity","guide"],function(e){var t=s.capitalize(e),e="_"+e;this["get"+t]=function(){return this[e]},this["set"+t]=function(t){t!=this[e]&&(this[e]=t,this._changed("_locked"===e?128:129))}},{}),{beans:!0,_locked:!1,_visible:!0,_blendMode:"normal",_opacity:1,_guide:!1,isSelected:function(){if(this._selectChildren)for(var e=this._children,t=0,n=e.length;t<n;t++)if(e[t].isSelected())return!0;return this._selected},setSelected:function(e,t){if(!t&&this._selectChildren)for(var n=this._children,r=0,i=n.length;r<i;r++)n[r].setSelected(e);(e=!!e)^this._selected&&(this._selected=e,this._project._updateSelection(this),this._changed(129))},_selected:!1,isFullySelected:function(){var e=this._children;if(e&&this._selected){for(var t=0,n=e.length;t<n;t++)if(!e[t].isFullySelected())return!1;return!0}return this._selected},setFullySelected:function(e){var t=this._children;if(t)for(var n=0,r=t.length;n<r;n++)t[n].setFullySelected(e);this.setSelected(e,!0)},isClipMask:function(){return this._clipMask},setClipMask:function(e){this._clipMask!=(e=!!e)&&(this._clipMask=e,e&&(this.setFillColor(null),this.setStrokeColor(null)),this._changed(129),this._parent&&this._parent._changed(1024))},_clipMask:!1,getData:function(){return this._data||(this._data={}),this._data},setData:function(e){this._data=e},getPosition:function(e){var t=this._position,n=e?p:m;if(!t){var r=this._pivot;t=this._position=r?this._matrix._transformPoint(r):this.getBounds().getCenter(!0)}return new n(t.x,t.y,this,"setPosition")},setPosition:function(){this.translate(p.read(arguments).subtract(this.getPosition(!0)))},getPivot:function(e){var t=this._pivot;if(t){var n=e?p:m;t=new n(t.x,t.y,this,"setPivot")}return t},setPivot:function(){this._pivot=p.read(arguments,0,{clone:!0,readNull:!0}),this._position=o},_pivot:null},s.each(["bounds","strokeBounds","handleBounds","roughBounds","internalBounds","internalRoughBounds"],function(e){var t="get"+s.capitalize(e),n=e.match(/^internal(.*)$/),r=n?"get"+n[1]:null;this[t]=function(n){var i=this._boundsGetter,a=!r&&("string"==typeof i?i:i&&i[t])||t,o=this._getCachedBounds(a,n,this,r);return"bounds"===e?new y(o.x,o.y,o.width,o.height,this,"setBounds"):o}},{beans:!0,_getBounds:function(e,t,n){var r=this._children;if(!r||0==r.length)return new w;C._updateBoundsCache(this,n);for(var i=1/0,a=-i,o=i,s=a,l=0,c=r.length;l<c;l++){var u=r[l];if(u._visible&&!u.isEmpty()){var h=u._getCachedBounds(e,t&&t.chain(u._matrix),n);i=Math.min(h.x,i),o=Math.min(h.y,o),a=Math.max(h.x+h.width,a),s=Math.max(h.y+h.height,s)}}return isFinite(i)?new w(i,o,a-i,s-o):new w},setBounds:function(){var e=w.read(arguments),t=this.getBounds(),n=new b,r=e.getCenter();n.translate(r),e.width==t.width&&e.height==t.height||n.scale(0!=t.width?e.width/t.width:1,0!=t.height?e.height/t.height:1),r=t.getCenter(),n.translate(-r.x,-r.y),this.transform(n)},_getCachedBounds:function(e,t,n,r){t=t&&t.orNullIfIdentity();var i=r?null:this._matrix.orNullIfIdentity(),a=(!t||t.equals(i))&&e;if(C._updateBoundsCache(this._parent||this._parentSymbol,n),a&&this._bounds&&this._bounds[a])return this._bounds[a].clone();var o=this._getBounds(r||e,t||i,n);if(a){this._bounds||(this._bounds={});var s=this._bounds[a]=o.clone();s._internal=!!r}return o},statics:{_updateBoundsCache:function(e,t){if(e){var n=t._id,r=e._boundsCache=e._boundsCache||{ids:{},list:[]};r.ids[n]||(r.list.push(t),r.ids[n]=t)}},_clearBoundsCache:function(e){var t=e._boundsCache;if(t){e._bounds=e._position=e._boundsCache=o;for(var n=0,r=t.list,i=r.length;n<i;n++){var a=r[n];a!==e&&(a._bounds=a._position=o,a._boundsCache&&C._clearBoundsCache(a))}}}}}),{beans:!0,_decompose:function(){return this._decomposed=this._matrix.decompose()},getRotation:function(){var e=this._decomposed||this._decompose();return e&&e.rotation},setRotation:function(e){var t=this.getRotation();if(null!=t&&null!=e){var n=this._decomposed;this.rotate(e-t),n.rotation=e,this._decomposed=n}},getScaling:function(e){var t=this._decomposed||this._decompose(),n=t&&t.scaling,r=e?p:m;return n&&new r(n.x,n.y,this,"setScaling")},setScaling:function(){var e=this.getScaling();if(e){var t=p.read(arguments,0,{clone:!0}),n=this._decomposed;this.scale(t.x/e.x,t.y/e.y),n.scaling=t,this._decomposed=n}},getMatrix:function(){return this._matrix},setMatrix:function(){var e=this._matrix;e.initialize.apply(e,arguments),this._applyMatrix?this.transform(null,!0):this._changed(9)},getGlobalMatrix:function(e){var t=this._globalMatrix,n=this._project._updateVersion;if(t&&t._updateVersion!==n&&(t=null),!t){t=this._globalMatrix=this._matrix.clone();var r=this._parent;r&&t.preConcatenate(r.getGlobalMatrix(!0)),t._updateVersion=n}return e?t:t.clone()},getApplyMatrix:function(){return this._applyMatrix},setApplyMatrix:function(e){(this._applyMatrix=this._canApplyMatrix&&!!e)&&this.transform(null,!0)},getTransformContent:"#getApplyMatrix",setTransformContent:"#setApplyMatrix"},{getProject:function(){return this._project},_setProject:function(e,t){if(this._project!==e){this._project&&this._installEvents(!1),this._project=e;for(var n=this._children,r=0,i=n&&n.length;r<i;r++)n[r]._setProject(e);t=!0}t&&this._installEvents(!0)},getView:function(){return this._project.getView()},_installEvents:function e(t){e.base.call(this,t);for(var n=this._children,r=0,i=n&&n.length;r<i;r++)n[r]._installEvents(t)},getLayer:function(){for(var e=this;e=e._parent;)if(e instanceof S)return e;return null},getParent:function(){return this._parent},setParent:function(e){return e.addChild(this)},getChildren:function(){return this._children},setChildren:function(e){this.removeChildren(),this.addChildren(e)},getFirstChild:function(){return this._children&&this._children[0]||null},getLastChild:function(){return this._children&&this._children[this._children.length-1]||null},getNextSibling:function(){return this._parent&&this._parent._children[this._index+1]||null},getPreviousSibling:function(){return this._parent&&this._parent._children[this._index-1]||null},getIndex:function(){return this._index},equals:function(e){return e===this||e&&this._class===e._class&&this._style.equals(e._style)&&this._matrix.equals(e._matrix)&&this._locked===e._locked&&this._visible===e._visible&&this._blendMode===e._blendMode&&this._opacity===e._opacity&&this._clipMask===e._clipMask&&this._guide===e._guide&&this._equals(e)||!1},_equals:function(e){return s.equals(this._children,e._children)},clone:function(e){return this._clone(new this.constructor(C.NO_INSERT),e)},_clone:function(e,t,n){var r=["_locked","_visible","_blendMode","_opacity","_clipMask","_guide"],i=this._children;e.setStyle(this._style);for(var a=0,l=i&&i.length;a<l;a++)e.addChild(i[a].clone(!1),!0);for(var a=0,l=r.length;a<l;a++){var c=r[a];this.hasOwnProperty(c)&&(e[c]=this[c])}return n!==!1&&e._matrix.initialize(this._matrix),e.setApplyMatrix(this._applyMatrix),e.setPivot(this._pivot),e.setSelected(this._selected),e._data=this._data?s.clone(this._data):null,(t||t===o)&&e.insertAbove(this),this._name&&e.setName(this._name,!0),e},copyTo:function(e){return e.addChild(this.clone(!1))},rasterize:function(e){var t=this.getStrokeBounds(),n=(e||this.getView().getResolution())/72,r=t.getTopLeft().floor(),i=t.getBottomRight().ceil(),a=new g(i.subtract(r)),o=ne.getCanvas(a.multiply(n)),l=o.getContext("2d"),c=(new b).scale(n).translate(r.negate());l.save(),c.applyToContext(l),this.draw(l,new s({matrices:[c]})),l.restore();var u=new T(C.NO_INSERT);return u.setCanvas(o),u.transform((new b).translate(r.add(a.divide(2))).scale(1/n)),u.insertAbove(this),u},contains:function(){return!!this._contains(this._matrix._inverseTransform(p.read(arguments)))},_contains:function(e){if(this._children){for(var t=this._children.length-1;t>=0;t--)if(this._children[t].contains(e))return!0;return!1}return e.isInside(this.getInternalBounds())},isInside:function(){return w.read(arguments).contains(this.getBounds())},_asPathItem:function(){return new z.Rectangle({rectangle:this.getInternalBounds(),matrix:this._matrix,insert:!1})},intersects:function(e,t){return e instanceof C&&this._asPathItem().getIntersections(e._asPathItem(),null,t||e._matrix,!0).length>0},hitTest:function(){return this._hitTest(p.read(arguments),N.getOptions(s.read(arguments)))},_hitTest:function(e,t){function n(t,n){var r=d["get"+n]();if(e.subtract(r).divide(l).length<=1)return new N(t,h,{name:s.hyphenate(n),point:r})}if(this._locked||!this._visible||this._guide&&!t.guides||this.isEmpty())return null;var r=this._matrix,i=t._totalMatrix,a=this.getView(),o=t._totalMatrix=i?i.chain(r):this.getGlobalMatrix().preConcatenate(a._matrix),l=t._tolerancePadding=new g(z._getPenPadding(1,o.inverted())).multiply(Math.max(t.tolerance,1e-6));if(e=r._inverseTransform(e),!this._children&&!this.getInternalRoughBounds().expand(l.multiply(2))._containsPoint(e))return null;var c,u=!(t.guides&&!this._guide||t.selected&&!this._selected||t.type&&t.type!==s.hyphenate(this._class)||t.class&&!(this instanceof t.class)),h=this;if(u&&(t.center||t.bounds)&&this._parent){var d=this.getInternalBounds();if(t.center&&(c=n("center","Center")),!c&&t.bounds)for(var f=["TopLeft","TopRight","BottomLeft","BottomRight","LeftCenter","TopCenter","RightCenter","BottomCenter"],p=0;p<8&&!c;p++)c=n("bounds",f[p])}var m=!c&&this._children;if(m)for(var v=this._getChildHitTestOptions(t),p=m.length-1;p>=0&&!c;p--)c=m[p]._hitTest(e,v);return!c&&u&&(c=this._hitTestSelf(e,t)),c&&c.point&&(c.point=r.transform(c.point)),t._totalMatrix=i,c},_getChildHitTestOptions:function(e){return e},_hitTestSelf:function(e,t){if(t.fill&&this.hasFill()&&this._contains(e))return new N("fill",this)},matches:function(e,t){function n(e,t){for(var r in e)if(e.hasOwnProperty(r)){var i=e[r],a=t[r];if(s.isPlainObject(i)&&s.isPlainObject(a)){if(!n(i,a))return!1}else if(!s.equals(i,a))return!1}return!0}var r=typeof e;if("object"===r){for(var i in e)if(e.hasOwnProperty(i)&&!this.matches(i,e[i]))return!1}else{if("function"===r)return e(this);var a=/^(empty|editable)$/.test(e)?this["is"+s.capitalize(e)]():"type"===e?s.hyphenate(this._class):this[e];if(/^(constructor|class)$/.test(e)){if(!(this instanceof t))return!1}else if(t instanceof RegExp){if(!t.test(a))return!1}else if("function"==typeof t){if(!t(a))return!1}else if(s.isPlainObject(t)){if(!n(t,a))return!1}else if(!s.equals(a,t))return!1}return!0},getItems:function(e){return C._getItems(this._children,e,this._matrix)},getItem:function(e){return C._getItems(this._children,e,this._matrix,null,!0)[0]||null},statics:{_getItems:function e(t,n,r,i,a){if(!i&&"object"==typeof n){var o=n.overlapping,l=n.inside,c=o||l,u=c&&w.read([c]);i={items:[],inside:!!l,overlapping:!!o,rect:u,path:o&&new z.Rectangle({rectangle:u,insert:!1})},c&&(n=s.set({},n,{inside:!0,overlapping:!0}))}var h=i&&i.items,u=i&&i.rect;r=u&&(r||new b);for(var d=0,f=t&&t.length;d<f;d++){var p=t[d],m=r&&r.chain(p._matrix),g=!0;if(u){var c=p.getBounds(m);if(!u.intersects(c))continue;i.inside&&u.contains(c)||i.overlapping&&(c.contains(u)||i.path.intersects(p,m))||(g=!1)}if(g&&p.matches(n)&&(h.push(p),a))break;if(e(p._children,n,m,i,a),a&&h.length>0)break}return h}}},{importJSON:function(e){var t=s.importJSON(e,this);return t!==this?this.addChild(t):t},addChild:function(e,t){return this.insertChild(o,e,t)},insertChild:function(e,t,n){var r=t?this.insertChildren(e,[t],n):null;return r&&r[0]},addChildren:function(e,t){return this.insertChildren(this._children.length,e,t)},insertChildren:function(e,t,n,r){var i=this._children;if(i&&t&&t.length>0){t=Array.prototype.slice.apply(t);for(var a=t.length-1;a>=0;a--){var o=t[a];if(!r||o instanceof r){var l=o._parent===this&&o._index<e;o._remove(!1,!0)&&l&&e--}else t.splice(a,1)}s.splice(i,t,e,0);for(var c=this._project,u=c&&c._changes,a=0,h=t.length;a<h;a++){var o=t[a];o._parent=this,o._setProject(this._project,!0),o._name&&o.setName(o._name),u&&this._changed(5)}this._changed(11)}else t=null;return t},_insertSibling:function(e,t,n){return this._parent?this._parent.insertChild(e,t,n):null},insertAbove:function(e,t){return e._insertSibling(e._index+1,this,t)},insertBelow:function(e,t){return e._insertSibling(e._index,this,t)},sendToBack:function(){return(this._parent||this instanceof S&&this._project).insertChild(0,this)},bringToFront:function(){return(this._parent||this instanceof S&&this._project).addChild(this)},appendTop:"#addChild",appendBottom:function(e){return this.insertChild(0,e)},moveAbove:"#insertAbove",moveBelow:"#insertBelow",reduce:function(){if(this._children&&1===this._children.length){var e=this._children[0].reduce();return e.insertAbove(this),e.setStyle(this._style),this.remove(),e}return this},_removeNamed:function(){var e=this._parent;if(e){var t=e._children,n=e._namedChildren,r=this._name,i=n[r],a=i?i.indexOf(this):-1;a!==-1&&(t[r]==this&&delete t[r],i.splice(a,1),i.length?t[r]=i[i.length-1]:delete n[r])}},_remove:function(e,t){var n=this._parent;if(n){if(this._name&&this._removeNamed(),null!=this._index&&s.splice(n._children,null,this._index,1),this._installEvents(!1),e){var r=this._project;r&&r._changes&&this._changed(5)}return t&&n._changed(11),this._parent=null,!0}return!1},remove:function(){return this._remove(!0,!0)},replaceWith:function(e){var t=e&&e.insertBelow(this);return t&&this.remove(),t},removeChildren:function(e,t){if(!this._children)return null;e=e||0,t=s.pick(t,this._children.length);for(var n=s.splice(this._children,null,e,t-e),r=n.length-1;r>=0;r--)n[r]._remove(!0,!1);return n.length>0&&this._changed(11),n},clear:"#removeChildren",reverseChildren:function(){if(this._children){this._children.reverse();for(var e=0,t=this._children.length;e<t;e++)this._children[e]._index=e;this._changed(11)}},isEmpty:function(){return!this._children||0===this._children.length},isEditable:function(){for(var e=this;e;){if(!e._visible||e._locked)return!1;e=e._parent}return!0},hasFill:function(){return this.getStyle().hasFill()},hasStroke:function(){return this.getStyle().hasStroke()},hasShadow:function(){return this.getStyle().hasShadow()},_getOrder:function(e){function t(e){var t=[];do t.unshift(e);while(e=e._parent);return t}for(var n=t(this),r=t(e),i=0,a=Math.min(n.length,r.length);i<a;i++)if(n[i]!=r[i])return n[i]._index<r[i]._index?1:-1;return 0},hasChildren:function(){return this._children&&this._children.length>0},isInserted:function(){return!!this._parent&&this._parent.isInserted()},isAbove:function(e){return this._getOrder(e)===-1},isBelow:function(e){return 1===this._getOrder(e)},isParent:function(e){return this._parent===e},isChild:function(e){return e&&e._parent===this},isDescendant:function(e){for(var t=this;t=t._parent;)if(t==e)return!0;return!1},isAncestor:function(e){return!!e&&e.isDescendant(this)},isSibling:function(e){return this._parent===e._parent},isGroupedWith:function(e){for(var t=this._parent;t;){if(t._parent&&/^(Group|Layer|CompoundPath)$/.test(t._class)&&e.isDescendant(t))return!0;t=t._parent}return!1},translate:function(){var e=new b;return this.transform(e.translate.apply(e,arguments))},rotate:function(e){return this.transform((new b).rotate(e,p.read(arguments,1,{readNull:!0})||this.getPosition(!0)))}},s.each(["scale","shear","skew"],function(e){this[e]=function(){var t=p.read(arguments),n=p.read(arguments,0,{readNull:!0});return this.transform((new b)[e](t,n||this.getPosition(!0)))}},{}),{transform:function(e,t,n,r){e&&e.isIdentity()&&(e=null);var i=this._matrix,a=(t||this._applyMatrix)&&(!i.isIdentity()||e||t&&n&&this._children);if(!e&&!a)return this;if(e&&i.preConcatenate(e),a=a&&this._transformContent(i,n,r)){var o=this._pivot,s=this._style,l=s.getFillColor(!0),c=s.getStrokeColor(!0);o&&i._transformPoint(o,o,!0),l&&l.transform(i),c&&c.transform(i),i.reset(!0),r&&this._canApplyMatrix&&(this._applyMatrix=!0)}var u=this._bounds,h=this._position;this._changed(9);var d=u&&e&&e.decompose();if(d&&!d.shearing&&d.rotation%90===0){for(var f in u){var p=u[f];!a&&p._internal||e._transformBounds(p,p)}var m=this._boundsGetter,p=u[m&&m.getBounds||m||"getBounds"];p&&(this._position=p.getCenter(!0)),this._bounds=u}else e&&h&&(this._position=e._transformPoint(h,h));return this},_transformContent:function(e,t,n){var r=this._children;if(r){for(var i=0,a=r.length;i<a;i++)r[i].transform(e,!0,t,n);return!0}},globalToLocal:function(){return this.getGlobalMatrix(!0)._inverseTransform(p.read(arguments))},localToGlobal:function(){return this.getGlobalMatrix(!0)._transformPoint(p.read(arguments))},parentToLocal:function(){return this._matrix._inverseTransform(p.read(arguments))},localToParent:function(){return this._matrix._transformPoint(p.read(arguments))},fitBounds:function(e,t){e=w.read(arguments);var n=this.getBounds(),r=n.height/n.width,i=e.height/e.width,a=(t?r>i:r<i)?e.width/n.width:e.height/n.height,o=new w(new p,new g(n.width*a,n.height*a));o.setCenter(e.getCenter()),this.setBounds(o)},_setStyles:function(e){var t=this._style,n=t.getFillColor(),r=t.getStrokeColor(),i=t.getShadowColor();if(n&&(e.fillStyle=n.toCanvasStyle(e)),r){var o=t.getStrokeWidth();if(o>0){e.strokeStyle=r.toCanvasStyle(e),e.lineWidth=o;var s=t.getStrokeJoin(),l=t.getStrokeCap(),c=t.getMiterLimit();if(s&&(e.lineJoin=s),l&&(e.lineCap=l),c&&(e.miterLimit=c),a.support.nativeDash){var u=t.getDashArray(),h=t.getDashOffset();u&&u.length&&("setLineDash"in e?(e.setLineDash(u),e.lineDashOffset=h):(e.mozDash=u,e.mozDashOffset=h))}}}if(i){var d=t.getShadowBlur();if(d>0){e.shadowColor=i.toCanvasStyle(e),e.shadowBlur=d;var f=this.getShadowOffset();e.shadowOffsetX=f.x,e.shadowOffsetY=f.y}}},draw:function(e,t,n){function r(e){return o?o.chain(e):e}var i=this._updateVersion=this._project._updateVersion;if(this._visible&&0!==this._opacity){var a=t.matrices,o=t.viewMatrix,s=this._matrix,l=a[a.length-1].chain(s);if(l.isInvertible()){a.push(l),t.updateMatrix&&(l._updateVersion=i,this._globalMatrix=l);var c,u,h,d=this._blendMode,f=this._opacity,p="normal"===d,m=re.nativeModes[d],g=p&&1===f||t.dontStart||t.clip||(m||p&&f<1)&&this._canComposite(),v=t.pixelRatio||1;if(!g){var w=this.getStrokeBounds(r(l));if(!w.width||!w.height)return;h=t.offset,u=t.offset=w.getTopLeft().floor(),c=e,e=ne.getContext(w.getSize().ceil().add(1).multiply(v)),1!==v&&e.scale(v,v)}e.save();var y=n?n.chain(s):!this.getStrokeScaling(!0)&&r(l),b=!g&&t.clipItem,_=!y||b;if(g?(e.globalAlpha=f,m&&(e.globalCompositeOperation=d)):_&&e.translate(-u.x,-u.y),_&&(g?s:r(l)).applyToContext(e),b&&t.clipItem.draw(e,t.extend({clip:!0})),y){e.setTransform(v,0,0,v,0,0);var x=t.offset;x&&e.translate(-x.x,-x.y)}this._draw(e,t,y),e.restore(),a.pop(),t.clip&&!t.dontFinish&&e.clip(),g||(re.process(d,e,c,f,u.subtract(h).multiply(v)),ne.release(e),t.offset=h)}}},_isUpdated:function(e){var t=this._parent;if(t instanceof R)return t._isUpdated(e);var n=this._updateVersion===e;return!n&&t&&t._visible&&t._isUpdated(e)&&(this._updateVersion=e,n=!0),n},_drawSelection:function(e,t,n,r,i){if((this._drawSelected||this._boundsSelected)&&this._isUpdated(i)){var a=this.getSelectedColor(!0)||this.getLayer().getSelectedColor(!0),o=t.chain(this.getGlobalMatrix(!0));if(e.strokeStyle=e.fillStyle=a?a.toCanvasStyle(e):"#009dec",this._drawSelected&&this._drawSelected(e,o,r),this._boundsSelected){var s=n/2,l=o._transformCorners(this.getInternalBounds());e.beginPath();for(var c=0;c<8;c++)e[0===c?"moveTo":"lineTo"](l[c],l[++c]);e.closePath(),e.stroke();for(var c=0;c<8;c++)e.fillRect(l[c]-s,l[++c]-s,n,n)}}},_canComposite:function(){return!1}},s.each(["down","drag","up","move"],function(e){this["removeOn"+s.capitalize(e)]=function(){var t={};return t[e]=!0,this.removeOn(t)}},{removeOn:function(e){for(var t in e)if(e[t]){var n="mouse"+t,r=this._project,i=r._removeSets=r._removeSets||{};i[n]=i[n]||{},i[n][this._id]=this}return this}})),k=C.extend({_class:"Group",_selectChildren:!0,_serializeFields:{children:[]},initialize:function(e){this._children=[],this._namedChildren={},this._initialize(e)||this.addChildren(Array.isArray(e)?e:arguments)},_changed:function e(t){e.base.call(this,t),1026&t&&(this._clipItem=o)},_getClipItem:function(){var e=this._clipItem;if(e===o){e=null;for(var t=0,n=this._children.length;t<n;t++){var r=this._children[t];if(r._clipMask){e=r;break}}this._clipItem=e}return e},isClipped:function(){return!!this._getClipItem()},setClipped:function(e){var t=this.getFirstChild();t&&t.setClipMask(e)},_draw:function(e,t){var n=t.clip,r=!n&&this._getClipItem(),i=!0;if(t=t.extend({clipItem:r,clip:!1}),n?this._currentPath?(e.currentPath=this._currentPath,i=!1):(e.beginPath(),t.dontStart=t.dontFinish=!0):r&&r.draw(e,t.extend({clip:!0})),i)for(var a=0,o=this._children.length;a<o;a++){var s=this._children[a];s!==r&&s.draw(e,t)}n&&(this._currentPath=e.currentPath)}}),S=k.extend({_class:"Layer",initialize:function(e){var t=s.isPlainObject(e)?new s(e):{children:Array.isArray(e)?e:arguments},n=t.insert;t.insert=!1,k.call(this,t),(n||n===o)&&(this._project.addChild(this),this.activate())},_remove:function e(t,n){if(this._parent)return e.base.call(this,t,n);if(null!=this._index){var r=this._project;return r._activeLayer===this&&(r._activeLayer=this.getNextSibling()||this.getPreviousSibling()),s.splice(r.layers,null,this._index,1),this._installEvents(!1),t&&r._changes&&this._changed(5),n&&(r._needsUpdate=!0),!0}return!1},getNextSibling:function e(){return this._parent?e.base.call(this):this._project.layers[this._index+1]||null},getPreviousSibling:function e(){return this._parent?e.base.call(this):this._project.layers[this._index-1]||null},isInserted:function e(){return this._parent?e.base.call(this):null!=this._index},activate:function(){this._project._activeLayer=this},_insertSibling:function e(t,n,r){return this._parent?e.base.call(this,t,n,r):this._project.insertChild(t,n,r)}}),P=C.extend({_class:"Shape",_applyMatrix:!1,_canApplyMatrix:!1,_boundsSelected:!0,_serializeFields:{type:null,size:null,radius:null},initialize:function(e){this._initialize(e)},_equals:function(e){return this._type===e._type&&this._size.equals(e._size)&&s.equals(this._radius,e._radius)},clone:function(e){var t=new P(C.NO_INSERT);return t.setType(this._type),t.setSize(this._size),t.setRadius(this._radius),this._clone(t,e)},getType:function(){return this._type},setType:function(e){this._type=e},getShape:"#getType",setShape:"#setType",getSize:function(){var e=this._size;return new v(e.width,e.height,this,"setSize")},setSize:function(){var e=g.read(arguments);if(this._size){if(!this._size.equals(e)){var t=this._type,n=e.width,r=e.height;if("rectangle"===t){var i=g.min(this._radius,e.divide(2));this._radius.set(i.width,i.height)}else"circle"===t?(n=r=(n+r)/2,this._radius=n/2):"ellipse"===t&&this._radius.set(n/2,r/2);this._size.set(n,r),this._changed(9)}}else this._size=e.clone()},getRadius:function(){var e=this._radius;return"circle"===this._type?e:new v(e.width,e.height,this,"setRadius")},setRadius:function(e){var t=this._type;if("circle"===t){if(e===this._radius)return;var n=2*e;this._radius=e,this._size.set(n,n)}else if(e=g.read(arguments),this._radius){if(this._radius.equals(e))return;if(this._radius.set(e.width,e.height),"rectangle"===t){var n=g.max(this._size,e.multiply(2));this._size.set(n.width,n.height)}else"ellipse"===t&&this._size.set(2*e.width,2*e.height)}else this._radius=e.clone();this._changed(9)},isEmpty:function(){return!1},toPath:function(e){var t=this._clone(new(z[s.capitalize(this._type)])({center:new p,size:this._size,radius:this._radius,insert:!1}),e);return a.settings.applyMatrix&&t.setApplyMatrix(!0),t},_draw:function(e,t,n){var r=this._style,i=r.hasFill(),a=r.hasStroke(),o=t.dontFinish||t.clip,s=!n;if(i||a||o){var l=this._type,c=this._radius,u="circle"===l;if(t.dontStart||e.beginPath(),s&&u)e.arc(0,0,c,0,2*Math.PI,!0);else{var h=u?c:c.width,d=u?c:c.height,f=this._size,p=f.width,m=f.height;if(s&&"rectangle"===l&&0===h&&0===d)e.rect(-p/2,-m/2,p,m);else{var g=p/2,v=m/2,w=.44771525016920644,y=h*w,b=d*w,_=[-g,-v+d,-g,-v+b,-g+y,-v,-g+h,-v,g-h,-v,g-y,-v,g,-v+b,g,-v+d,g,v-d,g,v-b,g-y,v,g-h,v,-g+h,v,-g+y,v,-g,v-b,-g,v-d];n&&n.transform(_,_,32),e.moveTo(_[0],_[1]),e.bezierCurveTo(_[2],_[3],_[4],_[5],_[6],_[7]),g!==h&&e.lineTo(_[8],_[9]),e.bezierCurveTo(_[10],_[11],_[12],_[13],_[14],_[15]),v!==d&&e.lineTo(_[16],_[17]),e.bezierCurveTo(_[18],_[19],_[20],_[21],_[22],_[23]),g!==h&&e.lineTo(_[24],_[25]),e.bezierCurveTo(_[26],_[27],_[28],_[29],_[30],_[31])}}e.closePath()}o||!i&&!a||(this._setStyles(e),i&&(e.fill(r.getWindingRule()),e.shadowColor="rgba(0,0,0,0)"),a&&e.stroke())},_canComposite:function(){return!(this.hasFill()&&this.hasStroke())},_getBounds:function(e,t){var n=new w(this._size).setCenter(0,0);return"getBounds"!==e&&this.hasStroke()&&(n=n.expand(this.getStrokeWidth())),t?t._transformBounds(n):n}},new function(){function e(e,t,n){var r=e._radius;if(!r.isZero())for(var i=e._size.divide(2),a=0;a<4;a++){var o=new p(1&a?1:-1,a>1?1:-1),s=o.multiply(i),l=s.subtract(o.multiply(r)),c=new w(s,l);if((n?c.expand(n):c).contains(t))return l}}function t(e,t){var n=e.getAngleInRadians(),r=2*t.width,i=2*t.height,a=r*Math.sin(n),o=i*Math.cos(n);return r*i/(2*Math.sqrt(a*a+o*o))}return{_contains:function t(n){if("rectangle"===this._type){var r=e(this,n);return r?n.subtract(r).divide(this._radius).getLength()<=1:t.base.call(this,n)}return n.divide(this.size).getLength()<=.5},_hitTestSelf:function n(r,i){var a=!1;if(this.hasStroke()){var o=this._type,s=this._radius,l=this.getStrokeWidth()+2*i.tolerance;if("rectangle"===o){var c=e(this,r,l);if(c){var u=r.subtract(c);a=2*Math.abs(u.getLength()-t(u,s))<=l}else{var h=new w(this._size).setCenter(0,0),d=h.expand(l),f=h.expand(-l);a=d._containsPoint(r)&&!f._containsPoint(r)}}else"ellipse"===o&&(s=t(r,s)),a=2*Math.abs(r.getLength()-s)<=l}return a?new N("stroke",this):n.base.apply(this,arguments)}}},{statics:new function(){function e(e,t,n,r,i){var a=new P(s.getNamed(i));return a._type=e,a._size=n,a._radius=r,a.translate(t)}return{Circle:function(){var t=p.readNamed(arguments,"center"),n=s.readNamed(arguments,"radius");return e("circle",t,new g(2*n),n,arguments)},Rectangle:function(){var t=w.readNamed(arguments,"rectangle"),n=g.min(g.readNamed(arguments,"radius"),t.getSize(!0).divide(2));return e("rectangle",t.getCenter(!0),t.getSize(!0),n,arguments)},Ellipse:function(){var t=P._readEllipse(arguments),n=t.radius;return e("ellipse",t.center,n.multiply(2),n,arguments)},_readEllipse:function(e){var t,n;if(s.hasNamed(e,"radius"))t=p.readNamed(e,"center"),n=g.readNamed(e,"radius");else{var r=w.readNamed(e,"rectangle");t=r.getCenter(!0),n=r.getSize(!0).divide(2)}return{center:t,radius:n}}}}}),T=C.extend({_class:"Raster",_applyMatrix:!1,_canApplyMatrix:!1,_boundsGetter:"getBounds",_boundsSelected:!0,_serializeFields:{crossOrigin:null,source:null},initialize:function(e,t){this._initialize(e,t!==o&&p.read(arguments,1))||("string"==typeof e?this.setSource(e):this.setImage(e)),this._size||(this._size=new g,this._loaded=!1)},_equals:function(e){return this.getSource()===e.getSource()},clone:function(e){var t=new T(C.NO_INSERT),n=this._image,r=this._canvas;if(n)t.setImage(n);else if(r){var i=ne.getCanvas(this._size);i.getContext("2d").drawImage(r,0,0),t.setImage(i)}return t._crossOrigin=this._crossOrigin,this._clone(t,e)},getSize:function(){var e=this._size;return new v(e?e.width:0,e?e.height:0,this,"setSize")},setSize:function(){var e=g.read(arguments);if(!e.equals(this._size))if(e.width>0&&e.height>0){var t=this.getElement();this.setImage(ne.getCanvas(e)),t&&this.getContext(!0).drawImage(t,0,0,e.width,e.height)}else this._canvas&&ne.release(this._canvas),this._size=e.clone()},getWidth:function(){return this._size?this._size.width:0},setWidth:function(e){this.setSize(e,this.getHeight())},getHeight:function(){return this._size?this._size.height:0},setHeight:function(e){this.setSize(this.getWidth(),e)},isEmpty:function(){var e=this._size;return!e||0===e.width&&0===e.height},getResolution:function(){var e=this._matrix,t=new p(0,0).transform(e),n=new p(1,0).transform(e).subtract(t),r=new p(0,1).transform(e).subtract(t);return new g(72/n.getLength(),72/r.getLength())},getPpi:"#getResolution",getImage:function(){return this._image},setImage:function(e){this._canvas&&ne.release(this._canvas),e&&e.getContext?(this._image=null,this._canvas=e,this._loaded=!0):(this._image=e,this._canvas=null,this._loaded=e&&e.complete),this._size=new g(e?e.naturalWidth||e.width:0,e?e.naturalHeight||e.height:0), +this._context=null,this._changed(521)},getCanvas:function(){if(!this._canvas){var e=ne.getContext(this._size);try{this._image&&e.drawImage(this._image,0,0),this._canvas=e.canvas}catch(t){ne.release(e)}}return this._canvas},setCanvas:"#setImage",getContext:function(e){return this._context||(this._context=this.getCanvas().getContext("2d")),e&&(this._image=null,this._changed(513)),this._context},setContext:function(e){this._context=e},getSource:function(){return this._image&&this._image.src||this.toDataURL()},setSource:function(e){function t(){var e=r.getView();e&&(a=e._scope,r.setImage(n),r.emit("load"),e.update())}var n,r=this,i=this._crossOrigin;n=document.getElementById(e)||new Image,i&&(n.crossOrigin=i),n.naturalWidth&&n.naturalHeight?setTimeout(t,0):(X.add(n,{load:t}),n.src||(n.src=e)),this.setImage(n)},getCrossOrigin:function(){return this._image&&this._image.crossOrigin||this._crossOrigin||""},setCrossOrigin:function(e){this._crossOrigin=e,this._image&&(this._image.crossOrigin=e)},getElement:function(){return this._canvas||this._loaded&&this._image}},{beans:!1,getSubCanvas:function(){var e=w.read(arguments),t=ne.getContext(e.getSize());return t.drawImage(this.getCanvas(),e.x,e.y,e.width,e.height,0,0,e.width,e.height),t.canvas},getSubRaster:function(){var e=w.read(arguments),t=new T(C.NO_INSERT);return t.setImage(this.getSubCanvas(e)),t.translate(e.getCenter().subtract(this.getSize().divide(2))),t._matrix.preConcatenate(this._matrix),t.insertAbove(this),t},toDataURL:function(){var e=this._image&&this._image.src;if(/^data:/.test(e))return e;var t=this.getCanvas();return t?t.toDataURL.apply(t,arguments):null},drawImage:function(e){var t=p.read(arguments,1);this.getContext(!0).drawImage(e,t.x,t.y)},getAverageColor:function(e){var t,n;e?e instanceof B?(n=e,t=e.getBounds()):e.width?t=new w(e):e.x&&(t=new w(e.x-.5,e.y-.5,1,1)):t=this.getBounds();var r=32,i=Math.min(t.width,r),a=Math.min(t.height,r),o=T._sampleContext;o?o.clearRect(0,0,r+1,r+1):o=T._sampleContext=ne.getContext(new g(r)),o.save();var l=(new b).scale(i/t.width,a/t.height).translate(-t.x,-t.y);l.applyToContext(o),n&&n.draw(o,new s({clip:!0,matrices:[l]})),this._matrix.applyToContext(o);var c=this.getElement(),u=this._size;c&&o.drawImage(c,-u.width/2,-u.height/2),o.restore();for(var h=o.getImageData(.5,.5,Math.ceil(i),Math.ceil(a)).data,d=[0,0,0],f=0,p=0,m=h.length;p<m;p+=4){var v=h[p+3];f+=v,v/=255,d[0]+=h[p]*v,d[1]+=h[p+1]*v,d[2]+=h[p+2]*v}for(var p=0;p<3;p++)d[p]/=f;return f?V.read(d):null},getPixel:function(){var e=p.read(arguments),t=this.getContext().getImageData(e.x,e.y,1,1).data;return new V("rgb",[t[0]/255,t[1]/255,t[2]/255],t[3]/255)},setPixel:function(){var e=p.read(arguments),t=V.read(arguments),n=t._convert("rgb"),r=t._alpha,i=this.getContext(!0),a=i.createImageData(1,1),o=a.data;o[0]=255*n[0],o[1]=255*n[1],o[2]=255*n[2],o[3]=null!=r?255*r:255,i.putImageData(a,e.x,e.y)},createImageData:function(){var e=g.read(arguments);return this.getContext().createImageData(e.width,e.height)},getImageData:function(){var e=w.read(arguments);return e.isEmpty()&&(e=new w(this._size)),this.getContext().getImageData(e.x,e.y,e.width,e.height)},setImageData:function(e){var t=p.read(arguments,1);this.getContext(!0).putImageData(e,t.x,t.y)},_getBounds:function(e,t){var n=new w(this._size).setCenter(0,0);return t?t._transformBounds(n):n},_hitTestSelf:function(e){if(this._contains(e)){var t=this;return new N("pixel",t,{offset:e.add(t._size.divide(2)).round(),color:{get:function(){return t.getPixel(this.offset)}}})}},_draw:function(e){var t=this.getElement();t&&(e.globalAlpha=this._opacity,e.drawImage(t,-this._size.width/2,-this._size.height/2))},_canComposite:function(){return!0}}),M=C.extend({_class:"PlacedSymbol",_applyMatrix:!1,_canApplyMatrix:!1,_boundsGetter:{getBounds:"getStrokeBounds"},_boundsSelected:!0,_serializeFields:{symbol:null},initialize:function(e,t){this._initialize(e,t!==o&&p.read(arguments,1))||this.setSymbol(e instanceof E?e:new E(e))},_equals:function(e){return this._symbol===e._symbol},getSymbol:function(){return this._symbol},setSymbol:function(e){this._symbol=e,this._changed(9)},clone:function(e){var t=new M(C.NO_INSERT);return t.setSymbol(this._symbol),this._clone(t,e)},isEmpty:function(){return this._symbol._definition.isEmpty()},_getBounds:function(e,t,n){var r=this.symbol._definition;return r._getCachedBounds(e,t&&t.chain(r._matrix),n)},_hitTestSelf:function(e,t){var n=this._symbol._definition._hitTest(e,t);return n&&(n.item=this),n},_draw:function(e,t){this.symbol._definition.draw(e,t)}}),N=s.extend({_class:"HitResult",initialize:function(e,t,n){this.type=e,this.item=t,n&&(n.enumerable=!0,this.inject(n))},statics:{getOptions:function(e){return new s({type:null,tolerance:a.settings.hitTolerance,fill:!e,stroke:!e,segments:!e,handles:!1,ends:!1,center:!1,bounds:!1,guides:!1,selected:!1},e)}}}),I=s.extend({_class:"Segment",beans:!0,initialize:function(e,t,n,r,i,a){var s,l,c,u=arguments.length;0===u||(1===u?"point"in e?(s=e.point,l=e.handleIn,c=e.handleOut):s=e:2===u&&"number"==typeof e?s=arguments:u<=3?(s=e,l=t,c=n):(s=e!==o?[e,t]:null,l=n!==o?[n,r]:null,c=i!==o?[i,a]:null)),new L(s,this,"_point"),new L(l,this,"_handleIn"),new L(c,this,"_handleOut")},_serialize:function(e){return s.serialize(this.hasHandles()?[this._point,this._handleIn,this._handleOut]:this._point,e,!0)},_changed:function(e){var t=this._path;if(t){var n,r=t._curves,i=this._index;r&&(e&&e!==this._point&&e!==this._handleIn||!(n=i>0?r[i-1]:t._closed?r[r.length-1]:null)||n._changed(),e&&e!==this._point&&e!==this._handleOut||!(n=r[i])||n._changed()),t._changed(25)}},getPoint:function(){return this._point},setPoint:function(){var e=p.read(arguments);this._point.set(e.x,e.y)},getHandleIn:function(){return this._handleIn},setHandleIn:function(){var e=p.read(arguments);this._handleIn.set(e.x,e.y)},getHandleOut:function(){return this._handleOut},setHandleOut:function(){var e=p.read(arguments);this._handleOut.set(e.x,e.y)},hasHandles:function(){return!this._handleIn.isZero()||!this._handleOut.isZero()},clearHandles:function(){this._handleIn.set(0,0),this._handleOut.set(0,0)},_selectionState:0,isSelected:function(e){var t=this._selectionState;return e?e===this._point?!!(4&t):e===this._handleIn?!!(1&t):e===this._handleOut&&!!(2&t):!!(7&t)},setSelected:function(e,t){var n=this._path,e=!!e,r=this._selectionState,i=r,a=t?t===this._point?4:t===this._handleIn?1:t===this._handleOut?2:0:7;e?r|=a:r&=~a,this._selectionState=r,n&&r!==i&&(n._updateSelection(this,i,r),n._changed(129))},getIndex:function(){return this._index!==o?this._index:null},getPath:function(){return this._path||null},getCurve:function(){var e=this._path,t=this._index;return e?(t>0&&!e._closed&&t===e._segments.length-1&&t--,e.getCurves()[t]||null):null},getLocation:function(){var e=this.getCurve();return e?new O(e,this===e._segment1?0:1):null},getNext:function(){var e=this._path&&this._path._segments;return e&&(e[this._index+1]||this._path._closed&&e[0])||null},getPrevious:function(){var e=this._path&&this._path._segments;return e&&(e[this._index-1]||this._path._closed&&e[e.length-1])||null},isFirst:function(){return 0===this._index},isLast:function(){var e=this._path;return e&&this._index===e._segments.length-1||!1},reverse:function(){var e=this._handleIn,t=this._handleOut,n=e._x,r=e._y;e.set(t._x,t._y),t.set(n,r)},reversed:function(){return new I(this._point,this._handleOut,this._handleIn)},remove:function(){return!!this._path&&!!this._path.removeSegment(this._index)},clone:function(){return new I(this._point,this._handleIn,this._handleOut)},equals:function(e){return e===this||e&&this._class===e._class&&this._point.equals(e._point)&&this._handleIn.equals(e._handleIn)&&this._handleOut.equals(e._handleOut)||!1},toString:function(){var e=["point: "+this._point];return this._handleIn.isZero()||e.push("handleIn: "+this._handleIn),this._handleOut.isZero()||e.push("handleOut: "+this._handleOut),"{ "+e.join(", ")+" }"},transform:function(e){this._transformCoordinates(e,new Array(6),!0),this._changed()},_transformCoordinates:function(e,t,n){var r=this._point,i=n&&this._handleIn.isZero()?null:this._handleIn,a=n&&this._handleOut.isZero()?null:this._handleOut,o=r._x,s=r._y,l=2;return t[0]=o,t[1]=s,i&&(t[l++]=i._x+o,t[l++]=i._y+s),a&&(t[l++]=a._x+o,t[l++]=a._y+s),e&&(e._transformCoordinates(t,t,l/2),o=t[0],s=t[1],n?(r._x=o,r._y=s,l=2,i&&(i._x=t[l++]-o,i._y=t[l++]-s),a&&(a._x=t[l++]-o,a._y=t[l++]-s)):(i||(t[l++]=o,t[l++]=s),a||(t[l++]=o,t[l++]=s))),t}}),L=p.extend({initialize:function(e,t,n){var r,i,a;if(e)if((r=e[0])!==o)i=e[1];else{var s=e;(r=s.x)===o&&(s=p.read(arguments),r=s.x),i=s.y,a=s.selected}else r=i=0;this._x=r,this._y=i,this._owner=t,t[n]=this,a&&this.setSelected(!0)},set:function(e,t){return this._x=e,this._y=t,this._owner._changed(this),this},_serialize:function(e){var t=e.formatter,n=t.number(this._x),r=t.number(this._y);return this.isSelected()?{x:n,y:r,selected:!0}:[n,r]},getX:function(){return this._x},setX:function(e){this._x=e,this._owner._changed(this)},getY:function(){return this._y},setY:function(e){this._y=e,this._owner._changed(this)},isZero:function(){return d.isZero(this._x)&&d.isZero(this._y)},setSelected:function(e){this._owner.setSelected(e,this)},isSelected:function(){return this._owner.isSelected(this)}}),A=s.extend({_class:"Curve",initialize:function(e,t,n,r,i,a,o,s){var l,c,u,h,d,f,p=arguments.length;3===p?(this._path=e,l=t,c=n):0===p?(l=new I,c=new I):1===p?"segment1"in e?(l=new I(e.segment1),c=new I(e.segment2)):"point1"in e?(u=e.point1,d=e.handle1,f=e.handle2,h=e.point2):Array.isArray(e)&&(u=[e[0],e[1]],h=[e[6],e[7]],d=[e[2]-e[0],e[3]-e[1]],f=[e[4]-e[6],e[5]-e[7]]):2===p?(l=new I(e),c=new I(t)):4===p?(u=e,d=t,f=n,h=r):8===p&&(u=[e,t],h=[o,s],d=[n-e,r-t],f=[i-o,a-s]),this._segment1=l||new I(u,null,d),this._segment2=c||new I(h,f,null)},_serialize:function(e){return s.serialize(this.hasHandles()?[this.getPoint1(),this.getHandle1(),this.getHandle2(),this.getPoint2()]:[this.getPoint1(),this.getPoint2()],e,!0)},_changed:function(){this._length=this._bounds=o},clone:function(){return new A(this._segment1,this._segment2)},toString:function(){var e=["point1: "+this._segment1._point];return this._segment1._handleOut.isZero()||e.push("handle1: "+this._segment1._handleOut),this._segment2._handleIn.isZero()||e.push("handle2: "+this._segment2._handleIn),e.push("point2: "+this._segment2._point),"{ "+e.join(", ")+" }"},remove:function(){var e=!1;if(this._path){var t=this._segment2,n=t._handleOut;e=t.remove(),e&&this._segment1._handleOut.set(n.x,n.y)}return e},getPoint1:function(){return this._segment1._point},setPoint1:function(){var e=p.read(arguments);this._segment1._point.set(e.x,e.y)},getPoint2:function(){return this._segment2._point},setPoint2:function(){var e=p.read(arguments);this._segment2._point.set(e.x,e.y)},getHandle1:function(){return this._segment1._handleOut},setHandle1:function(){var e=p.read(arguments);this._segment1._handleOut.set(e.x,e.y)},getHandle2:function(){return this._segment2._handleIn},setHandle2:function(){var e=p.read(arguments);this._segment2._handleIn.set(e.x,e.y)},getSegment1:function(){return this._segment1},getSegment2:function(){return this._segment2},getPath:function(){return this._path},getIndex:function(){return this._segment1._index},getNext:function(){var e=this._path&&this._path._curves;return e&&(e[this._segment1._index+1]||this._path._closed&&e[0])||null},getPrevious:function(){var e=this._path&&this._path._curves;return e&&(e[this._segment1._index-1]||this._path._closed&&e[e.length-1])||null},isFirst:function(){return 0===this._segment1._index},isLast:function(){var e=this._path;return e&&this._segment1._index===e._curves.length-1||!1},isSelected:function(){return this.getPoint1().isSelected()&&this.getHandle2().isSelected()&&this.getHandle2().isSelected()&&this.getPoint2().isSelected()},setSelected:function(e){this.getPoint1().setSelected(e),this.getHandle1().setSelected(e),this.getHandle2().setSelected(e),this.getPoint2().setSelected(e)},getValues:function(e){return A.getValues(this._segment1,this._segment2,e)},getPoints:function(){for(var e=this.getValues(),t=[],n=0;n<8;n+=2)t.push(new p(e[n],e[n+1]));return t},getLength:function(){return null==this._length&&(this._length=A.getLength(this.getValues(),0,1)),this._length},getArea:function(){return A.getArea(this.getValues())},getLine:function(){return new _(this._segment1._point,this._segment2._point)},getPart:function(e,t){return new A(A.getPart(this.getValues(),e,t))},getPartLength:function(e,t){return A.getLength(this.getValues(),e,t)},getIntersections:function(e){return A._getIntersections(this.getValues(),e&&e!==this?e.getValues():null,this,e,[],{})},_getParameter:function(e,t){return t?e:e&&e.curve===this?e.parameter:e===o&&t===o?.5:this.getParameterAt(e,0)},divide:function(e,t,n){var r=this._getParameter(e,t),i=4e-7,a=1-i,o=null;if(r>=i&&r<=a){var s=A.subdivide(this.getValues(),r),l=s[0],c=s[1],u=n||this.hasHandles(),h=this._segment1,d=this._segment2,f=this._path;u&&(h._handleOut.set(l[2]-l[0],l[3]-l[1]),d._handleIn.set(c[4]-c[6],c[5]-c[7]));var m=l[6],g=l[7],v=new I(new p(m,g),u&&new p(l[4]-m,l[5]-g),u&&new p(c[2]-m,c[3]-g));f?(f.insert(h._index+1,v),o=this.getNext()):(this._segment2=v,o=new A(v,d))}return o},split:function(e,t){return this._path?this._path.split(this._segment1._index,this._getParameter(e,t)):null},reversed:function(){return new A(this._segment2.reversed(),this._segment1.reversed())},clearHandles:function(){this._segment1._handleOut.set(0,0),this._segment2._handleIn.set(0,0)},statics:{getValues:function(e,t,n){var r=e._point,i=e._handleOut,a=t._handleIn,o=t._point,s=[r._x,r._y,r._x+i._x,r._y+i._y,o._x+a._x,o._y+a._y,o._x,o._y];return n&&n._transformCoordinates(s,s,4),s},subdivide:function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],s=e[4],l=e[5],c=e[6],u=e[7];t===o&&(t=.5);var h=1-t,d=h*n+t*i,f=h*r+t*a,p=h*i+t*s,m=h*a+t*l,g=h*s+t*c,v=h*l+t*u,w=h*d+t*p,y=h*f+t*m,b=h*p+t*g,_=h*m+t*v,x=h*w+t*b,E=h*y+t*_;return[[n,r,d,f,w,y,x,E],[x,E,b,_,g,v,c,u]]},solveCubic:function(e,t,n,r,i,a){var o=e[t],s=e[t+2],l=e[t+4],c=e[t+6],u=3*(s-o),h=3*(l-s)-u,f=c-o-u-h;return d.solveCubic(f,h,u,o-n,r,i,a)},getParameterOf:function(e,t){var n=new p(e[0],e[1]),r=new p(e[6],e[7]),i=1e-12,a=t.isClose(n,i)?0:t.isClose(r,i)?1:null;if(null!==a)return a;for(var o=[t.x,t.y],s=[],l=2e-7,c=0;c<2;c++)for(var u=A.solveCubic(e,c,o[c],s,0,1),h=0;h<u;h++)if(a=s[h],t.isClose(A.getPoint(e,a),l))return a;return t.isClose(n,l)?0:t.isClose(r,l)?1:null},getNearestParameter:function(e,t){function n(n){if(n>=0&&n<=1){var r=t.getDistance(A.getPoint(e,n),!0);if(r<d)return d=r,f=n,!0}}if(A.isStraight(e)){var r=e[0],i=e[1],a=e[6],o=e[7],s=a-r,l=o-i,c=s*s+l*l;if(0===c)return 0;var u=((t.x-r)*s+(t.y-i)*l)/c;return u<1e-12?0:u>.999999999999?1:A.getParameterOf(e,new p(r+u*s,i+u*l))}for(var h=100,d=1/0,f=0,m=0;m<=h;m++)n(m/h);for(var g=1/(2*h);g>4e-7;)n(f-g)||n(f+g)||(g/=2);return f},getPart:function(e,t,n){var r=t>n;if(r){var i=t;t=n,n=i}return t>0&&(e=A.subdivide(e,t)[1]),n<1&&(e=A.subdivide(e,(n-t)/(1-t))[0]),r?[e[6],e[7],e[4],e[5],e[2],e[3],e[0],e[1]]:e},hasHandles:function(e){var t=d.isZero;return!(t(e[0]-e[2])&&t(e[1]-e[3])&&t(e[4]-e[6])&&t(e[5]-e[7]))},isFlatEnough:function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],s=e[5],l=e[6],c=e[7],u=3*i-2*n-l,h=3*a-2*r-c,d=3*o-2*l-n,f=3*s-2*c-r;return Math.max(u*u,d*d)+Math.max(h*h,f*f)<10*t*t},getArea:function(e){var t=e[0],n=e[1],r=e[6],i=e[7],a=(e[2]+t)/2,o=(e[3]+n)/2,s=(e[4]+e[6])/2,l=(e[5]+e[7])/2;return 6*((t-a)*(o+n)+(a-s)*(l+o)+(s-r)*(i+l))/10},getBounds:function(e){for(var t=e.slice(0,2),n=t.slice(),r=[0,0],i=0;i<2;i++)A._addBounds(e[i],e[i+2],e[i+4],e[i+6],i,0,t,n,r);return new w(t[0],t[1],n[0]-t[0],n[1]-t[1])},_addBounds:function(e,t,n,r,i,a,o,s,l){function c(e,t){var n=e-t,r=e+t;n<o[i]&&(o[i]=n),r>s[i]&&(s[i]=r)}var u=3*(t-n)-e+r,h=2*(e+n)-4*t,f=t-e,p=d.solveQuadratic(u,h,f,l),m=4e-7,g=1-m;c(r,0);for(var v=0;v<p;v++){var w=l[v],y=1-w;m<w&&w<g&&c(y*y*y*e+3*y*y*w*t+3*y*w*w*n+w*w*w*r,a)}}}},s.each(["getBounds","getStrokeBounds","getHandleBounds","getRoughBounds"],function(e){this[e]=function(){this._bounds||(this._bounds={});var t=this._bounds[e];if(!t){var n=this._path;t=this._bounds[e]=z[e]([this._segment1,this._segment2],!1,n&&n.getStyle())}return t.clone()}},{}),s.each({isStraight:function(e,t,n){if(t.isZero()&&n.isZero())return!0;if(e.isZero())return!1;if(t.isCollinear(e)&&n.isCollinear(e)){var r=e.dot(e),i=e.dot(t)/r,a=e.dot(n)/r;return i>=0&&i<=1&&a<=0&&a>=-1}return!1},isLinear:function(e,t,n){var r=e.divide(3);return t.equals(r)&&n.negate().equals(r)}},function(e,t){this[t]=function(){var t=this._segment1,n=this._segment2;return e(n._point.subtract(t._point),t._handleOut,n._handleIn)},this.statics[t]=function(t){var n=t[0],r=t[1],i=t[6],a=t[7];return e(new p(i-n,a-r),new p(t[2]-n,t[3]-r),new p(t[4]-i,t[5]-a))}},{statics:{},hasHandles:function(){return!this._segment1._handleOut.isZero()||!this._segment2._handleIn.isZero()},isCollinear:function(e){return e&&this.isStraight()&&e.isStraight()&&this.getLine().isCollinear(e.getLine())},isHorizontal:function(){return this.isStraight()&&Math.abs(this.getTangentAt(.5,!0).y)<1e-7},isVertical:function(){return this.isStraight()&&Math.abs(this.getTangentAt(.5,!0).x)<1e-7}}),{beans:!1,getParameterAt:function(e,t){return A.getParameterAt(this.getValues(),e,t)},getParameterOf:function(){return A.getParameterOf(this.getValues(),p.read(arguments))},getLocationAt:function(e,t){var n=t?e:this.getParameterAt(e);return null!=n&&n>=0&&n<=1?new O(this,n):null},getLocationOf:function(){return this.getLocationAt(this.getParameterOf(p.read(arguments)),!0)},getOffsetOf:function(){var e=this.getLocationOf.apply(this,arguments);return e?e.getOffset():null},getNearestLocation:function(){var e=p.read(arguments),t=this.getValues(),n=A.getNearestParameter(t,e),r=A.getPoint(t,n);return new O(this,n,r,null,e.getDistance(r))},getNearestPoint:function(){return this.getNearestLocation.apply(this,arguments).getPoint()}},new function(){var e=["getPoint","getTangent","getNormal","getWeightedTangent","getWeightedNormal","getCurvature"];return s.each(e,function(e){this[e+"At"]=function(t,n){var r=this.getValues();return A[e](r,n?t:A.getParameterAt(r,t,0))}},{statics:{evaluateMethods:e}})},new function(){function e(e){var t=e[0],n=e[1],r=e[2],i=e[3],a=e[4],o=e[5],s=e[6],l=e[7],c=9*(r-a)+3*(s-t),u=6*(t+a)-12*r,h=3*(r-t),d=9*(i-o)+3*(l-n),f=6*(n+o)-12*i,p=3*(i-n);return function(e){var t=(c*e+u)*e+h,n=(d*e+f)*e+p;return Math.sqrt(t*t+n*n)}}function t(e,t){return Math.max(2,Math.min(16,Math.ceil(32*Math.abs(t-e))))}function n(e,t,n,r){if(null==t||t<0||t>1)return null;var i,a,o=e[0],s=e[1],l=e[2],c=e[3],u=e[4],h=e[5],d=e[6],f=e[7],m=4e-7,g=1-m;if(0===n&&(t<m||t>g)){var v=t<m;i=v?o:d,a=v?s:f}else{var w=3*(l-o),y=3*(u-l)-w,b=d-o-w-y,_=3*(c-s),x=3*(h-c)-_,E=f-s-_-x;if(0===n)i=((b*t+y)*t+w)*t+o,a=((E*t+x)*t+_)*t+s;else{if(t<m?(i=w,a=_):t>g?(i=3*(d-u),a=3*(f-h)):(i=(3*b*t+2*y)*t+w,a=(3*E*t+2*x)*t+_),r){0===i&&0===a&&(t<m||t>g)&&(i=u-l,a=h-c);var C=Math.sqrt(i*i+a*a);C&&(i/=C,a/=C)}if(3===n){var k=6*b*t+2*y,S=6*E*t+2*x,P=Math.pow(i*i+a*a,1.5);i=0!==P?(i*S-a*k)/P:0,a=0}}}return 2===n?new p(a,-i):new p(i,a)}return{statics:{getLength:function(n,r,i){if(r===o&&(r=0),i===o&&(i=1),0===r&&1===i&&A.isStraight(n)){var a=n[6]-n[0],s=n[7]-n[1];return Math.sqrt(a*a+s*s)}var l=e(n);return d.integrate(l,r,i,t(r,i))},getParameterAt:function(n,r,i){function a(e){return m+=d.integrate(h,i,e,t(i,e)),i=e,m-r}if(i===o&&(i=r<0?1:0),0===r)return i;var s=Math.abs,l=r>0,c=l?i:0,u=l?1:i,h=e(n),f=d.integrate(h,c,u,t(c,u));if(s(r-f)<1e-12)return l?u:c;if(s(r)>f)return null;var p=r/f,m=0;return d.findRoot(a,h,i+p,c,u,32,1e-12)},getPoint:function(e,t){return n(e,t,0,!1)},getTangent:function(e,t){return n(e,t,1,!0)},getWeightedTangent:function(e,t){return n(e,t,1,!1)},getNormal:function(e,t){return n(e,t,2,!0)},getWeightedNormal:function(e,t){return n(e,t,2,!1)},getCurvature:function(e,t){return n(e,t,3,!1).x}}}},new function(){function e(e,t,n,r,i,a,o,s,l,c,u){var h=t.startConnected,d=t.endConnected,f=4e-7,p=1-f;if(null==i&&(i=A.getParameterOf(n,a)),null!==i&&i>=(h?f:0)&&i<=(d?p:1)&&(null==l&&(l=A.getParameterOf(o,c)),null!==l&&l>=(d?f:0)&&l<=(h?p:1))){var m=t.renormalize;if(m){var g=m(i,l);i=g[0],l=g[1]}var v=new O(r,i,a||A.getPoint(n,i),u),w=new O(s,l,c||A.getPoint(o,l),u),y=v.getPath()===w.getPath()&&v.getIndex()>w.getIndex(),b=y?w:v,_=t.include;v._intersection=w,w._intersection=v,_&&!_(b)||O.insert(e,b,!0)}}function t(i,a,o,s,l,c,u,h,d,f,p,m,g){if(!(++g>=24)){var v,w,y=a[0],b=a[1],x=a[6],E=a[7],C=_.getSignedDistance,k=C(y,b,x,E,a[2],a[3]),S=C(y,b,x,E,a[4],a[5]),P=k*S>0?.75:4/9,T=P*Math.min(0,k,S),M=P*Math.max(0,k,S),N=C(y,b,x,E,i[0],i[1]),I=C(y,b,x,E,i[2],i[3]),L=C(y,b,x,E,i[4],i[5]),O=C(y,b,x,E,i[6],i[7]),B=n(N,I,L,O),z=B[0],R=B[1];if(null!=(v=r(z,R,T,M))&&null!=(w=r(z.reverse(),R.reverse(),T,M))){i=A.getPart(i,v,w);var D=w-v,j=u+(h-u)*v,F=u+(h-u)*w;if(p>.5&&D>.5)if(F-j>f-d){var q=A.subdivide(i,.5),V=j+(F-j)/2;t(a,q[0],s,o,l,c,d,f,j,V,D,!m,g),t(a,q[1],s,o,l,c,d,f,V,F,D,!m,g)}else{var q=A.subdivide(a,.5),V=d+(f-d)/2;t(q[0],i,s,o,l,c,d,V,j,F,D,!m,g),t(q[1],i,s,o,l,c,V,f,j,F,D,!m,g)}else if(Math.max(f-d,F-j)<1e-7){var U=j+(F-j)/2,W=d+(f-d)/2;i=o.getValues(),a=s.getValues(),e(l,c,m?a:i,m?s:o,m?W:U,null,m?i:a,m?o:s,m?U:W,null)}else D>1e-12&&t(a,i,s,o,l,c,d,f,j,F,D,!m,g)}}}function n(e,t,n,r){var i,a=[0,e],o=[1/3,t],s=[2/3,n],l=[1,r],c=t-(2*e+r)/3,u=n-(e+2*r)/3;if(c*u<0)i=[[a,o,l],[a,s,l]];else{var h=c/u;i=[h>=2?[a,o,l]:h<=.5?[a,s,l]:[a,o,s,l],[a,l]]}return(c||u)<0?i.reverse():i}function r(e,t,n,r){return e[0][1]<n?i(e,!0,n):t[0][1]>r?i(t,!1,r):e[0][0]}function i(e,t,n){for(var r=e[0][0],i=e[0][1],a=1,o=e.length;a<o;a++){var s=e[a][0],l=e[a][1];if(t?l>=n:l<=n)return l===n?s:r+(n-i)*(s-r)/(l-i);r=s,i=l}return null}function a(t,n,r,i,a,o){for(var s=A.isStraight(t),l=s?n:t,c=s?t:n,u=c[0],h=c[1],f=c[6],p=c[7],m=f-u,g=p-h,v=Math.atan2(-g,m),w=Math.sin(v),y=Math.cos(v),b=[],_=0;_<8;_+=2){var x=l[_]-u,E=l[_+1]-h;b.push(x*y-E*w,x*w+E*y)}for(var C=[],k=A.solveCubic(b,1,0,C,0,1),_=0;_<k;_++){var S=C[_],P=A.getPoint(l,S),T=A.getParameterOf(c,P);if(null!==T){var M=A.getPoint(c,T),N=s?T:S,I=s?S:T;(!o.endConnected||I>d.CURVETIME_EPSILON)&&e(a,o,t,r,N,s?M:P,n,i,I,s?P:M)}}}function o(t,n,r,i,a,o){var s=_.intersect(t[0],t[1],t[6],t[7],n[0],n[1],n[6],n[7]);s&&e(a,o,t,r,null,s,n,i,null,s)}return{statics:{_getIntersections:function(n,r,i,s,l,c){if(!r)return A._getSelfIntersection(n,i,l,c);var u=n[0],h=n[1],d=n[6],f=n[7],m=r[0],g=r[1],v=r[6],w=r[7],y=(3*n[2]+u)/4,b=(3*n[3]+h)/4,_=(3*n[4]+d)/4,x=(3*n[5]+f)/4,E=(3*r[2]+m)/4,C=(3*r[3]+g)/4,k=(3*r[4]+v)/4,S=(3*r[5]+w)/4,P=Math.min,T=Math.max;if(!(T(u,y,_,d)>=P(m,E,k,v)&&P(u,y,_,d)<=T(m,E,k,v)&&T(h,b,x,f)>=P(g,C,S,w)&&P(h,b,x,f)<=T(g,C,S,w)))return l;if(!c.startConnected&&!c.endConnected){var M=A.getOverlaps(n,r);if(M){for(var N=0;N<2;N++){var I=M[N];e(l,c,n,i,I[0],null,r,s,I[1],null,!0)}return l}}var L=A.isStraight(n),O=A.isStraight(r),B=L&&O,z=1e-12,R=l.length;if((B?o:L||O?a:t)(n,r,i,s,l,c,0,1,0,1,0,!1,0),B&&l.length>R)return l;var D=new p(u,h),j=new p(d,f),F=new p(m,g),q=new p(v,w);return D.isClose(F,z)&&e(l,c,n,i,0,D,r,s,0,F),!c.startConnected&&D.isClose(q,z)&&e(l,c,n,i,0,D,r,s,1,q),!c.endConnected&&j.isClose(F,z)&&e(l,c,n,i,1,j,r,s,0,F),j.isClose(q,z)&&e(l,c,n,i,1,j,r,s,1,q),l},_getSelfIntersection:function(e,t,n,r){var i=e[0],a=e[1],o=e[2],s=e[3],l=e[4],c=e[5],u=e[6],h=e[7],f=new _(i,a,u,h,!1),m=f.getSide(new p(o,s),!0),g=f.getSide(new p(l,c),!0);if(m===g){var v=(i-l)*(s-h)+(o-u)*(c-a);if(v*m>0)return n}var w=u-3*l+3*o-i,y=l-2*o+i,b=o-i,x=h-3*c+3*s-a,E=c-2*s+a,C=s-a,k=x*b-w*C,S=x*y-w*E,P=E*b-y*C;if(k*k-4*S*P<0){var T,M=[],N=d.solveCubic(w*w+x*x,3*(w*y+x*E),2*(y*y+E*E)+w*b+x*C,y*b+E*C,M,0,1);if(N>0){for(var I=0,L=0;I<N;I++){var O=Math.abs(t.getCurvatureAt(M[I],!0));O>L&&(L=O,T=M[I])}var B=A.subdivide(e,T);r.endConnected=!0,r.renormalize=function(e,t){return[e*T,t*(1-T)+T]},A._getIntersections(B[0],B[1],t,t,n,r)}}return n},getOverlaps:function(e,t){function n(e){var t=e[6]-e[0],n=e[7]-e[1];return t*t+n*n}var r=Math.abs,i=4e-7,a=2e-7,o=A.isStraight(e),s=A.isStraight(t),l=o&&s;if(l){var c=n(e)<n(t),u=c?t:e,h=c?e:t,d=new _(u[0],u[1],u[6],u[7]);if(d.getDistance(new p(h[0],h[1]))>a||d.getDistance(new p(h[6],h[7]))>a)return null}else if(o^s)return null;for(var f=[e,t],m=[],g=0,v=0;g<2&&m.length<2;g+=0===v?0:1,v^=1){var w=A.getParameterOf(f[1^g],new p(f[g][0===v?0:6],f[g][0===v?1:7]));if(null!=w){var y=0===g?[v,w]:[w,v];(0===m.length||r(y[0]-m[0][0])>i&&r(y[1]-m[0][1])>i)&&m.push(y)}if(1===g&&0===m.length)break}if(2!==m.length)m=null;else if(!l){var b=A.getPart(e,m[0][0],m[1][0]),x=A.getPart(t,m[0][1],m[1][1]);(r(x[2]-b[2])>a||r(x[3]-b[3])>a||r(x[4]-b[4])>a||r(x[5]-b[5])>a)&&(m=null)}return m}}}}),O=s.extend({_class:"CurveLocation",beans:!0,initialize:function e(t,n,r,i,a){if(n>.9999996){var o=t.getNext();o&&(n=0,t=o)}this._id=f.get(e),this._setCurve(t),this._parameter=n,this._point=r||t.getPointAt(n,!0),this._overlap=i,this._distance=a,this._intersection=this._next=this._prev=null},_setCurve:function(e){var t=e._path;this._version=t?t._version:0,this._curve=e,this._segment=null,this._segment1=e._segment1,this._segment2=e._segment2},_setSegment:function(e){this._setCurve(e.getCurve()),this._segment=e,this._parameter=e===this._segment1?0:1,this._point=e._point.clone()},getSegment:function(){var e=this.getCurve(),t=this._segment;if(!t){var n=this.getParameter();0===n?t=e._segment1:1===n?t=e._segment2:null!=n&&(t=e.getPartLength(0,n)<e.getPartLength(n,1)?e._segment1:e._segment2),this._segment=t}return t},getCurve:function(){function e(e){var t=e&&e.getCurve();if(t&&null!=(r._parameter=t.getParameterOf(r._point)))return r._setCurve(t),r._segment=e,t}var t=this._curve,n=t&&t._path,r=this;return n&&n._version!==this._version&&(t=this._parameter=this._curve=this._offset=null),t||e(this._segment)||e(this._segment1)||e(this._segment2.getPrevious())},getPath:function(){var e=this.getCurve();return e&&e._path},getIndex:function(){var e=this.getCurve();return e&&e.getIndex()},getParameter:function(){var e=this.getCurve(),t=this._parameter;return e&&null==t?this._parameter=e.getParameterOf(this._point):t},getPoint:function(){return this._point},getOffset:function(){var e=this._offset;if(null==e){e=0;var t=this.getPath(),n=this.getIndex();if(t&&null!=n)for(var r=t.getCurves(),i=0;i<n;i++)e+=r[i].getLength();this._offset=e+=this.getCurveOffset()}return e},getCurveOffset:function(){var e=this.getCurve(),t=this.getParameter();return null!=t&&e&&e.getPartLength(0,t)},getIntersection:function(){return this._intersection},getDistance:function(){return this._distance},divide:function(){var e=this.getCurve(),t=null;return e&&(t=e.divide(this.getParameter(),!0),t&&this._setSegment(t._segment1)),t},split:function(){var e=this.getCurve();return e?e.split(this.getParameter(),!0):null},equals:function(e,t){var n=this===e,r=2e-7;if(!n&&e instanceof O&&this.getPath()===e.getPath()&&this.getPoint().isClose(e.getPoint(),r)){var i=this.getCurve(),a=e.getCurve(),o=Math.abs,s=o((i.isLast()&&a.isFirst()?-1:i.getIndex())+this.getParameter()-((a.isLast()&&i.isFirst()?-1:a.getIndex())+e.getParameter()));n=(s<4e-7||(s=o(this.getOffset()-e.getOffset()))<r||o(this.getPath().getLength()-s)<r)&&(t||!this._intersection&&!e._intersection||this._intersection&&this._intersection.equals(e._intersection,!0))}return n},toString:function(){var e=[],t=this.getPoint(),n=h.instance;t&&e.push("point: "+t);var r=this.getIndex();null!=r&&e.push("index: "+r);var i=this.getParameter();return null!=i&&e.push("parameter: "+n.number(i)),null!=this._distance&&e.push("distance: "+n.number(this._distance)),"{ "+e.join(", ")+" }"},isTouching:function(){var e=this._intersection;if(e&&this.getTangent().isCollinear(e.getTangent())){var t=this.getCurve(),n=e.getCurve();return!(t.isStraight()&&n.isStraight()&&t.getLine().intersect(n.getLine()))}return!1},isCrossing:function(){function e(e,t,n){return t<n?e>t&&e<n:e>t&&e<=u||e>=-u&&e<n}var t=this._intersection;if(!t)return!1;var n=this.getParameter(),r=t.getParameter(),i=4e-7,a=1-i;if(n>=i&&n<=a||r>=i&&r<=a)return!this.isTouching();var o=this.getCurve(),s=o.getPrevious(),l=t.getCurve(),c=l.getPrevious(),u=Math.PI;if(!s||!c)return!1;var h=s.getTangentAt(a,!0).negate().getAngleInRadians(),d=o.getTangentAt(i,!0).getAngleInRadians(),f=c.getTangentAt(a,!0).negate().getAngleInRadians(),p=l.getTangentAt(i,!0).getAngleInRadians();return e(f,h,d)^e(p,h,d)&&e(f,d,h)^e(p,d,h)},isOverlap:function(){return!!this._overlap}},s.each(A.evaluateMethods,function(e){var t=e+"At";this[e]=function(){var e=this.getParameter(),n=this.getCurve();return null!=e&&n&&n[t](e,!0)}},{preserve:!0}),new function(){function e(e,t,n){function r(n,r){for(var a=n+r;a>=-1&&a<=i;a+=r){var o=e[(a%i+i)%i];if(!t.getPoint().isClose(o.getPoint(),2e-7))break;if(t.equals(o))return o}return null}for(var i=e.length,a=0,o=i-1;a<=o;){var s,l=a+o>>>1,c=e[l];if(n&&(s=t.equals(c)?c:r(l,-1)||r(l,1)))return t._overlap&&(s._overlap=s._intersection._overlap=!0),s;var u=t.getPath(),h=c.getPath(),d=u===h?t.getIndex()+t.getParameter()-(c.getIndex()+c.getParameter()):u._id-h._id;d<0?o=l-1:a=l+1}return e.splice(a,0,t),t}return{statics:{insert:e,expand:function(t){for(var n=t.slice(),r=0,i=t.length;r<i;r++)e(n,t[r]._intersection,!1);return n}}}}),B=C.extend({_class:"PathItem",initialize:function(){},getIntersections:function(e,t,n,r){var i=this===e||!e,a=this._matrix.orNullIfIdentity(),o=i?a:(n||e._matrix).orNullIfIdentity();if(!i&&!this.getBounds(a).touches(e.getBounds(o)))return[];for(var s,e,l=this.getCurves(),c=i?l:e.getCurves(),u=l.length,h=i?u:c.length,d=[],f=[],p=0;p<h;p++)d[p]=c[p].getValues(o);for(var p=0;p<u;p++){var m=l[p],g=i?d[p]:m.getValues(a),v=m.getPath();v!==e&&(e=v,s=[],f.push(s)),i&&A._getSelfIntersection(g,m,s,{include:t,startConnected:1===u&&m.getPoint1().equals(m.getPoint2())});for(var w=i?p+1:0;w<h;w++){if(r&&s.length)return s;var y=c[w];A._getIntersections(g,d[w],m,y,s,{include:t,startConnected:i&&m.getPrevious()===y,endConnected:i&&m.getNext()===y})}}s=[];for(var p=0,b=f.length;p<b;p++)s.push.apply(s,f[p]);return s},getCrossings:function(e){return this.getIntersections(e,function(e){return e.isCrossing()})},_asPathItem:function(){return this},setPathData:function(e){function t(e,t){var n=+r[e];return s&&(n+=l[t]),n}function n(e){return new p(t(e,"x"),t(e+1,"y"))}var r,i,a,o=e.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/gi),s=!1,l=new p,c=new p;this.clear();for(var u=0,h=o&&o.length;u<h;u++){var d=o[u],f=d[0],m=f.toLowerCase();r=d.match(/[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g);var v=r&&r.length;switch(s=f===m,"z"!==i||/[mz]/.test(m)||this.moveTo(l=c),m){case"m":case"l":for(var w="m"===m,y=0;y<v;y+=2)this[0===y&&w?"moveTo":"lineTo"](l=n(y));a=l,w&&(c=l);break;case"h":case"v":for(var b="h"===m?"x":"y",y=0;y<v;y++)l[b]=t(y,b),this.lineTo(l);a=l;break;case"c":for(var y=0;y<v;y+=6)this.cubicCurveTo(n(y),a=n(y+2),l=n(y+4));break;case"s":for(var y=0;y<v;y+=4)this.cubicCurveTo(/[cs]/.test(i)?l.multiply(2).subtract(a):l,a=n(y),l=n(y+2)),i=m;break;case"q":for(var y=0;y<v;y+=4)this.quadraticCurveTo(a=n(y),l=n(y+2));break;case"t":for(var y=0;y<v;y+=2)this.quadraticCurveTo(a=/[qt]/.test(i)?l.multiply(2).subtract(a):l,l=n(y)),i=m;break;case"a":for(var y=0;y<v;y+=7)this.arcTo(l=n(y+5),new g(+r[y],+r[y+1]),+r[y+2],+r[y+4],+r[y+3]);break;case"z":this.closePath(!0)}i=m}},_canComposite:function(){return!(this.hasFill()&&this.hasStroke())},_contains:function(e){var t=this._getWinding(e,!1,!0);return!!("evenodd"===this.getWindingRule()?1&t:t)}}),z=B.extend({_class:"Path",_serializeFields:{segments:[],closed:!1},initialize:function(e){this._closed=!1,this._segments=[],this._version=0;var t=Array.isArray(e)?"object"==typeof e[0]?e:arguments:!e||e.size!==o||e.x===o&&e.point===o?null:arguments;t&&t.length>0?this.setSegments(t):(this._curves=o,this._selectedSegmentState=0,t||"string"!=typeof e||(this.setPathData(e),e=null)),this._initialize(!t&&e)},_equals:function(e){ +return this._closed===e._closed&&s.equals(this._segments,e._segments)},clone:function(e){var t=new z(C.NO_INSERT);return t.setSegments(this._segments),t._closed=this._closed,this._clockwise!==o&&(t._clockwise=this._clockwise),this._clone(t,e)},_changed:function e(t){if(e.base.call(this,t),8&t){var n=this._parent;if(n&&(n._currentPath=o),this._length=this._area=this._clockwise=this._monoCurves=o,16&t)this._version++;else if(this._curves)for(var r=0,i=this._curves.length;r<i;r++)this._curves[r]._changed()}else 32&t&&(this._bounds=o)},getStyle:function(){var e=this._parent;return(e instanceof R?e:this)._style},getSegments:function(){return this._segments},setSegments:function(e){var t=this.isFullySelected();this._segments.length=0,this._selectedSegmentState=0,this._curves=o,e&&e.length>0&&this._add(I.readAll(e)),t&&this.setFullySelected(!0)},getFirstSegment:function(){return this._segments[0]},getLastSegment:function(){return this._segments[this._segments.length-1]},getCurves:function(){var e=this._curves,t=this._segments;if(!e){var n=this._countCurves();e=this._curves=new Array(n);for(var r=0;r<n;r++)e[r]=new A(this,t[r],t[r+1]||t[0])}return e},getFirstCurve:function(){return this.getCurves()[0]},getLastCurve:function(){var e=this.getCurves();return e[e.length-1]},isClosed:function(){return this._closed},setClosed:function(e){if(this._closed!=(e=!!e)){if(this._closed=e,this._curves){var t=this._curves.length=this._countCurves();e&&(this._curves[t-1]=new A(this,this._segments[t-1],this._segments[0]))}this._changed(25)}}},{beans:!0,getPathData:function(e,t){function n(t,n){t._transformCoordinates(e,m,!1),r=m[0],i=m[1],g?(v.push("M"+p.pair(r,i)),g=!1):(s=m[2],l=m[3],s===r&&l===i&&c===a&&u===o?n||v.push("l"+p.pair(r-a,i-o)):v.push("c"+p.pair(c-a,u-o)+" "+p.pair(s-a,l-o)+" "+p.pair(r-a,i-o))),a=r,o=i,c=m[4],u=m[5]}var r,i,a,o,s,l,c,u,d=this._segments,f=d.length,p=new h(t),m=new Array(6),g=!0,v=[];if(0===f)return"";for(var w=0;w<f;w++)n(d[w]);return this._closed&&f>0&&(n(d[0],!0),v.push("z")),v.join("")}},{isEmpty:function(){return 0===this._segments.length},_transformContent:function(e){for(var t=new Array(6),n=0,r=this._segments.length;n<r;n++)this._segments[n]._transformCoordinates(e,t,!0);return!0},_add:function(e,t){for(var n=this._segments,r=this._curves,i=e.length,a=null==t,t=a?n.length:t,o=0;o<i;o++){var s=e[o];s._path&&(s=e[o]=s.clone()),s._path=this,s._index=t+o,s._selectionState&&this._updateSelection(s,0,s._selectionState)}if(a)n.push.apply(n,e);else{n.splice.apply(n,[t,0].concat(e));for(var o=t+i,l=n.length;o<l;o++)n[o]._index=o}if(r){var c=this._countCurves(),u=t+i-1===c?t-1:t,h=u,d=Math.min(u+i,c);e._curves&&(r.splice.apply(r,[u,0].concat(e._curves)),h+=e._curves.length);for(var o=h;o<d;o++)r.splice(o,0,new A(this,null,null));this._adjustCurves(u,d)}return this._changed(25),e},_adjustCurves:function(e,t){for(var n,r=this._segments,i=this._curves,a=e;a<t;a++)n=i[a],n._path=this,n._segment1=r[a],n._segment2=r[a+1]||r[0],n._changed();(n=i[this._closed&&0===e?r.length-1:e-1])&&(n._segment2=r[e]||r[0],n._changed()),(n=i[t])&&(n._segment1=r[t],n._changed())},_countCurves:function(){var e=this._segments.length;return!this._closed&&e>0?e-1:e},add:function(e){return arguments.length>1&&"number"!=typeof e?this._add(I.readAll(arguments)):this._add([I.read(arguments)])[0]},insert:function(e,t){return arguments.length>2&&"number"!=typeof t?this._add(I.readAll(arguments,1),e):this._add([I.read(arguments,1)],e)[0]},addSegment:function(){return this._add([I.read(arguments)])[0]},insertSegment:function(e){return this._add([I.read(arguments,1)],e)[0]},addSegments:function(e){return this._add(I.readAll(e))},insertSegments:function(e,t){return this._add(I.readAll(t),e)},removeSegment:function(e){return this.removeSegments(e,e+1)[0]||null},removeSegments:function(e,t,n){e=e||0,t=s.pick(t,this._segments.length);var r=this._segments,i=this._curves,a=r.length,o=r.splice(e,t-e),l=o.length;if(!l)return o;for(var c=0;c<l;c++){var u=o[c];u._selectionState&&this._updateSelection(u,u._selectionState,0),u._index=u._path=null}for(var c=e,h=r.length;c<h;c++)r[c]._index=c;if(i){var d=e>0&&t===a+(this._closed?1:0)?e-1:e,i=i.splice(d,l);n&&(o._curves=i.slice(1)),this._adjustCurves(d,d)}return this._changed(25),o},clear:"#removeSegments",hasHandles:function(){for(var e=this._segments,t=0,n=e.length;t<n;t++)if(e[t].hasHandles())return!0;return!1},clearHandles:function(){for(var e=this._segments,t=0,n=e.length;t<n;t++)e[t].clearHandles()},getLength:function(){if(null==this._length){for(var e=this.getCurves(),t=0,n=0,r=e.length;n<r;n++)t+=e[n].getLength();this._length=t}return this._length},getArea:function(){if(null==this._area){for(var e=this._segments,t=e.length,n=t-1,r=0,i=0,a=this._closed?t:n;i<a;i++)r+=A.getArea(A.getValues(e[i],e[i<n?i+1:0]));this._area=r}return this._area},isClockwise:function(){return this._clockwise!==o?this._clockwise:this.getArea()>=0},setClockwise:function(e){this.isClockwise()!=(e=!!e)&&this.reverse(),this._clockwise=e},isFullySelected:function(){var e=this._segments.length;return this._selected&&e>0&&this._selectedSegmentState===7*e},setFullySelected:function(e){e&&this._selectSegments(!0),this.setSelected(e)},setSelected:function e(t){t||this._selectSegments(!1),e.base.call(this,t)},_selectSegments:function(e){var t=this._segments.length;this._selectedSegmentState=e?7*t:0;for(var n=0;n<t;n++)this._segments[n]._selectionState=e?7:0},_updateSelection:function(e,t,n){e._selectionState=n;var r=this._selectedSegmentState+=n-t;r>0&&this.setSelected(!0)},flatten:function(e){for(var t=new D(this,64,.1),n=0,r=t.length/Math.ceil(t.length/e),i=t.length+(this._closed?-r:r)/2,a=[];n<=i;)a.push(new I(t.getPointAt(n))),n+=r;this.setSegments(a)},reduce:function(){for(var e=this.getCurves(),t=e.length-1;t>=0;t--){var n=e[t];n.hasHandles()||0!==n.getLength()&&!n.isCollinear(n.getNext())||n.remove()}return this},simplify:function(e){if(this._segments.length>2){var t=new j(this,e||2.5);this.setSegments(t.fit())}},split:function(e,t){if(null===t)return null;if(1===arguments.length){var n=e;if("number"==typeof n&&(n=this.getLocationAt(n)),!n)return null;e=n.index,t=n.parameter}var r=4e-7,i=1-r;t>=i&&(e++,t--);var a=this.getCurves();if(e>=0&&e<a.length){t>=r&&a[e++].divide(t,!0);var o,s=this.removeSegments(e,this._segments.length,!0);return this._closed?(this.setClosed(!1),o=this):(o=new z(C.NO_INSERT),o.insertAbove(this,!0),this._clone(o)),o._add(s,0),this.addSegment(s[0]),o}return null},reverse:function(){this._segments.reverse();for(var e=0,t=this._segments.length;e<t;e++){var n=this._segments[e],r=n._handleIn;n._handleIn=n._handleOut,n._handleOut=r,n._index=e}this._curves=null,this._clockwise!==o&&(this._clockwise=!this._clockwise),this._changed(9)},join:function(e){if(e){var t=e._segments,n=this.getLastSegment(),r=e.getLastSegment();if(!r)return this;n&&n._point.equals(r._point)&&e.reverse();var i=e.getFirstSegment();if(n&&n._point.equals(i._point))n.setHandleOut(i._handleOut),this._add(t.slice(1));else{var a=this.getFirstSegment();a&&a._point.equals(i._point)&&e.reverse(),r=e.getLastSegment(),a&&a._point.equals(r._point)?(a.setHandleIn(r._handleIn),this._add(t.slice(0,t.length-1),0)):this._add(t.slice())}e._closed&&this._add([t[0]]),e.remove()}var o=this.getFirstSegment(),s=this.getLastSegment();return o!==s&&o._point.equals(s._point)&&(o.setHandleIn(s._handleIn),s.remove(),this.setClosed(!0)),this},toShape:function(e){function t(e,t){var n=c[e],r=n.getNext(),i=c[t],a=i.getNext();return n._handleOut.isZero()&&r._handleIn.isZero()&&i._handleOut.isZero()&&a._handleIn.isZero()&&r._point.subtract(n._point).isCollinear(a._point.subtract(i._point))}function n(e){var t=c[e],n=t.getPrevious(),r=t.getNext();return n._handleOut.isZero()&&t._handleIn.isZero()&&t._handleOut.isZero()&&r._handleIn.isZero()&&t._point.subtract(n._point).isOrthogonal(r._point.subtract(t._point))}function r(e){var t=c[e],n=t.getNext(),r=t._handleOut,i=n._handleIn,a=.5522847498307936;if(r.isOrthogonal(i)){var o=t._point,s=n._point,l=new _(o,r,!0).intersect(new _(s,i,!0),!0);return l&&d.isZero(r.getLength()/l.subtract(o).getLength()-a)&&d.isZero(i.getLength()/l.subtract(s).getLength()-a)}return!1}function i(e,t){return c[e]._point.getDistance(c[t]._point)}if(!this._closed)return null;var a,o,s,l,c=this._segments;if(!this.hasHandles()&&4===c.length&&t(0,2)&&t(1,3)&&n(1)?(a=P.Rectangle,o=new g(i(0,3),i(0,1)),l=c[1]._point.add(c[2]._point).divide(2)):8===c.length&&r(0)&&r(2)&&r(4)&&r(6)&&t(1,5)&&t(3,7)?(a=P.Rectangle,o=new g(i(1,6),i(0,3)),s=o.subtract(new g(i(0,7),i(1,2))).divide(2),l=c[3]._point.add(c[4]._point).divide(2)):4===c.length&&r(0)&&r(1)&&r(2)&&r(3)&&(d.isZero(i(0,2)-i(1,3))?(a=P.Circle,s=i(0,2)/2):(a=P.Ellipse,s=new g(i(2,0)/2,i(3,1)/2)),l=c[1]._point),a){var u=this.getPosition(!0),h=this._clone(new a({center:u,size:o,radius:s,insert:!1}),e,!1);return h.rotate(l.subtract(u).getAngle()+90),h}return null},_hitTestSelf:function(e,t){function n(t,n){return e.subtract(t).divide(n).length<=1}function r(e,r,i){if(!t.selected||r.isSelected()){var a=e._point;if(r!==a&&(r=r.add(a)),n(r,b))return new N(i,f,{segment:e,point:r})}}function i(e,n){return(n||t.segments)&&r(e,e._point,"segment")||!n&&t.handles&&(r(e,e._handleIn,"handle-in")||r(e,e._handleOut,"handle-out"))}function a(e){u.add(e)}function o(t){if(("round"!==s||"round"!==l)&&(u=new z({internal:!0,closed:!0}),w||t._index>0&&t._index<v-1?"round"!==s&&(t._handleIn.isZero()||t._handleOut.isZero())&&z._addBevelJoin(t,s,C,c,a,!0):"round"!==l&&z._addSquareCap(t,l,C,a,!0),!u.isEmpty())){var r;return u.contains(e)||(r=u.getNearestLocation(e))&&n(r.getPoint(),y)}return n(t._point,b)}var s,l,c,u,h,d,f=this,m=this.getStyle(),g=this._segments,v=g.length,w=this._closed,y=t._tolerancePadding,b=y,_=t.stroke&&m.hasStroke(),x=t.fill&&m.hasFill(),E=t.curves,C=_?m.getStrokeWidth()/2:x&&t.tolerance>0||E?0:null;if(null!==C&&(C>0?(s=m.getStrokeJoin(),l=m.getStrokeCap(),c=C*m.getMiterLimit(),b=y.add(new p(C,C))):s=l="round"),!t.ends||t.segments||w){if(t.segments||t.handles)for(var k=0;k<v;k++)if(d=i(g[k]))return d}else if(d=i(g[0],!0)||i(g[v-1],!0))return d;if(null!==C){if(h=this.getNearestLocation(e)){var S=h.getParameter();0===S||1===S&&v>1?o(h.getSegment())||(h=null):n(h.getPoint(),b)||(h=null)}if(!h&&"miter"===s&&v>1)for(var k=0;k<v;k++){var P=g[k];if(e.getDistance(P._point)<=c&&o(P)){h=P.getLocation();break}}}return!h&&x&&this._contains(e)||h&&!_&&!E?new N("fill",this):h?new N(_?"stroke":"curve",this,{location:h,point:h.getPoint()}):null}},s.each(A.evaluateMethods,function(e){this[e+"At"]=function(t,n){var r=this.getLocationAt(t,n);return r&&r[e]()}},{beans:!1,getLocationOf:function(){for(var e=p.read(arguments),t=this.getCurves(),n=0,r=t.length;n<r;n++){var i=t[n].getLocationOf(e);if(i)return i}return null},getOffsetOf:function(){var e=this.getLocationOf.apply(this,arguments);return e?e.getOffset():null},getLocationAt:function(e,t){var n=this.getCurves(),r=0;if(t){var i=~~e,a=n[i];return a?a.getLocationAt(e-i,!0):null}for(var o=0,s=n.length;o<s;o++){var l=r,a=n[o];if(r+=a.getLength(),r>e)return a.getLocationAt(e-l)}return n.length>0&&e<=this.getLength()?new O(n[n.length-1],1):null},getNearestLocation:function(){for(var e=p.read(arguments),t=this.getCurves(),n=1/0,r=null,i=0,a=t.length;i<a;i++){var o=t[i].getNearestLocation(e);o._distance<n&&(n=o._distance,r=o)}return r},getNearestPoint:function(){return this.getNearestLocation.apply(this,arguments).getPoint()}}),new function(){function e(e,t,n,r){function i(t){var n=o[t],r=o[t+1];h==n&&d==r||(e.beginPath(),e.moveTo(h,d),e.lineTo(n,r),e.stroke(),e.beginPath(),e.arc(n,r,a,0,2*Math.PI,!0),e.fill())}for(var a=r/2,o=new Array(6),s=0,l=t.length;s<l;s++){var c=t[s];c._transformCoordinates(n,o,!1);var u=c._selectionState,h=o[0],d=o[1];if(1&u&&i(2),2&u&&i(4),e.fillRect(h-a,d-a,r,r),!(4&u)){var f=e.fillStyle;e.fillStyle="#ffffff",e.fillRect(h-a+1,d-a+1,r-2,r-2),e.fillStyle=f}}}function t(e,t,n){function r(t){if(n)t._transformCoordinates(n,p,!1),i=p[0],a=p[1];else{var r=t._point;i=r._x,a=r._y}if(m)e.moveTo(i,a),m=!1;else{if(n)l=p[2],c=p[3];else{var d=t._handleIn;l=i+d._x,c=a+d._y}l===i&&c===a&&u===o&&h===s?e.lineTo(i,a):e.bezierCurveTo(u,h,l,c,i,a)}if(o=i,s=a,n)u=p[4],h=p[5];else{var d=t._handleOut;u=o+d._x,h=s+d._y}}for(var i,a,o,s,l,c,u,h,d=t._segments,f=d.length,p=new Array(6),m=!0,g=0;g<f;g++)r(d[g]);t._closed&&f>0&&r(d[0])}return{_draw:function(e,n,r){function i(e){return h[(e%d+d)%d]}var o=n.dontStart,s=n.dontFinish||n.clip,l=this.getStyle(),c=l.hasFill(),u=l.hasStroke(),h=l.getDashArray(),d=!a.support.nativeDash&&u&&h&&h.length;if(o||e.beginPath(),!o&&this._currentPath?e.currentPath=this._currentPath:(c||u&&!d||s)&&(t(e,this,r),this._closed&&e.closePath(),o||(this._currentPath=e.currentPath)),!s&&(c||u)&&(this._setStyles(e),c&&(e.fill(l.getWindingRule()),e.shadowColor="rgba(0,0,0,0)"),u)){if(d){o||e.beginPath();var f,p=new D(this,32,.25,r),m=p.length,g=-l.getDashOffset(),v=0;for(g%=m;g>0;)g-=i(v--)+i(v--);for(;g<m;)f=g+i(v++),(g>0||f>0)&&p.drawPart(e,Math.max(g,0),Math.max(f,0)),g=f+i(v++)}e.stroke()}},_drawSelected:function(n,r){n.beginPath(),t(n,this,r),n.stroke(),e(n,this._segments,r,a.settings.handleSize)}}},new function(){function e(e){var t=e.length,n=[],r=[],i=2;n[0]=e[0]/i;for(var a=1;a<t;a++)r[a]=1/i,i=(a<t-1?4:2)-r[a],n[a]=(e[a]-n[a-1])/i;for(var a=1;a<t;a++)n[t-a-1]-=r[t-a]*n[t-a];return n}return{smooth:function(){var t=this._segments,n=t.length,r=this._closed,i=n,a=0;if(!(n<=2)){r&&(a=Math.min(n,4),i+=2*Math.min(n,a));for(var o=[],s=0;s<n;s++)o[s+a]=t[s]._point;if(r)for(var s=0;s<a;s++)o[s]=t[s+n-a]._point,o[s+n+a]=t[s]._point;else i--;for(var l=[],s=1;s<i-1;s++)l[s]=4*o[s]._x+2*o[s+1]._x;l[0]=o[0]._x+2*o[1]._x,l[i-1]=3*o[i-1]._x;for(var c=e(l),s=1;s<i-1;s++)l[s]=4*o[s]._y+2*o[s+1]._y;l[0]=o[0]._y+2*o[1]._y,l[i-1]=3*o[i-1]._y;var u=e(l);if(r){for(var s=0,h=n;s<a;s++,h++){var d=s/a,f=1-d,m=s+a,g=h+a;c[h]=c[s]*d+c[h]*f,u[h]=u[s]*d+u[h]*f,c[g]=c[m]*f+c[g]*d,u[g]=u[m]*f+u[g]*d}i--}for(var v=null,s=a;s<=i-a;s++){var w=t[s-a];v&&w.setHandleIn(v.subtract(w._point)),s<i&&(w.setHandleOut(new p(c[s],u[s]).subtract(w._point)),v=s<i-1?new p(2*o[s+1]._x-c[s+1],2*o[s+1]._y-u[s+1]):new p((o[i]._x+c[i-1])/2,(o[i]._y+u[i-1])/2))}if(r&&v){var w=this._segments[0];w.setHandleIn(v.subtract(w._point))}}}}},new function(){function e(e){var t=e._segments;if(0===t.length)throw new Error("Use a moveTo() command first");return t[t.length-1]}return{moveTo:function(){var e=this._segments;1===e.length&&this.removeSegment(0),e.length||this._add([new I(p.read(arguments))])},moveBy:function(){throw new Error("moveBy() is unsupported on Path items.")},lineTo:function(){this._add([new I(p.read(arguments))])},cubicCurveTo:function(){var t=p.read(arguments),n=p.read(arguments),r=p.read(arguments),i=e(this);i.setHandleOut(t.subtract(i._point)),this._add([new I(r,n.subtract(r))])},quadraticCurveTo:function(){var t=p.read(arguments),n=p.read(arguments),r=e(this)._point;this.cubicCurveTo(t.add(r.subtract(t).multiply(1/3)),t.add(n.subtract(t).multiply(1/3)),n)},curveTo:function(){var t=p.read(arguments),n=p.read(arguments),r=s.pick(s.read(arguments),.5),i=1-r,a=e(this)._point,o=t.subtract(a.multiply(i*i)).subtract(n.multiply(r*r)).divide(2*r*i);if(o.isNaN())throw new Error("Cannot put a curve through points with parameter = "+r);this.quadraticCurveTo(o,n)},arcTo:function(){var t,n,r,i,a,o=e(this),l=o._point,c=p.read(arguments),u=s.peek(arguments),h=s.pick(u,!0);if("boolean"==typeof h)var d=l.add(c).divide(2),t=d.add(d.subtract(l).rotate(h?-90:90));else if(s.remain(arguments)<=2)t=c,c=p.read(arguments);else{var f=g.read(arguments);if(f.isZero())return this.lineTo(c);var m=s.read(arguments),h=!!s.read(arguments),v=!!s.read(arguments),d=l.add(c).divide(2),w=l.subtract(d).rotate(-m),y=w.x,x=w.y,E=Math.abs,C=E(f.width),k=E(f.height),S=C*C,P=k*k,T=y*y,M=x*x,N=Math.sqrt(T/S+M/P);if(N>1&&(C*=N,k*=N,S=C*C,P=k*k),N=(S*P-S*M-P*T)/(S*M+P*T),E(N)<1e-12&&(N=0),N<0)throw new Error("Cannot create an arc with the given arguments");n=new p(C*x/k,-k*y/C).multiply((v===h?-1:1)*Math.sqrt(N)).rotate(m).add(d),a=(new b).translate(n).rotate(m).scale(C,k),i=a._inverseTransform(l),r=i.getDirectedAngle(a._inverseTransform(c)),!h&&r>0?r-=360:h&&r<0&&(r+=360)}if(t){var L=new _(l.add(t).divide(2),t.subtract(l).rotate(90),!0),A=new _(t.add(c).divide(2),c.subtract(t).rotate(90),!0),O=new _(l,c),B=O.getSide(t);if(n=L.intersect(A,!0),!n){if(!B)return this.lineTo(c);throw new Error("Cannot create an arc with the given arguments")}i=l.subtract(n),r=i.getDirectedAngle(c.subtract(n));var z=O.getSide(n);0===z?r=B*Math.abs(r):B===z&&(r+=r<0?360:-360)}for(var R=Math.abs(r),D=R>=360?4:Math.ceil(R/90),j=r/D,F=j*Math.PI/360,q=4/3*Math.sin(F)/(1+Math.cos(F)),V=[],U=0;U<=D;U++){var w=c,W=null;if(U<D&&(W=i.rotate(90).multiply(q),a?(w=a._transformPoint(i),W=a._transformPoint(i.add(W)).subtract(w)):w=n.add(i)),0===U)o.setHandleOut(W);else{var G=i.rotate(-90).multiply(q);a&&(G=a._transformPoint(i.add(G)).subtract(w)),V.push(new I(w,G,W))}i=i.rotate(j)}this._add(V)},lineBy:function(){var t=p.read(arguments),n=e(this)._point;this.lineTo(n.add(t))},curveBy:function(){var t=p.read(arguments),n=p.read(arguments),r=s.read(arguments),i=e(this)._point;this.curveTo(i.add(t),i.add(n),r)},cubicCurveBy:function(){var t=p.read(arguments),n=p.read(arguments),r=p.read(arguments),i=e(this)._point;this.cubicCurveTo(i.add(t),i.add(n),i.add(r))},quadraticCurveBy:function(){var t=p.read(arguments),n=p.read(arguments),r=e(this)._point;this.quadraticCurveTo(r.add(t),r.add(n))},arcBy:function(){var t=e(this)._point,n=t.add(p.read(arguments)),r=s.pick(s.peek(arguments),!0);"boolean"==typeof r?this.arcTo(n,r):this.arcTo(n,t.add(p.read(arguments)))},closePath:function(e){this.setClosed(!0),e&&this.join()}}},{_getBounds:function(e,t){return z[e](this._segments,this._closed,this.getStyle(),t)},statics:{getBounds:function(e,t,n,r,i){function a(e){e._transformCoordinates(r,s,!1);for(var t=0;t<2;t++)A._addBounds(l[t],l[t+4],s[t+2],s[t],t,i?i[t]:0,c,u,h);var n=l;l=s,s=n}var o=e[0];if(!o)return new w;for(var s=new Array(6),l=o._transformCoordinates(r,new Array(6),!1),c=l.slice(0,2),u=c.slice(),h=new Array(2),d=1,f=e.length;d<f;d++)a(e[d]);return t&&a(o),new w(c[0],c[1],u[0]-c[0],u[1]-c[1])},getStrokeBounds:function(e,t,n,r){function i(e){h=h.include(r?r._transformPoint(e,e):e)}function a(e){h=h.unite(m.setCenter(r?r._transformPoint(e._point):e._point))}function o(e,t){var n=e._handleIn,r=e._handleOut;"round"===t||!n.isZero()&&!r.isZero()&&n.isCollinear(r)?a(e):z._addBevelJoin(e,t,c,p,i)}function s(e,t){"round"===t?a(e):z._addSquareCap(e,t,c,i)}if(!n.hasStroke())return z.getBounds(e,t,n,r);for(var l=e.length-(t?0:1),c=n.getStrokeWidth()/2,u=z._getPenPadding(c,r),h=z.getBounds(e,t,n,r,u),d=n.getStrokeJoin(),f=n.getStrokeCap(),p=c*n.getMiterLimit(),m=new w(new g(u).multiply(2)),v=1;v<l;v++)o(e[v],d);return t?o(e[0],d):l>0&&(s(e[0],f),s(e[e.length-1],f)),h},_getPenPadding:function(e,t){if(!t)return[e,e];var n=t.shiftless(),r=n.transform(new p(e,0)),i=n.transform(new p(0,e)),a=r.getAngleInRadians(),o=r.getLength(),s=i.getLength(),l=Math.sin(a),c=Math.cos(a),u=Math.tan(a),h=-Math.atan(s*u/o),d=Math.atan(s/(u*o));return[Math.abs(o*Math.cos(h)*c-s*Math.sin(h)*l),Math.abs(s*Math.sin(d)*c+o*Math.cos(d)*l)]},_addBevelJoin:function(e,t,n,r,i,a){var o=e.getCurve(),s=o.getPrevious(),l=o.getPointAt(0,!0),c=s.getNormalAt(1,!0),u=o.getNormalAt(0,!0),h=c.getDirectedAngle(u)<0?-n:n;if(c.setLength(h),u.setLength(h),a&&(i(l),i(l.add(c))),"miter"===t){var d=new _(l.add(c),new p(-c.y,c.x),!0).intersect(new _(l.add(u),new p(-u.y,u.x),!0),!0);if(d&&l.getDistance(d)<=r&&(i(d),!a))return}a||i(l.add(c)),i(l.add(u))},_addSquareCap:function(e,t,n,r,i){var a=e._point,o=e.getLocation(),s=o.getNormal().multiply(n);i&&(r(a.subtract(s)),r(a.add(s))),"square"===t&&(a=a.add(s.rotate(0===o.getParameter()?-90:90))),r(a.add(s)),r(a.subtract(s))},getHandleBounds:function(e,t,n,r,i,a){for(var o=new Array(6),s=1/0,l=-s,c=s,u=l,h=0,d=e.length;h<d;h++){var f=e[h];f._transformCoordinates(r,o,!1);for(var p=0;p<6;p+=2){var m=0===p?a:i,g=m?m[0]:0,v=m?m[1]:0,y=o[p],b=o[p+1],_=y-g,x=y+g,E=b-v,C=b+v;_<s&&(s=_),x>l&&(l=x),E<c&&(c=E),C>u&&(u=C)}}return new w(s,c,l-s,u-c)},getRoughBounds:function(e,t,n,r){var i=n.hasStroke()?n.getStrokeWidth()/2:0,a=i;return i>0&&("miter"===n.getStrokeJoin()&&(a=i*n.getMiterLimit()),"square"===n.getStrokeCap()&&(a=Math.max(a,i*Math.sqrt(2)))),z.getHandleBounds(e,t,n,r,z._getPenPadding(i,r),z._getPenPadding(a,r))}}});z.inject({statics:new function(){function e(e,t,n){var r=s.getNamed(n),i=new z(r&&r.insert===!1&&C.NO_INSERT);return i._add(e),i._closed=t,i.set(r)}function t(t,n,i){for(var a=new Array(4),o=0;o<4;o++){var s=r[o];a[o]=new I(s._point.multiply(n).add(t),s._handleIn.multiply(n),s._handleOut.multiply(n))}return e(a,!0,i)}var n=.5522847498307936,r=[new I([-1,0],[0,n],[0,-n]),new I([0,-1],[-n,0],[n,0]),new I([1,0],[0,-n],[0,n]),new I([0,1],[n,0],[-n,0])];return{Line:function(){return e([new I(p.readNamed(arguments,"from")),new I(p.readNamed(arguments,"to"))],!1,arguments)},Circle:function(){var e=p.readNamed(arguments,"center"),n=s.readNamed(arguments,"radius");return t(e,new g(n),arguments)},Rectangle:function(){var t,r=w.readNamed(arguments,"rectangle"),i=g.readNamed(arguments,"radius",0,{readNull:!0}),a=r.getBottomLeft(!0),o=r.getTopLeft(!0),s=r.getTopRight(!0),l=r.getBottomRight(!0);if(!i||i.isZero())t=[new I(a),new I(o),new I(s),new I(l)];else{i=g.min(i,r.getSize(!0).divide(2));var c=i.width,u=i.height,h=c*n,d=u*n;t=[new I(a.add(c,0),null,[-h,0]),new I(a.subtract(0,u),[0,d]),new I(o.add(0,u),null,[0,-d]),new I(o.add(c,0),[-h,0],null),new I(s.subtract(c,0),null,[h,0]),new I(s.add(0,u),[0,-d],null),new I(l.subtract(0,u),null,[0,d]),new I(l.subtract(c,0),[h,0])]}return e(t,!0,arguments)},RoundRectangle:"#Rectangle",Ellipse:function(){var e=P._readEllipse(arguments);return t(e.center,e.radius,arguments)},Oval:"#Ellipse",Arc:function(){var e=p.readNamed(arguments,"from"),t=p.readNamed(arguments,"through"),n=p.readNamed(arguments,"to"),r=s.getNamed(arguments),i=new z(r&&r.insert===!1&&C.NO_INSERT);return i.moveTo(e),i.arcTo(t,n),i.set(r)},RegularPolygon:function(){for(var t=p.readNamed(arguments,"center"),n=s.readNamed(arguments,"sides"),r=s.readNamed(arguments,"radius"),i=360/n,a=!(n%3),o=new p(0,a?-r:r),l=a?-1:.5,c=new Array(n),u=0;u<n;u++)c[u]=new I(t.add(o.rotate((u+l)*i)));return e(c,!0,arguments)},Star:function(){for(var t=p.readNamed(arguments,"center"),n=2*s.readNamed(arguments,"points"),r=s.readNamed(arguments,"radius1"),i=s.readNamed(arguments,"radius2"),a=360/n,o=new p(0,-1),l=new Array(n),c=0;c<n;c++)l[c]=new I(t.add(o.rotate(a*c).multiply(c%2?i:r)));return e(l,!0,arguments)}}}});var R=B.extend({_class:"CompoundPath",_serializeFields:{children:[]},initialize:function(e){this._children=[],this._namedChildren={},this._initialize(e)||("string"==typeof e?this.setPathData(e):this.addChildren(Array.isArray(e)?e:arguments))},insertChildren:function e(t,n,r){for(var i=n.length-1;i>=0;i--){var a=n[i];a instanceof R&&(n.splice.apply(n,[i,1].concat(a.removeChildren())),a.remove())}n=e.base.call(this,t,n,r,z);for(var i=0,s=!r&&n&&n.length;i<s;i++){var a=n[i];a._clockwise===o&&a.setClockwise(0===a._index)}return n},reverse:function(){for(var e=this._children,t=0,n=e.length;t<n;t++)e[t].reverse()},smooth:function(){for(var e=0,t=this._children.length;e<t;e++)this._children[e].smooth()},reduce:function e(){for(var t=this._children,n=t.length-1;n>=0;n--){var r=t[n].reduce();r.isEmpty()&&t.splice(n,1)}if(0===t.length){var r=new z(C.NO_INSERT);return r.insertAbove(this),r.setStyle(this._style),this.remove(),r}return e.base.call(this)},isClockwise:function(){var e=this.getFirstChild();return e&&e.isClockwise()},setClockwise:function(e){this.isClockwise()!==!!e&&this.reverse()},getFirstSegment:function(){var e=this.getFirstChild();return e&&e.getFirstSegment()},getLastSegment:function(){var e=this.getLastChild();return e&&e.getLastSegment()},getCurves:function(){for(var e=this._children,t=[],n=0,r=e.length;n<r;n++)t.push.apply(t,e[n].getCurves());return t},getFirstCurve:function(){var e=this.getFirstChild();return e&&e.getFirstCurve()},getLastCurve:function(){var e=this.getLastChild();return e&&e.getFirstCurve()},getArea:function(){for(var e=this._children,t=0,n=0,r=e.length;n<r;n++)t+=e[n].getArea();return t}},{beans:!0,getPathData:function(e,t){for(var n=this._children,r=[],i=0,a=n.length;i<a;i++){var o=n[i],s=o._matrix;r.push(o.getPathData(e&&!s.isIdentity()?e.chain(s):e,t))}return r.join(" ")}},{_getChildHitTestOptions:function(e){return e.class===z||"path"===e.type?e:new s(e,{fill:!1})},_draw:function(e,t,n){var r=this._children;if(0!==r.length){if(this._currentPath)e.currentPath=this._currentPath;else{t=t.extend({dontStart:!0,dontFinish:!0}),e.beginPath();for(var i=0,a=r.length;i<a;i++)r[i].draw(e,t,n);this._currentPath=e.currentPath}if(!t.clip){this._setStyles(e);var o=this._style;o.hasFill()&&(e.fill(o.getWindingRule()),e.shadowColor="rgba(0,0,0,0)"),o.hasStroke()&&e.stroke()}}},_drawSelected:function(e,t,n){for(var r=this._children,i=0,a=r.length;i<a;i++){var o=r[i],s=o._matrix;n[o._id]||o._drawSelected(e,s.isIdentity()?t:t.chain(s))}}},new function(){function e(e,t){var n=e._children;if(t&&0===n.length)throw new Error("Use a moveTo() command first");return n[n.length-1]}var t={moveTo:function(){var t=e(this),n=t&&t.isEmpty()?t:new z(C.NO_INSERT);n!==t&&this.addChild(n),n.moveTo.apply(n,arguments)},moveBy:function(){var t=e(this,!0),n=t&&t.getLastSegment(),r=p.read(arguments);this.moveTo(n?r.add(n._point):r)},closePath:function(t){e(this,!0).closePath(t)}};return s.each(["lineTo","cubicCurveTo","quadraticCurveTo","curveTo","arcTo","lineBy","cubicCurveBy","quadraticCurveBy","curveBy","arcBy"],function(n){t[n]=function(){var t=e(this,!0);t[n].apply(t,arguments)}}),t});B.inject(new function(){function e(e,t){var n=e.clone(!1).reduce().transform(null,!0,!0);return t?n.resolveCrossings().reorient():n}function t(e,t,n,r,i){var a=new e(C.NO_INSERT);return a.addChildren(t,!0),i&&(a=a.reduce()),a.insertAbove(r&&n.isSibling(r)&&n.getIndex()<r.getIndex()?r:n),a.setStyle(n._style),a}function n(n,i,o){function c(e){for(var t=0,n=e.length;t<n;t++){var r=e[t];f.push.apply(f,r._segments),p.push.apply(p,r._getMonoCurves())}}if(!n._children&&!n._closed)return r(n,i,o);var u=e(n,!0),h=i&&n!==i&&e(i,!0);h&&/^(subtract|exclude)$/.test(o)^h.isClockwise()!==u.isClockwise()&&h.reverse();var d=O.expand(u.getIntersections(h,function(e){return h&&e.isOverlap()||e.isCrossing()}));a(d);var f=[],p=[];c(u._children||[u]),h&&c(h._children||[h]);for(var m=0,g=d.length;m<g;m++)s(d[m]._segment,u,h,p,o);for(var m=0,g=f.length;m<g;m++){var v=f[m];null==v._winding&&s(v,u,h,p,o)}return t(R,l(f,o),n,i,!0)}function r(n,r,i){function a(e){if(s.contains(e.getPointAt(e.getLength()/2))^c)return u.unshift(e),!0}if(!r||!r._children&&!r._closed||!/^(subtract|intersect)$/.test(i))return null;for(var o=e(n,!1),s=e(r,!1),l=o.getIntersections(s,function(e){return e.isOverlap()||e.isCrossing()}),c="subtract"===i,u=[],h=l.length-1;h>=0;h--){var d=l[h].split();d&&(a(d)&&d.getFirstSegment().setHandleIn(0,0),o.getLastSegment().setHandleOut(0,0))}return a(o),t(k,u,n,r)}function i(e,t){for(var n=e;n;){if(n===t)return;n=n._prev}for(;e._next&&e._next!==t;)e=e._next;if(!e._next){for(;t._prev;)t=t._prev;e._next=t,t._prev=e}}function a(e){for(var t,n,r=4e-7,a=1-r,o=!1,s=[],l=e.length-1;l>=0;l--){var c=e[l],u=c._curve,h=c._parameter,d=h;u!==t?o=!u.hasHandles():n>0&&(h/=n);var f;h<r?f=u._segment1:h>a?f=u._segment2:(f=u.divide(h,!0,!0)._segment1,o&&s.push(f)),c._setSegment(f);var p=f._intersection,m=c._intersection;if(p){i(p,m);for(var g=p;g;)i(g._intersection,p),g=g._next}else f._intersection=m;t=u,n=d}for(var l=0,v=s.length;l<v;l++)s[l].clearHandles()}function o(e,t,n,r){var i=2e-7,a=4e-7,s=1-a,l=e.x,c=e.y,u=0,h=0,f=[],m=Math.abs;if(n){for(var g=-(1/0),v=1/0,w=c-i,y=c+i,b=0,_=t.length;b<_;b++){var x=t[b].values;if(A.solveCubic(x,0,l,f,0,1)>0)for(var E=f.length-1;E>=0;E--){var C=A.getPoint(x,f[E]).y;C<w&&C>g?g=C:C>y&&C<v&&(v=C)}}g=(g+c)/2,v=(v+c)/2,g>-(1/0)&&(u=o(new p(l,g),t,!1,r)),v<1/0&&(h=o(new p(l,v),t,!1,r))}else for(var k,S,P=l-i,T=l+i,M=!1,b=0,_=t.length;b<_;b++){var N=t[b],x=N.values,I=N.winding;if(I&&(1===I&&c>=x[1]&&c<=x[7]||c>=x[7]&&c<=x[1])&&1===A.solveCubic(x,1,c,f,0,1)){var L=f[0];if(!(L>s&&M&&N.next!==t[b+1]||L<a&&S>s&&N.previous===k)){var O=A.getPoint(x,L).x,B=A.getTangent(x,L).y,z=!1;d.isZero(B)&&!A.isStraight(x)||L<a&&B*A.getTangent(N.previous.values,1).y<0||L>s&&B*A.getTangent(N.next.values,0).y<0?r&&O>=P&&O<=T&&(++u,++h,z=!0):O<=P?(u+=I,z=!0):O>=T&&(h+=I,z=!0),N.previous!==t[b-1]&&(M=L<a&&z)}k=N,S=L}}return Math.max(m(u),m(h))}function s(e,t,n,r,i){var a=2e-7,s=[],l=e,c=0,u=0;do{var h=e.getCurve(),d=h.getLength();s.push({segment:e,curve:h,length:d}),c+=d,e=e.getNext()}while(e&&!e._intersection&&e!==l);for(var f=0;f<3;f++)for(var d=c*(f+1)/4,p=0,m=s.length;p<m;p++){var g=s[p],v=g.length;if(d<=v){(d<a||v-d<a)&&(d=v/2);var h=g.curve,w=h._path,y=w._parent,b=h.getPointAt(d),_=h.isHorizontal();y instanceof R&&(w=y),u+="subtract"===i&&n&&(w===t&&n._getWinding(b,_)||w===n&&!t._getWinding(b,_))?0:o(b,r,_);break}d-=v}for(var x=Math.round(u/3),E=s.length-1;E>=0;E--)s[E].segment._winding=x}function l(e,t){function n(e,t){if(e._visited)return!1;if(!u)return!0;var n=e._winding,r=e._intersection;return r&&t&&h&&r.isOverlap()&&(n=h[n]||n),u(n)}function r(e){return e===o||e===s}function i(e,t){if(!e._next)return e;for(;e;){var i=e._segment,a=i.getNext(),o=a._intersection;if(r(a)||!i._visited&&!a._visited&&(!u||(!t||n(i))&&(!(t&&o&&o.isOverlap())&&n(a)||!t&&o&&n(o._segment))))return e;e=e._next}return null}function a(e,t){for(;e;){var n=e._segment;if(r(n))return n;e=e[t?"_next":"_prev"]}}for(var o,s,l=[],u=c[t],h={unite:{1:2},intersect:{2:1}}[t],f=0,p=e.length;f<p;f++){var m=e[f],g=null,v=!1;if(n(m,!0)){for(o=s=null;!v;){var w=m._intersection,y=g&&m._handleIn;w=w&&(i(w,!0)||i(w,!1))||w;var b=w&&w._segment;if(b&&n(b)&&(m=b),m._visited){if(v=r(m),!v&&w){var _=a(w,!0)||a(w,!1);_&&(m=_,v=!0)}break}g||(g=new z(C.NO_INSERT),o=m,s=b),g.add(new I(m._point,y,m._handleOut)),m._visited=!0,m=m.getNext(),v=r(m)}v?(g.firstSegment.setHandleIn(m._handleIn),g.setClosed(!0)):g&&(console.error("Boolean operation resulted in open path","segments =",g._segments.length,"length =",g.getLength()),g=null),g&&(g._segments.length>8||!d.isZero(g.getArea()))&&(l.push(g),g=null)}}return l}var c={unite:function(e){return 1===e||0===e},intersect:function(e){return 2===e},subtract:function(e){return 1===e},exclude:function(e){return 1===e}};return{_getWinding:function(e,t,n){return o(e,this._getMonoCurves(),t,n)},unite:function(e){return n(this,e,"unite")},intersect:function(e){return n(this,e,"intersect")},subtract:function(e){return n(this,e,"subtract")},exclude:function(e){return n(this,e,"exclude")},divide:function(e){return t(k,[this.subtract(e),this.intersect(e)],this,e,!0)},resolveCrossings:function(){var e=this.getCrossings();if(!e.length)return this;a(O.expand(e));for(var n=this._children||[this],r=[],i=0,o=n.length;i<o;i++)r.push.apply(r,n[i]._segments);return t(R,l(r),this,null,!1)}}}),z.inject({_getMonoCurves:function(){function e(e){var t=e[1],i=e[7],a={values:e,winding:t===i?0:t>i?-1:1,previous:n,next:null};n&&(n.next=a),r.push(a),n=a}function t(t){if(0!==A.getLength(t)){var n=t[1],r=t[3],i=t[5],a=t[7];if(A.isStraight(t))e(t);else{var o=3*(r-i)-n+a,s=2*(n+i)-4*r,l=r-n,c=4e-7,u=1-c,h=[],f=d.solveQuadratic(o,s,l,h,c,u);if(0===f)e(t);else{h.sort();var p=h[0],m=A.subdivide(t,p);e(m[0]),f>1&&(p=(h[1]-p)/(1-p),m=A.subdivide(m[1],p),e(m[0])),e(m[1])}}}}var n,r=this._monoCurves;if(!r){r=this._monoCurves=[];for(var i=this.getCurves(),a=this._segments,o=0,s=i.length;o<s;o++)t(i[o].getValues());if(!this._closed&&a.length>1){var l=a[a.length-1]._point,c=a[0]._point,u=l._x,h=l._y,f=c._x,p=c._y;t([u,h,u,h,f,p,f,p])}if(r.length>0){var m=r[0],g=r[r.length-1];m.previous=g, +g.next=m}}return r},getInteriorPoint:function(){var e=this.getBounds(),t=e.getCenter(!0);if(!this.contains(t)){for(var n=this._getMonoCurves(),r=[],i=t.y,a=[],o=0,s=n.length;o<s;o++){var l=n[o].values;if((1===n[o].winding&&i>=l[1]&&i<=l[7]||i>=l[7]&&i<=l[1])&&A.solveCubic(l,1,i,r,0,1)>0)for(var c=r.length-1;c>=0;c--)a.push(A.getPoint(l,r[c]).x);if(a.length>1)break}t.x=(a[0]+a[1])/2}return t},reorient:function(){return this.setClockwise(!0),this}}),R.inject({_getMonoCurves:function(){for(var e=this._children,t=[],n=0,r=e.length;n<r;n++)t.push.apply(t,e[n]._getMonoCurves());return t},reorient:function(){var e=this.removeChildren().sort(function(e,t){return t.getBounds().getArea()-e.getBounds().getArea()});if(e.length>0){this.addChildren(e);for(var t=e[0].isClockwise(),n=1,r=e.length;n<r;n++){for(var i=e[n].getInteriorPoint(),a=0,o=n-1;o>=0;o--)e[o].contains(i)&&a++;e[n].setClockwise(a%2===0&&t)}}return this}});var D=s.extend({_class:"PathIterator",initialize:function(e,t,n,r){function i(e,t){var n=A.getValues(e,t,r);s.push(n),a(n,e._index,0,1)}function a(e,t,r,i){if(i-r>u&&!A.isFlatEnough(e,n||.25)){var o=A.subdivide(e,.5),s=(r+i)/2;a(o[0],t,r,s),a(o[1],t,s,i)}else{var h=e[6]-e[0],d=e[7]-e[1],f=Math.sqrt(h*h+d*d);f>1e-6&&(c+=f,l.push({offset:c,value:i,index:t}))}}for(var o,s=[],l=[],c=0,u=1/(t||32),h=e._segments,d=h[0],f=1,p=h.length;f<p;f++)o=h[f],i(d,o),d=o;e._closed&&i(o,h[0]),this.curves=s,this.parts=l,this.length=c,this.index=0},getParameterAt:function(e){for(var t,n=this.index;t=n,!(0==n||this.parts[--n].offset<e););for(var r=this.parts.length;t<r;t++){var i=this.parts[t];if(i.offset>=e){this.index=t;var a=this.parts[t-1],o=a&&a.index==i.index?a.value:0,s=a?a.offset:0;return{value:o+(i.value-o)*(e-s)/(i.offset-s),index:i.index}}}var i=this.parts[this.parts.length-1];return{value:1,index:i.index}},drawPart:function(e,t,n){t=this.getParameterAt(t),n=this.getParameterAt(n);for(var r=t.index;r<=n.index;r++){var i=A.getPart(this.curves[r],r==t.index?t.value:0,r==n.index?n.value:1);r==t.index&&e.moveTo(i[0],i[1]),e.bezierCurveTo.apply(e,i.slice(2))}}},s.each(A.evaluateMethods,function(e){this[e+"At"]=function(t,n){var r=this.getParameterAt(t);return A[e](this.curves[r.index],r.value,n)}},{})),j=s.extend({initialize:function(e,t){for(var n,r=this.points=[],i=e._segments,a=0,o=i.length;a<o;a++){var s=i[a].point.clone();n&&n.equals(s)||(r.push(s),n=s)}e._closed&&(this.closed=!0,r.unshift(r[r.length-1]),r.push(r[1])),this.error=t},fit:function(){var e=this.points,t=e.length,n=this.segments=t>0?[new I(e[0])]:[];return t>1&&this.fitCubic(0,t-1,e[1].subtract(e[0]).normalize(),e[t-2].subtract(e[t-1]).normalize()),this.closed&&(n.shift(),n.pop()),n},fitCubic:function(e,t,n,r){if(t-e==1){var i=this.points[e],a=this.points[t],o=i.getDistance(a)/3;return void this.addCurve([i,i.add(n.normalize(o)),a.add(r.normalize(o)),a])}for(var s,l=this.chordLengthParameterize(e,t),c=Math.max(this.error,this.error*this.error),u=!0,h=0;h<=4;h++){var d=this.generateBezier(e,t,l,n,r),f=this.findMaxError(e,t,d,l);if(f.error<this.error&&u)return void this.addCurve(d);if(s=f.index,f.error>=c)break;u=this.reparameterize(e,t,l,d),c=f.error}var p=this.points[s-1].subtract(this.points[s]),m=this.points[s].subtract(this.points[s+1]),g=p.add(m).divide(2).normalize();this.fitCubic(e,s,n,g),this.fitCubic(s,t,g.negate(),r)},addCurve:function(e){var t=this.segments[this.segments.length-1];t.setHandleOut(e[1].subtract(e[0])),this.segments.push(new I(e[3],e[2].subtract(e[3])))},generateBezier:function(e,t,n,r,i){for(var a=1e-12,o=this.points[e],s=this.points[t],l=[[0,0],[0,0]],c=[0,0],u=0,h=t-e+1;u<h;u++){var d=n[u],f=1-d,p=3*d*f,m=f*f*f,g=p*f,v=p*d,w=d*d*d,y=r.normalize(g),b=i.normalize(v),_=this.points[e+u].subtract(o.multiply(m+g)).subtract(s.multiply(v+w));l[0][0]+=y.dot(y),l[0][1]+=y.dot(b),l[1][0]=l[0][1],l[1][1]+=b.dot(b),c[0]+=y.dot(_),c[1]+=b.dot(_)}var x,E,C=l[0][0]*l[1][1]-l[1][0]*l[0][1];if(Math.abs(C)>a){var k=l[0][0]*c[1]-l[1][0]*c[0],S=c[0]*l[1][1]-c[1]*l[0][1];x=S/C,E=k/C}else{var P=l[0][0]+l[0][1],T=l[1][0]+l[1][1];x=E=Math.abs(P)>a?c[0]/P:Math.abs(T)>a?c[1]/T:0}var M,N,I=s.getDistance(o),L=a*I;if(x<L||E<L)x=E=I/3;else{var A=s.subtract(o);M=r.normalize(x),N=i.normalize(E),M.dot(A)-N.dot(A)>I*I&&(x=E=I/3,M=N=null)}return[o,o.add(M||r.normalize(x)),s.add(N||i.normalize(E)),s]},reparameterize:function(e,t,n,r){for(var i=e;i<=t;i++)n[i-e]=this.findRoot(r,this.points[i],n[i-e]);for(var i=1,a=n.length;i<a;i++)if(n[i]<=n[i-1])return!1;return!0},findRoot:function(e,t,n){for(var r=[],i=[],a=0;a<=2;a++)r[a]=e[a+1].subtract(e[a]).multiply(3);for(var a=0;a<=1;a++)i[a]=r[a+1].subtract(r[a]).multiply(2);var o=this.evaluate(3,e,n),s=this.evaluate(2,r,n),l=this.evaluate(1,i,n),c=o.subtract(t),u=s.dot(s)+c.dot(l);return Math.abs(u)<1e-6?n:n-c.dot(s)/u},evaluate:function(e,t,n){for(var r=t.slice(),i=1;i<=e;i++)for(var a=0;a<=e-i;a++)r[a]=r[a].multiply(1-n).add(r[a+1].multiply(n));return r[0]},chordLengthParameterize:function(e,t){for(var n=[0],r=e+1;r<=t;r++)n[r-e]=n[r-e-1]+this.points[r].getDistance(this.points[r-1]);for(var r=1,i=t-e;r<=i;r++)n[r]/=n[i];return n},findMaxError:function(e,t,n,r){for(var i=Math.floor((t-e+1)/2),a=0,o=e+1;o<t;o++){var s=this.evaluate(3,n,r[o-e]),l=s.subtract(this.points[o]),c=l.x*l.x+l.y*l.y;c>=a&&(a=c,i=o)}return{error:a,index:i}}}),F=C.extend({_class:"TextItem",_boundsSelected:!0,_applyMatrix:!1,_canApplyMatrix:!1,_serializeFields:{content:null},_boundsGetter:"getBounds",initialize:function(e){this._content="",this._lines=[];var t=e&&s.isPlainObject(e)&&e.x===o&&e.y===o;this._initialize(t&&e,!t&&p.read(arguments))},_equals:function(e){return this._content===e._content},_clone:function e(t,n,r){return t.setContent(this._content),e.base.call(this,t,n,r)},getContent:function(){return this._content},setContent:function(e){this._content=""+e,this._lines=this._content.split(/\r\n|\n|\r/gm),this._changed(265)},isEmpty:function(){return!this._content},getCharacterStyle:"#getStyle",setCharacterStyle:"#setStyle",getParagraphStyle:"#getStyle",setParagraphStyle:"#setStyle"}),q=F.extend({_class:"PointText",initialize:function(){F.apply(this,arguments)},clone:function(e){return this._clone(new q(C.NO_INSERT),e)},getPoint:function(){var e=this._matrix.getTranslation();return new m(e.x,e.y,this,"setPoint")},setPoint:function(){var e=p.read(arguments);this.translate(e.subtract(this._matrix.getTranslation()))},_draw:function(e){if(this._content){this._setStyles(e);var t=this._style,n=this._lines,r=t.getLeading(),i=e.shadowColor;e.font=t.getFontStyle(),e.textAlign=t.getJustification();for(var a=0,o=n.length;a<o;a++){e.shadowColor=i;var s=n[a];t.hasFill()&&(e.fillText(s,0,0),e.shadowColor="rgba(0,0,0,0)"),t.hasStroke()&&e.strokeText(s,0,0),e.translate(0,r)}}},_getBounds:function(e,t){var n=this._style,r=this._lines,i=r.length,a=n.getJustification(),o=n.getLeading(),s=this.getView().getTextWidth(n.getFontStyle(),r),l=0;"left"!==a&&(l-=s/("center"===a?2:1));var c=new w(l,i?-.75*o:0,s,i*o);return t?t._transformBounds(c,c):c}}),V=s.extend(new function(){function e(e){var n,r=e.match(/^#(\w{1,2})(\w{1,2})(\w{1,2})$/);if(r){n=[0,0,0];for(var a=0;a<3;a++){var o=r[a+1];n[a]=parseInt(1==o.length?o+o:o,16)/255}}else if(r=e.match(/^rgba?\((.*)\)$/)){n=r[1].split(",");for(var a=0,s=n.length;a<s;a++){var o=+n[a];n[a]=a<3?o/255:o}}else{var l=i[e];if(!l){t||(t=ne.getContext(1,1),t.globalCompositeOperation="copy"),t.fillStyle="rgba(0,0,0,0)",t.fillStyle=e,t.fillRect(0,0,1,1);var c=t.getImageData(0,0,1,1).data;l=i[e]=[c[0]/255,c[1]/255,c[2]/255]}n=l.slice()}return n}var t,n={gray:["gray"],rgb:["red","green","blue"],hsb:["hue","saturation","brightness"],hsl:["hue","saturation","lightness"],gradient:["gradient","origin","destination","highlight"]},r={},i={},a=[[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]],o={"rgb-hsb":function(e,t,n){var r=Math.max(e,t,n),i=Math.min(e,t,n),a=r-i,o=0===a?0:60*(r==e?(t-n)/a+(t<n?6:0):r==t?(n-e)/a+2:(e-t)/a+4);return[o,0===r?0:a/r,r]},"hsb-rgb":function(e,t,n){e=(e/60%6+6)%6;var r=Math.floor(e),i=e-r,r=a[r],o=[n,n*(1-t),n*(1-t*i),n*(1-t*(1-i))];return[o[r[0]],o[r[1]],o[r[2]]]},"rgb-hsl":function(e,t,n){var r=Math.max(e,t,n),i=Math.min(e,t,n),a=r-i,o=0===a,s=o?0:60*(r==e?(t-n)/a+(t<n?6:0):r==t?(n-e)/a+2:(e-t)/a+4),l=(r+i)/2,c=o?0:l<.5?a/(r+i):a/(2-r-i);return[s,c,l]},"hsl-rgb":function(e,t,n){if(e=(e/360%1+1)%1,0===t)return[n,n,n];for(var r=[e+1/3,e,e-1/3],i=n<.5?n*(1+t):n+t-n*t,a=2*n-i,o=[],s=0;s<3;s++){var l=r[s];l<0&&(l+=1),l>1&&(l-=1),o[s]=6*l<1?a+6*(i-a)*l:2*l<1?i:3*l<2?a+(i-a)*(2/3-l)*6:a}return o},"rgb-gray":function(e,t,n){return[.2989*e+.587*t+.114*n]},"gray-rgb":function(e){return[e,e,e]},"gray-hsb":function(e){return[0,0,e]},"gray-hsl":function(e){return[0,0,e]},"gradient-rgb":function(){return[]},"rgb-gradient":function(){return[]}};return s.each(n,function(e,t){r[t]=[],s.each(e,function(e,i){var a=s.capitalize(e),o=/^(hue|saturation)$/.test(e),l=r[t][i]="gradient"===e?function(e){var t=this._components[0];return e=U.read(Array.isArray(e)?e:arguments,0,{readNull:!0}),t!==e&&(t&&t._removeOwner(this),e&&e._addOwner(this)),e}:"gradient"===t?function(){return p.read(arguments,0,{readNull:"highlight"===e,clone:!0})}:function(e){return null==e||isNaN(e)?0:e};this["get"+a]=function(){return this._type===t||o&&/^hs[bl]$/.test(this._type)?this._components[i]:this._convert(t)[i]},this["set"+a]=function(e){this._type===t||o&&/^hs[bl]$/.test(this._type)||(this._components=this._convert(t),this._properties=n[t],this._type=t),this._components[i]=l.call(this,e),this._changed()}},this)},{_class:"Color",_readIndex:!0,initialize:function t(i){var a,o,s,l,c=Array.prototype.slice,u=arguments,h=0;Array.isArray(i)&&(u=i,i=u[0]);var d=null!=i&&typeof i;if("string"===d&&i in n&&(a=i,i=u[1],Array.isArray(i)?(o=i,s=u[2]):(this.__read&&(h=1),u=c.call(u,1),d=typeof i)),!o){if(l="number"===d?u:"object"===d&&null!=i.length?i:null){a||(a=l.length>=3?"rgb":"gray");var p=n[a].length;s=l[p],this.__read&&(h+=l===arguments?p+(null!=s?1:0):1),l.length>p&&(l=c.call(l,0,p))}else if("string"===d)a="rgb",o=e(i),4===o.length&&(s=o[3],o.length--);else if("object"===d)if(i.constructor===t){if(a=i._type,o=i._components.slice(),s=i._alpha,"gradient"===a)for(var m=1,g=o.length;m<g;m++){var v=o[m];v&&(o[m]=v.clone())}}else if(i.constructor===U)a="gradient",l=u;else{a="hue"in i?"lightness"in i?"hsl":"hsb":"gradient"in i||"stops"in i||"radial"in i?"gradient":"gray"in i?"gray":"rgb";var w=n[a],y=r[a];this._components=o=[];for(var m=0,g=w.length;m<g;m++){var b=i[w[m]];null==b&&0===m&&"gradient"===a&&"stops"in i&&(b={stops:i.stops,radial:i.radial}),b=y[m].call(this,b),null!=b&&(o[m]=b)}s=i.alpha}this.__read&&a&&(h=1)}if(this._type=a||"rgb",this._id=f.get(t),!o){this._components=o=[];for(var y=r[this._type],m=0,g=y.length;m<g;m++){var b=y[m].call(this,l&&l[m]);null!=b&&(o[m]=b)}}this._components=o,this._properties=n[this._type],this._alpha=s,this.__read&&(this.__read=h)},_serialize:function(e,t){var n=this.getComponents();return s.serialize(/^(gray|rgb)$/.test(this._type)?n:[this._type].concat(n),e,!0,t)},_changed:function(){this._canvasStyle=null,this._owner&&this._owner._changed(65)},_convert:function(e){var t;return this._type===e?this._components.slice():(t=o[this._type+"-"+e])?t.apply(this,this._components):o["rgb-"+e].apply(this,o[this._type+"-rgb"].apply(this,this._components))},convert:function(e){return new V(e,this._convert(e),this._alpha)},getType:function(){return this._type},setType:function(e){this._components=this._convert(e),this._properties=n[e],this._type=e},getComponents:function(){var e=this._components.slice();return null!=this._alpha&&e.push(this._alpha),e},getAlpha:function(){return null!=this._alpha?this._alpha:1},setAlpha:function(e){this._alpha=null==e?null:Math.min(Math.max(e,0),1),this._changed()},hasAlpha:function(){return null!=this._alpha},equals:function(e){var t=s.isPlainValue(e,!0)?V.read(arguments):e;return t===this||t&&this._class===t._class&&this._type===t._type&&this._alpha===t._alpha&&s.equals(this._components,t._components)||!1},toString:function(){for(var e=this._properties,t=[],n="gradient"===this._type,r=h.instance,i=0,a=e.length;i<a;i++){var o=this._components[i];null!=o&&t.push(e[i]+": "+(n?o:r.number(o)))}return null!=this._alpha&&t.push("alpha: "+r.number(this._alpha)),"{ "+t.join(", ")+" }"},toCSS:function(e){function t(e){return Math.round(255*(e<0?0:e>1?1:e))}var n=this._convert("rgb"),r=e||null==this._alpha?1:this._alpha;return n=[t(n[0]),t(n[1]),t(n[2])],r<1&&n.push(r<0?0:r),e?"#"+((1<<24)+(n[0]<<16)+(n[1]<<8)+n[2]).toString(16).slice(1):(4==n.length?"rgba(":"rgb(")+n.join(",")+")"},toCanvasStyle:function(e){if(this._canvasStyle)return this._canvasStyle;if("gradient"!==this._type)return this._canvasStyle=this.toCSS();var t,n=this._components,r=n[0],i=r._stops,a=n[1],o=n[2];if(r._radial){var s=o.getDistance(a),l=n[3];if(l){var c=l.subtract(a);c.getLength()>s&&(l=a.add(c.normalize(s-.1)))}var u=l||a;t=e.createRadialGradient(u.x,u.y,0,a.x,a.y,s)}else t=e.createLinearGradient(a.x,a.y,o.x,o.y);for(var h=0,d=i.length;h<d;h++){var f=i[h];t.addColorStop(f._rampPoint,f._color.toCanvasStyle())}return this._canvasStyle=t},transform:function(e){if("gradient"===this._type){for(var t=this._components,n=1,r=t.length;n<r;n++){var i=t[n];e._transformPoint(i,i,!0)}this._changed()}},statics:{_types:n,random:function(){var e=Math.random;return new V(e(),e(),e())}}})},new function(){var e={add:function(e,t){return e+t},subtract:function(e,t){return e-t},multiply:function(e,t){return e*t},divide:function(e,t){return e/t}};return s.each(e,function(e,t){this[t]=function(t){t=V.read(arguments);for(var n=this._type,r=this._components,i=t._convert(n),a=0,o=r.length;a<o;a++)i[a]=e(r[a],i[a]);return new V(n,i,null!=this._alpha?e(this._alpha,t.getAlpha()):null)}},{})}),U=s.extend({_class:"Gradient",initialize:function(e,t){this._id=f.get(),e&&this._set(e)&&(e=t=null),this._stops||this.setStops(e||["white","black"]),null==this._radial&&this.setRadial("string"==typeof t&&"radial"===t||t||!1)},_serialize:function(e,t){return t.add(this,function(){return s.serialize([this._stops,this._radial],e,!0,t)})},_changed:function(){for(var e=0,t=this._owners&&this._owners.length;e<t;e++)this._owners[e]._changed()},_addOwner:function(e){this._owners||(this._owners=[]),this._owners.push(e)},_removeOwner:function(e){var t=this._owners?this._owners.indexOf(e):-1;t!=-1&&(this._owners.splice(t,1),0===this._owners.length&&(this._owners=o))},clone:function(){for(var e=[],t=0,n=this._stops.length;t<n;t++)e[t]=this._stops[t].clone();return new U(e,this._radial)},getStops:function(){return this._stops},setStops:function(e){if(this.stops)for(var t=0,n=this._stops.length;t<n;t++)this._stops[t]._owner=o;if(e.length<2)throw new Error("Gradient stop list needs to contain at least two stops.");this._stops=W.readAll(e,0,{clone:!0});for(var t=0,n=this._stops.length;t<n;t++){var r=this._stops[t];r._owner=this,r._defaultRamp&&r.setRampPoint(t/(n-1))}this._changed()},getRadial:function(){return this._radial},setRadial:function(e){this._radial=e,this._changed()},equals:function(e){if(e===this)return!0;if(e&&this._class===e._class&&this._stops.length===e._stops.length){for(var t=0,n=this._stops.length;t<n;t++)if(!this._stops[t].equals(e._stops[t]))return!1;return!0}return!1}}),W=s.extend({_class:"GradientStop",initialize:function(e,t){if(e){var n,r;t===o&&Array.isArray(e)?(n=e[0],r=e[1]):e.color?(n=e.color,r=e.rampPoint):(n=e,r=t),this.setColor(n),this.setRampPoint(r)}},clone:function(){return new W(this._color.clone(),this._rampPoint)},_serialize:function(e,t){return s.serialize([this._color,this._rampPoint],e,!0,t)},_changed:function(){this._owner&&this._owner._changed(65)},getRampPoint:function(){return this._rampPoint},setRampPoint:function(e){this._defaultRamp=null==e,this._rampPoint=e||0,this._changed()},getColor:function(){return this._color},setColor:function(e){this._color=V.read(arguments),this._color===e&&(this._color=e.clone()),this._color._owner=this,this._changed()},equals:function(e){return e===this||e&&this._class===e._class&&this._color.equals(e._color)&&this._rampPoint==e._rampPoint||!1}}),G=s.extend(new function(){var e={fillColor:o,strokeColor:o,strokeWidth:1,strokeCap:"butt",strokeJoin:"miter",strokeScaling:!0,miterLimit:10,dashOffset:0,dashArray:[],windingRule:"nonzero",shadowColor:o,shadowBlur:0,shadowOffset:new p,selectedColor:o,fontFamily:"sans-serif",fontWeight:"normal",fontSize:12,font:"sans-serif",leading:null,justification:"left"},t={strokeWidth:97,strokeCap:97,strokeJoin:97,strokeScaling:105,miterLimit:97,fontFamily:9,fontWeight:9,fontSize:9,font:9,leading:9,justification:9},n={beans:!0},r={_defaults:e,_textDefaults:new s(e,{fillColor:new V}),beans:!0};return s.each(e,function(e,i){var a=/Color$/.test(i),l="shadowOffset"===i,c=s.capitalize(i),u=t[i],h="set"+c,d="get"+c;r[h]=function(e){var t=this._owner,n=t&&t._children;if(n&&n.length>0&&!(t instanceof R))for(var r=0,s=n.length;r<s;r++)n[r]._style[h](e);else{var l=this._values[i];l!==e&&(a&&(l&&(l._owner=o),e&&e.constructor===V&&(e._owner&&(e=e.clone()),e._owner=t)),this._values[i]=e,t&&t._changed(u||65))}},r[d]=function(e){var t,n=this._owner,r=n&&n._children;if(!r||0===r.length||e||n instanceof R){var t=this._values[i];if(t===o)t=this._defaults[i],t&&t.clone&&(t=t.clone());else{var c=a?V:l?p:null;!c||t&&t.constructor===c||(this._values[i]=t=c.read([t],0,{readNull:!0,clone:!0}),t&&a&&(t._owner=n))}return t}for(var u=0,h=r.length;u<h;u++){var f=r[u]._style[d]();if(0===u)t=f;else if(!s.equals(t,f))return o}return t},n[d]=function(e){return this._style[d](e)},n[h]=function(e){this._style[h](e)}}),C.inject(n),r},{_class:"Style",initialize:function(e,t,n){this._values={},this._owner=t,this._project=t&&t._project||n||a.project,t instanceof F&&(this._defaults=this._textDefaults),e&&this.set(e)},set:function(e){var t=e instanceof G,n=t?e._values:e;if(n)for(var r in n)if(r in this._defaults){var i=n[r];this[r]=i&&t&&i.clone?i.clone():i}},equals:function(e){return e===this||e&&this._class===e._class&&s.equals(this._values,e._values)||!1},hasFill:function(){return!!this.getFillColor()},hasStroke:function(){return!!this.getStrokeColor()&&this.getStrokeWidth()>0},hasShadow:function(){return!!this.getShadowColor()&&this.getShadowBlur()>0},getView:function(){return this._project.getView()},getFontStyle:function(){var e=this.getFontSize();return this.getFontWeight()+" "+e+(/[a-z]/i.test(e+"")?" ":"px ")+this.getFontFamily()},getFont:"#getFontFamily",setFont:"#setFontFamily",getLeading:function e(){var t=e.base.call(this),n=this.getFontSize();return/pt|em|%|px/.test(n)&&(n=this.getView().getPixelSize(n)),null!=t?t:1.2*n}}),H=new function(){function e(e,t,n,r){for(var i=["","webkit","moz","Moz","ms","o"],a=t[0].toUpperCase()+t.substring(1),o=0;o<6;o++){var s=i[o],l=s?s+a:t;if(l in e){if(!n)return e[l];e[l]=r;break}}}return{getStyles:function(e){var t=e&&9!==e.nodeType?e.ownerDocument:e,n=t&&t.defaultView;return n&&n.getComputedStyle(e,"")},getBounds:function(e,t){var n,r=e.ownerDocument,i=r.body,a=r.documentElement;try{n=e.getBoundingClientRect()}catch(e){n={left:0,top:0,width:0,height:0}}var o=n.left-(a.clientLeft||i.clientLeft||0),s=n.top-(a.clientTop||i.clientTop||0);if(!t){var l=r.defaultView;o+=l.pageXOffset||a.scrollLeft||i.scrollLeft,s+=l.pageYOffset||a.scrollTop||i.scrollTop}return new w(o,s,n.width,n.height)},getViewportBounds:function(e){var t=e.ownerDocument,n=t.defaultView,r=t.documentElement;return new w(0,0,n.innerWidth||r.clientWidth,n.innerHeight||r.clientHeight)},getOffset:function(e,t){return H.getBounds(e,t).getPoint()},getSize:function(e){return H.getBounds(e,!0).getSize()},isInvisible:function(e){return H.getSize(e).equals(new g(0,0))},isInView:function(e){return!H.isInvisible(e)&&H.getViewportBounds(e).intersects(H.getBounds(e,!0))},getPrefixed:function(t,n){return e(t,n)},setPrefixed:function(t,n,r){if("object"==typeof n)for(var i in n)e(t,i,!0,n[i]);else e(t,n,!0,r)}}},X={add:function(e,t){for(var n in t)for(var r=t[n],i=n.split(/[\s,]+/g),a=0,o=i.length;a<o;a++)e.addEventListener(i[a],r,!1)},remove:function(e,t){for(var n in t)for(var r=t[n],i=n.split(/[\s,]+/g),a=0,o=i.length;a<o;a++)e.removeEventListener(i[a],r,!1)},getPoint:function(e){var t=e.targetTouches?e.targetTouches.length?e.targetTouches[0]:e.changedTouches[0]:e;return new p(t.pageX||t.clientX+document.documentElement.scrollLeft,t.pageY||t.clientY+document.documentElement.scrollTop)},getTarget:function(e){return e.target||e.srcElement},getRelatedTarget:function(e){return e.relatedTarget||e.toElement},getOffset:function(e,t){return X.getPoint(e).subtract(H.getOffset(t||X.getTarget(e)))},stop:function(e){e.stopPropagation(),e.preventDefault()}};X.requestAnimationFrame=new function(){function e(){for(var t=i.length-1;t>=0;t--){var o=i[t],s=o[0],l=o[1];(!l||("true"==c.getAttribute(l,"keepalive")||a)&&H.isInView(l))&&(i.splice(t,1),s())}n&&(i.length?n(e):r=!1)}var t,n=H.getPrefixed(window,"requestAnimationFrame"),r=!1,i=[],a=!0;return X.add(window,{focus:function(){a=!0},blur:function(){a=!1}}),function(a,o){i.push([a,o]),n?r||(n(e),r=!0):t||(t=setInterval(e,1e3/60))}};var K=s.extend(l,{_class:"View",initialize:function e(t,n){function r(e){return n[e]||parseInt(n.getAttribute(e),10)}function i(){var e=H.getSize(n);return e.isNaN()||e.isZero()?new g(r("width"),r("height")):e}this._project=t,this._scope=t._scope,this._element=n;var a;this._pixelRatio||(this._pixelRatio=window.devicePixelRatio||1),this._id=n.getAttribute("id"),null==this._id&&n.setAttribute("id",this._id="view-"+e._id++),X.add(n,this._viewEvents);var o="none";if(H.setPrefixed(n.style,{userSelect:o,touchAction:o,touchCallout:o,contentZooming:o,userDrag:o,tapHighlightColor:"rgba(0,0,0,0)"}),c.hasAttribute(n,"resize")){var s=this;X.add(window,this._windowEvents={resize:function(){s.setViewSize(i())}})}if(this._setViewSize(a=i()),c.hasAttribute(n,"stats")&&"undefined"!=typeof Stats){this._stats=new Stats;var l=this._stats.domElement,u=l.style,h=H.getOffset(n);u.position="absolute",u.left=h.x+"px",u.top=h.y+"px",document.body.appendChild(l)}e._views.push(this),e._viewsById[this._id]=this,this._viewSize=a,(this._matrix=new b)._owner=this,this._zoom=1,e._focused||(e._focused=this),this._frameItems={},this._frameItemCount=0},remove:function(){return!!this._project&&(K._focused===this&&(K._focused=null),K._views.splice(K._views.indexOf(this),1),delete K._viewsById[this._id],this._project._view===this&&(this._project._view=null),X.remove(this._element,this._viewEvents),X.remove(window,this._windowEvents),this._element=this._project=null,this.off("frame"),this._animate=!1,this._frameItems={},!0)},_events:s.each(["onResize","onMouseDown","onMouseUp","onMouseMove"],function(e){this[e]={install:function(e){this._installEvent(e)},uninstall:function(e){this._uninstallEvent(e)}}},{onFrame:{install:function(){this.play()},uninstall:function(){this.pause()}}}),_animate:!1,_time:0,_count:0,_requestFrame:function(){var e=this;X.requestAnimationFrame(function(){e._requested=!1,e._animate&&(e._requestFrame(),e._handleFrame())},this._element),this._requested=!0},_handleFrame:function(){a=this._scope;var e=Date.now()/1e3,t=this._before?e-this._before:0;this._before=e,this._handlingFrame=!0,this.emit("frame",new s({delta:t,time:this._time+=t,count:this._count++})),this._stats&&this._stats.update(),this._handlingFrame=!1,this.update()},_animateItem:function(e,t){var n=this._frameItems;t?(n[e._id]={item:e,time:0,count:0},1===++this._frameItemCount&&this.on("frame",this._handleFrameItems)):(delete n[e._id],0===--this._frameItemCount&&this.off("frame",this._handleFrameItems))},_handleFrameItems:function(e){for(var t in this._frameItems){var n=this._frameItems[t];n.item.emit("frame",new s(e,{time:n.time+=e.delta,count:n.count++}))}},_update:function(){this._project._needsUpdate=!0,this._handlingFrame||(this._animate?this._handleFrame():this.update())},_changed:function(e){1&e&&(this._project._needsUpdate=!0)},_transform:function(e){this._matrix.concatenate(e),this._bounds=null,this._update()},getElement:function(){return this._element},getPixelRatio:function(){return this._pixelRatio},getResolution:function(){return 72*this._pixelRatio},getViewSize:function(){var e=this._viewSize;return new v(e.width,e.height,this,"setViewSize")},setViewSize:function(){var e=g.read(arguments),t=e.subtract(this._viewSize);t.isZero()||(this._viewSize.set(e.width,e.height),this._setViewSize(e),this._bounds=null,this.emit("resize",{size:e,delta:t}),this._update())},_setViewSize:function(e){var t=this._element;t.width=e.width,t.height=e.height},getBounds:function(){return this._bounds||(this._bounds=this._matrix.inverted()._transformBounds(new w(new p,this._viewSize))),this._bounds},getSize:function(){return this.getBounds().getSize()},getCenter:function(){return this.getBounds().getCenter()},setCenter:function(){var e=p.read(arguments);this.scrollBy(e.subtract(this.getCenter()))},getZoom:function(){return this._zoom},setZoom:function(e){this._transform((new b).scale(e/this._zoom,this.getCenter())),this._zoom=e},isVisible:function(){return H.isInView(this._element)},scrollBy:function(){this._transform((new b).translate(p.read(arguments).negate()))},play:function(){this._animate=!0,this._requested||this._requestFrame()},pause:function(){this._animate=!1},draw:function(){this.update()},projectToView:function(){return this._matrix._transformPoint(p.read(arguments))},viewToProject:function(){return this._matrix._inverseTransform(p.read(arguments))}},{statics:{_views:[],_viewsById:{},_id:0,create:function(e,t){return"string"==typeof t&&(t=document.getElementById(t)),new Q(e,t)}}},new function(){function e(e){var t=X.getTarget(e);return t.getAttribute&&K._viewsById[t.getAttribute("id")]}function t(e,t){return e.viewToProject(X.getOffset(t,e._element))}function n(){if(!K._focused||!K._focused.isVisible())for(var e=0,t=K._views.length;e<t;e++){var n=K._views[e];if(n&&n.isVisible()){K._focused=o=n;break}}}function r(e,t,n){e._handleEvent("mousemove",t,n);var r=e._scope.tool;return r&&r._handleEvent(u&&r.responds("mousedrag")?"mousedrag":"mousemove",t,n),e.update(),r}var i,a,o,s,l,c,u=!1,h=window.navigator;h.pointerEnabled||h.msPointerEnabled?(s="pointerdown MSPointerDown",l="pointermove MSPointerMove",c="pointerup pointercancel MSPointerUp MSPointerCancel"):(s="touchstart",l="touchmove",c="touchend touchcancel","ontouchstart"in window&&h.userAgent.match(/mobile|tablet|ip(ad|hone|od)|android|silk/i)||(s+=" mousedown",l+=" mousemove",c+=" mouseup"));var d={"selectstart dragstart":function(e){u&&e.preventDefault()}},f={mouseout:function(e){var n=K._focused,i=X.getRelatedTarget(e);!n||i&&"HTML"!==i.nodeName||r(n,t(n,e),e)},scroll:n};d[s]=function(n){var r=K._focused=e(n),a=t(r,n);u=!0,r._handleEvent("mousedown",a,n),(i=r._scope.tool)&&i._handleEvent("mousedown",a,n),r.update()},f[l]=function(s){var l=K._focused;if(!u){var c=e(s);c?(l!==c&&r(l,t(l,s),s),a=l,l=K._focused=o=c):o&&o===l&&(l=K._focused=a,n())}if(l){var h=t(l,s);(u||l.getBounds().contains(h))&&(i=r(l,h,s))}},f[c]=function(e){var n=K._focused;if(n&&u){var r=t(n,e);u=!1,n._handleEvent("mouseup",r,e),i&&i._handleEvent("mouseup",r,e),n.update()}},X.add(document,f),X.add(window,{load:n});var p={mousedown:{mousedown:1,mousedrag:1,click:1,doubleclick:1},mouseup:{mouseup:1,mousedrag:1,click:1,doubleclick:1},mousemove:{mousedrag:1,mousemove:1,mouseenter:1,mouseleave:1}};return{_viewEvents:d,_handleEvent:function(){},_installEvent:function(e){var t=this._eventCounters;if(t)for(var n in p)t[n]=(t[n]||0)+(p[n][e]||0)},_uninstallEvent:function(e){var t=this._eventCounters;if(t)for(var n in p)t[n]-=p[n][e]||0},statics:{updateFocus:n}}}),Q=K.extend({_class:"CanvasView",initialize:function(e,t){if(!(t instanceof HTMLCanvasElement)){var n=g.read(arguments,1);if(n.isZero())throw new Error("Cannot create CanvasView with the provided argument: "+[].slice.call(arguments,1));t=ne.getCanvas(n)}if(this._context=t.getContext("2d"),this._eventCounters={},this._pixelRatio=1,!/^off|false$/.test(c.getAttribute(t,"hidpi"))){var r=window.devicePixelRatio||1,i=H.getPrefixed(this._context,"backingStorePixelRatio")||1;this._pixelRatio=r/i}K.call(this,e,t)},_setViewSize:function(e){var t=this._element,n=this._pixelRatio,r=e.width,i=e.height;if(t.width=r*n,t.height=i*n,1!==n){if(!c.hasAttribute(t,"resize")){var a=t.style;a.width=r+"px",a.height=i+"px"}this._context.scale(n,n)}},getPixelSize:function(e){var t,n=a.browser;if(n&&n.firefox){var r=this._element.parentNode,i=document.createElement("div");i.style.fontSize=e,r.appendChild(i),t=parseFloat(H.getStyles(i).fontSize),r.removeChild(i)}else{var o=this._context,s=o.font;o.font=e+" serif",t=parseFloat(o.font),o.font=s}return t},getTextWidth:function(e,t){var n=this._context,r=n.font,i=0;n.font=e;for(var a=0,o=t.length;a<o;a++)i=Math.max(i,n.measureText(t[a]).width);return n.font=r,i},update:function(e){var t=this._project;if(!t||!e&&!t._needsUpdate)return!1;var n=this._context,r=this._viewSize;return n.clearRect(0,0,r.width+1,r.height+1),t.draw(n,this._matrix,this._pixelRatio),t._needsUpdate=!1,!0}},new function(){function e(e,t,n,r,i,a){function o(e){if(e.responds(t)&&(s||(s=new J(t,n,r,i,a?r.subtract(a):null)),e.emit(t,s)&&s.isStopped))return n.preventDefault(),!0}for(var s,l=i;l;){if(o(l))return!0;l=l.getParent()}return!!o(e)}var t,n,r,i,a,o,s,l,c;return{_handleEvent:function(u,h,d){if(this._eventCounters[u]){var f=this._project,p=f.hitTest(h,{tolerance:0,fill:!0,stroke:!0}),m=p&&p.item,g=!1;switch(u){case"mousedown":for(g=e(this,u,d,h,m),l=a==m&&Date.now()-c<300,i=a=m,t=n=r=h,s=!g&&m;s&&!s.responds("mousedrag");)s=s._parent;break;case"mouseup":g=e(this,u,d,h,m,t),s&&(n&&!n.equals(h)&&e(this,"mousedrag",d,h,s,n),m!==s&&(r=h,e(this,"mousemove",d,h,m,r))),!g&&m&&m===i&&(c=Date.now(),e(this,l&&i.responds("doubleclick")?"doubleclick":"click",d,t,m),l=!1),i=s=null;break;case"mousemove":s&&(g=e(this,"mousedrag",d,h,s,n)),g||(m!==o&&(r=h),g=e(this,u,d,h,m,r)),n=r=h,m!==o&&(e(this,"mouseleave",d,h,o),o=m,e(this,"mouseenter",d,h,m))}return g}}}}),Y=s.extend({_class:"Event",initialize:function(e){this.event=e},isPrevented:!1,isStopped:!1,preventDefault:function(){this.isPrevented=!0,this.event.preventDefault()},stopPropagation:function(){this.isStopped=!0,this.event.stopPropagation()},stop:function(){this.stopPropagation(),this.preventDefault()},getModifiers:function(){return $.modifiers}}),Z=Y.extend({_class:"KeyEvent",initialize:function(e,t,n,r){Y.call(this,r),this.type=e?"keydown":"keyup",this.key=t,this.character=n},toString:function(){return"{ type: '"+this.type+"', key: '"+this.key+"', character: '"+this.character+"', modifiers: "+this.getModifiers()+" }"}}),$=new function(){function e(n,i,u,h){var d,f=u?String.fromCharCode(u):"",p=r[i],m=p||f.toLowerCase(),g=n?"keydown":"keyup",v=K._focused,w=v&&v.isVisible()&&v._scope,y=w&&w.tool;if(c[m]=n,n?l[i]=u:delete l[i],p&&(d=s.camelize(p))in o){o[d]=n;var b=a.browser;if("command"===d&&b&&b.mac)if(n)t={};else{for(var _ in t)_ in l&&e(!1,_,t[_],h);t=null}}else n&&t&&(t[i]=u);y&&y.responds(g)&&(a=w,y.emit(g,new Z(n,m,f,h)),v&&v.update())}var t,n,r={8:"backspace",9:"tab",13:"enter",16:"shift",17:"control",18:"option",19:"pause",20:"caps-lock",27:"escape",32:"space",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",46:"delete",91:"command",93:"command",224:"command"},i={9:!0,13:!0,32:!0},o=new s({shift:!1,control:!1,option:!1,command:!1,capsLock:!1,space:!1}),l={},c={};return X.add(document,{keydown:function(t){var a=t.which||t.keyCode;a in r||o.command?e(!0,a,a in i||o.command?a:0,t):n=a},keypress:function(t){null!=n&&(e(!0,n,t.which||t.keyCode,t),n=null)},keyup:function(t){var n=t.which||t.keyCode;n in l&&e(!1,n,l[n],t)}}),X.add(window,{blur:function(t){for(var n in l)e(!1,n,l[n],t)}}),{modifiers:o,isDown:function(e){return!!c[e]}}},J=Y.extend({_class:"MouseEvent",initialize:function(e,t,n,r,i){Y.call(this,t),this.type=e,this.point=n,this.target=r,this.delta=i},toString:function(){return"{ type: '"+this.type+"', point: "+this.point+", target: "+this.target+(this.delta?", delta: "+this.delta:"")+", modifiers: "+this.getModifiers()+" }"; +}}),ee=Y.extend({_class:"ToolEvent",_item:null,initialize:function(e,t,n){this.tool=e,this.type=t,this.event=n},_choosePoint:function(e,t){return e?e:t?t.clone():null},getPoint:function(){return this._choosePoint(this._point,this.tool._point)},setPoint:function(e){this._point=e},getLastPoint:function(){return this._choosePoint(this._lastPoint,this.tool._lastPoint)},setLastPoint:function(e){this._lastPoint=e},getDownPoint:function(){return this._choosePoint(this._downPoint,this.tool._downPoint)},setDownPoint:function(e){this._downPoint=e},getMiddlePoint:function(){return!this._middlePoint&&this.tool._lastPoint?this.tool._point.add(this.tool._lastPoint).divide(2):this._middlePoint},setMiddlePoint:function(e){this._middlePoint=e},getDelta:function(){return!this._delta&&this.tool._lastPoint?this.tool._point.subtract(this.tool._lastPoint):this._delta},setDelta:function(e){this._delta=e},getCount:function(){return/^mouse(down|up)$/.test(this.type)?this.tool._downCount:this.tool._count},setCount:function(e){this.tool[/^mouse(down|up)$/.test(this.type)?"downCount":"count"]=e},getItem:function(){if(!this._item){var e=this.tool._scope.project.hitTest(this.getPoint());if(e){for(var t=e.item,n=t._parent;/^(Group|CompoundPath)$/.test(n._class);)t=n,n=n._parent;this._item=t}}return this._item},setItem:function(e){this._item=e},toString:function(){return"{ type: "+this.type+", point: "+this.getPoint()+", count: "+this.getCount()+", modifiers: "+this.getModifiers()+" }"}}),te=(u.extend({_class:"Tool",_list:"tools",_reference:"tool",_events:["onActivate","onDeactivate","onEditOptions","onMouseDown","onMouseUp","onMouseDrag","onMouseMove","onKeyDown","onKeyUp"],initialize:function(e){u.call(this),this._firstMove=!0,this._count=0,this._downCount=0,this._set(e)},getMinDistance:function(){return this._minDistance},setMinDistance:function(e){this._minDistance=e,null!=e&&null!=this._maxDistance&&e>this._maxDistance&&(this._maxDistance=e)},getMaxDistance:function(){return this._maxDistance},setMaxDistance:function(e){this._maxDistance=e,null!=this._minDistance&&null!=e&&e<this._minDistance&&(this._minDistance=e)},getFixedDistance:function(){return this._minDistance==this._maxDistance?this._minDistance:null},setFixedDistance:function(e){this._minDistance=this._maxDistance=e},_updateEvent:function(e,t,n,r,i,a,o){if(!i){if(null!=n||null!=r){var s=null!=n?n:0,l=t.subtract(this._point),c=l.getLength();if(c<s)return!1;if(null!=r&&0!=r)if(c>r)t=this._point.add(l.normalize(r));else if(o)return!1}if(a&&t.equals(this._point))return!1}switch(this._lastPoint=i&&"mousemove"==e?t:this._point,this._point=t,e){case"mousedown":this._lastPoint=this._downPoint,this._downPoint=this._point,this._downCount++;break;case"mouseup":this._lastPoint=this._downPoint}return this._count=i?0:this._count+1,!0},_fireEvent:function(e,t){var n=a.project._removeSets;if(n){"mouseup"===e&&(n.mousedrag=null);var r=n[e];if(r){for(var i in r){var o=r[i];for(var s in n){var l=n[s];l&&l!=r&&delete l[o._id]}o.remove()}n[e]=null}}return this.responds(e)&&this.emit(e,new ee(this,e,t))},_handleEvent:function(e,t,n){a=this._scope;var r=!1;switch(e){case"mousedown":this._updateEvent(e,t,null,null,!0,!1,!1),r=this._fireEvent(e,n);break;case"mousedrag":for(var i=!1,o=!1;this._updateEvent(e,t,this.minDistance,this.maxDistance,!1,i,o);)r=this._fireEvent(e,n)||r,i=!0,o=!0;break;case"mouseup":!t.equals(this._point)&&this._updateEvent("mousedrag",t,this.minDistance,this.maxDistance,!1,!1,!1)&&(r=this._fireEvent("mousedrag",n)),this._updateEvent(e,t,null,this.maxDistance,!1,!1,!1),r=this._fireEvent(e,n)||r,this._updateEvent(e,t,null,null,!0,!1,!1),this._firstMove=!0;break;case"mousemove":for(;this._updateEvent(e,t,this.minDistance,this.maxDistance,this._firstMove,!0,!1);)r=this._fireEvent(e,n)||r,this._firstMove=!1}return r&&n.preventDefault(),r}}),{request:function(e,t,n,r){r=r===o||r;var i=new(window.ActiveXObject||XMLHttpRequest)("Microsoft.XMLHTTP");return i.open(e.toUpperCase(),t,r),"overrideMimeType"in i&&i.overrideMimeType("text/plain"),i.onreadystatechange=function(){if(4===i.readyState){var e=i.status;if(0!==e&&200!==e)throw new Error("Could not load "+t+" (Error "+e+")");n.call(i,i.responseText)}},i.send(null)}}),ne={canvases:[],getCanvas:function(e,t){var n,r=!0;"object"==typeof e&&(t=e.height,e=e.width),n=this.canvases.length?this.canvases.pop():document.createElement("canvas");var i=n.getContext("2d");return n.width===e&&n.height===t?r&&i.clearRect(0,0,e+1,t+1):(n.width=e,n.height=t),i.save(),n},getContext:function(e,t){return this.getCanvas(e,t).getContext("2d")},release:function(e){var t=e.canvas?e.canvas:e;t.getContext("2d").restore(),this.canvases.push(t)}},re=new function(){function e(e,t,n){return.2989*e+.587*t+.114*n}function t(t,n,r,i){var a=i-e(t,n,r);f=t+a,p=n+a,m=r+a;var i=e(f,p,m),o=g(f,p,m),s=v(f,p,m);if(o<0){var l=i-o;f=i+(f-i)*i/l,p=i+(p-i)*i/l,m=i+(m-i)*i/l}if(s>255){var c=255-i,u=s-i;f=i+(f-i)*c/u,p=i+(p-i)*c/u,m=i+(m-i)*c/u}}function n(e,t,n){return v(e,t,n)-g(e,t,n)}function r(e,t,n,r){var i,a=[e,t,n],o=v(e,t,n),s=g(e,t,n);s=s===e?0:s===t?1:2,o=o===e?0:o===t?1:2,i=0===g(s,o)?1===v(s,o)?2:1:0,a[o]>a[s]?(a[i]=(a[i]-a[s])*r/(a[o]-a[s]),a[o]=r):a[i]=a[o]=0,a[s]=0,f=a[0],p=a[1],m=a[2]}var i,a,o,l,c,u,h,d,f,p,m,g=Math.min,v=Math.max,w=Math.abs,y={multiply:function(){f=c*i/255,p=u*a/255,m=h*o/255},screen:function(){f=c+i-c*i/255,p=u+a-u*a/255,m=h+o-h*o/255},overlay:function(){f=c<128?2*c*i/255:255-2*(255-c)*(255-i)/255,p=u<128?2*u*a/255:255-2*(255-u)*(255-a)/255,m=h<128?2*h*o/255:255-2*(255-h)*(255-o)/255},"soft-light":function(){var e=i*c/255;f=e+c*(255-(255-c)*(255-i)/255-e)/255,e=a*u/255,p=e+u*(255-(255-u)*(255-a)/255-e)/255,e=o*h/255,m=e+h*(255-(255-h)*(255-o)/255-e)/255},"hard-light":function(){f=i<128?2*i*c/255:255-2*(255-i)*(255-c)/255,p=a<128?2*a*u/255:255-2*(255-a)*(255-u)/255,m=o<128?2*o*h/255:255-2*(255-o)*(255-h)/255},"color-dodge":function(){f=0===c?0:255===i?255:g(255,255*c/(255-i)),p=0===u?0:255===a?255:g(255,255*u/(255-a)),m=0===h?0:255===o?255:g(255,255*h/(255-o))},"color-burn":function(){f=255===c?255:0===i?0:v(0,255-255*(255-c)/i),p=255===u?255:0===a?0:v(0,255-255*(255-u)/a),m=255===h?255:0===o?0:v(0,255-255*(255-h)/o)},darken:function(){f=c<i?c:i,p=u<a?u:a,m=h<o?h:o},lighten:function(){f=c>i?c:i,p=u>a?u:a,m=h>o?h:o},difference:function(){f=c-i,f<0&&(f=-f),p=u-a,p<0&&(p=-p),m=h-o,m<0&&(m=-m)},exclusion:function(){f=c+i*(255-c-c)/255,p=u+a*(255-u-u)/255,m=h+o*(255-h-h)/255},hue:function(){r(i,a,o,n(c,u,h)),t(f,p,m,e(c,u,h))},saturation:function(){r(c,u,h,n(i,a,o)),t(f,p,m,e(c,u,h))},luminosity:function(){t(c,u,h,e(i,a,o))},color:function(){t(i,a,o,e(c,u,h))},add:function(){f=g(c+i,255),p=g(u+a,255),m=g(h+o,255)},subtract:function(){f=v(c-i,0),p=v(u-a,0),m=v(h-o,0)},average:function(){f=(c+i)/2,p=(u+a)/2,m=(h+o)/2},negation:function(){f=255-w(255-i-c),p=255-w(255-a-u),m=255-w(255-o-h)}},b=this.nativeModes=s.each(["source-over","source-in","source-out","source-atop","destination-over","destination-in","destination-out","destination-atop","lighter","darker","copy","xor"],function(e){this[e]=!0},{}),_=ne.getContext(1,1);s.each(y,function(e,t){var n="darken"===t,r=!1;_.save();try{_.fillStyle=n?"#300":"#a00",_.fillRect(0,0,1,1),_.globalCompositeOperation=t,_.globalCompositeOperation===t&&(_.fillStyle=n?"#a00":"#300",_.fillRect(0,0,1,1),r=_.getImageData(0,0,1,1).data[0]!==n?170:51)}catch(e){}_.restore(),b[t]=r}),ne.release(_),this.process=function(e,t,n,r,s){var g=t.canvas,v="normal"===e;if(v||b[e])n.save(),n.setTransform(1,0,0,1,0,0),n.globalAlpha=r,v||(n.globalCompositeOperation=e),n.drawImage(g,s.x,s.y),n.restore();else{var w=y[e];if(!w)return;for(var _=n.getImageData(s.x,s.y,g.width,g.height),x=_.data,E=t.getImageData(0,0,g.width,g.height).data,C=0,k=x.length;C<k;C+=4){i=E[C],c=x[C],a=E[C+1],u=x[C+1],o=E[C+2],h=x[C+2],l=E[C+3],d=x[C+3],w();var S=l*r/255,P=1-S;x[C]=S*f+P*c,x[C+1]=S*p+P*u,x[C+2]=S*m+P*h,x[C+3]=l*r+P*d}n.putImageData(_,s.x,s.y)}}},ie=s.each({fillColor:["fill","color"],strokeColor:["stroke","color"],strokeWidth:["stroke-width","number"],strokeCap:["stroke-linecap","string"],strokeJoin:["stroke-linejoin","string"],strokeScaling:["vector-effect","lookup",{true:"none",false:"non-scaling-stroke"},function(e,t){return!t&&(e instanceof B||e instanceof P||e instanceof F)}],miterLimit:["stroke-miterlimit","number"],dashArray:["stroke-dasharray","array"],dashOffset:["stroke-dashoffset","number"],fontFamily:["font-family","string"],fontWeight:["font-weight","string"],fontSize:["font-size","number"],justification:["text-anchor","lookup",{left:"start",center:"middle",right:"end"}],opacity:["opacity","number"],blendMode:["mix-blend-mode","string"]},function(e,t){var n=s.capitalize(t),r=e[2];this[t]={type:e[1],property:t,attribute:e[0],toSVG:r,fromSVG:r&&s.each(r,function(e,t){this[e]=t},{}),exportFilter:e[3],get:"get"+n,set:"set"+n}},{}),ae={href:"http://www.w3.org/1999/xlink",xlink:"http://www.w3.org/2000/xmlns"};return new function(){function e(e,t){for(var n in t){var r=t[n],i=ae[n];"number"==typeof r&&(r=b.number(r)),i?e.setAttributeNS(i,n,r):e.setAttribute(n,r)}return e}function t(t,n){return e(document.createElementNS("http://www.w3.org/2000/svg",t),n)}function n(e,t,n){var r=new s,i=e.getTranslation();if(t){e=e.shiftless();var a=e._inverseTransform(i);r[n?"cx":"x"]=a.x,r[n?"cy":"y"]=a.y,i=null}if(!e.isIdentity()){var o=e.decompose();if(o&&!o.shearing){var l=[],c=o.rotation,u=o.scaling;i&&!i.isZero()&&l.push("translate("+b.point(i)+")"),d.isZero(u.x-1)&&d.isZero(u.y-1)||l.push("scale("+b.point(u)+")"),c&&l.push("rotate("+b.number(c)+")"),r.transform=l.join(" ")}else r.transform="matrix("+e.getValues().join(",")+")"}return r}function r(r,i){for(var a=n(r._matrix),o=r._children,s=t("g",a),l=0,c=o.length;l<c;l++){var u=o[l],h=w(u,i);if(h)if(u.isClipMask()){var d=t("clipPath");d.appendChild(h),g(u,d,"clip"),e(s,{"clip-path":"url(#"+d.id+")"})}else s.appendChild(h)}return s}function i(e,r){var i=n(e._matrix,!0),a=e.getSize(),o=e.getImage();return i.x-=a.width/2,i.y-=a.height/2,i.width=a.width,i.height=a.height,i.href=r.embedImages===!1&&o&&o.src||e.toDataURL(),t("image",i)}function a(e,r){var i=r.matchShapes;if(i){var a=e.toShape(!1);if(a)return o(a,r)}var s,l=e._segments,c=n(e._matrix);if(0===l.length)return null;if(i&&!e.hasHandles())if(l.length>=3){s=e._closed?"polygon":"polyline";for(var u=[],h=0,d=l.length;h<d;h++)u.push(b.point(l[h]._point));c.points=u.join(" ")}else{s="line";var f=l[0]._point,p=l[l.length-1]._point;c.set({x1:f.x,y1:f.y,x2:p.x,y2:p.y})}else s="path",c.d=e.getPathData(null,r.precision);return t(s,c)}function o(e){var r=e._type,i=e._radius,a=n(e._matrix,!0,"rectangle"!==r);if("rectangle"===r){r="rect";var o=e._size,s=o.width,l=o.height;a.x-=s/2,a.y-=l/2,a.width=s,a.height=l,i.isZero()&&(i=null)}return i&&("circle"===r?a.r=i:(a.rx=i.width,a.ry=i.height)),t(r,a)}function l(e,r){var i=n(e._matrix),a=e.getPathData(null,r.precision);return a&&(i.d=a),t("path",i)}function c(e,r){var i=n(e._matrix,!0),a=e.getSymbol(),o=m(a,"symbol"),s=a.getDefinition(),l=s.getBounds();return o||(o=t("symbol",{viewBox:b.rectangle(l)}),o.appendChild(w(s,r)),g(a,o,"symbol")),i.href="#"+o.id,i.x+=l.x,i.y+=l.y,i.width=b.number(l.width),i.height=b.number(l.height),i.overflow="visible",t("use",i)}function u(e){var n=m(e,"color");if(!n){var r,i=e.getGradient(),a=i._radial,o=e.getOrigin().transform(),s=e.getDestination().transform();if(a){r={cx:o.x,cy:o.y,r:o.getDistance(s)};var l=e.getHighlight();l&&(l=l.transform(),r.fx=l.x,r.fy=l.y)}else r={x1:o.x,y1:o.y,x2:s.x,y2:s.y};r.gradientUnits="userSpaceOnUse",n=t((a?"radial":"linear")+"Gradient",r);for(var c=i._stops,u=0,h=c.length;u<h;u++){var d=c[u],f=d._color,p=f.getAlpha();r={offset:d._rampPoint,"stop-color":f.toCSS(!0)},p<1&&(r["stop-opacity"]=p),n.appendChild(t("stop",r))}g(e,n,"color")}return"url(#"+n.id+")"}function f(e){var r=t("text",n(e._matrix,!0));return r.textContent=e._content,r}function p(t,n,r){var i={},a=!r&&t.getParent();return null!=t._name&&(i.id=t._name),s.each(ie,function(e){var n=e.get,r=e.type,o=t[n]();if(e.exportFilter?e.exportFilter(t,o):!a||!s.equals(a[n](),o)){if("color"===r&&null!=o){var l=o.getAlpha();l<1&&(i[e.attribute+"-opacity"]=l)}i[e.attribute]=null==o?"none":"number"===r?b.number(o):"color"===r?o.gradient?u(o,t):o.toCSS(!0):"array"===r?o.join(","):"lookup"===r?e.toSVG[o]:o}}),1===i.opacity&&delete i.opacity,t._visible||(i.visibility="hidden"),e(n,i)}function m(e,t){return _||(_={ids:{},svgs:{}}),e&&_.svgs[t+"-"+e._id]}function g(e,t,n){_||m();var r=_.ids[n]=(_.ids[n]||0)+1;t.id=n+"-"+r,_.svgs[n+"-"+e._id]=t}function v(e,n){var r=e,i=null;if(_){r="svg"===e.nodeName.toLowerCase()&&e;for(var a in _.svgs)i||(r||(r=t("svg"),r.appendChild(e)),i=r.insertBefore(t("defs"),r.firstChild)),i.appendChild(_.svgs[a]);_=null}return n.asString?(new XMLSerializer).serializeToString(r):r}function w(e,t,n){var r=E[e._class],i=r&&r(e,t);if(i){var a=t.onExport;a&&(i=a(e,i,t)||i);var o=JSON.stringify(e._data);o&&"{}"!==o&&"null"!==o&&i.setAttribute("data-paper-data",o)}return i&&p(e,i,n)}function y(e){return e||(e={}),b=new h(e.precision),e}var b,_,E={Group:r,Layer:r,Raster:i,Path:a,Shape:o,CompoundPath:l,PlacedSymbol:c,PointText:f};C.inject({exportSVG:function(e){return e=y(e),v(w(this,e,!0),e)}}),x.inject({exportSVG:function(e){e=y(e);var r=this.layers,i=this.getView(),a=i.getViewSize(),o=t("svg",{x:0,y:0,width:a.width,height:a.height,version:"1.1",xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}),s=o,l=i._matrix;l.isIdentity()||(s=o.appendChild(t("g",n(l))));for(var c=0,u=r.length;c<u;c++)s.appendChild(w(r[c],e,!0));return v(o,e)}})},new function(){function e(e,t,n,r){var i=ae[t],a=i?e.getAttributeNS(i,t):e.getAttribute(t);return"null"===a&&(a=null),null==a?r?null:n?"":0:n?a:parseFloat(a)}function t(t,n,r,i){return n=e(t,n,!1,i),r=e(t,r,!1,i),!i||null!=n&&null!=r?new p(n,r):null}function n(t,n,r,i){return n=e(t,n,!1,i),r=e(t,r,!1,i),!i||null!=n&&null!=r?new g(n,r):null}function r(e,t,n){return"none"===e?null:"number"===t?parseFloat(e):"array"===t?e?e.split(/[\s,]+/g).map(parseFloat):[]:"color"===t?v(e)||e:"lookup"===t?n[e]:e}function i(e,t,n,r){var i=e.childNodes,a="clippath"===t,o=new k,s=o._project,l=s._currentStyle,c=[];if(a||(o=m(o,e,r),s._currentStyle=o._style.clone()),r)for(var u=e.querySelectorAll("defs"),h=0,d=u.length;h<d;h++)y(u[h],n,!1);for(var h=0,d=i.length;h<d;h++){var f,p=i[h];1!==p.nodeType||"defs"===p.nodeName.toLowerCase()||!(f=y(p,n,!1))||f instanceof E||c.push(f)}return o.addChildren(c),a&&(o=m(o.reduce(),e,r)),s._currentStyle=l,(a||"defs"===t)&&(o.remove(),o=null),o}function l(e,t){for(var n=e.getAttribute("points").match(/[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g),r=[],i=0,a=n.length;i<a;i+=2)r.push(new p(parseFloat(n[i]),parseFloat(n[i+1])));var o=new z(r);return"polygon"===t&&o.closePath(),o}function c(e){var t=e.getAttribute("d"),n={pathData:t};return(t.match(/m/gi)||[]).length>1||/z\S+/i.test(t)?new R(n):new z(n)}function u(n,r){var i,a=(e(n,"href",!0)||"").substring(1),o="radialgradient"===r;if(a)i=M[a].getGradient();else{for(var s=n.childNodes,l=[],c=0,u=s.length;c<u;c++){var h=s[c];1===h.nodeType&&l.push(m(new W,h))}i=new U(l,o)}var d,f,p;return o?(d=t(n,"cx","cy"),f=d.add(e(n,"r"),0),p=t(n,"fx","fy",!0)):(d=t(n,"x1","y1"),f=t(n,"x2","y2")),m(new V(i,d,f,p),n),null}function h(e,t,n,r){for(var i=(r.getAttribute(n)||"").split(/\)\s*/g),a=new b,o=0,s=i.length;o<s;o++){var l=i[o];if(!l)break;for(var c=l.split(/\(\s*/),u=c[0],h=c[1].split(/[\s,]+/g),d=0,f=h.length;d<f;d++)h[d]=parseFloat(h[d]);switch(u){case"matrix":a.concatenate(new b(h[0],h[1],h[2],h[3],h[4],h[5]));break;case"rotate":a.rotate(h[0],h[1],h[2]);break;case"translate":a.translate(h[0],h[1]);break;case"scale":a.scale(h);break;case"skewX":a.skew(h[0],0);break;case"skewY":a.skew(0,h[0])}}e.transform(a)}function d(e,t,n){var r=e["fill-opacity"===n?"getFillColor":"getStrokeColor"]();r&&r.setAlpha(parseFloat(t))}function f(e,t,n){var r=e.attributes[t],i=r&&r.value;if(!i){var a=s.camelize(t);i=e.style[a],i||n.node[a]===n.parent[a]||(i=n.node[a])}return i?"none"===i?null:i:o}function m(e,t,n){var r={node:H.getStyles(t)||{},parent:!n&&H.getStyles(t.parentNode)||{}};return s.each(S,function(n,i){var a=f(t,i,r);a!==o&&(e=s.pick(n(e,a,i,t,r),e))}),e}function v(e){var t=e&&e.match(/\((?:#|)([^)']+)/);return t&&M[t[1]]}function y(e,t,n){function r(e){a=o;var r=y(e,t,n),i=t.onLoad,s=o.project&&o.getView();i&&i.call(this,r),s.update()}if(!e)return null;t?"function"==typeof t&&(t={onLoad:t}):t={};var i=e,o=a;if(n)if("string"!=typeof e||/^.*</.test(e)){if("undefined"!=typeof File&&e instanceof File){var l=new FileReader;return l.onload=function(){r(l.result)},l.readAsText(e)}}else{if(i=document.getElementById(e),!i)return te.request("get",e,r);e=null}if("string"==typeof e&&(i=(new DOMParser).parseFromString(e,"image/svg+xml")),!i.nodeName)throw new Error("Unsupported SVG source: "+e);var c,u=i.nodeName.toLowerCase(),h=_[u],d=i.getAttribute&&i.getAttribute("data-paper-data"),f=o.settings,p=f.applyMatrix;if(f.applyMatrix=!1,c=h&&h(i,u,t,n)||null,f.applyMatrix=p,c){"#document"===u||c instanceof k||(c=m(c,i,n));var g=t.onImport;g&&(c=g(i,c,t)||c),t.expandShapes&&c instanceof P&&(c.remove(),c=c.toPath()),d&&(c._data=JSON.parse(d))}return n&&(M={},c&&s.pick(t.applyMatrix,p)&&c.matrix.apply(!0,!0)),c}var _={"#document":function(e,t,n,r){for(var i=e.childNodes,a=0,o=i.length;a<o;a++){var s=i[a];if(1===s.nodeType){var l=s.nextSibling;document.body.appendChild(s);var c=y(s,n,r);return l?e.insertBefore(s,l):e.appendChild(s),c}}},g:i,svg:i,clippath:i,polygon:l,polyline:l,path:c,lineargradient:u,radialgradient:u,image:function(r){var i=new T(e(r,"href",!0));return i.on("load",function(){var e=n(r,"width","height");this.setSize(e);var i=this._matrix._transformPoint(t(r,"x","y").add(e.divide(2)));this.translate(i)}),i},symbol:function(e,t,n,r){return new E(i(e,t,n,r),!0)},defs:i,use:function(n){var r=(e(n,"href",!0)||"").substring(1),i=M[r],a=t(n,"x","y");return i?i instanceof E?i.place(a):i.clone().translate(a):null},circle:function(n){return new P.Circle(t(n,"cx","cy"),e(n,"r"))},ellipse:function(e){return new P.Ellipse({center:t(e,"cx","cy"),radius:n(e,"rx","ry")})},rect:function(e){var r=t(e,"x","y"),i=n(e,"width","height"),a=n(e,"rx","ry");return new P.Rectangle(new w(r,i),a)},line:function(e){return new z.Line(t(e,"x1","y1"),t(e,"x2","y2"))},text:function(e){var n=new q(t(e,"x","y").add(t(e,"dx","dy")));return n.setContent(e.textContent.trim()||""),n}},S=s.set(s.each(ie,function(e){this[e.attribute]=function(t,n){if(t[e.set](r(n,e.type,e.fromSVG)),"color"===e.type&&t instanceof P){var i=t[e.get]();i&&i.transform((new b).translate(t.getPosition(!0).negate()))}}},{}),{id:function(e,t){M[t]=e,e.setName&&e.setName(t)},"clip-path":function(e,t){var n=v(t);if(n){if(n=n.clone(),n.setClipMask(!0),!(e instanceof k))return new k(n,e);e.insertChild(0,n)}},gradientTransform:h,transform:h,"fill-opacity":d,"stroke-opacity":d,visibility:function(e,t){e.setVisible("visible"===t)},display:function(e,t){e.setVisible(null!==t)},"stop-color":function(e,t){e.setColor&&e.setColor(t)},"stop-opacity":function(e,t){e._color&&e._color.setAlpha(parseFloat(t))},offset:function(e,t){var n=t.match(/(.*)%$/);e.setRampPoint(n?n[1]/100:parseFloat(t))},viewBox:function(e,t,i,a,o){var s=new w(r(t,"array")),l=n(a,"width","height",!0);if(e instanceof k){var c=l?s.getSize().divide(l):1,u=(new b).translate(s.getPoint()).scale(c);e.transform(u.inverted())}else if(e instanceof E){l&&s.setSize(l);var h="visible"!=f(a,"overflow",o),d=e._definition;h&&!s.contains(d.getBounds())&&(h=new P.Rectangle(s).transform(d._matrix),h.setClipMask(!0),d.addChild(h))}}}),M={};C.inject({importSVG:function(e,t){return this.addChild(y(e,t,!0))}}),x.inject({importSVG:function(e,t){return this.activate(),y(e,t,!0)}})},a=new(c.inject(s.exports,{enumerable:!0,Base:s,Numerical:d,Key:$})),r=a,i="function"==typeof r?r.call(t,n,t,e):r,!(i!==o&&(e.exports=i)),a}},function(e,t,n){"use strict";var r=n(4),i=n(105),a=r.createClass({displayName:"BSplineGraphic",componentWillMount:function(){var e=this;this.cvs=void 0,this.ctx=void 0,this.key=void 0,this.keyCode=void 0,this.mouseX=void 0,this.mouseY=void 0,this.isMouseDown=void 0,this.width=0,this.height=0,this.activeDistance=9,this.points=[],this.knots=[],this.weights=[],this.nodes=[],this.cp=void 0,this.dx=void 0,this.dy=void 0;var t=this.props.sketch;Object.keys(t).forEach(function(n){e[n]=t[n],"function"==typeof e[n]&&(e[n]=e[n].bind(e))})},render:function(){return r.createElement("canvas",{className:"bspline-graphic",ref:"sketch"})},keydownlisten:function(e){this.setKeyboardValues(e),this.keyDown()},keyuplisten:function(e){this.setKeyboardValues(e),this.keyUp()},keypresslisten:function(e){this.setKeyboardValues(e),this.keyPressed()},mousedownlisten:function(e){this.setMouseValues(e),this.mouseDown()},mouseuplisten:function(e){this.setMouseValues(e),this.mouseUp()},mousemovelisten:function(e){this.setMouseValues(e),this.mouseMove(),this.isMouseDown&&this.mouseDrag&&this.mouseDrag()},wheellissten:function(e){e.preventDefault(),this.scrolled(e.deltaY<0?1:-1)},componentDidMount:function(){var e=this.cvs=this.refs.sketch;e.addEventListener("keydown",this.keydownlisten),e.addEventListener("keyup",this.keyuplisten),e.addEventListener("keypress",this.keypresslisten),e.addEventListener("mousedown",this.mousedownlisten),e.addEventListener("mouseup",this.mouseuplisten),e.addEventListener("mousemove",this.mousemovelisten),this.props.scrolling&&e.addEventListener("wheel",this.wheellissten),this.setup()},componentWillUnmount:function(){var e=this.cvs=this.refs.sketch;e.removeEventListener("keydown",this.keydownlisten),e.removeEventListener("keyup",this.keyuplisten),e.removeEventListener("keypress",this.keypresslisten),e.removeEventListener("mousedown",this.mousedownlisten),e.removeEventListener("mouseup",this.mouseuplisten),e.removeEventListener("mousemove",this.mousemovelisten),this.props.scrolling&&e.removeEventListener("wheel",this.wheellissten)},drawCurve:function(e){e=e||this.points;var t=this.ctx,n=this.weights.length>0&&this.weights;t.beginPath();var r=i(0,this.degree,e,this.knots,n);t.moveTo(r[0],r[1]);for(var a=.01;a<1;a+=.01)r=i(a,this.degree,e,this.knots,n),t.lineTo(r[0],r[1]);r=i(1,this.degree,e,this.knots,n),t.lineTo(r[0],r[1]),t.stroke(),t.closePath()},drawKnots:function(e){var t=this,n=this.knots,r=this.weights.length>0&&this.weights;n.forEach(function(a,o){if(!(o<t.degree||o>n.length-1-t.degree)){var s=i(a,t.degree,e,n,r,!1,!0);t.circle(s[0],s[1],3)}})},drawNodes:function(e){var t,n=this;this.stroke(150),this.nodes.forEach(function(r,a){try{t=i(r,n.degree,e,n.knots,!1,!1,!0),n.line(t[0],t[1],e[a][0],e[a++][1])}catch(e){console.error(e)}})},formKnots:function(e,t){if(t=t===!0,!t)return this.formUniformKnots(e);var n,r=e.length,i=[],a=r-this.degree;for(n=1;n<r-this.degree;n++)i.push(n+this.degree);for(n=0;n<=this.degree;n++)i=[this.degree].concat(i);for(n=0;n<=this.degree;n++)i.push(a+this.degree);return i},formUniformKnots:function(e){for(var t=[],n=this.points.length+this.degree;n>=0;n--)t.push(n);return t.reverse()},formNodes:function(e,t){var n,r,i,a=[this.degree,e.length-1-this.degree],o=[];for(r=0;r<this.points.length;r++){for(n=0,i=1;i<=this.degree;i++)n+=e[r+i];n/=this.degree,n<e[a[0]]||n>e[a[1]]||o.push(n)}return o},formWeights:function(e){var t=[];return e.forEach(function(e){return t.push(1)}),t},setDegree:function(e){this.degree+=e,this.knots=this.formKnots(this.points),this.nodes=this.formNodes(this.knots,this.points)},near:function(e,t,n){var r=e.x-t,i=e.y-n,a=Math.sqrt(r*r+i*i);return a<this.activeDistance},getCurrentPoint:function(e,t){for(var n=0;n<this.points.length;n++)if(this.near(this.points[n],e,t))return this.points[n]},keyDown:function(){"ArrowUp"===this.key&&this.setDegree(1),"ArrowDown"===this.key&&this.degree>1&&this.setDegree(-1),this.redraw()},keyUp:function(){},keyPressed:function(){},mouseDown:function(){this.isMouseDown=!0,this.cp=this.getCurrentPoint(this.mouseX,this.mouseY),this.cp||(this.points.push({x:this.mouseX,y:this.mouseY}),this.knots=this.formKnots(this.points),this.nodes=this.formNodes(this.knots,this.points)),this.redraw()},mouseUp:function(){this.isMouseDown=!1,this.cp=!1,this.redraw()},mouseDrag:function(){this.cp&&(this.cp.x=this.mouseX,this.cp.y=this.mouseY,this.redraw())},mouseMove:function(){},scrolled:function(e){if(this.cp=this.getCurrentPoint(this.mouseX,this.mouseY),this.cp){var t=this.points.indexOf(this.cp);this.weights.length>t&&(this.weights[t]+=.1*e,this.weights[t]<0&&(this.weights[t]=0)),t=this.points.indexOf(this.cp,t+1),t!==-1&&this.weights.length>t&&(this.weights[t]+=.1*e,this.weights[t]<0&&(this.weights[t]=0)),this.redraw()}},setKeyboardValues:function(e){e.ctrlKey||e.metaKey||e.altKey||e.preventDefault(),this.key=e.key,this.keyCode=e.code},setMouseValues:function(e){var t=this.cvs.getBoundingClientRect();this.mouseX=e.clientX-t.left,this.mouseY=e.clientY-t.top},size:function(e,t){this.width=0|e,this.height=0|(t||e),this.cvs.width=this.width,this.cvs.height=this.height,this.ctx=this.cvs.getContext("2d")},redraw:function(){this.draw()},clear:function(){this.ctx.clearRect(0,0,this.width,this.height)},grid:function(e){e=(0|(e||10))+.5,this.stroke(200,200,220);for(var t=e;t<this.width-1;t+=e)this.line(t,0,t,this.height);for(var n=e;n<this.height-1;n+=e)this.line(0,n,this.width,n)},circle:function(e,t,n){var r=this.ctx;r.beginPath(),r.moveTo(e,t),r.arc(e,t,n,0,2*Math.PI),r.stroke(),r.closePath()},line:function(e,t,n,r){var i=this.ctx;i.beginPath(),i.moveTo(e,t),i.lineTo(n,r),i.stroke(),i.closePath()},stroke:function(e,t,n,r){return"string"==typeof e?this.ctx.strokeStyle=e:(void 0===t&&(t=e,n=e),void 0===r&&(r=1),void(this.ctx.strokeStyle=this.rgba(e,t,n,r)))},noStroke:function(){this.ctx.strokeStyle="none"},fill:function(e,t,n,r){return"string"==typeof e?this.ctx.fillStyle=e:(void 0===t&&(t=e,n=e),void 0===r&&(r=1),void(this.ctx.fillStyle=this.rgba(e,t,n,r)))},noFill:function(){this.ctx.fillStyle="none"},rgba:function(e,t,n,r){return"rgba("+e+","+t+","+n+","+r+")"},beginPath:function(){this.ctx.beginPath(),this.bp=!0},vertex:function(e,t){return this.bp?(this.ctx.moveTo(e,t),void(this.bp=!1)):this.ctx.lineTo(e,t)},endPath:function(){this.ctx.stroke(),this.ctx.closePath()}});e.exports=a},function(e,t,n){"use strict";var r=n(4),i=r.createClass({displayName:"Footer",render:function(){return r.createElement("footer",{className:"copyright"},'This article is © 2011-2016 to me, Mike "Pomax" Kamermans, but the text, code, and images are ',r.createElement("a",{href:"https://github.com/Pomax/bezierinfo/blob/gh-pages/LICENSE.md"},"almost no rights reserved"),". Go do something cool with it!")}});e.exports=i},function(e,t,n){"use strict";var r=n(4),i=n(114),a=n(38),o=function(e){return Object.keys(a).map(e)},s=o(function(e,t){var n=a[e];return r.createElement(n,{key:e,name:e,number:t})}),l=r.createClass({displayName:"FullArticle",render:function(){return r.createElement(i,null,s)}});e.exports=l},function(e,t,n){"use strict";var r=n(4),i={render:function(){return r.createElement("figure",{className:!!this.props.inline&&"inline"},r.createElement("canvas",{ref:"canvas",tabIndex:"0",style:{width:this.panelCount*this.defaultWidth+"px",height:this.defaultHeight+"px"},onMouseDown:this.mouseDown,onMouseMove:this.mouseMove,onMouseUp:this.mouseUp,onClick:this.onClick,onKeyUp:this.onKeyUp,onKeyDown:this.onKeyDown,onKeyPress:this.onKeyPress}),r.createElement("figcaption",null,this.props.title," ",this.props.children))},componentDidMount:function(){var e=this.refs.canvas,t=this.getPixelRatio();e.width=this.defaultWidth*t,e.height=this.defaultHeight*t,this.cvs=e;var r=e.getContext("2d");if(this.ctx=r,this.ctx.scale(t,t),this.props.paperjs){var i=this.Paper=n(106);i.setup(e)}this.props.setup&&this.props.setup(this),this.props.draw&&this.props.draw(this,this.curve),this.props.autoplay&&this.play()}},a=n(118);Object.keys(a).forEach(function(e){i[e]=a[e]}),e.exports=r.createClass(i)},function(e,t,n){"use strict";var r=n(4),i=r.createClass({displayName:"Header",render:function(){return r.createElement("header",null,r.createElement("h1",null,"A Primer on Bézier Curves"),r.createElement("h2",null,"A free, online book for when you really need to know how to do Bézier things."))}});e.exports=i},function(e,t,n){"use strict";var r=n(4),i=r.createClass({displayName:"KnotController",getInitialState:function(){return{owner:!1,knots:[]}},bindKnots:function(e,t){this.setState({owner:e,knots:t})},render:function(){var e=this,t="range",n=0,i=this.state.knots.length,a=1;return r.createElement("section",{className:"knot-controls"},r.createElement("h2",null,"knot values"),this.state.knots.map(function(o,s){var l={type:t,min:n,max:i,step:a,value:o,onChange:function(t){var n=e.state.knots;n[s]=t.target.value,e.setState({knots:n},function(){e.state.owner.redraw()})}};return r.createElement("div",{key:"knot"+s},n,r.createElement("input",l),i," (= ",o,")")}))}});e.exports=i},function(e,t,n){"use strict";var r=n(4),i=n(97),a=i.Link,o=n(38),s=Object.keys(o),l=n(64),c=r.createClass({displayName:"Navigation",generateNavItem:function(e,t){var n=o[e],i=n.getDefaultProps().title,c=l.locale;"undefined"!=typeof window&&window.location.toString().indexOf(c)===-1&&(c="");var u=(c?"./"+c+"/":".")+"#"+e,h=r.createElement("a",{href:u},i);this.props.fullNav&&(h=r.createElement(a,{to:e},i));var d=s.length-1;return t===d&&(t=null),r.createElement("li",{key:e,"data-number":t},h)},generateNav:function(){return this.props.compact?null:r.createElement("div",{ref:"navigation"},r.createElement("navigation",{className:this.props.compact?"compact":null},r.createElement("ul",{className:"navigation"},s.map(this.generateNavItem))))},render:function(){return this.generateNav()}});e.exports=c},function(e,t,n){"use strict";var r=n(4),i=n(116),a=n(111),o=n(115),s=n(120).LocaleSwitcher,l=n(113),c=n(108),u=r.createClass({displayName:"Page",renderCompactContent:function(e){return r.createElement("div",null,r.createElement(o,{prev:this.props.prev,next:this.props.next,position:"before"}),this.props.children,r.createElement(o,{prev:this.props.prev,next:this.props.next,position:"after"}))},renderCompactRoot:function(e){return r.createElement("div",null,this.props.children,e)},renderPageContent:function(e){return r.createElement("div",null,r.createElement(s,null),e,this.props.children)},render:function(){var e,t=this.props.compact,n="/"===this.props.name,o=r.createElement(l,{compact:t&&!n});return e=t?n?this.renderCompactRoot(o):this.renderCompactContent(o):this.renderPageContent(o),r.createElement("div",null,r.createElement(i,null),r.createElement(a,null),e,r.createElement(c,null))}});e.exports=u},function(e,t,n){"use strict";var r=n(4),i=n(97),a=i.Link,o=n(38),s=Object.keys(o),l=r.createClass({displayName:"Relatives",getInitialState:function(){var e=this.props.prev;e=e>-1&&{to:s[e],title:o[s[e]].getDefaultProps().title};var t=this.props.next;return t=t<s.length&&{to:s[t],title:o[s[t]].getDefaultProps().title},{prev:e,next:t}},render:function(){return this.props.prev||this.props.next?r.createElement("table",{className:"relatives "+this.props.position},r.createElement("tbody",null,r.createElement("tr",null,r.createElement("td",null,this.state.prev?r.createElement(a,{className:"prev",to:this.state.prev.to},this.props.prev+". "+this.state.prev.title):null),r.createElement("td",{className:"toc"},r.createElement(a,{to:"/"},"ToC")),r.createElement("td",null,this.state.next?r.createElement(a,{className:"next",to:this.state.next.to},this.props.next+". "+this.state.next.title):null)))):null}});e.exports=l},function(e,t,n){"use strict";var r=n(4),i=r.createClass({displayName:"Ribbon",getInitialState:function(){return{href:"http://github.com/pomax/BezierInfo-2"}},render:function(){return r.createElement("div",{className:"ribbon"},r.createElement("img",{src:"images/ribbon.png",alt:"This page on GitHub",style:{border:"none"},useMap:"#githubmap", +width:"200px",height:"149px"}),r.createElement("map",{name:"githubmap"},r.createElement("area",{shape:"poly",coords:"30,0, 200,0, 200,114",href:this.state.href,alt:"This page on GitHub"})))}});e.exports=i},function(e,t,n){"use strict";var r=n(4),i=r.createClass({displayName:"WeightController",getInitialState:function(){return{owner:!1,weights:[],closed:!1}},bindWeights:function(e,t,n){this.setState({owner:e,weights:t,closed:n})},render:function(){var e=this,t="range",n=0,i=this.state.weights.length,a=1,o=this.state.closed,s=this.state.weights.length;return o!==!1&&(s-=o),r.createElement("section",{className:"knot-controls"},r.createElement("h2",null,"weight values"),this.state.weights.map(function(l,c){if(o&&c>=s)return null;var u={type:t,min:n,max:i,step:a,value:l,onChange:function(t){var n=e.state.weights;n[c]=t.target.value,o&&c<o&&(n[c+s]=t.target.value),e.setState({weights:n},function(){e.state.owner.redraw()})}};return r.createElement("div",{key:"knot"+c},n,r.createElement("input",u),i," (= ",l,")")}))}});e.exports=i},function(e,t,n){"use strict";var r="undefined"!=typeof window,i=n(207),a=n(205),o=function(e){e=e||window.event;var t=e.target||e.srcElement,n=t.getBoundingClientRect();e.offsetX=e.clientX-n.left,e.offsetY=e.clientY-n.top},s={Paper:!1,defaultWidth:275,defaultHeight:275,panelCount:1,Bezier:a,utils:a.getUtils(),curve:!1,mx:0,my:0,cx:0,cy:0,mp:!1,offset:{x:0,y:0},lpts:[],colorSeed:0,playing:!1,frame:0,playinterval:33,animate:function(){this.playing&&(this.frame++,setTimeout(this.animate,this.playinterval),this.props.draw(this,this.curve))},getFrame:function(){return this.frame},getPlayInterval:function(){return this.playinterval},play:function(){this.playing=!0,this.animate()},pause:function(){this.playing=!1},redraw:function(){this.props.draw&&this.props.draw(this,this.curve)},mouseDown:function(e){var t=this;o(e),this.mx=e.offsetX,this.my=e.offsetY,this.movingPoint=!1,this.dragging=!1,this.down=!0,this.lpts.forEach(function(e,n){Math.abs(t.mx-e.x)<10&&Math.abs(t.my-e.y)<10&&(t.movingPoint=!0,t.mp=e,t.mp_idx=n,t.cx=e.x,t.cy=e.y)}),this.props.onMouseDown&&this.props.onMouseDown(e,this),"setCapture"in e.target&&e.target.setCapture()},mouseMove:function(e){if(o(e),!this.props.static){this.down&&(this.dragging=!0);var t=!1;if(this.lpts.forEach(function(n){var r=e.offsetX,i=e.offsetY;Math.abs(r-n.x)<10&&Math.abs(i-n.y)<10&&(t=t||!0)}),this.cvs.style.cursor=t?"pointer":"default",this.hover={x:e.offsetX,y:e.offsetY},this.movingPoint)if(this.ox=e.offsetX-this.mx,this.oy=e.offsetY-this.my,this.mp.x=Math.max(0,Math.min(this.defaultWidth,this.cx+this.ox)),this.mp.y=Math.max(0,Math.min(this.defaultHeight,this.cy+this.oy)),this.curve.forEach){for(var n,r,i=0;i<this.curve.length;i++)if(n=this.curve[i],r=n.points,r.indexOf(this.mp)>-1){n.update();break}}else this.curve&&this.curve.update&&this.curve.update()}this.props.onMouseMove&&this.props.onMouseMove(e,this),this.dragging&&this.props.onMouseDrag&&this.props.onMouseDrag(e,this),this.props.static||this.playing||!this.props.draw||this.props.draw(this,this.curve)},mouseUp:function(e){return this.down=!1,this.movingPoint?(this.movingPoint=!1,this.mp=!1,void(this.props.onMouseUp&&this.props.onMouseUp(e,this))):void(this.props.onMouseUp&&this.props.onMouseUp(e,this))},onClick:function(e){o(e),this.mx=e.offsetX,this.my=e.offsetY,!this.dragging&&this.props.onClick&&this.props.onClick(e,this)},onKeyUp:function(e){this.props.onKeyUp&&(this.props.onKeyUp(e,this),!this.playing&&this.props.draw&&this.props.draw(this,this.curve))},onKeyDown:function(e){this.props.onKeyDown&&(this.props.onKeyDown(e,this),!this.playing&&this.props.draw&&this.props.draw(this,this.curve))},onKeyPress:function(e){this.props.onKeyPress&&(this.props.onKeyPress(e,this),!this.playing&&this.props.draw&&this.props.draw(this,this.curve))},reset:function(){this.refs.canvas.width=this.refs.canvas.width,this.ctx.strokeStyle="black",this.ctx.lineWidth=1,this.ctx.fillStyle="none";var e=this.getPixelRatio();this.ctx.scale(e,e),this.offset={x:0,y:0},this.colorSeed=0},setSize:function(e,t){this.defaultWidth=e,this.defaultHeight=t;var n=this.refs.canvas;n.style.width=this.panelCount*e+"px",n.style.height=t+"px";var r=this.getPixelRatio();n.width=this.panelCount*e*r,n.height=t*r,this.ctx.scale(r,r)},setCurves:function(e){this.setCurve(e)},setCurve:function(e){var t=[];e=e instanceof Array?e:Array.prototype.slice.call(arguments),e.forEach(function(e){t=t.concat(e.points)}),this.curve=1===e.length?e[0]:e,this.lpts=t},getPanelWidth:function(){return this.defaultWidth},getPanelHeight:function(){return this.defaultHeight},getDefaultQuadratic:function(){return new this.Bezier(70,250,20,110,250,60)},getDefaultCubic:function(){return new this.Bezier(120,160,35,200,220,260,220,40)},getPixelRatio:function(){return window.devicePixelRatio||1},toImage:function(){var e=this.refs.canvas.toDataURL(),t=new Image;return t.src=e,t.devicePixelRatio=this.getPixelRatio(),t},setPanelCount:function(e){this.panelCount=e;var t=this.refs.canvas;t.width=e*this.defaultWidth*this.getPixelRatio(),t.style.width=e*this.defaultWidth+"px"},setOffset:function(e){this.offset=e},setColor:function(e){this.ctx.strokeStyle=e},getColor:function(){return this.ctx.strokeStyle||"black"},setWeight:function(e){this.ctx.lineWidth=e},noColor:function(e){this.ctx.strokeStyle="transparent"},setRandomColor:function(e){e="undefined"==typeof e?1:e;var t=this.colorSeed%360,n=1,r=.34;this.colorSeed+=87,this.ctx.strokeStyle=i.hsl(t,n,r).alpha(e).css()},setRandomFill:function(e){e="undefined"==typeof e?1:e;var t=this.colorSeed%360,n=1,r=.34;this.colorSeed+=87,this.ctx.fillStyle=i.hsl(t,n,r).alpha(e).css()},setFill:function(e){this.ctx.fillStyle=e},getFill:function(){return this.ctx.fillStyle||"transparent"},noFill:function(){this.ctx.fillStyle="transparent"},drawSkeleton:function(e,t,n){t=t||{x:0,y:0};var r=e.points;if(r.length>2){this.ctx.strokeStyle="lightgrey",this.drawLine(r[0],r[1],t);for(var i=r.length-2,a=1;a<i;a++)this.drawLine(r[a],r[a+1],t);this.drawLine(r[i],r[i+1],t)}this.ctx.strokeStyle="black",this.drawPoints(r,t),n||this.drawCoordinates(e,t)},drawGrid:function(e,t,n){var r,i,a,o,s,l,c=this.defaultWidth,u=this.defaultHeight,h=c/e,d=h/2,f=u/t,p=f/2;for(r=0;r<e;r++)i=d+r*h,s={x:i,y:0},l={x:i,y:u},this.drawLine(s,l,n);for(a=0;a<t;a++)o=p+a*f,s={x:0,y:o},l={x:c,y:o},this.drawLine(s,l,n)},drawHull:function(e,t,n){var r=e instanceof Array?e:e.hull(t);return 6===r.length?(this.drawLine(r[0],r[1],n),this.drawLine(r[1],r[2],n),this.drawLine(r[3],r[4],n)):(this.drawLine(r[0],r[1],n),this.drawLine(r[1],r[2],n),this.drawLine(r[2],r[3],n),this.drawLine(r[4],r[5],n),this.drawLine(r[5],r[6],n),this.drawLine(r[7],r[8],n)),r},drawCoordinates:function(e,t){var n=this;t=t||{x:0,y:0};var r=e.points;this.setFill("black"),r.forEach(function(e){n.text("("+e.x+","+e.y+")",{x:e.x+t.x+5,y:e.y+t.y+10})})},drawFunction:function(e,t){var n,r,i=e.start||0,a=e(i),o=e.end||1,s=e(o),l=e.step||.01,c=e.scale||1;for(r=l;r<o;r+=l)n=e(r,c),this.drawLine(a,n,t),a=n;this.drawLine(n,s,t)},drawCurve:function(e,t){var n=this;t=t||{x:0,y:0};var r=e.points;if(r.length<=3||5<=r.length){var i=e.getLUT(100),a=i[0];return void i.forEach(function(e,r){r&&(n.drawLine(a,e,t),a=e)})}var o=t.x+this.offset.x,s=t.y+this.offset.y;this.ctx.beginPath(),this.ctx.moveTo(r[0].x+o,r[0].y+s),3===r.length?this.ctx.quadraticCurveTo(r[1].x+o,r[1].y+s,r[2].x+o,r[2].y+s):4===r.length&&this.ctx.bezierCurveTo(r[1].x+o,r[1].y+s,r[2].x+o,r[2].y+s,r[3].x+o,r[3].y+s),this.ctx.stroke(),this.ctx.closePath()},drawLine:function(e,t,n){n=n||{x:0,y:0};var r=n.x+this.offset.x,i=n.y+this.offset.y;this.ctx.beginPath(),this.ctx.moveTo(e.x+r,e.y+i),this.ctx.lineTo(t.x+r,t.y+i),this.ctx.stroke()},drawPoint:function(e,t){this.drawCircle(e,1,t)},drawPoints:function(e,t){t=t||{x:0,y:0},e.forEach(function(e){this.drawCircle(e,0!==t.x||0!==t.y?1.5:3,t)}.bind(this))},drawArc:function(e,t){t=t||{x:0,y:0};var n=t.x+this.offset.x,r=t.y+this.offset.y;this.ctx.beginPath(),this.ctx.moveTo(e.x+n,e.y+r),this.ctx.arc(e.x+n,e.y+r,e.r,e.s,e.e),this.ctx.lineTo(e.x+n,e.y+r),this.ctx.fill(),this.ctx.stroke()},drawCircle:function(e,t,n){n=n||{x:0,y:0};var r=n.x+this.offset.x,i=n.y+this.offset.y;this.ctx.beginPath(),this.ctx.arc(e.x+r,e.y+i,t,0,2*Math.PI),this.ctx.stroke()},drawbbox:function(e,t){t=t||{x:0,y:0};var n=t.x+this.offset.x,r=t.y+this.offset.y;this.ctx.beginPath(),this.ctx.moveTo(e.x.min+n,e.y.min+r),this.ctx.lineTo(e.x.min+n,e.y.max+r),this.ctx.lineTo(e.x.max+n,e.y.max+r),this.ctx.lineTo(e.x.max+n,e.y.min+r),this.ctx.closePath(),this.ctx.stroke()},drawRect:function(e,t,n){n=n||{x:0,y:0};var r=n.x+this.offset.x,i=n.y+this.offset.y,a=e.x+r,o=e.y+i,s=t.x-e.x,l=t.y-e.y;this.ctx.beginPath(),this.ctx.moveTo(a,o),this.ctx.lineTo(a+s,o),this.ctx.lineTo(a+s,o+l),this.ctx.lineTo(a,o+l),this.ctx.closePath(),this.ctx.fill(),this.ctx.stroke()},drawPath:function(e,t){var n=this;t=t||{x:0,y:0};var r=t.x+this.offset.x,i=t.y+this.offset.y;this.ctx.beginPath(),e.forEach(function(e,t){return 0===t?n.ctx.moveTo(e.x+r,e.y+i):void n.ctx.lineTo(e.x+r,e.y+i)}),closed&&this.ctx.closePath(),this.ctx.fill(),this.ctx.stroke()},drawShape:function(e,t){t=t||{x:0,y:0};var n=t.x+this.offset.x,r=t.y+this.offset.y,i=e.forward.points.length-1;this.ctx.beginPath(),this.ctx.moveTo(n+e.startcap.points[0].x,r+e.startcap.points[0].y),this.ctx.lineTo(n+e.startcap.points[3].x,r+e.startcap.points[3].y),3===i?this.ctx.bezierCurveTo(n+e.forward.points[1].x,r+e.forward.points[1].y,n+e.forward.points[2].x,r+e.forward.points[2].y,n+e.forward.points[3].x,r+e.forward.points[3].y):this.ctx.quadraticCurveTo(n+e.forward.points[1].x,r+e.forward.points[1].y,n+e.forward.points[2].x,r+e.forward.points[2].y),this.ctx.lineTo(n+e.endcap.points[3].x,r+e.endcap.points[3].y),3===i?this.ctx.bezierCurveTo(n+e.back.points[1].x,r+e.back.points[1].y,n+e.back.points[2].x,r+e.back.points[2].y,n+e.back.points[3].x,r+e.back.points[3].y):this.ctx.quadraticCurveTo(n+e.back.points[1].x,r+e.back.points[1].y,n+e.back.points[2].x,r+e.back.points[2].y),this.ctx.closePath(),this.ctx.fill(),this.ctx.stroke()},text:function(e,t,n){n=n||{x:0,y:0},this.offset&&(n.x+=this.offset.x,n.y+=this.offset.y),this.ctx.fillText(e,t.x+n.x,t.y+n.y)},image:function(e,t){var n=this;t=t||{x:0,y:0},this.offset&&(t.x+=this.offset.x,t.y+=this.offset.y);var r=e.devicePixelRatio||1;e.loaded?this.ctx.drawImage(e,t.x,t.y,e.width/r,e.height/r):e.onload=function(){e.loaded=!0,n.ctx.drawImage(e,t.x,t.y,e.width/r,e.height/r)}},drawAxes:function(e,t,n,r,i,a,o,s){s=s||{x:0,y:0};var l=this.getPanelWidth();this.drawLine({x:e,y:e},{x:l-e,y:e},s),this.drawLine({x:e,y:e},{x:e,y:l-e},s),this.setFill("black"),this.text(t+" →",{x:s.x+l/2,y:s.y+15}),this.text(n,{x:s.x+e,y:s.y+15}),this.text(r,{x:s.x+l-e,y:s.y+15}),this.text(i,{x:s.x+5,y:s.y+l/2-e}),this.text("↓",{x:s.x+5,y:s.y+l/2}),this.text(a,{x:s.x+4,y:s.y+e+5}),this.text(o,{x:s.x+2,y:s.y+l-e+10})}};r&&(window["Bezier Graphics API"]=s),e.exports=s},function(e,t,n){"use strict";var r=n(4),i=n(63),a=new i,o="locale-switcher";e.exports=function(e){return r.createElement("div",{className:"locale-switcher"},a.getContent(o,this))}},function(e,t,n){"use strict";e.exports={LocaleSwitcher:n(119)}},function(e,t,n){"use strict";e.exports={onClick:function(e,t){t.t=t.curve.on({x:e.offsetX,y:e.offsetY},7),(t.t<.05||t.t>.95)&&(t.t=!1),t.redraw()},setupQuadratic:function(e){var t=e.getDefaultQuadratic();t.points[0].y-=10,e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();t.points[2].y-=20,e.setCurve(t),e.lut=t.getLUT(100)},draw:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n=e.getPanelHeight();if(e.setColor("black"),e.t){e.drawCircle(e.curve.get(e.t),3),e.setColor("lightgrey");var r,i,a,o=e.drawHull(t,e.t),s=e.utils;6===o.length?(r=t.points[1],i=o[5],a=s.lli4(r,i,t.points[0],t.points[2]),e.setColor("lightgrey"),e.drawLine(t.points[0],t.points[2])):10===o.length&&(r=o[5],i=o[9],a=s.lli4(r,i,t.points[0],t.points[3]),e.setColor("lightgrey"),e.drawLine(t.points[0],t.points[3])),e.setColor("#00FF00"),e.drawLine(r,i),e.setColor("red"),e.drawLine(i,a),e.setColor("black"),e.drawCircle(a,3),e.setFill("black"),e.text("A",{x:10+r.x,y:r.y}),e.text("B (t = "+e.utils.round(e.t,2)+")",{x:10+i.x,y:i.y}),e.text("C",{x:10+a.x,y:a.y});var l=s.dist(r,i),c=s.dist(i,a),u=l/c;e.text("d1 (A-B): "+s.round(l,2)+", d2 (B-C): "+s.round(c,2)+", ratio (d1/d2): "+s.round(u,4),{x:10,y:n-7})}},setCT:function(e,t){t.t=e.offsetX/t.getPanelWidth()},drawCTgraph:function(e){e.reset(),e.setColor("black");var t=e.getPanelWidth(),n=20,r=t-2*n;e.drawAxes(n,"t",0,1,"u",0,1),e.setColor("blue");var i=function(t){var i=e.u(t),a={x:n+t*r,y:n+i*r};return a};if(e.drawFunction(i),e.t){var a=e.u(e.t),o=e.utils.round(a,3),s=e.utils.round(1-a,3),l=i(e.t);e.drawLine({x:l.x,y:n},l),e.drawLine({x:n,y:l.y},l),e.drawCircle(l,3),e.setFill("blue"),e.text(" t = "+e.utils.round(e.t,3),{x:l.x+10,y:l.y-7}),e.text("u(t) = "+e.utils.round(a,3),{x:l.x+10,y:l.y+7}),e.setFill("black"),e.text("C = "+o+" * start + "+s+" * end",{x:t/2-n,y:n+r})}},drawQCT:function(e){e.u=e.u||function(e){var t=(e-1)*(e-1),n=2*e*e-2*e+1;return t/n},this.drawCTgraph(e)},drawCCT:function(e){e.u=e.u||function(e){var t=(1-e)*(1-e)*(1-e),n=e*e*e+t;return t/n},this.drawCTgraph(e)}}},function(e,t,n){"use strict";var r=n(121),i=n(0);e.exports=i("abc",r)},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},align:function(e,t){var n=t.p1.x,r=t.p1.y,i=-Math.atan2(t.p2.y-r,t.p2.x-n),a=Math.cos,o=Math.sin,s=function(e){return{x:(e.x-n)*a(i)-(e.y-r)*o(i),y:(e.x-n)*o(i)+(e.y-r)*a(i)}};return e.map(s)},draw:function(e,t){e.setPanelCount(2),e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n=t.points,r={p1:n[0],p2:n[n.length-1]},i=this.align(n,r),a=new e.Bezier(i),o=e.getPanelWidth(),s=e.getPanelHeight(),l={x:o,y:0};e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:s},l),l.x+=o/4,l.y+=s/2,e.setColor("grey"),e.drawLine({x:0,y:-s/2},{x:0,y:s/2},l),e.drawLine({x:-o/4,y:0},{x:o,y:0},l),e.setFill("grey"),e.setColor("black"),e.drawSkeleton(a,l),e.drawCurve(a,l)}}},function(e,t,n){"use strict";var r=n(123),i=n(0);e.exports=i("aligning",r)},function(e,t,n){"use strict";var r=Math.atan2,i=Math.PI,a=2*i,o=Math.cos,s=Math.sin;e.exports={statics:{keyHandlingOptions:{propName:"error",values:{38:.1,40:-.1},controller:function(e){e.error<.1&&(e.error=.1)}}},setupCircle:function(e){var t=new e.Bezier(70,70,140,40,240,130);e.setCurve(t)},setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.error=.5},getCCenter:function(e,t,n,l){var c,u=n.x-t.x,h=n.y-t.y,d=l.x-n.x,f=l.y-n.y,p=u*o(i/2)-h*s(i/2),m=u*s(i/2)+h*o(i/2),g=d*o(i/2)-f*s(i/2),v=d*s(i/2)+f*o(i/2),w=(t.x+n.x)/2,y=(t.y+n.y)/2,b=(n.x+l.x)/2,_=(n.y+l.y)/2,x=w+p,E=y+m,C=b+g,k=_+v,S=e.utils.lli8(w,y,x,E,b,_,C,k),P=e.utils.dist(S,t),T=r(t.y-S.y,t.x-S.x),M=r(n.y-S.y,n.x-S.x),N=r(l.y-S.y,l.x-S.x);return T<N?((T>M||M>N)&&(T+=a),T>N&&(c=N,N=T,T=c)):N<M&&M<T?(c=N,N=T,T=c):N+=a,S.s=T,S.e=N,S.r=P,S},drawCircle:function(e,t){e.reset();var n=t.points,r=this.getCCenter(e,n[0],n[1],n[2]);e.setColor("grey"),e.drawCircle(r,e.utils.dist(r,n[0])),e.setColor("black"),n.forEach(function(t){return e.drawCircle(t,3)});var i;e.setColor("blue"),e.drawLine(n[0],n[1]),i={x:(n[0].x+n[1].x)/2,y:(n[0].y+n[1].y)/2},e.drawLine(i,{x:r.x+(r.x-i.x),y:r.y+(r.y-i.y)}),e.setColor("red"),e.drawLine(n[1],n[2]),i={x:(n[1].x+n[2].x)/2,y:(n[1].y+n[2].y)/2},e.drawLine(i,{x:r.x+(r.x-i.x),y:r.y+(r.y-i.y)}),e.setColor("green"),e.drawLine(n[2],n[0]),i={x:(n[2].x+n[0].x)/2,y:(n[2].y+n[0].y)/2},e.drawLine(i,{x:r.x+(r.x-i.x),y:r.y+(r.y-i.y)}),e.setColor("black"),e.drawPoint(r),e.setFill("black"),e.text("Intersection point",r,{x:-25,y:10})},drawSingleArc:function(e,t){e.reset();var n=t.arcs(e.error);e.drawSkeleton(t),e.drawCurve(t);var r=n[0];e.setColor("red"),e.setFill("rgba(255,0,0,0.2)"),e.debug=!0,e.drawArc(r),e.setFill("black"),e.text("Arc approximation with total error "+e.utils.round(e.error,1),{x:10,y:15})},drawArcs:function(e,t){e.reset();var n=t.arcs(e.error);e.drawSkeleton(t),e.drawCurve(t),n.forEach(function(t){e.setRandomColor(.3),e.setFill(e.getColor()),e.drawArc(t)}),e.setFill("black"),e.text("Arc approximation with total error "+e.utils.round(e.error,1)+" per arc segment",{x:10,y:15})}}},function(e,t,n){"use strict";var r=n(125),i=n(0),a=n(13);e.exports=a(i("arcapproximation",r))},function(e,t,n){"use strict";var r=Math.sin,i=2*Math.PI;e.exports={setup:function(e){var t,n=e.getPanelWidth(),a=e.getPanelHeight();this.generator||(t=function(e,t){return t=t||1,{x:e*n/i,y:t*r(e)}},t.start=0,t.end=i,t.step=.1,t.scale=a/3,this.generator=t)},drawSine:function(e,t){var n=e.getPanelWidth(),r=e.getPanelHeight(),i=this.generator;i.dheight=t,e.setColor("black"),e.drawLine({x:0,y:r/2},{x:n,y:r/2}),e.drawFunction(i,{x:0,y:r/2})},drawSlices:function(e,t){var n=e.getPanelWidth(),r=e.getPanelHeight(),a=n/i,o=0,s=t<=25?1:0;e.reset(),e.setColor("transparent"),e.setFill("rgba(150,150,255, 0.4)");for(var l,c,u,h=i/t,d=h/2;d<i+h/2;d+=h)l=this.generator(d),c={x:l.x-a*h/2+s,y:0},u={x:l.x+a*h/2-s,y:l.y*this.generator.scale},s||e.setFill("rgba(150,150,255,"+(.4+.3*Math.random())+")"),e.drawRect(c,u,{x:0,y:r/2}),o+=h*Math.abs(l.y*this.generator.scale);e.setFill("black");var f=(400*r/3|0)/100,p=(100*o|0)/100;e.text("Approximating with "+t+" strips (true area: "+f+"): "+p,{x:10,y:r-15})},drawCoarseIntegral:function(e){e.reset(),this.drawSlices(e,10),this.drawSine(e)},drawFineIntegral:function(e){e.reset(),this.drawSlices(e,24),this.drawSine(e)},drawSuperFineIntegral:function(e){e.reset(),this.drawSlices(e,99),this.drawSine(e)},setupCurve:function(e){var t=e.getDefaultCubic();e.setCurve(t)},drawCurve:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n=t.length();e.setFill("black"),e.text("Curve length: "+n+" pixels",{x:10,y:15})}}},function(e,t,n){"use strict";var r=n(127),i=n(0);e.exports=i("arclength",r)},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"steps",values:{38:1,40:-1},controller:function(e){e.steps<1&&(e.steps=1)}}},setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t),e.steps=10},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.steps=16},draw:function(e,t){e.reset(),e.drawSkeleton(t);for(var n,r=t.getLUT(e.steps),i=1/e.steps,a=t.points[0],o=i;o<1+i;o+=i)n=t.get(Math.min(o,1)),e.setColor("red"),e.drawLine(a,n),a=n;for(var s,l,c,u=t.length(),h=0,d=0;d<r.length-1;d++)a=r[d],s=r[d+1],l=s.x-a.x,c=s.y-a.y,h+=Math.sqrt(l*l+c*c);h=(100*h|0)/100,u=(100*u|0)/100,e.text("Approximate length, "+e.steps+" steps: "+h+" (true: "+u+")",{x:10,y:15})}}},function(e,t,n){"use strict";var r=n(129),i=n(0),a=n(13);e.exports=a(i("arclengthapprox",r))},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},draw:function(e,t){e.reset(),e.setColor("#00FF00"),e.drawbbox(t.bbox()),e.setColor("black"),e.drawSkeleton(t),e.drawCurve(t),e.setColor("red"),t.extrema().values.forEach(function(n){e.drawCircle(t.get(n),3)})}}},function(e,t,n){"use strict";var r=n(131),i=n(0);e.exports=i("boundingbox",r)},function(e,t,n){"use strict";e.exports={degree:3,activeDistance:9,setup:function(){this.size(600,300),this.draw()},draw:function(){var e=this;this.clear(),this.grid(25);var t=this.points[0];this.points.forEach(function(n){e.stroke(200),e.line(n.x,n.y,t.x,t.y),t=n,e.stroke(0),e.circle(t.x,t.y,4)}),this.drawSplineData()},drawSplineData:function(){if(!(this.points.length<=this.degree)){var e=this.points.map(function(e){return[e.x,e.y]});this.drawCurve(e),this.drawKnots(e)}}}},function(e,t,n){"use strict";e.exports={degree:3,activeDistance:9,setup:function(){this.size(400,400);for(var e=2*Math.PI,t=0;t<e;t+=e/9)this.points.push({x:this.width/2+100*Math.cos(t),y:this.height/2+100*Math.sin(t)});this.knots=this.formKnots(this.points);var n=0|Math.round(this.points.length/2);this.knots[n+0]=this.knots[n],this.knots[n+1]=this.knots[n],this.knots[n+2]=this.knots[n];for(var r=n+3;r<this.knots.length;r++)this.knots[r]=this.knots[r-1]+1;this.props.controller&&this.props.controller(this,this.knots),this.draw()},draw:function(){var e=this;this.clear(),this.grid(25);var t=this.points[0];this.points.forEach(function(n){e.stroke(200),e.line(n.x,n.y,t.x,t.y),t=n,e.stroke(0),e.circle(t.x,t.y,4)}),this.drawSplineData()},drawSplineData:function(){if(!(this.points.length<=this.degree)){var e=this.points.map(function(e){return[e.x,e.y]});this.drawCurve(e),this.drawKnots(e)}}}},function(e,t,n){"use strict";e.exports={basicSketch:n(133),interpolationGraph:n(137),uniformBSpline:n(140),centerCutBSpline:n(134),openUniformBSpline:n(138),rationalUniformBSpline:n(139),bindKnots:function(e,t,n){this.refs[n].bindKnots(e,t)},bindWeights:function(e,t,n,r){this.refs[r].bindWeights(e,t,n)}}},function(e,t,n){"use strict";var r=n(135),i=n(0);e.exports=i("bsplines",r)},function(e,t,n){"use strict";var r=["#C00","#CC0","#0C0","#0CC","#00C","#C0C","#600","#660","#060","#066","#006","#606"];e.exports={degree:3,activeDistance:9,cache:{N:[]},setup:function(){this.size(600,300),this.points=[{x:0,y:0},{x:100,y:-100},{x:200,y:100},{x:300,y:-100},{x:400,y:100},{x:500,y:0}],this.knots=this.formKnots(this.points),this.props.controller&&this.props.controller(this,this.knots),this.draw()},draw:function(){this.clear();var e=25;this.grid(e),this.stroke(0),this.line(e,0,e,this.height);var t=this.height-e;this.line(0,t,this.width,t);for(var n=this.degree,r=this.points.length||4,i=0;i<r+1+n;i++)this.drawN(i,n,e,(this.width-e)/(2*(r+2)),this.height-2*e)},drawN:function(e,t,n,i,a){this.stroke(r[e]);this.knots;this.beginPath();for(var o=e-1,s=o,l=.1,c=e+t+1;s<c;s+=l){var u=n+e*i+s*i,h=this.height-n-this.N(e,t,s)*a;this.vertex(u,h)}this.endPath()},N:function(e,t,n){var r=this.knots[e],i=this.knots[e+1],a=this.knots[e+t-1],o=this.knots[e+t];if(1===t)return r<=n&&n<=i?1:0;var s=n-r,l=a-r,c=0===l?0:s/l,u=o-n,h=o-i,d=0===h?0:u/h,f=0;if(0!==c){var p=this.ensureN(e,t-1,n);f=void 0===p?this.N(e,t-1,n):p}var m=0;if(0!==d){var g=this.ensureN(e+1,t-1,n);m=void 0===g?this.N(e+1,t-1,n):g}return this.cacheN(e,t,n,c*f+d*m),this.cache.N[e][t][n]},ensureN:function(e,t,n){this.cache.N||(this.cache.N=[]);var r=this.cache.N;return r[e]||(r[e]=[]),r[e][t]||(r[e][t]=[]),r[e][t][n]},cacheN:function(e,t,n,r){this.ensureN(e,t,n),this.cache.N[e][t][n]=r}}},function(e,t,n){"use strict";e.exports={degree:3,activeDistance:9,setup:function(){this.size(400,400);for(var e=2*Math.PI,t=0;t<e;t+=e/10)this.points.push({x:this.width/2+100*Math.cos(t),y:this.height/2+100*Math.sin(t)});this.knots=this.formKnots(this.points,!0),this.props.controller&&this.props.controller(this,this.knots),this.draw()},draw:function(){var e=this;this.clear(),this.grid(25);var t=this.points[0];this.points.forEach(function(n){e.stroke(200),e.line(n.x,n.y,t.x,t.y),t=n,e.stroke(0),e.circle(t.x,t.y,4)}),this.drawSplineData()},drawSplineData:function(){if(!(this.points.length<=this.degree)){var e=this.points.map(function(e){return[e.x,e.y]});this.drawCurve(e),this.drawKnots(e)}}}},function(e,t,n){"use strict";e.exports={degree:3,activeDistance:9,weights:[],setup:function(){this.size(400,400);for(var e=2*Math.PI,t=this.width/3,n=0;n<6;n++)this.points.push({x:this.width/2+t*Math.cos(n/6*e),y:this.height/2+t*Math.sin(n/6*e)});this.points=this.points.concat(this.points.slice(0,3)),this.closed=this.degree,this.knots=this.formKnots(this.points),this.weights=this.formWeights(this.points),this.props.controller&&this.props.controller(this,this.knots,this.weights,this.closed),this.draw()},draw:function(){var e=this;this.clear(),this.grid(25);var t=this.points[0];this.points.forEach(function(n){e.stroke(200),e.line(n.x,n.y,t.x,t.y),t=n,e.stroke(0),e.circle(t.x,t.y,4)}),this.drawSplineData()},drawSplineData:function(){if(!(this.points.length<=this.degree)){var e=this.points.map(function(e){return[e.x,e.y]});this.drawCurve(e),this.drawKnots(e)}}}},function(e,t,n){"use strict";e.exports={degree:3,activeDistance:9,setup:function(){this.size(400,400);for(var e=2*Math.PI,t=0;t<e;t+=e/10)this.points.push({x:this.width/2+100*Math.cos(t),y:this.height/2+100*Math.sin(t)});this.knots=this.formKnots(this.points),this.props.controller&&this.props.controller(this,this.knots),this.draw()},draw:function(){var e=this;this.clear(),this.grid(25);var t=this.points[0];this.points.forEach(function(n){e.stroke(200),e.line(n.x,n.y,t.x,t.y),t=n,e.stroke(0),e.circle(t.x,t.y,4)}),this.drawSplineData()},drawSplineData:function(){if(!(this.points.length<=this.degree)){var e=this.points.map(function(e){return[e.x,e.y]});this.drawCurve(e),this.drawKnots(e)}}}},function(e,t,n){"use strict";e.exports={setup:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.reset(),e._map_loaded=!1},draw:function(e,t){var n=400,r=n,i=this.unit,a={x:n/2,y:r/2};e.setSize(n,r),e.setPanelCount(2),e.reset(),e.drawSkeleton(t),e.drawCurve(t),e.offset.x+=400,e._map_loaded?e.image(e._map_image):setTimeout(function(){this.drawBase(e,t),this.draw(e,t)}.bind(this),100),e.drawLine({x:0,y:0},{x:0,y:r});var o=[{x:0,y:0},{x:0,y:i},{x:i,y:i},this.forwardTransform(t.points,i)],s=new e.Bezier(o);e.setColor("blue"),e.drawCurve(s,a),e.drawCircle(o[3],3,a)},forwardTransform:function(e,t){t=t||1;var n=e[0],r=e[1],i=e[2],a=e[3],o=-n.x+a.x-(-n.x+r.x)*(-n.y+a.y)/(-n.y+r.y),s=-n.x+i.x-(-n.x+r.x)*(-n.y+i.y)/(-n.y+r.y),l=t*o/s,c=t*(-n.y+a.y)/(-n.y+r.y),u=t-t*(-n.y+i.y)/(-n.y+r.y),h=u*o/s,d=c+h;return{x:l,y:d}},drawBase:function(e,t){e.reset();var n=400,r=n,i=this.unit=n/5,a={x:n/2,y:r/2};e.setSize(n,r),e.setColor("lightgrey");for(var o=0;o<n;o+=i/2)e.drawLine({x:o,y:0},{x:o,y:r});for(var s=0;s<r;s+=i/2)e.drawLine({x:0,y:s},{x:n,y:s});e.setColor("black"),e.drawLine({x:n/2,y:0},{x:n/2,y:r}),e.drawLine({x:0,y:r/2},{x:n,y:r/2}),e.setColor("green"),e.drawLine({x:-n/2,y:i},{x:n/2,y:i},a),e.setColor("black"),e.setFill("black"),e.drawCircle({x:0,y:0},4,a),e.text("(0,0)",{x:5+a.x,y:15+a.y}),e.drawCircle({x:0,y:i},4,a),e.text("(0,1)",{x:5+a.x,y:i+15+a.y}),e.drawCircle({x:i,y:i},4,a),e.text("(1,1)",{x:i+5+a.x,y:i+15+a.y}),e.setWeight(1.5),e.setColor("#FF0000"),e.setFill(e.getColor());var l=[],c=1,u=1;for(o=-10;o<=1;o+=.01)s=(-o*o+2*o+3)/4,o>-10&&(l.push({x:i*c,y:i*u}),e.drawLine({x:i*c,y:i*u},{x:i*o,y:i*s},a)),c=o,u=s;l.push({x:i*c,y:i*u}),e.text("Curve form has cusp →",{x:n/2-2*i,y:r/2+i/2.5}),e.setColor("#FF00FF"),e.setFill(e.getColor());var h=Math.sqrt;for(o=1;o>=0;o-=.005)l.push({x:i*c,y:i*u}),s=.5*(h(3)*h(4*o-o*o)-o),e.drawLine({x:i*c,y:i*u},{x:i*o,y:i*s},a),c=o,u=s;for(l.push({x:i*c,y:i*u}),e.text("← Curve forms a loop at t = 1",{x:n/2+i/4,y:r/2+i/1.5}),e.setColor("#3300FF"),e.setFill(e.getColor()),o=0;o>-n;o-=.01)l.push({x:i*c,y:i*u}),s=(-o*o+3*o)/3,e.drawLine({x:i*c,y:i*u},{x:i*o,y:i*s},a),c=o,u=s;l.push({x:i*c,y:i*u}),e.text("← Curve forms a loop at t = 0",{x:n/2-i+10,y:r/2-1.25*i}),e.setColor("transparent"),e.setFill("rgba(255,120,100,0.2)"),e.drawPath(l,a),l=[{x:-n/2,y:i},{x:n/2,y:i},{x:n/2,y:r},{x:-n/2,y:r}],e.setFill("rgba(0,200,0,0.2)"),e.drawPath(l,a),e.setColor("black"),e.setFill(e.getColor()),e.text("← Curve form has one inflection →",{x:n/2-i,y:r/2+1.75*i}),e.text("← Plain curve ↕",{x:n/2+i/2,y:r/6}),e.text("↕ Double inflection",{x:10,y:r/2-10}),e._map_image=e.toImage(),e._map_loaded=!0}}},function(e,t,n){"use strict";var r=n(141),i=n(0);e.exports=i("canonical",r)},function(e,t,n){"use strict";var r=n(0);e.exports=r("catmullconv")},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"distance",values:{38:1,40:-1}}},setup:function(e){e.setPanelCount(3),e.lpts=[{x:56,y:153},{x:144,y:83},{x:188,y:185}],e.distance=0},convert:function(e,t,n,r){var i=.5;return[t,{x:t.x+(n.x-e.x)/(6*i),y:t.y+(n.y-e.y)/(6*i)},{x:n.x-(r.x-t.x)/(6*i),y:n.y-(r.y-t.y)/(6*i)},n]},draw:function(e){e.reset(),e.setColor("lightblue"),e.drawGrid(10,10);var t=e.lpts;e.setColor("black"),e.setFill("black"),t.forEach(function(t,n){e.drawCircle(t,3),e.text("point "+(n+1),t,{x:10,y:7})});var n=e.getPanelWidth(),r=e.getPanelHeight(),i={x:n,y:0};e.setColor("lightblue"),e.drawGrid(10,10,i),e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:r},i),t.forEach(function(t,n){e.drawCircle(t,3,i)});var a=t[0],o=t[1],s=t[2],l=s.x-a.x,c=s.y-a.y,u=Math.sqrt(l*l+c*c);l/=u,c/=u,e.drawLine(a,s,i);var h={x:a.x+(s.x-o.x)-e.distance*l,y:a.y+(s.y-o.y)-e.distance*c},d={x:a.x+(s.x-o.x)+e.distance*l,y:a.y+(s.y-o.y)+e.distance*c},f=e.utils.lli4(a,s,o,{x:(h.x+d.x)/2,y:(h.y+d.y)/2});e.setColor("blue"),e.drawCircle(f,3,i),e.drawLine(t[1],f,i),e.setColor("#666"),e.drawLine(f,h,i),e.drawLine(f,d,i),e.setFill("blue"),e.text("p0",h,{x:-20+i.x,y:i.y+2}),e.text("p4",d,{x:10+i.x,y:i.y+2}),e.setColor("red"),e.drawCircle(h,3,i),e.drawLine(o,h,i),e.drawLine(a,{x:a.x+(o.x-h.x)/5,y:a.y+(o.y-h.y)/5},i),e.setColor("#00FF00"),e.drawCircle(d,3,i),e.drawLine(o,d,i),e.drawLine(s,{x:s.x+(d.x-o.x)/5,y:s.y+(d.y-o.y)/5},i);var p=new e.Bezier(this.convert(h,a,o,s)),m=new e.Bezier(this.convert(a,o,s,d));e.setColor("lightgrey"),e.drawCurve(p,i),e.drawCurve(m,i),i.x+=n,e.setColor("lightblue"),e.drawGrid(10,10,i),e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:r},i),e.drawCurve(p,i),e.drawCurve(m,i),e.drawPoints(p.points,i),e.drawPoints(m.points,i),e.setColor("lightgrey"),e.drawLine(p.points[0],p.points[1],i),e.drawLine(p.points[2],m.points[1],i),e.drawLine(m.points[2],m.points[3],i)}}},function(e,t,n){"use strict";var r=n(144),i=n(0),a=n(13);e.exports=a(i("catmullmoulding",r))},function(e,t,n){"use strict";var r=Math.sin,i=Math.cos;e.exports={setup:function(e){e.w=e.getPanelWidth(),e.h=e.getPanelHeight(),e.pad=20,e.r=e.w/2-e.pad,e.mousePt=!1,e.angle=0;var t={x:e.w-e.pad,y:e.h/2};e.setCurve(new e.Bezier(t,t,t))},draw:function(e,t){e.reset(),e.setColor("lightgrey"),e.drawGrid(1,1),e.setColor("red"),e.drawCircle({x:e.w/2,y:e.h/2},e.r),e.setColor("transparent"),e.setFill("rgba(100,255,100,0.4)");var n={x:e.w/2,y:e.h/2,r:e.r,s:e.angle<0?e.angle:0,e:e.angle<0?0:e.angle};e.drawArc(n),e.setColor("black"),e.drawSkeleton(t),e.drawCurve(t)},onMouseMove:function(e,t){var n=e.offsetX-t.w/2,a=e.offsetY-t.h/2,o=Math.atan2(a,n),s=t.curve.points,l=t.r,c=(i(o)-1)/r(o);s[1]={x:t.w/2+l*(i(o)-c*r(o)),y:t.w/2+l*(r(o)+c*i(o))},s[2]={x:t.w/2+t.r*i(o),y:t.w/2+t.r*r(o)},t.setCurve(new t.Bezier(s)),t.angle=o}}},function(e,t,n){"use strict";var r=n(146),i=n(0);e.exports=i("circles",r)},function(e,t,n){"use strict";var r=Math.sin,i=Math.cos,a=Math.tan;e.exports={setup:function(e){e.setSize(400,400),e.w=e.getPanelWidth(),e.h=e.getPanelHeight(),e.pad=80,e.r=e.w/2-e.pad,e.mousePt=!1,e.angle=0;var t={x:e.w-e.pad,y:e.h/2};e.setCurve(new e.Bezier(t,t,t,t))},guessCurve:function(e,t,n){var r={x:(e.x+n.x)/2,y:(e.y+n.y)/2},i={x:t.x+(t.x-r.x)/3,y:t.y+(t.y-r.y)/3},a=(n.x-e.x)/4,o=(n.y-e.y)/4,s={x:t.x-a,y:t.y-o},l={x:t.x+a,y:t.y+o},c={x:i.x+2*(s.x-i.x),y:i.y+2*(s.y-i.y)},u={x:i.x+2*(l.x-i.x),y:i.y+2*(l.y-i.y)},h={x:e.x+2*(c.x-e.x),y:e.y+2*(c.y-e.y)},d={x:n.x+2*(u.x-n.x),y:n.y+2*(u.y-n.y)};return[h,d]},draw:function(e,t){e.reset(),e.setColor("lightgrey"),e.drawGrid(1,1),e.setColor("rgba(255,0,0,0.4)"),e.drawCircle({x:e.w/2,y:e.h/2},e.r),e.setColor("transparent"),e.setFill("rgba(100,255,100,0.4)");var n={x:e.w/2,y:e.h/2,r:e.r,s:e.angle<0?e.angle:0,e:e.angle<0?0:e.angle};e.drawArc(n);var a={x:e.w/2+e.r*i(e.angle/2),y:e.w/2+e.r*r(e.angle/2)},o=t.points[0],s=t.points[3],l=this.guessCurve(o,a,s),c=new e.Bezier([o,l[0],l[1],s]);e.setColor("rgb(140,140,255)"),e.drawLine(c.points[0],c.points[1]),e.drawLine(c.points[1],c.points[2]),e.drawLine(c.points[2],c.points[3]),e.setColor("blue"),e.drawCurve(c),e.drawCircle(c.points[1],3),e.drawCircle(c.points[2],3),e.drawSkeleton(t),e.setColor("black"),e.drawLine(t.points[1],t.points[2]),e.drawCurve(t)},onMouseMove:function(e,t){var n=e.offsetX-t.w/2,o=e.offsetY-t.h/2;if(!(n>t.w/2)){var s=Math.atan2(o,n);s<0&&(s=2*Math.PI+s); +var l=t.curve.points,c=t.r,u=4*a(s/4)/3;l[1]={x:t.w/2+c,y:t.w/2+c*u},l[2]={x:t.w/2+t.r*(i(s)+u*r(s)),y:t.w/2+t.r*(r(s)-u*i(s))},l[3]={x:t.w/2+t.r*i(s),y:t.w/2+t.r*r(s)},t.setCurve(new t.Bezier(l)),t.angle=s}},drawCircle:function(e){e.setSize(325,325),e.reset();var t=e.getPanelWidth(),n=e.getPanelHeight(),r=60,i=t/2-r,a=.55228,o={x:-r/2,y:-r/4},s=new e.Bezier([{x:t/2+i,y:n/2},{x:t/2+i,y:n/2+a*i},{x:t/2+a*i,y:n/2+i},{x:t/2,y:n/2+i}]);e.setColor("lightgrey"),e.drawLine({x:0,y:n/2},{x:t+r,y:n/2},o),e.drawLine({x:t/2,y:0},{x:t/2,y:n+r},o);var l=s.points;e.setColor("red"),e.drawPoint(l[0],o),e.drawPoint(l[1],o),e.drawPoint(l[2],o),e.drawPoint(l[3],o),e.drawCurve(s,o),e.setColor("rgb(255,160,160)"),e.drawLine(l[0],l[1],o),e.drawLine(l[1],l[2],o),e.drawLine(l[2],l[3],o),e.setFill("red"),e.text(l[0].x-t/2+","+(l[0].y-n/2),{x:l[0].x+7,y:l[0].y+3},o),e.text(l[1].x-t/2+","+(l[1].y-n/2),{x:l[1].x+7,y:l[1].y+3},o),e.text(l[2].x-t/2+","+(l[2].y-n/2),{x:l[2].x+7,y:l[2].y+7},o),e.text(l[3].x-t/2+","+(l[3].y-n/2),{x:l[3].x,y:l[3].y+13},o),l.forEach(function(e){e.x=-(e.x-t)}),e.setColor("blue"),e.drawCurve(s,o),e.drawLine(l[2],l[3],o),e.drawPoint(l[2],o),e.setFill("blue"),e.text("reflected",{x:l[2].x-r/2,y:l[2].y+13},o),e.setColor("rgb(200,200,255)"),e.drawLine(l[1],l[0],o),e.drawPoint(l[1],o),l.forEach(function(e){e.y=-(e.y-n)}),e.setColor("green"),e.drawCurve(s,o),l.forEach(function(e){e.x=-(e.x-t)}),e.setColor("purple"),e.drawCurve(s,o),e.drawLine(l[1],l[0],o),e.drawPoint(l[1],o),e.setFill("purple"),e.text("reflected",{x:l[1].x+10,y:l[1].y+3},o),e.setColor("rgb(200,200,255)"),e.drawLine(l[2],l[3],o),e.drawPoint(l[2],o),e.setColor("black"),e.setFill("black"),e.drawLine({x:t/2,y:n/2},{x:t/2+i-2,y:n/2},o),e.drawLine({x:t/2,y:n/2},{x:t/2,y:n/2+i-2},o),e.text("r = "+i,{x:t/2+i/3,y:n/2+10},o)}}},function(e,t,n){"use strict";var r=n(148),i=n(0);e.exports=i("circles_cubic",r)},function(e,t,n){"use strict";e.exports={componentDidMount:function(){if("undefined"!=typeof document){var e=document.createElement("script");e.src="lib/site/disqus.js",e.async=!0,document.head.appendChild(e)}}}},function(e,t,n){"use strict";var r=n(150),i=n(0);e.exports=i("comments",r)},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=e.getDefaultQuadratic();t.points[2].x=210,e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},draw:function(e,t){e.setPanelCount(3),e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n=t.order,r=20,i=t.points,a=e.getPanelWidth(),o=a-2*r,s=e.getPanelHeight(),l={x:a,y:0},c=JSON.parse(JSON.stringify(i)).map(function(e,t){return{x:o*t/n,y:e.x}});e.drawLine({x:0,y:0},{x:0,y:s},l),e.drawAxes(r,"t",0,1,"x",0,a,l),l.x+=r,e.drawCurve(new e.Bezier(c),l),l.x+=a-r;var u=JSON.parse(JSON.stringify(i)).map(function(e,t){return{x:o*t/n,y:e.y}});e.drawLine({x:0,y:0},{x:0,y:s},l),e.drawAxes(r,"t",0,1,"y",0,a,l),l.x+=r,e.drawCurve(new e.Bezier(u),l)}}},function(e,t,n){"use strict";var r=n(152),i=n(0);e.exports=i("components",r)},function(e,t,n){"use strict";e.exports={drawCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},drawCurve:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t)},drawFunction:function(e,t,n,r){e.setRandomColor(),e.drawFunction(r),e.setFill(e.getColor()),t&&e.text(t,n)},drawLerpBox:function(e,t,n,r){e.noColor(),e.setFill("rgba(0,0,100,0.2)");var i={x:r.x-5,y:n},a={x:r.x+5,y:t};e.drawRect(i,a),e.setColor("black")},drawLerpPoint:function(e,t,n,r,i){i.y=n+t*r,e.drawCircle(i,3),e.setFill("black"),e.text((1e4*t|0)/100+"%",{x:i.x+10,y:i.y+4}),e.noFill()},drawQuadraticLerp:function(e){e.reset();var t=e.getPanelWidth(),n=20,r=t-2*n;e.drawAxes(n,"t",0,1,"S","0%","100%");var i=e.hover;if(i&&i.x>=n&&i.x<=t-n){this.drawLerpBox(e,t,n,i);var a=(i.x-n)/r;this.drawLerpPoint(e,(1-a)*(1-a),n,r,i),this.drawLerpPoint(e,2*(1-a)*a,n,r,i),this.drawLerpPoint(e,a*a,n,r,i)}this.drawFunction(e,"first term",{x:2*n,y:r},function(e){return{x:n+e*r,y:n+r*(1-e)*(1-e)}}),this.drawFunction(e,"second term",{x:t/2-1.5*n,y:t/2+n},function(e){return{x:n+e*r,y:n+2*r*(1-e)*e}}),this.drawFunction(e,"third term",{x:r-2.5*n,y:r},function(e){return{x:n+e*r,y:n+r*e*e}})},drawCubicLerp:function(e){e.reset();var t=e.getPanelWidth(),n=20,r=t-2*n;e.drawAxes(n,"t",0,1,"S","0%","100%");var i=e.hover;if(i&&i.x>=n&&i.x<=t-n){this.drawLerpBox(e,t,n,i);var a=(i.x-n)/r;this.drawLerpPoint(e,(1-a)*(1-a)*(1-a),n,r,i),this.drawLerpPoint(e,3*(1-a)*(1-a)*a,n,r,i),this.drawLerpPoint(e,3*(1-a)*a*a,n,r,i),this.drawLerpPoint(e,a*a*a,n,r,i)}this.drawFunction(e,"first term",{x:2*n,y:r},function(e){return{x:n+e*r,y:n+r*(1-e)*(1-e)*(1-e)}}),this.drawFunction(e,"second term",{x:t/2-4*n,y:t/2},function(e){return{x:n+e*r,y:n+3*r*(1-e)*(1-e)*e}}),this.drawFunction(e,"third term",{x:t/2+2*n,y:t/2},function(e){return{x:n+e*r,y:n+3*r*(1-e)*e*e}}),this.drawFunction(e,"fourth term",{x:r-2.5*n,y:r},function(e){return{x:n+e*r,y:n+r*e*e*e}})},draw15thLerp:function(e){e.reset();var t=e.getPanelWidth(),n=20,r=t-2*n;e.drawAxes(n,"t",0,1,"S","0%","100%");var i,a=[1,15,105,455,1365,3003,5005,6435,6435,5005,3003,1365,455,105,15,1],o=e.hover;if(o&&o.x>=n&&o.x<=t-n)for(this.drawLerpBox(e,t,n,o),i=0;i<=15;i++){var s=(o.x-n)/r,l=a[i]*Math.pow(1-s,15-i)*Math.pow(s,i);this.drawLerpPoint(e,l,n,r,o)}for(i=0;i<=15;i++){var c=!1,u=!1;0===i&&(c="first term",u={x:n+5,y:r}),15===i&&(c="last term",u={x:t-3.5*n,y:r}),this.drawFunction(e,c,u,function(e){return{x:n+e*r,y:n+r*a[i]*Math.pow(1-e,15-i)*Math.pow(e,i)}})}}}},function(e,t,n){"use strict";var r=n(154),i=n(0);e.exports=i("control",r)},function(e,t,n){"use strict";var r=Math.abs;e.exports={setup:function(e){this.api=e,e.setPanelCount(3);var t=new e.Bezier(10,100,90,30,40,140,220,220),n=new e.Bezier(5,150,180,20,80,250,210,190);e.setCurve(t,n),this.pairReset()},pairReset:function(){this.prevstep=0,this.step=0},draw:function(e,t){var n=this;e.reset();var i={x:0,y:0};t.forEach(function(t){e.drawSkeleton(t),e.drawCurve(t)});var a=e.getPanelWidth(),o=e.getPanelHeight();if(i.x+=a,e.drawLine({x:0,y:0},{x:0,y:o},i),0===this.step&&(this.pairs=[{c1:t[0],c2:t[1]}]),this.step!==this.prevstep){var s=this.pairs;this.pairs=[],this.finals=[],s.forEach(function(t){if(t.c1.length()<.6&&t.c2.length()<.6)return n.finals.push(t);var r=t.c1.split(.5);e.setColor("black"),e.drawCurve(t.c1,i),e.setColor("red"),e.drawbbox(r.left.bbox(),i),e.drawbbox(r.right.bbox(),i);var a=t.c2.split(.5);e.setColor("black"),e.drawCurve(t.c2,i),e.setColor("blue"),e.drawbbox(a.left.bbox(),i),e.drawbbox(a.right.bbox(),i),r.left.overlaps(a.left)&&n.pairs.push({c1:r.left,c2:a.left}),r.left.overlaps(a.right)&&n.pairs.push({c1:r.left,c2:a.right}),r.right.overlaps(a.left)&&n.pairs.push({c1:r.right,c2:a.left}),r.right.overlaps(a.right)&&n.pairs.push({c1:r.right,c2:a.right})}),this.prevstep=this.step}else this.pairs.forEach(function(t){e.setColor("black"),e.drawCurve(t.c1,i),e.drawCurve(t.c2,i),e.setColor("red"),e.drawbbox(t.c1.bbox(),i),e.setColor("blue"),e.drawbbox(t.c2.bbox(),i)});0===this.pairs.length&&(this.pairReset(),this.draw(e,t)),i.x+=a,e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:o},i);var l,c,u=t[0].intersects(t[1]).map(function(e){var t=e.split("/").map(function(e){return parseFloat(e)});return{t1:t[0],t2:t[1]}}),h=u[0],d=function(e,t){return r(e.t1-t.t1)<.01&&r(e.t2-t.t2)<.01};for(c=1;c<u.length;c++)l=u[c],d(h,l)?u.splice(c--,1):h=l;e.setColor("lightblue"),e.drawCurve(t[0],i),e.drawCurve(t[1],i),e.setColor("blue"),u.forEach(function(n){e.drawCircle(t[0].get(n.t1),3,i)})},stepUp:function(){this.step++,this.api.redraw()}}},function(e,t,n){"use strict";var r=n(156),i=n(0);e.exports=i("curveintersection",r)},function(e,t,n){"use strict";e.exports={setup:function(e){var t=[{x:90,y:110},{x:25,y:40},{x:230,y:40},{x:150,y:240}];e.setCurve(new e.Bezier(t))},draw:function(e,t){if(e.reset(),e.drawSkeleton(t),e.drawCurve(t),e.hover){e.setColor("rgb(200,100,100)");for(var n=e.getPanelWidth(),r=e.hover.x/n,i=e.drawHull(t,r),a=4;a<=8;a++)e.drawCircle(i[a],3);var o=t.get(r);e.drawCircle(o,5),e.setFill("black"),e.drawCircle(o,3);var s=100*r|0;r=s/100,e.text("Sequential interpolation for "+s+"% (t="+r+")",{x:10,y:15})}}}},function(e,t,n){"use strict";var r=n(158),i=n(0);e.exports=i("decasteljau",r)},function(e,t,n){"use strict";var r=n(0);e.exports=r("derivatives")},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"step",values:{38:.1,40:-.1},controller:function(e){e.step<.1&&(e.step=.1)}}},setup:function(e){e.step=5},draw:function(e,t){var n=e.getPanelWidth(),r=n,i=n,a=r/2,o=i/2,s=a/2,l=o/2;e.reset(),e.setColor("black"),e.drawLine({x:0,y:o},{x:r,y:o}),e.drawLine({x:a,y:0},{x:a,y:i});for(var c,u={x:a,y:o},h=0;h<=e.step;h+=.1){c={x:s*Math.cos(h),y:l*Math.sin(h)},e.drawPoint(c,u);var d=h%1;(d<.05||d>.95)&&(e.text("t = "+Math.round(h),{x:u.x+1.25*s*Math.cos(h)-10,y:u.y+1.25*l*Math.sin(h)+5}),e.drawCircle(c,2,u))}}}},function(e,t,n){"use strict";var r=n(161),i=n(0),a=n(13);e.exports=a(i("explanation",r))},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=new e.Bezier(70,155,20,110,100,75);e.setCurve(t)},setupCubic:function(e){var t=new e.Bezier(60,105,75,30,215,115,140,160);e.setCurve(t)},draw:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t),e.setColor("lightgrey");var n,r,i=.05,a=-10,o=t.get(a-i);for(n=a;n<=i;n+=i)r=t.get(n),e.drawLine(o,r),o=r;o=t.get(1);var s=10;for(n=1+i;n<=s;n+=i)r=t.get(n),e.drawLine(o,r),o=r}}},function(e,t,n){"use strict";var r=n(163),i=n(0);e.exports=i("extended",r)},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=e.getDefaultQuadratic();t.points[2].x=210,e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},draw:function(e,t){e.setPanelCount(3),e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n=t.order+1,r=20,i=t.points,a=e.getPanelWidth(),o=e.getPanelHeight(),s={x:a,y:0},l=JSON.parse(JSON.stringify(i)).map(function(e,t){return{x:a*t/n,y:e.x}});e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:o},s),e.drawAxes(r,"t",0,1,"x",0,a,s),s.x+=r;var c=new e.Bezier(l);e.drawCurve(c,s),e.setColor("red"),c.extrema().y.forEach(function(t){var n=c.get(t);e.drawCircle(n,3,s)}),s.x+=a-r;var u=JSON.parse(JSON.stringify(i)).map(function(e,t){return{x:a*t/n,y:e.y}});e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:o},s),e.drawAxes(r,"t",0,1,"y",0,a,s),s.x+=r;var h=new e.Bezier(u);e.drawCurve(h,s),e.setColor("red"),h.extrema().y.forEach(function(t){var n=h.get(t);e.drawCircle(n,3,s)})}}},function(e,t,n){"use strict";var r=n(165),i=n(0);e.exports=i("extremities",r)},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"steps",values:{38:1,40:-1},controller:function(e){e.steps<1&&(e.steps=1)}}},setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t),e.steps=3},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.steps=5},drawFlattened:function(e,t){e.reset(),e.setColor("#DDD"),e.drawSkeleton(t),e.setColor("#DDD"),e.drawCurve(t);for(var n,r=1/e.steps,i=t.points[0],a=r;a<1+r;a+=r)n=t.get(Math.min(a,1)),e.setColor("red"),e.drawLine(i,n),i=n;e.setFill("black"),e.text("Curve approximation using "+e.steps+" segments",{x:10,y:15})},values:{38:1,40:-1},onKeyDown:function(e,t){var n=this.values[e.keyCode];n&&(e.preventDefault(),t.steps+=n,t.steps<1&&(t.steps=1))}}},function(e,t,n){"use strict";var r=n(167),i=n(0),a=n(13);e.exports=a(i("flattening",r))},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"distance",values:{38:1,40:-1}}},setup:function(e,t){e.setCurve(t),e.distance=20},setupQuadratic:function(e){var t=e.getDefaultQuadratic();this.setup(e,t)},setupCubic:function(e){var t=e.getDefaultCubic();this.setup(e,t)},draw:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t),e.setColor("blue");var n=t.outline(0,0,e.distance,e.distance);n.curves.forEach(function(t){return e.drawCurve(t)})}}},function(e,t,n){"use strict";var r=n(169),i=n(0),a=n(13);e.exports=a(i("graduatedoffset",r))},function(e,t,n){"use strict";e.exports={setupCubic:function(e){var t=new e.Bezier(135,25,25,135,215,75,215,240);e.setCurve(t)},draw:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t),e.setColor("red"),t.inflections().forEach(function(n){e.drawCircle(t.get(n),5)})}}},function(e,t,n){"use strict";var r=n(171),i=n(0);e.exports=i("inflections",r)},function(e,t,n){"use strict";var r=Math.min,i=Math.max;e.exports={setupLines:function(e){var t=new e.Bezier([50,50,150,110]),n=new e.Bezier([50,250,170,170]);e.setCurve(t,n)},drawLineIntersection:function(e,t){e.reset();var n=e.utils.lli4,a=n(t[0].points[0],t[0].points[1],t[1].points[0],t[1].points[1]),o=0;t.forEach(function(t){if(e.drawSkeleton(t),e.setColor("black"),a){var n=t.points,s=r(n[0].x,n[1].x),l=r(n[0].y,n[1].y),c=i(n[0].x,n[1].x),u=i(n[0].y,n[1].y);s<=a.x&&l<=a.y&&c>=a.x&&u>=a.y&&(e.setColor("#00FF00"),o++)}e.drawCurve(t)}),a&&(e.setColor(o<2?"red":"#00FF00"),e.drawCircle(a,3))},setupQuadratic:function(e){var t=e.getDefaultQuadratic(),n=new e.Bezier([15,250,220,20]);e.setCurve(t,n)},setupCubic:function(e){var t=new e.Bezier([100,240,30,60,210,230,160,30]),n=new e.Bezier([25,260,230,20]);e.setCurve(t,n)},draw:function(e,t){e.reset(),t.forEach(function(t){e.drawSkeleton(t),e.drawCurve(t)});var n=e.utils,r={p1:t[1].points[0],p2:t[1].points[1]},i=n.align(t[0].points,r),a=new e.Bezier(i),o=n.roots(a.points);o.forEach(function(n){var r=t[0].get(n);e.drawCircle(r,3),e.text("t = "+n,{x:r.x+5,y:r.y+10})})}}},function(e,t,n){"use strict";var r=n(173),i=n(0);e.exports=i("intersections",r)},function(e,t,n){"use strict";e.exports={drawQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},drawCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},drawCurve:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t)}}},function(e,t,n){"use strict";var r=n(175),i=n(0);e.exports=i("introduction",r)},function(e,t,n){"use strict";var r=n(0);e.exports=r("matrix")},function(e,t,n){"use strict";var r=n(0);e.exports=r("matrixsplit")},function(e,t,n){"use strict";var r=Math.abs;e.exports={setupQuadratic:function(e){e.setPanelCount(3);var t=e.getDefaultQuadratic();t.points[2].x-=30,e.setCurve(t)},setupCubic:function(e){e.setPanelCount(3);var t=new e.Bezier([100,230,30,160,200,50,210,160]);t.points[2].y-=20,e.setCurve(t),e.lut=t.getLUT(100)},saveCurve:function(e,t){t.t&&(t.setCurve(t.newcurve),t.t=!1,t.redraw())},findTValue:function(e,t){var n=t.curve.on({x:e.offsetX,y:e.offsetY},7);return!(n<.05||n>.95)&&n},markQB:function(e,t){if(t.t=this.findTValue(e,t),t.t){var n=t.t,i=2*n,a=i*n-i,o=a+1,s=r(a/o),l=t.curve,c=t.A=l.points[1],u=t.B=l.get(n);t.C=t.utils.lli4(c,u,l.points[0],l.points[2]),t.ratio=s}},markCB:function(e,t){if(t.t=this.findTValue(e,t),t.t){var n=t.t,i=1-n,a=n*n*n,o=i*i*i,s=a+o,l=s-1,c=r(l/s),u=t.curve,h=u.hull(n),d=t.A=h[5],f=t.B=u.get(n);t.db=u.derivative(n),t.C=t.utils.lli4(d,f,u.points[0],u.points[3]),t.ratio=c}},drag:function(e,t){if(t.t){var n=t.newB={x:e.offsetX,y:e.offsetY};t.newA={x:n.x-(t.C.x-n.x)/t.ratio,y:n.y-(t.C.y-n.y)/t.ratio}}},dragQB:function(e,t){t.t&&(this.drag(e,t),t.update=[t.newA])},dragCB:function(e,t){if(t.t){this.drag(e,t);var n=t.curve,r=n.hull(t.t),i=t.B,a=r[7],o=r[8],s={x:a.x-i.x,y:a.y-i.y},l={x:o.x-i.x,y:o.y-i.y},c=n.points,u={x:t.newB.x+s.x,y:t.newB.y+s.y},h={x:t.newA.x-(t.newA.x-u.x)/(1-t.t),y:t.newA.y-(t.newA.y-u.y)/(1-t.t)},d={x:t.newB.x+l.x,y:t.newB.y+l.y},f={x:t.newA.x+(d.x-t.newA.x)/t.t,y:t.newA.y+(d.y-t.newA.y)/t.t},p={x:c[0].x+(h.x-c[0].x)/t.t,y:c[0].y+(h.y-c[0].y)/t.t},m={x:c[3].x-(c[3].x-f.x)/(1-t.t),y:c[3].y-(c[3].y-f.y)/(1-t.t)};t.p1=u,t.p2=d,t.sc1=h,t.sc2=f,t.nc1=p,t.nc2=m,t.update=[p,m]}},drawMould:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n=e.getPanelWidth(),r=e.getPanelHeight(),i={x:n,y:0},a=e.utils.round;if(e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:r},i),e.drawLine({x:n,y:0},{x:n,y:r},i),e.t){e.drawCircle(t.get(e.t),3),e.npts=[t.points[0]].concat(e.update).concat([t.points.slice(-1)[0]]),e.newcurve=new e.Bezier(e.npts),e.setColor("lightgrey"),e.drawCurve(e.newcurve);var o=e.drawHull(e.newcurve,e.t,i);if(e.drawLine(e.npts[0],e.npts.slice(-1)[0],i),e.drawLine(e.newA,e.newB,i),e.setColor("grey"),e.drawCircle(e.newA,3,i),e.setColor("blue"),e.drawCircle(e.B,3,i),e.drawCircle(e.C,3,i),e.drawCircle(e.newB,3,i),e.drawLine(e.B,e.C,i),e.drawLine(e.newB,e.C,i),e.setFill("black"),e.text("A'",e.newA,{x:i.x+7,y:i.y+1}),e.text("start",t.get(0),{x:i.x+7,y:i.y+1}),e.text("end",t.get(1),{x:i.x+7,y:i.y+1}),e.setFill("blue"),e.text("B'",e.newB,{x:i.x+7,y:i.y+1}),e.text("B, at t = "+a(e.t,2),e.B,{x:i.x+7,y:i.y+1}),e.text("C",e.C,{x:i.x+7,y:i.y+1}),3===t.order){var s=t.hull(e.t);e.drawLine(s[7],s[8],i),e.drawLine(o[7],o[8],i),e.drawCircle(o[7],3,i),e.drawCircle(o[8],3,i),e.text("e1",o[7],{x:i.x+7,y:i.y+1}),e.text("e2",o[8],{x:i.x+7,y:i.y+1})}i.x+=n,e.setColor("lightgrey"),e.drawSkeleton(e.newcurve,i),e.setColor("black"),e.drawCurve(e.newcurve,i)}else i.x+=n,e.drawCurve(t,i)}}},function(e,t,n){"use strict";var r=n(179),i=n(0);e.exports=i("moulding",r)},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"distance",values:{38:1,40:-1}}},setup:function(e,t){e.setCurve(t),e.distance=20},setupQuadratic:function(e){var t=e.getDefaultQuadratic();this.setup(e,t)},setupCubic:function(e){var t=e.getDefaultCubic();this.setup(e,t)},draw:function(e,t){e.reset(),e.drawSkeleton(t);var n=t.reduce();n.forEach(function(t){e.setRandomColor(),e.drawCurve(t),e.drawCircle(t.points[0],1)});var r=n.slice(-1)[0];e.drawPoint(r.points[3]||r.points[2]),e.setColor("red");var i=t.offset(e.distance);i.forEach(function(t){e.drawPoint(t.points[0]),e.drawCurve(t)}),r=i.slice(-1)[0],e.drawPoint(r.points[3]||r.points[2]),e.setColor("blue"),i=t.offset(-e.distance),i.forEach(function(t){e.drawPoint(t.points[0]),e.drawCurve(t)}),r=i.slice(-1)[0],e.drawPoint(r.points[3]||r.points[2])}}},function(e,t,n){"use strict";var r=n(181),i=n(0),a=n(13);e.exports=a(i("offsetting",r))},function(e,t,n){"use strict";var r=Math.abs;e.exports={setup:function(e){e.lpts=[{x:56,y:153},{x:144,y:83},{x:188,y:185}]},onClick:function(e,t){3==t.lpts.length&&(t.lpts=[]),t.lpts.push({x:e.offsetX,y:e.offsetY}),t.redraw()},getQRatio:function(e){var t=2*e,n=t*e-t,i=n+1;return r(n/i)},getCRatio:function(e){var t=1-e,n=e*e*e,i=t*t*t,a=n+i,o=a-1;return r(o/a)},drawQuadratic:function(e,t){var n=["start","t=0.5","end"];if(e.reset(),e.setColor("lightblue"),e.drawGrid(10,10),e.setFill("black"),e.setColor("black"),e.lpts.forEach(function(t,r){e.drawCircle(t,3),e.text(n[r],t,{x:5,y:2})}),3===e.lpts.length){var r=e.lpts[0],i=e.lpts[2],a=e.lpts[1],o={x:(r.x+i.x)/2,y:(r.y+i.y)/2};e.setColor("blue"),e.drawLine(r,i),e.drawLine(a,o),e.drawCircle(o,3);var s=this.getQRatio(.5),l={x:a.x+(a.x-o.x)/s,y:a.y+(a.y-o.y)/s};t=new e.Bezier([r,l,i]),e.setColor("lightgrey"),e.drawLine(l,a),e.drawLine(l,r),e.drawLine(l,i),e.setColor("black"),e.drawCircle(l,1),e.drawCurve(t)}},drawCubic:function(e,t){var n=["start","t=0.5","end"];if(e.reset(),e.setFill("black"),e.setColor("black"),e.lpts.forEach(function(t,r){e.drawCircle(t,3),e.text(n[r],t,{x:5,y:2})}),e.setColor("lightblue"),e.drawGrid(10,10),3===e.lpts.length){var r=e.lpts[0],i=e.lpts[2],a=e.lpts[1],o={x:(r.x+i.x)/2,y:(r.y+i.y)/2};e.setColor("blue"),e.drawLine(r,i),e.drawLine(a,o),e.drawCircle(o,1);var s=this.getCRatio(.5),l={x:a.x+(a.x-o.x)/s,y:a.y+(a.y-o.y)/s},c=e.utils.dist(r,i),u=c/8,h=e.utils.dist(a,o),d=4,f=u+h/d,p=f*(i.x-r.x)/c,m=f*(i.y-r.y)/c,g={x:a.x-p,y:a.y-m},v={x:a.x+p,y:a.y+m},w={x:l.x+2*(g.x-l.x),y:l.y+2*(g.y-l.y)},y={x:l.x+2*(v.x-l.x),y:l.y+2*(v.y-l.y)},b={x:r.x+2*(w.x-r.x),y:r.y+2*(w.y-r.y)},_={x:i.x+2*(y.x-i.x),y:i.y+2*(y.y-i.y)};t=new e.Bezier([r,b,_,i]),e.drawLine(g,v),e.setColor("lightgrey"),e.drawLine(l,o),e.drawLine(l,w),e.drawLine(l,y),e.drawLine(r,b),e.drawLine(i,_),e.drawLine(b,_),e.setColor("black"),e.drawCircle(l,1),e.drawCircle(b,1),e.drawCircle(_,1),e.drawCurve(t)}}}},function(e,t,n){"use strict";var r=n(183),i=n(0);e.exports=i("pointcurves",r)},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},draw:function(e,t){e.reset(),e.drawSkeleton(t);var n,r,i,a,o,s,l=20;for(n=0;n<=10;n++)r=n/10,i=t.get(r),a=t.derivative(r),s=Math.sqrt(a.x*a.x+a.y*a.y),a={x:a.x/s,y:a.y/s},o=t.normal(r),e.setColor("blue"),e.drawLine(i,{x:i.x+a.x*l,y:i.y+a.y*l}),e.setColor("red"),e.drawLine(i,{x:i.x+o.x*l,y:i.y+o.y*l}),e.setColor("black"),e.drawCircle(i,3)}}},function(e,t,n){"use strict";var r=n(185),i=n(0);e.exports=i("pointvectors",r)},function(e,t,n){"use strict";var r=Math.atan2,i=Math.sqrt,a=Math.sin,o=Math.cos;e.exports={setupQuadratic:function(e){var t=e.getPanelWidth(),n=e.getPanelHeight(),r=t/2,i=n/2,a=40,o=[{x:r,y:a},{x:t-a,y:a},{x:t-a,y:i},{x:t-a,y:n-a},{x:r,y:n-a},{x:a,y:n-a},{x:a,y:i},{x:a,y:a}];e.lpts=o},setupCubic:function(e){var t=e.getPanelWidth(),n=e.getPanelHeight(),r=t/2,i=n/2,a=40,o=(t-2*a)/2,s=.55228,l=s*o,c=[{x:r,y:a},{x:r+l,y:a},{x:t-a,y:i-l},{x:t-a,y:i},{x:t-a,y:i+l},{x:r+l,y:n-a},{x:r,y:n-a},{x:r-l,y:n-a},{x:a,y:i+l},{x:a,y:i},{x:a,y:i-l},{x:r-l,y:a}];e.lpts=c},movePointsQuadraticLD:function(e,t){for(var n,r,i,a=1;a<4;a++)n=t+(2*a-2)+e.lpts.length,n=e.lpts[n%e.lpts.length],r=t+(2*a-1),r=e.lpts[r%e.lpts.length],i=t+2*a,i=e.lpts[i%e.lpts.length],i.x=r.x+(r.x-n.x),i.y=r.y+(r.y-n.y);i=t+6,i=e.lpts[i%e.lpts.length],e.problem=i},movePointsCubicLD:function(e,t){var n,r;t%3===1?(r=t-1,r+=r<0?e.lpts.length:0,n=t-2,n+=n<0?e.lpts.length:0):(r=(t+1)%e.lpts.length,n=(t+2)%e.lpts.length),r=e.lpts[r],n=e.lpts[n],n.x=r.x+(r.x-e.mp.x),n.y=r.y+(r.y-e.mp.y)},linkDerivatives:function(e,t){if(t.mp){var n=8===t.lpts.length,r=t.mp_idx;n?r%2!==0&&this.movePointsQuadraticLD(t,r):r%3!==0&&this.movePointsCubicLD(t,r)}},movePointsQuadraticDirOnly:function(e,t){var n,s,l;[-1,1].forEach(function(c){n=e.mp,s=t+c+e.lpts.length,s=e.lpts[s%e.lpts.length],l=t+2*c+e.lpts.length,l=e.lpts[l%e.lpts.length];var u=r(s.y-n.y,s.x-n.x),h=l.x-s.x,d=l.y-s.y,f=i(h*h+d*d);l.x=s.x+f*o(u),l.y=s.y+f*a(u)}),l=t+4,l=e.lpts[l%e.lpts.length],e.problem=l},movePointsCubicDirOnly:function(e,t){var n,s;t%3===1?(s=t-1,s+=s<0?e.lpts.length:0,n=t-2,n+=n<0?e.lpts.length:0):(s=(t+1)%e.lpts.length,n=(t+2)%e.lpts.length),s=e.lpts[s],n=e.lpts[n];var l=r(s.y-e.mp.y,s.x-e.mp.x),c=n.x-s.x,u=n.y-s.y,h=i(c*c+u*u);n.x=s.x+h*o(l),n.y=s.y+h*a(l)},linkDirection:function(e,t){if(t.mp){var n=8===t.lpts.length,r=t.mp_idx;n?r%2!==0&&this.movePointsQuadraticDirOnly(t,r):r%3!==0&&this.movePointsCubicDirOnly(t,r)}},bufferPoints:function(e,t){t.bpts=JSON.parse(JSON.stringify(t.lpts))},moveQuadraticPoint:function(e,t){this.moveCubicPoint(e,t),[-1,1].forEach(function(n){var s=t-n+e.lpts.length;s=e.lpts[s%e.lpts.length];var l=t-2*n+e.lpts.length;l=e.lpts[l%e.lpts.length];var c=t-3*n+e.lpts.length;c=e.lpts[c%e.lpts.length];var u=r(l.y-s.y,l.x-s.x),h=c.x-l.x,d=c.y-l.y,f=i(h*h+d*d);c.x=l.x+f*o(u),c.y=l.y+f*a(u)});var n=t+4;n=e.lpts[n%e.lpts.length],e.problem=n},moveCubicPoint:function(e,t){var n=e.bpts[t],r=e.lpts[t],i=r.x-n.x,a=r.y-n.y,o=e.lpts.length,s=t-1+o,l=t+1,c=e.bpts[s%o],u=e.bpts[l%o],h=e.lpts[s%o],d=e.lpts[l%o];return h.x=c.x+i,h.y=c.y+a,d.x=u.x+i,d.y=u.y+a,{x:i,y:a}},modelCurve:function(e,t){if(t.mp){var n=8===t.lpts.length,r=t.mp_idx;n?r%2!==0?this.movePointsQuadraticDirOnly(t,r):this.moveQuadraticPoint(t,r):r%3!==0?this.movePointsCubicDirOnly(t,r):this.moveCubicPoint(t,r)}},draw:function(e,t){e.reset();var n=e.lpts,r=8===n.length,i=r?new e.Bezier(n[0],n[1],n[2]):new e.Bezier(n[0],n[1],n[2],n[3]);e.drawSkeleton(i,!1,!0),e.drawCurve(i);var a=r?new e.Bezier(n[2],n[3],n[4]):new e.Bezier(n[3],n[4],n[5],n[6]);e.drawSkeleton(a,!1,!0),e.drawCurve(a);var o=r?new e.Bezier(n[4],n[5],n[6]):new e.Bezier(n[6],n[7],n[8],n[9]);e.drawSkeleton(o,!1,!0),e.drawCurve(o);var s=r?new e.Bezier(n[6],n[7],n[0]):new e.Bezier(n[9],n[10],n[11],n[0]);e.drawSkeleton(s,!1,!0),e.drawCurve(s),e.problem&&(e.setColor("red"),e.drawCircle(e.problem,5))}}},function(e,t,n){"use strict";var r=n(187),i=n(0);e.exports=i("polybezier",r)},function(e,t,n){"use strict";var r=n(0);e.exports=r("preface")},function(e,t,n){"use strict";e.exports={setup:function(e){e.setSize(320,320);var t=new e.Bezier([{x:248,y:188},{x:218,y:294},{x:45,y:290},{x:12,y:236},{x:14,y:82},{x:186,y:177},{x:221,y:90},{x:18,y:156},{x:34,y:57},{x:198,y:18}]);e.setCurve(t),e._lut=t.getLUT()},findClosest:function(e,t,n){var r,i,a=e.length,o=n(e[0],t),s=0;for(r=1;r<a;r++)i=n(e[r],t),i<o&&(s=r,o=i);return s/(a-1)},draw:function(e,t){if(e.reset(),e.drawSkeleton(t),e.drawCurve(t),e.mousePt){e.setColor("red"),e.setFill("red"),e.drawCircle(e.mousePt,3);var n=this.findClosest(e._lut,e.mousePt,e.utils.dist),r=t.get(n);e.drawLine(r,e.mousePt),e.drawCircle(r,3),e.text("t = "+e.utils.round(n,2),r,{x:10,y:3})}},onMouseMove:function(e,t){t.mousePt={x:e.offsetX,y:e.offsetY},t._lut=t.curve.getLUT()}}},function(e,t,n){"use strict";var r=n(190),i=n(0);e.exports=i("projections",r)},function(e,t,n){"use strict";var r={statics:{lower:function(e){var t=e.points,n=[],r=t.length;return t.forEach(function(e,i){if(!i)return n[i]=e;var a=i/r,o=1-a;n[i]={x:a*e.x+o*t[i-1].x,y:a*e.y+o*t[i-1].y}}),n.splice(r-1,1),n[r-2]=t[r-1],e.points=n,e},keyHandlingOptions:{values:{38:function(e){e.setCurve(e.curve.raise())},40:function(e){e.setCurve(r.lower(e.curve))}}}},getInitialState:function(){return{order:0}},setup:function(e){for(var t=[],n=e.getPanelWidth(),r=e.getPanelHeight(),i=0;i<10;i++)t.push({x:n/2+20*Math.random()+Math.cos(2*Math.PI*i/10)*(n/2-40),y:r/2+20*Math.random()+Math.sin(2*Math.PI*i/10)*(r/2-40)});var a=new e.Bezier(t);e.setCurve(a)},draw:function(e,t){e.reset();var n=t.points;this.setState({order:n.length});for(var r=n[0],i=0;i<=1;i+=.01){for(var a=JSON.parse(JSON.stringify(n));a.length>1;){for(var o=0;o<a.length-1;o++)a[o]={x:a[o].x+(a[o+1].x-a[o].x)*i,y:a[o].y+(a[o+1].y-a[o].y)*i};a.splice(a.length-1,1)}e.drawLine(r,a[0]),r=a[0]}r=n[0],e.setColor("black"),e.drawCircle(r,3),n.forEach(function(t){t!==r&&(e.setColor("#DDD"),e.drawLine(r,t),e.setColor("black"),e.drawCircle(t,3),r=t)})},getOrder:function(){var e=this.state.order;return e+=e%10===1&&11!==e?"st":e%10===2&&12!==e?"nd":e%10===3&&13!==e?"rd":"th"}};e.exports=r},function(e,t,n){"use strict";var r=n(192),i=n(0),a=n(13);e.exports=a(i("reordering",r))},function(e,t,n){"use strict";var r;e.exports={getInitialState:function(){return r=this.modes=["unite","intersect","exclude","subtract"],{mode:r[0]}},setMode:function(e){this.setState({mode:e})},formPath:function(e,t,n,r,i){t=t||0,n=n||0;var a=30,o=a/2;r=r||8*a,i=i||4*a;var s=r/2,l=i/2,c=s/3,u=l/3,h=e.Paper,d=h.Path,f=h.Point,p=new d;return p.moveTo(new f(t-s+2*a,n-l)),p.cubicCurveTo(new f(t-s+o,n-l+o),new f(t-s+o,n+l-o),new f(t-s+2*a,n+l)),p.cubicCurveTo(new f(t-c,n+u),new f(t+c,n+u),new f(t+s-2*a,n+l)),p.cubicCurveTo(new f(t+s-o,n+l-o),new f(t+s-o,n-l+o),new f(t+s-2*a,n-l)),p.cubicCurveTo(new f(t+c,n-u),new f(t-c,n-u),new f(t-s+2*a,n-l)),p.closePath(!0),p.strokeColor="rgb(100,100,255)",p},setup:function(e){var t=e.getPanelWidth(),n=40,i=t/2,a=t/2;e.c1=this.formPath(e,i,a),i+=n,a+=n,e.c2=this.formPath(e,i,a),this.state.mode=r[0]},onMouseMove:function(e,t){var n=e.offsetX,r=e.offsetY;t.c2.position={x:n,y:r}},draw:function(e){e.c3&&e.c3.remove();var t=e.c1,n=e.c2,r=t[this.state.mode].bind(t),i=e.c3=r(n);i.strokeColor="red",i.fillColor="rgba(255,100,100,0.4)",e.Paper.view.draw()}}},function(e,t,n){"use strict";var r=n(194),i=n(0);e.exports=i("shapes",r)},function(e,t,n){"use strict";e.exports={setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.forward=!0},drawSplit:function(e,t){e.setPanelCount(2),e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n={x:0,y:0},r=.5,i=t.get(.5),a=t.split(r);e.drawCurve(a.left),e.drawCurve(a.right),e.setColor("red"),e.drawCircle(i,3),e.setColor("black"),n.x=e.getPanelWidth(),e.drawLine({x:0,y:0},{x:0,y:e.getPanelHeight()},n),e.setColor("lightgrey"),e.drawCurve(t,n),e.drawCircle(i,4),n.x-=20,n.y-=20,e.drawSkeleton(a.left,n,!0),e.drawCurve(a.left,n),n.x+=40,n.y+=40,e.drawSkeleton(a.right,n,!0),e.drawCurve(a.right,n)},drawAnimated:function(e,t){e.setPanelCount(3),e.reset();var n=e.getFrame(),r=5*e.getPlayInterval(),i=n%r/r,a=n%(2*r)<r;a?i%=1:i=1-i%1;var o={x:0,y:0};e.setColor("lightblue"),e.drawHull(t,i),e.drawSkeleton(t),e.drawCurve(t);var s=t.get(i);e.drawCircle(s,4),e.setColor("black"),o.x+=e.getPanelWidth(),e.drawLine({x:0,y:0},{x:0,y:e.getPanelHeight()},o);var l=t.split(i);e.setColor("lightgrey"),e.drawCurve(t,o),e.drawHull(t,i,o),e.setColor("black"),e.drawCurve(l.left,o),e.drawPoints(l.left.points,o),e.setFill("black"),e.text("Left side of curve split at t = "+(100*i|0)/100,{x:10+o.x,y:15+o.y}),o.x+=e.getPanelWidth(),e.drawLine({x:0,y:0},{x:0,y:e.getPanelHeight()},o),e.setColor("lightgrey"),e.drawCurve(t,o),e.drawHull(t,i,o),e.setColor("black"),e.drawCurve(l.right,o),e.drawPoints(l.right.points,o),e.setFill("black"),e.text("Right side of curve split at t = "+(100*i|0)/100,{x:10+o.x,y:15+o.y})},togglePlay:function(e,t){t.playing?t.pause():t.play()}}},function(e,t,n){"use strict";var r=n(196),i=n(0);e.exports=i("splitting",r)},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},align:function(e,t){var n=t.p1.x,r=t.p1.y,i=-Math.atan2(t.p2.y-r,t.p2.x-n),a=Math.cos,o=Math.sin,s=function(e){return{x:(e.x-n)*a(i)-(e.y-r)*o(i),y:(e.x-n)*o(i)+(e.y-r)*a(i),a:i}};return e.map(s)},transpose:function(e,t,n){var r=n.x,i=n.y,a=Math.cos,o=Math.sin,s=[e.x.min,e.y.min,e.x.max,e.y.max];return[{x:s[0],y:s[1]},{x:s[2],y:s[1]},{x:s[2],y:s[3]},{x:s[0],y:s[3]}].map(function(e){var n=e.x,s=e.y;return{x:n*a(t)-s*o(t)+r,y:n*o(t)+s*a(t)+i}})},draw:function(e,t){e.reset();var n=t.points,r={p1:n[0],p2:n[n.length-1]},i=this.align(n,r),a=-i[0].a,o=new e.Bezier(i),s=o.bbox(),l=this.transpose(s,a,n[0]);e.setColor("#00FF00"),e.drawLine(l[0],l[1]),e.drawLine(l[1],l[2]),e.drawLine(l[2],l[3]),e.drawLine(l[3],l[0]),e.setColor("black"),e.drawSkeleton(t),e.drawCurve(t)}}},function(e,t,n){"use strict";var r=n(198),i=n(0);e.exports=i("tightbounds",r)},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"steps",values:{38:1,40:-1},controller:function(e){e.steps<1&&(e.steps=1)}}},setup:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.steps=8},generate:function(e,t,n,r,i){n.x+=r,n.y+=r;for(var a,o,s=t.length(),l=[{x:0,y:0,d:0}],c=1;c<=100;c++)a=c/100,o=t.split(a).left.length(),l.push({x:e.utils.map(a,0,1,0,i),y:e.utils.map(o,0,s,0,i),d:o,t:a});return l},draw:function(e,t,n){e.reset(),e.drawSkeleton(t),e.drawCurve(t);var r=t.length(),i=e.getPanelWidth(),a=e.getPanelHeight(),o=20,s=i-2*o;return n.x+=i,e.drawLine({x:0,y:0},{x:0,y:a},n),e.drawAxes(o,"t",0,1,"d",0,r,n),this.generate(e,t,n,o,s)},plotOnly:function(e,t){e.setPanelCount(2);for(var n={x:0,y:0},r=this.draw(e,t,n),i=0;i<r.length-1;i++)e.drawLine(r[i],r[i+1],n)},drawColoured:function(e,t){e.setPanelCount(3);var n,r,i=e.getPanelWidth(),a=e.getPanelHeight(),o=20,s=i-2*o,l={x:0,y:0},c=t.length(),u=this.draw(e,t,l),h=e.steps,d=[];for(n=0;n<=h;n++){var f=n*c/h;for(r=0;r<u.length;r++)if(u[r].d>f){r--;break}r<0&&(r=0),r===u.length&&(r=u.length-1),d.push(u[r])}for(n=0;n<u.length-1;n++)e.drawLine(u[n],u[n+1],l);d.forEach(function(t){var n={x:e.utils.map(t.t,0,1,0,s),y:0},r={x:0,y:e.utils.map(t.d,0,c,0,s)};e.setColor("black"),e.drawCircle(n,3,l),e.drawCircle(r,3,l),e.setColor("lightgrey"),e.drawLine(n,{x:n.x,y:r.y},l),e.drawLine(r,{x:n.x,y:r.y},l)}),l={x:2*i,y:0},e.drawLine({x:0,y:0},{x:0,y:a},l);var p=0,m=["rgb(240,0,200)","rgb(0,40,200)"];e.setColor(m[p]);var g,v=t.get(u[0].t);for(e.drawCircle(t.get(0),4,l),n=1,g;n<u.length;n++)g=t.get(u[n].t),e.drawLine(v,g,l),d.indexOf(u[n])!==-1&&(e.setColor(m[++p%m.length]),e.drawCircle(g,4,l)),v=g}}},function(e,t,n){"use strict";var r=n(200),i=n(0),a=n(13);e.exports=a(i("tracing",r))},function(e,t,n){"use strict";e.exports={setup:function(e){e.setPanelCount(3);var t=e.getDefaultQuadratic(); +e.setCurve(t),e.step=25},draw:function(e,t){var n,r,i,a,o,s,l,c,u=e.getPanelWidth(),h=t.points,d=h[0],f=h[1],p=h[2],m={x:0,y:0};for(e.reset(),e.setColor("black"),e.setFill("black"),e.drawSkeleton(t,m),e.text("First linear interpolation at "+e.step+"% steps",{x:5,y:15},m),m.x+=u,e.drawLine({x:0,y:0},{x:0,y:this.dim},m),e.drawSkeleton(t,m),e.text("Second interpolation at "+e.step+"% steps",{x:5,y:15},m),m.x+=u,e.drawLine({x:0,y:0},{x:0,y:this.dim},m),e.drawSkeleton(t,m),e.text("Curve points generated this way",{x:5,y:15},m),e.setColor("lightgrey"),a=1,s=20,c;a<s;a++)l=a/s,c=t.get(l),e.drawCircle(c,2,m);for(o=3*e.step;o>0;o-=e.step)a=o/100,a>1||(e.setRandomColor(),n={x:d.x+a*(f.x-d.x),y:d.y+a*(f.y-d.y)},r={x:f.x+a*(p.x-f.x),y:f.y+a*(p.y-f.y)},i={x:n.x+a*(r.x-n.x),y:n.y+a*(r.y-n.y)},m={x:0,y:0},e.drawCircle(n,3,m),e.drawCircle(r,3,m),e.setWeight(.5),e.drawLine(n,r,m),e.setWeight(1.5),e.drawLine(d,n,m),e.drawLine(f,r,m),e.setWeight(1),m.x+=u,e.drawCircle(n,3,m),e.drawCircle(r,3,m),e.setWeight(.5),e.drawLine(n,r,m),e.setWeight(1.5),e.drawLine(n,i,m),e.setWeight(1),e.drawCircle(i,3,m),m.x+=u,e.drawCircle(i,3,m),e.text(o+"%, or t = "+e.utils.round(a,2),{x:i.x+10+m.x,y:i.y+10+m.y}))},values:{38:1,40:-1},onKeyDown:function(e,t){var n=this.values[e.keyCode];n&&(e.preventDefault(),t.step+=n,t.step<1&&(t.step=1))}}},function(e,t,n){"use strict";var r=n(202),i=n(0);e.exports=i("whatis",r)},function(e,t,n){"use strict";var r=n(4),i=n(110),a=n(64),o=n(107),s=n(112),l=n(117);a.locale="en-GB",e.exports={locale:"en-GB",preface:{locale:"en-GB",title:"Preface",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"preface",title:"Preface"}),r.createElement("p",null,"In order to draw things in 2D, we usually rely on lines, which typically get classified into two categories: straight lines, and curves. The first of these are as easy to draw as they are easy to make a computer draw. Give a computer the first and last point in the line, and BAM! straight line. No questions asked."),r.createElement("p",null,"Curves, however, are a much bigger problem. While we can draw curves with ridiculous ease freehand, computers are a bit handicapped in that they can't draw curves unless there is a mathematical function that describes how it should be drawn. In fact, they even need this for straight lines, but the function is ridiculously easy, so we tend to ignore that as far as computers are concerned, all lines are \"functions\", regardless of whether they're straight or curves. However, that does mean that we need to come up with fast-to-compute functions that lead to nice looking curves on a computer. There's a number of these, and in this article we'll focus on a particular function that has received quite a bit of attention, and is used in pretty much anything that can draw curves: \"Bézier\" curves"),r.createElement("p",null,"They're named after ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Pierre_B%C3%A9zier"},"Pierre Bézier"),', who is principally responsible for getting them known to the world as a curve well-suited for design work (working for Renault and publishing his investigations in 1962), although he was not the first, or only one, to "invent" these type of curves. One might be tempted to say that the mathematician ',r.createElement("a",{href:"https://en.wikipedia.org/wiki/Paul_de_Casteljau"},"Paul de Casteljau"),' was first, investigating the nature of these curves in 1959 while working at Citroën, coming up with a really elegant way of figuring out how to draw them. However, de Casteljau did not publish his work, making the question "who was first" hard to answer in any absolute sense. Or is it? Bézier curves are, at their core, "Bernstein polynomials", a family of mathematical functions investigated by ',r.createElement("a",{href:"https://en.wikipedia.org/wiki/Sergei_Natanovich_Bernstein"},"Sergei Natanovich Bernstein"),", with publications on them at least as far back as 1912. Anyway, that's mostly trivia, what you are more likely to care about is that these curves are handy: you can link up multiple Bézier curves so that the combination looks like a single curve. If you've ever drawn Photoshop \"paths\" or worked with vector drawing programs like Flash, Illustrator or nkscape, those curves you've been drawing are Bézier curves."),r.createElement("p",null,"So, what if you need to program them yourself? What are the pitfalls? How do you draw them? What are the bounding boxes, how do you determine intersections, how can you extrude a curve, in short: how do you do everything that you might want when you do with these curves? That's what this page is for. Prepare to be mathed!"),r.createElement("p",null,"—Pomax (or in the tweetworld, ",r.createElement("a",{href:"https://twitter.com/TheRealPomax"},"@TheRealPomax"),")"),r.createElement("div",{className:"note"},r.createElement("h2",{id:"note-virtually-all-b-zier-graphics-are-interactive-"},"Note: virtually all Bézier graphics are interactive."),r.createElement("p",null,"This page uses interactive examples, relying heavily on ",r.createElement("a",{href:"http://pomax.github.io/bezierjs"},"Bezier.js"),', as well as "real" maths (in LaTeX form) which is typeset using the most excellent ',r.createElement("a",{href:"http://MathJax.org"},"MathJax")," library. The page is generated offline as a React application, using Webpack, which has made adding \"view source\" options considerably more challenging. I'm still trying to figure out how to add them back in, but it didn't feel like it should hold up deploying this update compared to the previous years' version."),r.createElement("h2",{id:"this-book-is-open-source-"},"This book is open source."),r.createElement("p",null,"This book is an open source software project, and lives on two github repositorites. The first is ",r.createElement("a",{href:"https://github.com/pomax/bezierinfo"},"https://github.com/pomax/bezierinfo")," and is the purely-for-presentation version you are viewing right now. The other repository is ",r.createElement("a",{href:"https://github.com/pomax/BezierInfo-2"},"https://github.com/pomax/BezierInfo-2"),", which is the development version, housing all the html, javascript, and css. You can fork either of these, and pretty much do with them as you please, except for passing it off as your own work wholesale, of course =)"),r.createElement("h2",{id:"how-complicated-is-the-maths-going-to-be-"},"How complicated is the maths going to be?"),r.createElement("p",null,"Most of the mathematics in this Primer are early high school maths. If you understand basic arithmetic, and you know how to read English, you should be able to get by just fine. There will at times be ",r.createElement("em",null,"far"),' more complicated maths, but if you don\'t feel like digesting them, you can safely skip over them by either skipping over the "detail boxes" in section or by just jumping to the end of a section with maths that looks too involving. The end of sections typically simply list the conclusions so you can just work with those values directly.'),r.createElement("h2",{id:"questions-comments-"},"Questions, comments:"),r.createElement("p",null,"If you have suggestions for new sections, hit up the ",r.createElement("a",{href:"https://github.com/pomax/BezierInfo-2/issues"},"Github issue tracker")," (also reachable from the repo linked to in the upper right). If you have questions about the material, there's currently no comment section while I'm doing the rewrite, but you can use the issue tracker for that as well. Once the rewrite is done, I'll add a general comment section back in, and maybe a more topical \"select this section of text and hit the 'question' button to ask a question about it\" system. We'll see."),r.createElement("h2",{id:"buy-me-a-coffee-"},"Buy me a coffee?"),r.createElement("p",null,"If you enjoyed this book, or you simply found it useful for something you were trying to get done, and you were wondering how to let me know you appreciated this book, you can always ",r.createElement("a",{href:"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QPRDLNGDANJSW"},"buy me a coffee"),", however-much a coffee is where you live. This work has grown over the years, from a small primer to a 70ish print-page-equivalent reader on the subject of Bézier curves, and a lot of coffee went into the making of it. I don't regret a minute I spent on writing it, but I can always do with some more coffee to keep on writing!")))}},introduction:{locale:"en-GB",title:"A lightning introduction",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"introduction",title:"A lightning introduction",number:"1"}),r.createElement("p",null,"Let's start with the good stuff: when we're talking about Bézier curves, we're talking about the things that you can see in the following graphics. They run from some start point to some end point, with their curvature influenced by one or more \"intermediate\" control points. Now, because all the graphics on this page are interactive, go manipulate those curves a bit: click-drag the points, and see how their shape changes based on what you do."),r.createElement("div",{className:"figure"},r.createElement(i,{inline:!0,title:"Quadratic Bézier curves",setup:e.drawQuadratic,draw:e.drawCurve}),r.createElement(i,{inline:!0,title:"Cubic Bézier curves",setup:e.drawCubic,draw:e.drawCurve})),r.createElement("p",null,"These curves are used a lot in computer aided design and computer aided manufacturing (CAD/CAM) applications, as well as in graphic design programs like Adobe Illustrator and Photoshop, Inkscape, the Gimp, etc. and in graphic technologies like scalable vector graphics (SVG) and OpenType fonts (ttf/otf). A lot of things use Bézier curves, so if you want to learn more about them... prepare to get your learn on!"))}},whatis:{locale:"en-GB",title:"So what makes a Bézier Curve?",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"whatis",title:"So what makes a Bézier Curve?",number:"2"}),r.createElement("p",null,"Playing with the points for curves may have given you a feel for how Bézier curves behave, but what ",r.createElement("em",null,"are")," Bézier curves, really? There are two ways to explain what a Bézier curve is, and they turn out to be the entirely equivalent, but one of them uses complicated maths, and the other uses really simple maths. So... let's start with the simple explanation:"),r.createElement("p",null,"Bezier curves are the result of ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Linear_interpolation"},"linear interpolations"),". That sounds complicated but you've been doing linear interpolation since you were very young: any time you had to point at something between two other things, you've been applying linear interpolation. It's simply \"picking a point between two points\"."),r.createElement("p",null,"If we know the distance between those two points, and we want a new point that is, say, 20% the distance away from the first point (and thus 80% the distance away from the second point) then we can compute that really easily:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/8090904d6448ed0c8e6151aecf62f361d51ead96.svg",width:"526.4rem",height:"107.8rem"}),r.createElement("p",null,"So let's look at that in action: the following graphic is interactive in that you can use your up and down arrow keys to increase or decrease the interpolation ratio, to see what happens. We start with three points, which gives us two lines. Linear interpolation over those lines gives use two points, between which we can again perform linear interpolation, yielding a single point. And that point —and all points we can form in this way for all ratios taken together— form our Bézier curve:"),r.createElement(i,{title:"Linear Interpolation leading to Bézier curves",setup:e.setup,draw:e.draw,onKeyDown:e.onKeyDown}),r.createElement("p",null,"And that brings us to the complicated maths: calculus."),r.createElement("p",null,'While it doesn\'t look like that\'s what we\'ve just done, we actually just drew a quadratic curve, in steps, rather than in a single go. One of the fascinating parts about Bézier curves is that they can both be described in terms of polynomial functions, as well as in terms of very simple interpolations of interpolations of [...]. That, in turn, means we can look at what these curves can do based on both "real maths" (by examining the functions, their derivatives, and all that stuff), as well as by looking at the "mechanical" composition (which tells us that a curve will never extend beyond the points we used to construct it, for instance)'),r.createElement("p",null,"So let's start looking at Bézier curves a bit more in depth. Their mathematical expressions, the properties we can derive from those, and the various things we can do to, and with, Bézier curves."))}},explanation:{locale:"en-GB",title:"The mathematics of Bézier curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"explanation",title:"The mathematics of Bézier curves",number:"3"}),r.createElement("p",null,'Bézier curves are a form of "parametric" function. Mathematically speaking, parametric functions are cheats: a "function" is actually a well defined term representing a mapping from any number of inputs to a ',r.createElement("strong",null,"single")," output. Numbers go in, a single number comes out. Change the numbers that go in, and the number that comes out is still a single number. Parametric functions cheat. They basically say \"alright, well, we want multiple values coming out, so we'll just use more than one function\". An illustration: Let's say we have a function that maps some value, let's call it ",r.createElement("i",null,"x"),", to some other value, using some kind of number manipulation:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/785e792c343b71d4e674ac94d8800940b30917ac.svg",width:"100.8rem",height:"18.2rem"}),r.createElement("p",null,"The notation ",r.createElement("i",null,"f(x)")," is the standard way to show that it's a function (by convention called ",r.createElement("i",null,"f")," if we're only listing one) and its output changes based on one variable (in this case, ",r.createElement("i",null,"x"),"). Change ",r.createElement("i",null,"x"),", and the output for ",r.createElement("i",null,"f(x)")," changes."),r.createElement("p",null,"So far so good. Now, let's look at parametric functions, and how they cheat. Let's take the following two functions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0dfe7562b43441e72201ff4cdd2e8b6e2e3ecb2d.svg",width:"98rem",height:"37.8rem"}),r.createElement("p",null,"There's nothing really remarkable about them, they're just a sine and cosine function, but you'll notice the inputs have different names. If we change the value for ",r.createElement("i",null,"a"),", we're not going to change the output value for ",r.createElement("i",null,"f(b)"),", since ",r.createElement("i",null,"a")," isn't used in that function. Parametric functions cheat by changing that. In a parametric function all the different functions share a variable, like this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ed6f533530199d1e99b3319ba137c1327b0459c0.svg",width:"105rem",height:"42rem"}),r.createElement("p",null,"Multiple functions, but only one variable. If we change the value for ",r.createElement("i",null,"t"),", we change the outcome of both ",r.createElement("i",null,"f",r.createElement("sub",null,"a"),"(t)")," and ",r.createElement("i",null,"f",r.createElement("sub",null,"b"),"(t)"),". You might wonder how that's useful, and the answer is actually pretty simple: if we change the labels ",r.createElement("i",null,"f",r.createElement("sub",null,"a"),"(t)")," and ",r.createElement("i",null,"f",r.createElement("sub",null,"b"),"(t)")," with what we usually mean with them for parametric curves, things might be a lot more obvious:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ea632ea75d6a2aeb6fe69c07feb6e76f81884746.svg",width:"81.19999999999999rem",height:"42rem"}),r.createElement("p",null,"There we go. ",r.createElement("i",null,"x"),"/",r.createElement("i",null,"y")," coordinates, linked through some mystery value ",r.createElement("i",null,"t"),"."),r.createElement("p",null,"So, parametric curves don't define a ",r.createElement("i",null,"y")," coordinate in terms of an ",r.createElement("i",null,"x"),' coordinate, like normal functions do, but they instead link the values to a "control" variable. If we vary the value of ',r.createElement("i",null,"t"),", then with every change we get ",r.createElement("strong",null,"two")," values, which we can use as (",r.createElement("i",null,"x"),",",r.createElement("i",null,"y"),") coordinates in a graph. The above set of functions, for instance, generates points on a circle: We can range ",r.createElement("i",null,"t")," from negative to positive infinity, and the resulting (",r.createElement("i",null,"x"),",",r.createElement("i",null,"y"),") coordinates will always lie on a circle with radius 1 around the origin (0,0). If we plot it for ",r.createElement("i",null,"t")," from 0 to 5, we get this (use your up and down arrow keys to change the plot end value):"),r.createElement(i,{preset:"empty",title:"A (partial) circle: x=sin(t), y=cos(t)",static:!0,setup:e.setup,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"Bézier curves are (one in many classes of) parametric functions, and are characterised by using the same base function for all its dimensions. Unlike the above example, where the ",r.createElement("i",null,"x")," and ",r.createElement("i",null,"y"),' values use different functions (one uses a sine, the other a cosine), Bézier curves use the "binomial polynomial" for both ',r.createElement("i",null,"x")," and ",r.createElement("i",null,"y"),". So what are binomial polynomials?"),r.createElement("p",null,"You may remember polynomials from high school, where they're those sums that look like:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3e8b26cf8833db7089d65e9c6b3953a3140bb19f.svg",width:"224rem",height:"21rem"}),r.createElement("p",null,"If they have a highest order term ",r.createElement("i",null,"x³")," they're called \"cubic\" polynomials, if it's ",r.createElement("i",null,"x²")," it's a \"square\" polynomial, if it's just ",r.createElement("i",null,"x")," it's a line (and if there aren't even any terms with ",r.createElement("i",null,"x")," it's not a polynomial!)"),r.createElement("p",null,"Bézier curves are polynomials of ",r.createElement("i",null,"t"),", rather than ",r.createElement("i",null,"x"),", with the value for ",r.createElement("i",null,"t")," fixed being between 0 and 1, with coefficients ",r.createElement("i",null,"a"),", ",r.createElement("i",null,"b"),' etc. taking the "binomial" form, which sounds fancy but is actually a pretty simple description for mixing values:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/565d935cab46bc995f53190102dadfdd1afc08f6.svg",width:"385rem",height:"68.6rem"}),r.createElement("p",null,"I know what you're thinking: that doesn't look too simple, but if we remove ",r.createElement("i",null,"t"),' and add in "times one", things suddenly look pretty easy. Check out these binomial terms:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/8c618738924e53a313a31fa407b3d91155525ee1.svg",width:"219.79999999999998rem",height:"91rem"}),r.createElement("p",null,'Notice that 2 is the same as 1+1, and 3 is 2+1 and 1+2, and 6 is 3+3... As you can see, each time we go up a dimension, we simply start and end with 1, and everything in between is just "the two numbers above it, added together". Now ',r.createElement("i",null,"that's")," easy to remember."),r.createElement("p",null,"There's an equally simple way to figure out how the polynomial terms work: if we rename ",r.createElement("i",null,"(1-t)")," to ",r.createElement("i",null,"a")," and ",r.createElement("i",null,"t")," to ",r.createElement("i",null,"b"),", and remove the weights for a moment, we get this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c8740a3a9a63b592e1480883a54024ebdaffaf05.svg",width:"316.4rem",height:"62.99999999999999rem"}),r.createElement("p",null,"It's basically just a sum of \"every combination of ",r.createElement("i",null,"a")," and ",r.createElement("i",null,"b"),'", progressively replacing ',r.createElement("i",null,"a"),"'s with ",r.createElement("i",null,"b"),"'s after every + sign. So that's actually pretty simple too. So now you know binomial polynomials, and just for completeness I'm going to show you the generic function for this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/444a01611e5709f702c36f6ca17aa2761c0877a9.svg",width:"315rem",height:"57.4rem"}),r.createElement("p",null,"And that's the full description for Bézier curves. Σ in this function indicates that this is a series of additions (using the variable listed below the Σ, starting at ...=<value> and ending at the value listed on top of the Σ)."),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"how-to-implement-the-basis-function"},"How to implement the basis function"),r.createElement("p",null,"We could naively implement the basis function as a mathematical construct, using the function as our guide, like this:"),r.createElement("pre",null,"function Bezier(n,t):\n sum = 0\n for(k=0; k<n; k++):\n sum += n!/(k!*(n-k)!) * (1-t)^(n-k) * t^(k)\n return sum\n"),r.createElement("p",null,"I say we could, because we're not going to: the factorial function is ",r.createElement("em",null,"incredibly"),' expensive. And, as we can see from the above explanation, we can actually create Pascal\'s triangle quite easily without it: just start at [1], then [1,1], then [1,2,1], then [1,3,3,1], and so on, with each next row fitting 1 more number than the previous row, starting and ending with "1", with all the numbers in between being the sum of the previous row\'s elements on either side "above" the one we\'re computing.'),r.createElement("p",null,"We can generate this as a list of lists lightning fast, and then never have to compute the binomial terms because we have a lookup table:"),r.createElement("pre",null,"lut = [ [1], // n=0\n [1,1], // n=1\n [1,2,1], // n=2\n [1,3,3,1], // n=3\n [1,4,6,4,1], // n=4\n [1,5,10,10,5,1], // n=5\n [1,6,15,20,15,6,1]] // n=6\n\nbinomial(n,k):\n while(n >= lut.length):\n s = lut.length\n nextRow = new array(size=s+1)\n nextRow[0] = 1\n for(i=1, prev=s-1; i<prev; i++):\n nextRow[i] = lut[prev][i-1] + lut[prev][i]\n nextRow[s] = 1\n lut.add(nextRow)\n return lut[n][k]\n"),r.createElement("p",null,"So what's going on here? First, we declare a lookup table with a size that's reasonably large enough to accommodate most lookups. Then, we declare a function to get us the values we need, and we make sure that if an n/k pair is requested that isn't in the LUT yet, we expand it first. Our basis function now looks like this:"),r.createElement("pre",null,"function Bezier(n,t):\n sum = 0\n for(k=0; k<=n; k++):\n sum += binomial(n,k) * (1-t)^(n-k) * t^(k)\n return sum\n"),r.createElement("p",null,"Perfect. Of course, we can optimize further. For most computer graphics purposes, we don't need arbitrary curves. We need quadratic and cubic curves (this primer actually does do arbitrary curves, so you'll find code similar to shown here), which means we can drastically simplify the code:"),r.createElement("pre",null,"function Bezier(2,t):\n t2 = t * t\n mt = 1-t\n mt2 = mt * mt\n return mt2 + 2*mt*t + t2\n\nfunction Bezier(3,t):\n t2 = t * t\n t3 = t2 * t\n mt = 1-t\n mt2 = mt * mt\n mt3 = mt2 * mt\n return mt3 + 3*mt2*t + 3*mt*t2 + t3\n"),r.createElement("p",null,"And now we know how to program the basis function. Exellent.")),r.createElement("p",null,"So, now we know what the base function(s) look(s) like, time to add in the magic that makes Bézier curves so special: control points."))}},control:{locale:"en-GB",title:"Controlling Bézier curvatures",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"control",title:"Controlling Bézier curvatures",number:"4"}),r.createElement("p",null,'Bézier curves are (like all "splines") interpolation functions, meaning they take a set of points, and generate values somewhere "between" those points. (One of the consequences of this is that you\'ll never be able to generate a point that lies outside the outline for the control points, commonly called the "hull" for the curve. Useful information!). In fact, we can visualize how each point contributes to the value generated by the function, so we can see which points are important, where, in the curve.'),r.createElement("p",null,'The following graphs show the interpolation functions for quadratic and cubic curves, with "S" being the strength of a point\'s contribution to the total sum of the Bézier function. Click or click-drag to see the interpolation percentages for each curve-defining point at a specific ',r.createElement("i",null,"t")," value."),r.createElement("div",{className:"figure"},r.createElement(i,{inline:!0,preset:"simple",title:"Quadratic interpolations",draw:e.drawQuadraticLerp}),r.createElement(i,{inline:!0,preset:"simple",title:"Cubic interpolations",draw:e.drawCubicLerp}),r.createElement(i,{inline:!0,preset:"simple",title:"15th order interpolations",draw:e.draw15thLerp})),r.createElement("p",null,"Also shown is the interpolation function for a 15",r.createElement("sup",null,"th")," order Bézier function. As you can see, the start and end point contribute considerably more to the curve's shape than any other point in the control point set."),r.createElement("p",null,'If we want to change the curve, we need to change the weights of each point, effectively changing the interpolations. The way to do this is about as straight forward as possible: just multiply each point with a value that changes its strength. These values are conventionally called "Weights", and we can add them to our original Bézier function:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/cc82da74955e71db3f5f0ab77dcc4664c0387bec.svg",width:"369.59999999999997rem",height:"57.4rem"}),r.createElement("p",null,'That looks complicated, but as it so happens, the "weights" are actually just the coordinate values we want our curve to have: for an ',r.createElement("i",null,"n",r.createElement("sup",null,"th"))," order curve, w",r.createElement("sub",null,"0")," is our start coordinate, w",r.createElement("sub",null,"n")," is our last coordinate, and everything in between is a controlling coordinate. Say we want a cubic curve that starts at (120,160), is controlled by (35,200) and (220,260) and ends at (220,40), we use this Bézier curve:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/853858526831a7ef3eb170efe49de397bb4913a1.svg",width:"496.99999999999994rem",height:"42rem"}),r.createElement("p",null,"Which gives us the curve we saw at the top of the article:"),r.createElement(i,{preset:"simple",title:"Our cubic Bézier curve",setup:e.drawCubic,draw:e.drawCurve}),r.createElement("p",null,"What else can we do with Bézier curves? Quite a lot, actually. The rest of this article covers a multitude of possible operations and algorithms that we can apply, and the tasks they achieve."),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"how-to-implement-the-weighted-basis-function"},"How to implement the weighted basis function"),r.createElement("p",null,"Given that we already know how to implement basis function, adding in the control points is remarkably easy:"),r.createElement("pre",null,"function Bezier(n,t,w[]):\n sum = 0\n for(k=0; k<n; k++):\n sum += w[k] * binomial(n,k) * (1-t)^(n-k) * t^(k)\n return sum\n"),r.createElement("p",null,"And for the extremely optimized versions:"),r.createElement("pre",null,"function Bezier(2,t,w[]):\n t2 = t * t\n mt = 1-t\n mt2 = mt * mt\n return w[0]*mt2 + w[1]*2*mt*t + w[2]*t2\n\nfunction Bezier(3,t,w[]):\n t2 = t * t\n t3 = t2 * t\n mt = 1-t\n mt2 = mt * mt\n mt3 = mt2 * mt\n return w[0]*mt3 + 3*w[1]*mt2*t + 3*w[2]*mt*t2 + w[3]*t3\n"),r.createElement("p",null,"And now we know how to program the weighted basis function.")))}},extended:{locale:"en-GB",title:"The Bézier interval [0,1]",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"extended",title:"The Bézier interval [0,1]",number:"5"}),r.createElement("p",null,"Now that we know the mathematics behind Bézier curves, there's one curious thing that you may have noticed: they always run from ",r.createElement("code",null,"t=0")," to ",r.createElement("code",null,"t=1"),". Why that particular interval?"),r.createElement("p",null,'It all has to do with how we run from "the start" of our curve to "the end" of our curve. If we have a value that is a mixture of two other values, then the general formula for this is:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7f5ebb8489a8d04beb28f47c8aac2632b78ae764.svg",width:"225.39999999999998rem",height:"16.799999999999997rem"}),r.createElement("p",null,"The obvious start and end values here need to be ",r.createElement("code",null,"a=1, b=0"),", so that the mixed value is 100% value 1, and 0% value 2, and ",r.createElement("code",null,"a=0, b=1"),', so that the mixed value is 0% value 1 and 100% value 2. Additionally, we don\'t want "a" and "b" to be independent: if they are, then we could just pick whatever values we like, and end up with a mixed value that is, for example, 100% value 1 ',r.createElement("strong",null,"and")," 100% value 2. In principle that's fine, but for Bézier curves we always want mixed values ",r.createElement("em",null,"between"),' the start and end point, so we need to make sure we can never set "a" and "b" to some values that lead to a mix value that sums to more than 100%. And that\'s easy:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d326c8f323ccd2da00d998b533ac26a1c04fcfba.svg",width:"225.39999999999998rem",height:"16.799999999999997rem"}),r.createElement("p",null,"With this we can guarantee that we never sum above 100%. By restricting ",r.createElement("code",null,"a")," to values in the interval [0,1], we will always be somewhere between our two values (inclusively), and we will always sum to a 100% mix."),r.createElement("p",null,'But... what if we use this form, used in the assumption that we will only ever use values between 0 and 1, and instead use values outside of that interval? Do things go horribly wrong? Well... not really, but we get to "see more".'),r.createElement("p",null,'In the case of Bézier curves, extending the interval simply makes our curve "keep going". Bézier curves are simply segments on some polynomial curve, so if we pick a wider interval we simply get to see more of the curve. So what do they look like?'),r.createElement("p",null,'The following two graphics show you Bézier curves rendered "the usual way", as well as the curves they "lie on" if we were to extend the ',r.createElement("code",null,"t"),' values much further. As you can see, there\'s a lot more "shape" hidden in the rest of the curve, and we can model those parts by moving the curve points around.'),r.createElement(i,{preset:"simple",title:"Quadratic infinite interval Bézier curve",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"simple",title:"Cubic infinite interval Bézier curve",setup:e.setupCubic,draw:e.draw}),r.createElement("p",null,"In fact, there are curves used in graphics design and computer modelling that do the opposite of Bézier curves, where rather than fixing the interval, and giving you free coordinates, they fix the coordinates, but give you freedom over the interval. A great example of this is the ",r.createElement("a",{ +href:"http://levien.com/phd/phd.html"},'"Spiro" curve'),", which is a curve based on part of a ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Euler_spiral"},"Cornu Spiral, also known as Euler's Spiral"),". It's a very aesthetically pleasing curve and you'll find it in quite a few graphics packages like ",r.createElement("a",{href:"https://fontforge.github.io"},"FontForge")," and ",r.createElement("a",{href:"https://inkscape.org"},"Inkscape"),", having even been used in font design (such as for the Inconsolata font)."))}},matrix:{locale:"en-GB",title:"Bézier curvatures as matrix operations",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"matrix",title:"Bézier curvatures as matrix operations",number:"6"}),r.createElement("p",null,"We can also represent Bézier as matrix operations, by expressing the Bézier formula as a polynomial basis function and a coefficients matrix, and the actual coordinates as matrix. Let's look at what this means for the cubic curve:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d961171d6d1dfc22bb1756901e79102147914360.svg",width:"491.4rem",height:"21rem"}),r.createElement("p",null,"Disregarding our actual coordinates for a moment, we have:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/f925c339011e6c38e47b9c3a571e02fca80eb5c3.svg",width:"371rem",height:"19.599999999999998rem"}),r.createElement("p",null,"We can write this as a sum of four expressions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/30d76165668bf15f62986503bea100f39c5b9fec.svg",width:"147rem",height:"78.39999999999999rem"}),r.createElement("p",null,"And we can expand these expressions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7ca5abe1124ba1e51b7f12e0469cb4b1407593b8.svg",width:"417.2rem",height:"78.39999999999999rem"}),r.createElement("p",null,"Furthermore, we can make all the 1 and 0 factors explicit:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/bccbb94942e3ff79579e4719106f4701c157727e.svg",width:"228.2rem",height:"78.39999999999999rem"}),r.createElement("p",null,"And ",r.createElement("em",null,"that"),", we can view as a series of four matrix operations:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d5f85d80fbbc62e1e8d58621b76f3d0224876b62.svg",width:"637rem",height:"75.6rem"}),r.createElement("p",null,"If we compact this into a single matrix operation, we get:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7140be48f45b2e7190fa8dffef5c05c47c038ab0.svg",width:"237.99999999999997rem",height:"75.6rem"}),r.createElement("p",null,"This kind of polynomial basis representation is generally written with the bases in increasing order, which means we need to flip our ",r.createElement("code",null,"t"),' matrix horizontally, and our big "mixing" matrix upside down:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/4e1849950a5c13f5135aa3412e0ee634cdc67301.svg",width:"237.99999999999997rem",height:"75.6rem"}),r.createElement("p",null,"And then finally, we can add in our original coordinates as a single third matrix:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5910e25a46d9e86ab34513017f1274628a40e5a7.svg",width:"338.79999999999995rem",height:"77rem"}),r.createElement("p",null,"We can perform the same trick for the quadratic curve, in which case we end up with:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e56e78e406d625c2a5ec584216f79a5fee00d8ea.svg",width:"275.79999999999995rem",height:"57.4rem"}),r.createElement("p",null,"If we plug in a ",r.createElement("code",null,"t")," value, and then multiply the matrices, we will get exactly the same values as when we evaluate the original polynomial function, or as when we evaluate the curve using progessive linear interpolation."),r.createElement("p",null,r.createElement("strong",null,"So: why would we bother with matrices?")," Matrix representations allow us to discover things about functions that would otherwise be hard to tell. It turns out that the curves form ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Triangular_matrix"},"triangular matrices"),", and they have a determinant equal to the product of the actual coordinates we use for our curve. It's also invertible, which means there's ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Invertible_matrix#The_invertible_matrix_theorem"},"a ton of properties")," that are all satisfied. Of course, the main question is: \"Why is this useful to us, now?\", and the answer to that is that it's not immediately useful, but you'll be seeing some instances where certain curve properties can be either computed via function manipulation, or via clever use of matrices, and sometimes the matrix approach can be (drastically) faster."),r.createElement("p",null,"So for now, just remember that we can represent curves this way, and let's move on."))}},decasteljau:{locale:"en-GB",title:"de Casteljau's algorithm",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"decasteljau",title:"de Casteljau's algorithm",number:"7"}),r.createElement("p",null,"If we want to draw Bézier curves we can run through all values of ",r.createElement("code",null,"t")," from 0 to 1 and then compute the weighted basis function, getting the ",r.createElement("code",null,"x/y"),' values we need to plot, but the more complex the curve gets, the more expensive this becomes. Instead, we can use "de Casteljau\'s algorithm" to draw curves, which is a geometric approach to drawing curves, and really easy to implement. So easy, in fact, you can do it by hand with a pencil and ruler.'),r.createElement("p",null,"Rather than using our calculus function to find ",r.createElement("code",null,"x/y")," values for ",r.createElement("code",null,"t"),", let's do this instead:"),r.createElement("ul",null,r.createElement("li",null,"treat ",r.createElement("code",null,"t")," as a ratio (which it is). t=0 is 0% along a line, t=1 is 100% along a line."),r.createElement("li",null,"Take all lines between the curve's defining points. For an order ",r.createElement("code",null,"n")," curve, that's ",r.createElement("code",null,"n")," lines."),r.createElement("li",null,"Place markers along each of these line, at distance ",r.createElement("code",null,"t"),". So if ",r.createElement("code",null,"t")," is 0.2, place the mark at 20% from the start, 80% from the end."),r.createElement("li",null,"Now form lines between ",r.createElement("code",null,"those")," points. This gives ",r.createElement("code",null,"n-1")," lines."),r.createElement("li",null,"Place markers along each of these line at distance ",r.createElement("code",null,"t"),"."),r.createElement("li",null,"Form lines between ",r.createElement("code",null,"those")," points. This'll be ",r.createElement("code",null,"n-2")," lines."),r.createElement("li",null,"place markers, form lines, place markers, etc."),r.createElement("li",null,"repeat this until you have only one line left. The point ",r.createElement("code",null,"t")," on that line coincides with the original curve point at ",r.createElement("code",null,"t"),".")),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"how-to-implement-de-casteljau-s-algorithm"},"How to implement de Casteljau's algorithm"),r.createElement("p",null,"Let's just use the algorithm we just specified, and implement that:"),r.createElement("pre",null,"function drawCurve(points[], t):\n if(points.length==1):\n draw(points[0])\n else:\n newpoints=array(points.size-1)\n for(i=0; i<newpoints.length; i++):\n newpoints[i] = (1-t) * points[i] + t * points[i+1]\n drawCurve(newpoints, t)\n"),r.createElement("p",null,"And done, that's the algorithm implemented. Except usually you don't get the luxury of overloading the \"+\" operator, so let's also give the code for when you need to work with ",r.createElement("code",null,"x")," and ",r.createElement("code",null,"y")," values:"),r.createElement("pre",null,"function drawCurve(points[], t):\n if(points.length==1):\n draw(points[0])\n else:\n newpoints=array(points.size-1)\n for(i=0; i<newpoints.length; i++):\n x = (1-t) * points[i].x + t * points[i+1].x\n y = (1-t) * points[i].y + t * points[i+1].y\n newpoints[i] = new point(x,y)\n drawCurve(newpoints, t)\n"),r.createElement("p",null,"So what does this do? This draws a point, if the passed list of points is only 1 point long. Otherwise it will create a new list of points that sit at the ",r.createElement("i",null,"t"),' ratios (i.e. the "markers" outlined in the above algorithm), and then call the draw function for this new list.')),r.createElement("p",null,"To see this in action, mouse-over the following sketch. Moving the mouse changes which curve point is explicitly evaluated using de Casteljau's algorithm, moving the cursor left-to-right (or, of course, right-to-left), shows you how a curve is generated using this approach."),r.createElement(i,{preset:"simple",title:"Traversing a curve using de Casteljau's algorithm",setup:e.setup,draw:e.draw}))}},flattening:{locale:"en-GB",title:"Simplified drawing",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"flattening",title:"Simplified drawing",number:"8"}),r.createElement("p",null,'We can also simplify the drawing process by "sampling" the curve at certain points, and then joining those points up with straight lines, a process known as "flattening", as we are reducing a curve to a simple sequence of straight, "flat" lines.'),r.createElement("p",null,'We can do this is by saying "we want X segments", and then sampling the curve at intervals that are spaced such that we end up with the number of segments we wanted. The advantage of this method is that it\'s fast: instead of evaluating 100 or even 1000 curve coordinates, we can sample a much lower number and still end up with a curve that sort-of-kind-of looks good enough. The disadvantage of course is that we lose the precision of working with "the real curve", so we usually can\'t use the flattened for for doing true intersection detection, or curvature alignment.'),r.createElement(i,{preset:"twopanel",title:"Flattening a quadratic curve",setup:e.setupQuadratic,draw:e.drawFlattened,onKeyDown:e.onKeyDown}),r.createElement(i,{preset:"twopanel",title:"Flattening a cubic curve",setup:e.setupCubic,draw:e.drawFlattened,onKeyDown:e.onKeyDown}),r.createElement("p",null,"Try clicking on the sketch and using your up and down arrow keys to lower the number of segments for both the quadratic and cubic curve. You'll notice that for certain curvatures, a low number of segments works quite well, but for more complex curvatures (try this for the cubic curve), a higher number is required to capture the curvature changes properly."),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"how-to-implement-curve-flattening"},"How to implement curve flattening"),r.createElement("p",null,"Let's just use the algorithm we just specified, and implement that:"),r.createElement("pre",null,"function flattenCurve(curve, segmentCount):\n step = 1/segmentCount;\n coordinates = [curve.getXValue(0), curve.getYValue(0)]\n for(i=1; i <= segmentCount; i++):\n t = i*step;\n coordinates.push[curve.getXValue(t), curve.getYValue(t)]\n return coordinates;\n"),r.createElement("p",null,'And done, that\'s the algorithm implemented. That just leaves drawing the resulting "curve" as a sequence of lines:'),r.createElement("pre",null,"function drawFlattenedCurve(curve, segmentCount):\n coordinates = flattenCurve(curve, segmentCount)\n coord = coordinates[0], _coords;\n for(i=1; i < coordinates.length; i++):\n _coords = coordinates[i]\n line(coords, _coords)\n coords = _coords\n"),r.createElement("p",null,"We start with the first coordinate as reference point, and then just draw lines between each point and its next point.")))}},splitting:{locale:"en-GB",title:"Splitting curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"splitting",title:"Splitting curves",number:"9"}),r.createElement("p",null,"With de Casteljau's algorithm we also find all the points we need to split up a Bézier curve into two, smaller curves, which taken together form the original curve. When we construct de Casteljau's skeleton for some value ",r.createElement("code",null,"t"),", the procedure gives us all the points we need to split a curve at that ",r.createElement("code",null,"t")," value: one curve is defined by all the inside skeleton points found prior to our on-curve point, with the other curve being defined by all the inside skeleton points after our on-curve point."),r.createElement(i,{title:"Splitting a curve",setup:e.setupCubic,draw:e.drawSplit}),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"implementing-curve-splitting"},"implementing curve splitting"),r.createElement("p",null,"We can implement curve splitting by bolting some extra logging onto the de Casteljau function:"),r.createElement("pre",null,"left=[]\nright=[]\nfunction drawCurve(points[], t):\n if(points.length==1):\n left.add(points[0])\n right.add(points[0])\n draw(points[0])\n else:\n newpoints=array(points.size-1)\n for(i=0; i<newpoints.length; i++):\n if(i==0):\n left.add(points[i])\n if(i==newpoints.length-1):\n right.add(points[i+1])\n newpoints[i] = (1-t) * points[i] + t * points[i+1]\n drawCurve(newpoints, t)\n"),r.createElement("p",null,"After running this function for some value ",r.createElement("code",null,"t"),", the ",r.createElement("code",null,"left")," and ",r.createElement("code",null,"right"),' arrays will contain all the coordinates for two new curves - one to the "left" of our ',r.createElement("code",null,"t"),' value, the other on the "right", of the same order as the original curve, and overlayed exactly on the original curve.')),r.createElement("p",null,"This is best illustrated with an animated graphic (click to play/pause):"),r.createElement(i,{preset:"threepanel",title:"Bézier curve splitting",setup:e.setupCubic,draw:e.drawAnimated,onClick:e.togglePlay}))}},matrixsplit:{locale:"en-GB",title:"Splitting curves using matrices",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"matrixsplit",title:"Splitting curves using matrices",number:"10"}),r.createElement("p",null,"Another way to split curves is to exploit the matrix representation of a Bézier curve. In ",r.createElement("a",{href:"#matrix"},"the section on matrices")," we saw that we can represent curves as matrix multiplications. Specifically, we saw these two forms for the quadratic, and cubic curves, respectively (using the reversed Bézier coefficients vector for legibility):"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e56e78e406d625c2a5ec584216f79a5fee00d8ea.svg",width:"275.79999999999995rem",height:"57.4rem"}),r.createElement("p",null,"and"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/01ea4f74c4785a19bedf18034b51510c5ce2ad8f.svg",width:"338.79999999999995rem",height:"77rem"}),r.createElement("p",null,"Let's say we want to split the curve at some point ",r.createElement("code",null,"t = z"),', forming two new (obviously smaller) Bézier curves. To find the coordinates for these two Bézier curves, we can use the matrix representation and some linear algebra. First, we split out the the actual "point on the curve" information as a new matrix multiplication:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d6fa091a86782480968c232ef86513c578030004.svg",width:"680.4rem",height:"57.4rem"}),r.createElement("p",null,"and"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d487e1e0181420995be49b25bc6595c9d0360435.svg",width:"845.5999999999999rem",height:"78.39999999999999rem"}),r.createElement("p",null,"If we could compact these matrices back to a form ",r.createElement("strong",null,"[t values] · [bezier matrix] · [column matrix]"),", with the first two staying the same, then that column matrix on the right would be the coordinates of a new Bézier curve that describes the first segment, from ",r.createElement("code",null,"t = 0")," to ",r.createElement("code",null,"t = z"),". As it turns out, we can do this quite easily, by exploiting some simple rules of linear algebra (and if you don't care about the derivations, just skip to the end of the box for the results!)."),r.createElement("div",{className:"note"},r.createElement("h2",{id:"deriving-new-hull-coordinates"},"Deriving new hull coordinates"),r.createElement("p",null,"Deriving the two segments upon splitting a curve takes a few steps, and the higher the curve order, the more work it is, so let's look at the quadratic curve first:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d4b8355c3f1f80aacfc2766423a30151c5180a02.svg",width:"365.4rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/fe5f623585a9bbb836f54164aecaadd3fc4ec953.svg",width:"259rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1eb9833685c9189c64d9cbdfdbb24a94e70e493f.svg",width:"259rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/55f9d31b32a3e8855f2d28c3253201c8963eefd1.svg",width:"257.59999999999997rem",height:"57.4rem"}),r.createElement("p",null,"We do this, because [",r.createElement("em",null,"M · M",r.createElement("sup",null,"-1")),"] is the identity matrix (a bit like multiplying something by x/x in calculus. It doesn't do anything to the function, but it does allow you to rewrite it to something that may be easier to work with, or can be broken up differently). Adding that as matrix multiplication has no effect on the total formula, but it does allow us to change the matrix sequence [",r.createElement("em",null,"something · M"),"] to a sequence [",r.createElement("em",null,"M · something"),"], and that makes a world of difference: if we know what [",r.createElement("em",null,"M",r.createElement("sup",null,"-1")," · Z · M"),"] is, we can apply that to our coordinates, and be left with a proper matrix representation of a quadratic Bézier curve (which is [",r.createElement("em",null,"T · M · P"),"]), with a new set of coordinates that represent the curve from ",r.createElement("em",null,"t = 0")," to ",r.createElement("em",null,"t = z"),". So let's get computing:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1dbabc115128a85389cbbcc75fbced48e5a2ca25.svg",width:"658rem",height:"58.8rem"}),r.createElement("p",null,"Excellent! Now we can form our new quadratic curve:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/2972cd74dab6560ea68189c2e53f247287cbefae.svg",width:"438.2rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/39b64e07c41ef6d734064f017036f6391321e924.svg",width:"502.59999999999997rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d615960f862664749c54858520c364efeb4a4c5a.svg",width:"516.6rem",height:"57.4rem"}),r.createElement("p",null,r.createElement("strong",null,r.createElement("em",null,"Brilliant")),": if we want a subcurve from ",r.createElement("code",null,"t = 0")," to ",r.createElement("code",null,"t = z"),", we can keep the first coordinate the same (which makes sense), our control point becomes a z-ratio mixture of the original control point and the start point, and the new end point is a mixture that looks oddly similar to a bernstein polynomial of degree two, except it uses (z-1) rather than (1-z)... These new coordinates are actually really easy to compute directly!"),r.createElement("p",null,"Of course, that's only one of the two curves. Getting the section from ",r.createElement("code",null,"t = z")," to ",r.createElement("code",null,"t = 1")," requires doing this again. We first observe what what we just did is actually evaluate the general interval [0,",r.createElement("code",null,"z"),"], which we wrote down simplified becuase of that zero, but we actually evaluated this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/a51e64df3cb31acf32d0ad5814c8c6cff41ae611.svg",width:"400.4rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b50cdfed6656e681d5885a14a3af3e67efa4ccb.svg",width:"329rem",height:"57.4rem"}),r.createElement("p",null,"If we want the interval [",r.createElement("em",null,"z"),",1], we will be evaluating this instead:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/eca8cfda9b7a3f0819ec38acc53f95af67bb26bb.svg",width:"484.4rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e8c983a3efd47356c971fe46add4d0cdf103cced.svg",width:"432.59999999999997rem",height:"60.199999999999996rem"}),r.createElement("p",null,"We're going to do the same trick, to turn ",r.createElement("code",null,"[something · M]")," into ",r.createElement("code",null,"[M · something]"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/a28b6dcc1335de19a065b6a04d8bb45d86122bb7.svg",width:"765.8rem",height:"60.199999999999996rem"}),r.createElement("p",null,"So, our final second curve looks like:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5851c9191acb59456e3706a8f6f1a0f85e691eda.svg",width:"442.4rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0333e63f50b3d43067dc299280f70e9eb98711bb.svg",width:"496.99999999999994rem",height:"60.199999999999996rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/00a133860115d7a4db4ddf62781b5ae2bffef088.svg",width:"516.6rem",height:"60.199999999999996rem"}),r.createElement("p",null,r.createElement("strong",null,r.createElement("em",null,"Nice")),": we see the same as before; can keep the last coordinate the same (which makes sense), our control point becomes a z-ratio mixture of the original control point and the end point, and the new start point is a mixture that looks oddly similar to a bernstein polynomial of degree two, except it uses (z-1) rather than (1-z). These new coordinates are ",r.createElement("em",null,"also")," really easy to compute directly!")),r.createElement("p",null,"So, using linear algebra rather than de Casteljau's algorithm, we have determined that for any quadratic curve split at some value ",r.createElement("code",null,"t = z"),", we get two subcurves that are described as Bézier curves with simple-to-derive coordinates."),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5769f44aea3344c32c497a3a77d236f524222b95.svg",width:"604.8rem",height:"57.4rem"}),r.createElement("p",null,"and"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1fdde935dc357642358bdf5e632d6539c9d4debd.svg",width:"599.1999999999999rem",height:"60.199999999999996rem"}),r.createElement("p",null,"We can do the same for cubic curves. However, I'll spare you the actual derivation (don't let that stop you from writing that out yourself, though) and simply show you the resulting new coordinate sets:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/44db09290062827525a9b23cbaf91e65063d86d7.svg",width:"883.4rem",height:"78.39999999999999rem"}),r.createElement("p",null,"and"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d6b1abe72bac1b55d184f2c4254769404371d06f.svg",width:"886.1999999999999rem",height:"81.19999999999999rem"}),r.createElement("p",null,"So, looking at our matrices, did we really need to compute the second segment matrix? No, we didn't. Actually having one segment's matrix means we implicitly have the other: push the values of each row in the matrix ",r.createElement("strong",null,r.createElement("em",null,"Q")),' to the right, with zeroes getting pushed off the right edge and appearing back on the left, and then flip the matrix vertically. Presto, you just "calculated" ',r.createElement("strong",null,r.createElement("em",null,"Q'")),"."),r.createElement("p",null,"Implementing curve splitting this way requires less recursion, and is just straight arithmetic with cached values, so can be cheaper on systems were recursion is expensive. If you're doing computation with devices that are good at matrix multiplication, chopping up a Bézier curve with this method will be a lot faster than applying de Casteljau."))}},reordering:{locale:"en-GB",title:"Lowering and elevating curve order",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"reordering",title:"Lowering and elevating curve order",number:"11"}),r.createElement("p",null,"One interesting property of Bézier curves is that an ",r.createElement("em",null,"n",r.createElement("sup",null,"th"))," order curve can always be perfectly represented by an ",r.createElement("em",null,"(n+1)",r.createElement("sup",null,"th"))," order curve, by giving the higher order curve specific control points."),r.createElement("p",null,'If we have a curve with three points, then we can create a four point curve that exactly reproduce the original curve as long as we give it the same start and end points, and for its two control points we pick "1/3',r.createElement("sup",null,"rd")," start + 2/3",r.createElement("sup",null,"rd"),' control" and "2/3',r.createElement("sup",null,"rd")," control + 1/3",r.createElement("sup",null,"rd"),' end", and now we have exactly the same curve as before, except represented as a cubic curve, rather than a quadratic curve.'),r.createElement("p",null,"The general rule for raising an ",r.createElement("em",null,"n",r.createElement("sup",null,"th"))," order curve to an ",r.createElement("em",null,"(n+1)",r.createElement("sup",null,"th"))," order curve is as follows (observing that the start and end weights are the same as the start and end weights for the old curve):"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c69c811b7fa790fbc7d082f29855b6f66243b454.svg",width:"803.5999999999999rem",height:"64.39999999999999rem"}),r.createElement("p",null,"However, this rule also has as direct consequence that you ",r.createElement("strong",null,"cannot")," generally safely lower a curve from ",r.createElement("em",null,"n",r.createElement("sup",null,"th"))," order to ",r.createElement("em",null,"(n-1)",r.createElement("sup",null,"th")),' order, because the control points cannot be "pulled apart" cleanly. We can try to, but the resulting curve will not be identical to the original, and may in fact look completely different.'),r.createElement("p",null,"We can apply this to a (semi) random curve, as is done in the following graphic. Select the sketch and press your up and down arrow keys to elevate or lower the curve order."),r.createElement(i,{preset:"simple",title:"A "+e.getOrder()+" order Bézier curve",setup:e.setup,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"There is a good, if mathematical, explanation on the matrices necessary for optimal reduction over on ",r.createElement("a",{href:"http://www.sirver.net/blog/2011/08/23/degree-reduction-of-bezier-curves"},"Sirver's Castle"),", which given time will find its way in a more direct description into this article."))}},derivatives:{locale:"en-GB",title:"Derivatives",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"derivatives",title:"Derivatives",number:"12"}),r.createElement("p",null,"There's a number of useful things that you can do with Bézier curves based on their derivative, and one of the more amusing observations about Bézier curves is that their derivatives are, in fact, also Bézier curves. In fact, the derivation of a Bézier curve is relatively straight forward, although we do need a bit of math. First, let's look at the derivative rule for Bézier curves, which is:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/17c8e825e1d2ae198cd7c33427870a3cf8ff31a1.svg",width:"350rem",height:"46.199999999999996rem"}),r.createElement("p",null,"which we can also write (observing that ",r.createElement("i",null,"b")," in this formula is the same as our ",r.createElement("i",null,"w")," weights, and that ",r.createElement("i",null,"n")," times a summation is the same as a summation where each term is multiplied by ",r.createElement("i",null,"n"),") as:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/a3a62e074a592e2c6497046261452ef89d1893d3.svg",width:"359.79999999999995rem",height:"46.199999999999996rem"}),r.createElement("p",null,"Or, in plain text: the derivative of an n",r.createElement("sup",null,"th")," degree Bézier curve is an (n-1)",r.createElement("sup",null,"th")," degree Bézier curve, with one fewer term, and new weights w'",r.createElement("sub",null,"0"),"...w'",r.createElement("sub",null,"n-1")," derived from the original weights as n(w",r.createElement("sub",null,"i+1")," - w",r.createElement("sub",null,"i"),"), so for a 3rd degree curve, with four weights, the derivative has three new weights w'",r.createElement("sub",null,"0")," = 3(w",r.createElement("sub",null,"1"),"-w",r.createElement("sub",null,"0"),"), w'",r.createElement("sub",null,"1")," = 3(w",r.createElement("sub",null,"2"),"-w",r.createElement("sub",null,"1"),") and w'",r.createElement("sub",null,"2")," = 3(w",r.createElement("sub",null,"3"),"-w",r.createElement("sub",null,"2"),")."),r.createElement("div",{className:"note"},r.createElement("h3",{id:"-slow-down-why-is-that-true-"},'"Slow down, why is that true?"'),r.createElement("p",null,"Sometimes just being told \"this is the derivative\" is nice, but you might want to see why this is indeed the case. As such, let's have a look at the proof for this derivative. First off, the weights are independent of the full Bézier function, so the derivative involves only the derivative of the polynomial basis function. So, let's find that:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1f8148ecaac6af494a8bb96d2f96f7a96f85d9e0.svg",width:"219.79999999999998rem",height:"37.8rem"}),r.createElement("p",null,"Applying the ",r.createElement("a",{href:"http://en.wikipedia.org/wiki/Product_rule"},"product")," and ",r.createElement("a",{href:"http://en.wikipedia.org/wiki/Chain_rule"},"chain")," rules gives us:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5dbfaadcef0cb26159cedb26c9c7c54ac008064d.svg",width:"432.59999999999997rem",height:"29.4rem"}),r.createElement("p",null,"Which is hard to work with, so let's expand that properly:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ebfac729364de2cfd10ba3b8b4a6a6c44e7b4578.svg",width:"361.2rem",height:"28rem"}),r.createElement("p",null,'Now, the trick is to turn this expression into something that has binomial coefficients again, so we want to end up with things that look like "x! over y!(x-y)!". If we can do that in a way that involves terms of ',r.createElement("i",null,"n-1")," and ",r.createElement("i",null,"k-1"),", we'll be on the right track."),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b2a6fe8fe85ddf02a05f618b9ab12d65cc60cb3c.svg",width:"574rem",height:"79.8rem"}),r.createElement("p",null,"And that's the first part done: the two components inside the parentheses are actually regular, lower order Bezier expressions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/222b5aafd8b8fca6dcfc04ca7ac4248f652752fd.svg",width:"560rem",height:"50.4rem"}),r.createElement("p",null,"Now to apply this to our weighted Bezier curves. We'll write out the plain curve formula that we saw earlier, and then work our way through to its derivative:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e2f7ff20e5f540af4cb96cae56a241f3ea3f52f0.svg",width:"553rem",height:"117.6rem"}),r.createElement("p",null,"If we expand this (with some color to show how terms line up), and reorder the terms by increasing values for ",r.createElement("i",null,"k")," we see the following:"),r.createElement("img",{ +className:"LaTeX SVG",src:"images/latex/2505458c9422a6a1dcc59ad2f5b134c1daf0c860.svg",width:"315rem",height:"114.8rem"}),r.createElement("p",null,"Two of these terms fall way: the first term falls away because there is no -1",r.createElement("sup",null,"st"),' term in a summation. As such, it always contributes "nothing", so we can safely completely ignore it for the purpose of finding the derivative function. The other term is the very last term in this expansion: one involving ',r.createElement("i",null,"B",r.createElement("sub",null,"n-1,n")),". This term would have a binomial coefficient of [",r.createElement("i",null,"i")," choose ",r.createElement("i",null,"i+1"),'], which is a non-existent binomial coefficient. Again, this term would contribute "nothing", so we can ignore it, too. This means we\'re left with:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/f058419c1a80d98e6f74ceaf385a1c4e1fc3c645.svg",width:"309.4rem",height:"74.19999999999999rem"}),r.createElement("p",null,"And that's just a summation of lower order curves:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/08a399ed22fbf888982020848612ab348e4cbfc3.svg",width:"751.8rem",height:"37.8rem"}),r.createElement("p",null,"We can rewrite this as a normal summation, and we're done:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b66421144e6848bbbe434a23b3a7b311ce9ff770.svg",width:"572.5999999999999rem",height:"53.199999999999996rem"})),r.createElement("p",null,"Let's rewrite that in a form similar to our original formula, so we can see the difference. We will first list our original formula for Bézier curves, and then the derivative:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/cc82da74955e71db3f5f0ab77dcc4664c0387bec.svg",width:"369.59999999999997rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/6c95e389e593152cd24eb52e891db7c7b37c4e97.svg",width:"560rem",height:"61.599999999999994rem"}),r.createElement("p",null,"What are the differences? In terms of the actual Bézier curve, virtually nothing! We lowered the order (rather than ",r.createElement("i",null,"n"),", it's now ",r.createElement("i",null,"n-1"),"), but it's still the same Bézier function. The only real difference is in how the weights change when we derive the curve's function. If we have four points A, B, C, and D, then the derivative will have three points, the second derivative two, and the third derivative one:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/34e8aadefa9d0ee443efe27a1fc76210eedb373c.svg",width:"548.8rem",height:"77rem"}),r.createElement("p",null,"We can keep performing this trick for as long as we have more than one weight. Once we have one weight left, the next step will see ",r.createElement("i",null,"k = 0"),', and the result of our "Bézier function" summation is zero, because we\'re not adding anything at all. As such, a quadratic curve has no second derivative, a cubic curve has no third derivative, and generalized: an ',r.createElement("i",null,"n",r.createElement("sup",null,"th"))," order curve has ",r.createElement("i",null,"n-1")," (meaningful) derivatives, with any further derivative being zero."))}},pointvectors:{locale:"en-GB",title:"Tangents and normals",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"pointvectors",title:"Tangents and normals",number:"13"}),r.createElement("p",null,'If you want to move objects along a curve, or "away from" a curve, the two vectors you\'re most interested in are the tangent vector and normal vector for curve points. These are actually really easy to find. For moving, and orienting, along a curve we use the tangent, which indicates the direction travel at specific points, and is literally just the first derivative of our curve:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/2271ae26977a681a1695d14ea8255564e716916e.svg",width:"148.39999999999998rem",height:"42rem"}),r.createElement("p",null,"This gives us the directional vector we want. We can normalize it to give us uniform directional vectors (having a length of 1.0) at each point, and then do whatever it is we want to do based on those directions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3cb2c4f5806142e83c66e1312520d0783d15201c.svg",width:"263.2rem",height:"26.599999999999998rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/72826b8f5053c299dbb2082678191e3564bb50a6.svg",width:"303.79999999999995rem",height:"60.199999999999996rem"}),r.createElement("p",null,"The tangent is very useful for moving along a line, but what if we want to move away from the curve instead, perpendicular to the curve at some point ",r.createElement("i",null,"t"),'? In that case we want the "normal" vector. This vector runs at a right angle to the direction of the curve, and is typically of length 1.0, so all we have to do is rotate the normalized directional vector and we\'re done:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/6cb29c325e059e236343bdd448c149ecc6d8795f.svg",width:"355.59999999999997rem",height:"62.99999999999999rem"}),r.createElement("div",{className:"note"},r.createElement("p",null,'Rotating coordinates is actually very easy, if you know the rule for it. You might find it explained as "applying a ',r.createElement("a",{href:"https://en.wikipedia.org/wiki/Rotation_matrix"},"rotation matrix"),', which is what we\'ll look at here, too. Essentially, the idea is to take the circles over which we can rotate, and simply "sliding the coordinates" over these circles by the desired angle. If we want a quarter circle turn, we take the coordinate, slide it along the cirle by a quarter turn, and done.'),r.createElement("p",null,"To turn any point ",r.createElement("i",null,"(x,y)")," into a rotated point ",r.createElement("i",null,"(x',y')")," (over 0,0) by some angle φ, we apply this nicely easy computation:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d3932ac925ad9f238029d888dc5432f6678f6491.svg",width:"191.79999999999998rem",height:"39.199999999999996rem"}),r.createElement("p",null,'Which is the "long" version of the following matrix transformation:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7297632eb150a8f5f37178612f71e5d0f2c367b1.svg",width:"221.2rem",height:"42rem"}),r.createElement("p",null,"And that's all we need to rotate any coordinate. Note that for quarter, half and three quarter turns these functions become even easier, since ",r.createElement("em",null,"sin")," and ",r.createElement("em",null,"cos")," for these angles are, respectively: 0 and 1, -1 and 0, and 0 and -1."),r.createElement("p",null,"But ",r.createElement("strong",null,r.createElement("em",null,"why"))," does this work? Why this matrix multiplication? ",r.createElement("a",{href:"http://en.wikipedia.org/wiki/Rotation_matrix#Decomposition_into_shears"},"Wikipedia")," (Technically, Thomas Herter and Klaus Lott) tells us that a rotation matrix can be treated as a sequence of three (elementary) shear operations. When we combine this into a single matrix operation (because all matrix multiplications can be collapsed), we get the matrix that you see above. ",r.createElement("a",{href:"http://datagenetics.com/blog/august32013/index.html"},"DataGenetics")," have an excellent article about this very thing: it's really quite cool, and I strongly recommend taking a quick break from this primer to read that article.")),r.createElement("p",null,"The following two graphics show the tangent and normal along a quadratic and cubic curve, with the direction vector coloured blue, and the normal vector coloured red (the markers are spaced out evenly as ",r.createElement("em",null,"t"),"-intervals, not spaced equidistant)."),r.createElement("div",{className:"figure"},r.createElement(i,{preset:"simple",title:"Quadratic Bézier tangents and normals",inline:!0,setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"simple",title:"Cubic Bézier tangents and normals",inline:!0,setup:e.setupCubic,draw:e.draw})))}},components:{locale:"en-GB",title:"Component functions",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"components",title:"Component functions",number:"14"}),r.createElement("p",null,'One of the first things people run into when they start using Bézier curves in their own programs is "I know how to draw the curve, but how do I determine the bounding box?". It\'s actually reasonably straight forward to do so, but it requires having some knowledge on exploiting math to get the values we need. For bounding boxes, we aren\'t actually interested in the curve itself, but only in its "extremities": the minimum and maximum values the curve has for its x- and y-axis values. If you remember your calculus (provided you ever took calculus, otherwise it\'s going to be hard to remember) we can determine function extremities using the first derivative of that function, but this poses a problem, since our function is parametric: every axis has its own function.'),r.createElement("p",null,"The solution: compute the derivative for each axis separately, and then fit them back together in the same way we do for the original."),r.createElement("p",null,'Let\'s look at how a parametric Bézier curve "splits up" into two normal functions, one for the x-axis and one for the y-axis. Note the left-most figure is again an interactive curve, without labeled axes (you get coordinates in the graph instead). The center and right-most figures are the component functions for computing the x-axis value, given a value for ',r.createElement("i",null,"t")," (between 0 and 1 inclusive), and the y-axis value, respectively."),r.createElement("p",null,"If you move points in a curve sideways, you should only see the middle graph change; likely, moving points vertically should only show a change in the right graph."),r.createElement(i,{preset:"simple",title:"Quadratic Bézier curve components",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"simple",title:"Cubic Bézier curve components",setup:e.setupCubic,draw:e.draw}))}},extremities:{locale:"en-GB",title:"Finding extremities: root finding",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"extremities",title:"Finding extremities: root finding",number:"15"}),r.createElement("p",null,"Now that we understand (well, superficially anyway) the component functions, we can find the extremities of our Bézier curve by finding maxima and minima on the component functions, by solving the equations B'(t) = 0 and B''(t) = 0. Although, in the case of quadratic curves there is no B''(t), so we only need to compute B'(t) = 0. So, how do we compute the first and second derivatives? Fairly easily, actually, until our derivatives are 4th order or higher... then things get really hard. But let's start simple:"),r.createElement("h3",{id:"quadratic-curves-linear-derivatives-"},"Quadratic curves: linear derivatives."),r.createElement("p",null,'Finding the solution for "where is this line 0" should be trivial:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/baa66be2d93813bf9ef4aef1dbfac3db772e30e2.svg",width:"138.6rem",height:"109.19999999999999rem"}),r.createElement("p",null,"Done. And quadratic curves have no meaningful second derivative, so we're ",r.createElement("em",null,"really")," done."),r.createElement("h3",{id:"cubic-curves-the-quadratic-formula-"},"Cubic curves: the quadratic formula."),r.createElement("p",null,"The derivative of a cubic curve is a quadratic curve, and finding the roots for a quadratic Bézier curve means we can apply the ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Quadratic_formula"},"Quadratic formula"),". If you've seen it before, you'll remember it, and if you haven't, it looks like this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d5882cc83b002196c8e701ad273ced103e2b4484.svg",width:"431.2rem",height:"42rem"}),r.createElement("p",null,"So, if we can express a Bézier component function as a plain polynomial, we're done: we just plug in the values into the quadratic formula, check if that square root is negative or not (if it is, there are no roots) and then just compute the two values that come out (because of that plus/minus sign we get two). Any value between 0 and 1 is a root that matters for Bézier curves, anything below or above that is irrelevant (because Bézier curves are only defined over the interval [0,1]). So, how do we convert?"),r.createElement("p",null,"First we turn our cubic Bézier function into a quadratic one, by following the rule mentioned at the end of the ",r.createElement("a",{href:"#derivatives"},"derivatives section"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d38fc2ce8c5af65b94b56897b8ae8d304c84a4b7.svg",width:"561.4rem",height:"37.8rem"}),r.createElement("p",null,"And then, using these ",r.createElement("em",null,"v")," values, we can find out what our ",r.createElement("em",null,"a"),", ",r.createElement("em",null,"b"),", and ",r.createElement("em",null,"c")," should be:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/292b2b9178aca5486da7e1a596e66091ba2ed282.svg",width:"330.4rem",height:"124.6rem"}),r.createElement("p",null,"This gives us thee coefficients ",r.createElement("em",null,"a"),", ",r.createElement("em",null,"b"),", and ",r.createElement("em",null,"c")," that are expressed in terms of ",r.createElement("em",null,"v")," values, where the ",r.createElement("em",null,"v")," values are just convenient expressions of our original ",r.createElement("em",null,"p")," values, so we can do some trivial substitution to get:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/2de779b7b9c6aa130b9aeadbb8c46878b94920a1.svg",width:"323.4rem",height:"65.8rem"}),r.createElement("p",null,"Easy peasy. We can now almost trivially find the roots by plugging those values into the quadratic formula. We also note that the second derivative of a cubic curve means computing the first derivative of a quadratic curve, and we just saw how to do that in the section above."),r.createElement("h3",{id:"quartic-curves-cardano-s-algorithm-"},"Quartic curves: Cardano's algorithm."),r.createElement("p",null,"Quartic—fourth degree—curves have a cubic function as derivative. Now, cubic functions are a bit of a problem because they're really hard to solve. But, way back in the 16",r.createElement("sup",null,"th")," century, ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Gerolamo_Cardano"},"Gerolamo Cardano"),' figured out that even if the general cubic function is really hard to solve, it can be rewritten to a form for which finding the roots is "easy", and then the only hard part is figuring out how to go from that form to the generic form. So:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/a16a0da87e138b1307973397275c296eb475b1b1.svg",width:"478.79999999999995rem",height:"21rem"}),r.createElement("p",null,'This is easier because for the "easier formula" we can use ',r.createElement("a",{href:"http://www.wolframalpha.com/input/?i=t^3+%2B+pt+%2B+q"},"regular calculus")," to find the roots (as a cubic function, however, it can have up to three roots, but two of those can be complex. For the purpose of Bézier curve extremities, we can completely ignore those complex roots, since our ",r.createElement("em",null,"t")," is a plain real number from 0 to 1)."),r.createElement("p",null,"So, the trick is to figure out how to turn the first formula into the second formula, and to then work out the maths that gives us the roots. This is explained in detail over at ",r.createElement("a",{href:"http://www.trans4mind.com/personal_development/mathematics/polynomials/cubicAlgebra.htm"},"Ken J. Ward's page")," for solving the cubic equation, so instead of showing the maths, I'm simply going to show the programming code for solving the cubic equation, with the complex roots getting totally ignored."),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"implementing-cardano-s-algorithm-for-finding-all-real-roots"},"Implementing Cardano's algorithm for finding all real roots"),r.createElement("p",null,'The "real roots" part is fairly important, because while you cannot take a square, cube, etc. root of a negative number in the "real" number space (denoted with ℝ), this is perfectly fine in the ',r.createElement("a",{href:"https://en.wikipedia.org/wiki/Complex_number"},'"complex" number')," space (denoted with ℂ). And, as it so happens, Cardano is also attributed as the first mathematician in history to have made use of complex numbers in his calculations. For this very algorithm!"),r.createElement("pre",null,"// A helper function to filter for values in the [0,1] interval:\nfunction accept(t) {\n return 0<=t && t <=1;\n}\n\n// A real-cuberoots-only function:\nfunction crt(v) {\n if(v<0) return -Math.pow(-v,1/3);\n return Math.pow(v,1/3);\n}\n\n// Now then: given cubic coordinates {pa, pb, pc, pd} find all roots.\nfunction getCubicRoots(pa, pb, pc, pd) {\n var d = (-pa + 3*pb - 3*pc + pd),\n a = (3*pa - 6*pb + 3*pc) / d,\n b = (-3*pa + 3*pb) / d,\n c = pa / d;\n\n var p = (3*b - a*a)/3,\n p3 = p/3,\n q = (2*a*a*a - 9*a*b + 27*c)/27,\n q2 = q/2,\n discriminant = q2*q2 + p3*p3*p3;\n\n // and some variables we're going to use later on:\n var u1,v1,root1,root2,root3;\n\n // three possible real roots:\n if (discriminant < 0) {\n var mp3 = -p/3,\n mp33 = mp3*mp3*mp3,\n r = sqrt( mp33 ),\n t = -q / (2*r),\n cosphi = t<-1 ? -1 : t>1 ? 1 : t,\n phi = acos(cosphi),\n crtr = cuberoot(r),\n t1 = 2*crtr;\n root1 = t1 * cos(phi/3) - a/3;\n root2 = t1 * cos((phi+2*pi)/3) - a/3;\n root3 = t1 * cos((phi+4*pi)/3) - a/3;\n return [root1, root2, root3].filter(accept);\n }\n\n // three real roots, but two of them are equal:\n if(discriminant === 0) {\n u1 = q2 < 0 ? cuberoot(-q2) : -cuberoot(q2);\n root1 = 2*u1 - a/3;\n root2 = -u1 - a/3;\n return [root1, root2].filter(accept);\n }\n\n // one real root, two complex roots\n var sd = sqrt(discriminant);\n u1 = cuberoot(sd - q2);\n v1 = cuberoot(sd + q2);\n root1 = u1 - v1 - a/3;\n return [root1].filter(accept);\n}\n")),r.createElement("p",null,'And that\'s it. The maths is complicated, but the code is pretty much just "follow the maths, while caching as many values as we can to reduce recomputing things as much as possible" and now we have a way to find all roots for a cubic function and can just move on with using that to find extremities of our curves.'),r.createElement("h3",{id:"quintic-and-higher-order-curves-finding-numerical-solutions"},"Quintic and higher order curves: finding numerical solutions"),r.createElement("p",null,"The problem with this is that as the order of the curve goes up, we can't actually solve those equations the normal way. We can't take the function, and then work out what the solutions are. Not to mention that even solving a third order derivative (for a fourth order curve) is already a royal pain in the backside. We need a better solution. We need numerical approaches."),r.createElement("p",null,'That\'s a fancy word for saying "rather than solve the function, treat the problem as a sequence of identical operations, the performing of which gets us closer and closer to the real answer". As it turns out, there is a really nice numerical root finding algorithm, called the ',r.createElement("a",{href:"http://en.wikipedia.org/wiki/Newton-Raphson"},"Newton-Raphson")," root finding method (yes, after ",r.createElement("em",null,r.createElement("a",{href:"https://en.wikipedia.org/wiki/Isaac_Newton"},"that"))," Newton), which we can make use of."),r.createElement("p",null,"The Newton-Raphson approach consists of picking a value ",r.createElement("em",null,"t")," (any will do), and getting the corresponding value at that ",r.createElement("em",null,"t")," value. For normal functions, we can treat that value as a height. If the height is zero, we're done, we have found a root. If it's not, we take the tangent of the curve at that point, and extend it until it passes the x-axis, which will be at some new point ",r.createElement("em",null,"t"),". We then repeat the procedure with this new value, and we keep doing this until we find our root."),r.createElement("p",null,"Mathematically, this means that for some ",r.createElement("em",null,"t"),", at step ",r.createElement("em",null,"n=1"),", we perform the following calculation until ",r.createElement("em",null,"f",r.createElement("sub",null,"y")),"(",r.createElement("em",null,"t"),") is zero, so that the next ",r.createElement("em",null,"t")," is the same as the one we already have:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b563256be7016370365935944308cf878cdbc29c.svg",width:"130.2rem",height:"47.599999999999994rem"}),r.createElement("p",null,"(The wikipedia article has a decent animation for this process, so I'm not adding a sketch for that here unless there are requests for it)"),r.createElement("p",null,"Now, this works well only if we can pick good starting points, and our curve is continuously differentiable and doesn't have oscillations. Glossing over the exact meaning of those terms, the curves we're dealing with conform to those constraints, so as long as we pick good starting points, this will work. So the question is: which starting points do we pick?"),r.createElement("p",null,"As it turns out, Newton-Raphson is so blindingly fast, so we could get away with just not picking: we simply run the algorithm from ",r.createElement("em",null,"t=0")," to ",r.createElement("em",null,"t=1")," at small steps (say, 1/200",r.createElement("sup",null,"th"),") and the result will be all the roots we want. Of course, this may pose problems for high order Bézier curves: 200 steps for a 200",r.createElement("sup",null,"th")," order Bézier curve is going to go wrong, but that's okay: there is no reason, ever, to use Bézier curves of crazy high orders. You might use a fifth order curve to get the \"nicest still remotely workable\" approximation of a full circle with a single Bézier curve, that's pretty much as high as you'll ever need to go."),r.createElement("h3",{id:"in-conclusion-"},"In conclusion:"),r.createElement("p",null,"So now that we know how to do root finding, we can determine the first and second derivative roots for our Bézier curves, and show those roots overlaid on the previous graphics:"),r.createElement(i,{preset:"simple",title:"Quadratic Bézier curve extremities",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"simple",title:"Cubic Bézier curve extremities",setup:e.setupCubic,draw:e.draw}))}},boundingbox:{locale:"en-GB",title:"Bounding boxes",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"boundingbox",title:"Bounding boxes",number:"16"}),r.createElement("p",null,"If we have the extremities, and the start/end points, a simple for loop that tests for min/max values for x and y means we have the four values we need to box in our curve:"),r.createElement("p",null,r.createElement("em",null,"Computing the bounding box for a Bézier curve"),":"),r.createElement("ol",null,r.createElement("li",null,"Find all ",r.createElement("em",null,"t")," value(s) for the curve derivative's x- and y-roots."),r.createElement("li",null,"Discard any ",r.createElement("em",null,"t")," value that's lower than 0 or higher than 1, because Bézier curves only use the interval [0,1]."),r.createElement("li",null,"Determine the lowest and highest value when plugging the values ",r.createElement("em",null,"t=0"),", ",r.createElement("em",null,"t=1")," and each of the found roots into the original functions: the lowest value is the lower bound, and the highest value is the upper bound for the bounding box we want to construct.")),r.createElement("p",null,"Applying this approach to our previous root finding, we get the following bounding boxes (with all curve extremity points shown on the curve):"),r.createElement(i,{preset:"simple",title:"Quadratic Bézier bounding box",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"simple",title:"Cubic Bézier bounding box",setup:e.setupCubic,draw:e.draw}),r.createElement("p",null,"We can construct even nicer boxes by aligning them along our curve, rather than along the x- and y-axis, but in order to do so we first need to look at how aligning works."))}},aligning:{locale:"en-GB",title:"Aligning curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"aligning",title:"Aligning curves",number:"17"}),r.createElement("p",null,'While there are an incredible number of curves we can define by varying the x- and y-coordinates for the control points, not all curves are actually distinct. For instance, if we define a curve, and then rotate it 90 degrees, it\'s still the same curve, and we\'ll find its extremities in the same spots, just at different draw coordinates. As such, one way to make sure we\'re working with a "unique" curve is to "axis-align" it.'),r.createElement("p",null,"Aligning also simplifies a curve's functions. We can translate (move) the curve so that the first point lies on (0,0), which turns our ",r.createElement("em",null,"n")," term polynomial functions into ",r.createElement("em",null,"n-1")," term functions. The order stays the same, but we have less terms. Then, we can rotate the curves so that the last point always lies on the x-axis, too, making its coordinate (...,0). This further simplifies the function for the y-component to an ",r.createElement("em",null,"n-2")," term function. For instance, if we have a cubic curve such as this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d253dc7ff011a8ae46f3351975f1d4beedd7a794.svg",width:"499.79999999999995rem",height:"42rem"}),r.createElement("p",null,"Then translating it so that the first coordinate lies on (0,0), moving all ",r.createElement("em",null,"x")," coordinates by -120, and all ",r.createElement("em",null,"y")," coordinates by -160, gives us:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b3ec747086a146c1b2c682afea6b1eae016c9a7a.svg",width:"482.99999999999994rem",height:"42rem"}),r.createElement("p",null,"If we then rotate the curve so that its end point lies on the x-axis, the coordinates (integer-rounded for illustrative purposes here) become:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/fd82fad845da25b074dff33bbc4aa563d5f367a7.svg",width:"474.59999999999997rem",height:"42rem"}),r.createElement("p",null,"If we drop all the zero-terms, this gives us:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b4d6e220358b2d00f0cf516f433fbe5ecb58f25d.svg",width:"386.4rem",height:"42rem"}),r.createElement("p",null,"We can see that our original curve definition has been simplified considerably. The following graphics illustrate the result of aligning our example curves to the x-axis, with the cubic case using the coordinates that were just used in the example formulae:"),r.createElement(i,{preset:"twopanel",title:"Aligning a quadratic curve",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"twopanel",title:"Aligning a cubic curve",setup:e.setupCubic,draw:e.draw}))}},tightbounds:{locale:"en-GB",title:"Tight boxes",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"tightbounds",title:"Tight boxes",number:"18"}),r.createElement("p",null,'With our knowledge of bounding boxes, and curve alignment, We can now form the "tight" bounding box for curves. We first align our curve, recording the translation we performed, "T", and the rotation angle we used, "R". We then determine the aligned curve\'s normal bounding box. Once we have that, we can map that bounding box back to our original curve by rotating it by -R, and then translating it by -T. We now have nice tight bounding boxes for our curves:'),r.createElement(i,{preset:"twopanel",title:"Aligning a quadratic curve",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"twopanel",title:"Aligning a cubic curve",setup:e.setupCubic,draw:e.draw}),r.createElement("p",null,"These are, strictly speaking, not necessarily the tightest possible bounding boxes. It is possible to compute the optimal bounding box by determining which spanning lines we need to effect a minimal box area, but because of the parametric nature of Bézier curves this is actually a rather costly operation, and the gain in bounding precision is often not worth it. If there is high demand for it, I'll add a section on how to precisely compute the best fit bounding box, but the maths is fairly gruelling and just not really worth spending time on."))}},inflections:{locale:"en-GB",title:"Curve inflections",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"inflections",title:"Curve inflections",number:"19"}),r.createElement("p",null,"Now that we know how to align a curve, there's one more thing we can calculate: inflection points. Imagine we have a variable size circle that we can slide up against our curve. We place it against the curve and adjust its radius so that where it touches the curve, the curvatures of the curve and the circle are the same, and then we start to slide the circle along the curve - for quadratic curves, we can always do this without the circle behaving oddly: we might have to change the radius of the circle as we slide it along, but it'll always sit against the same side of the curve."),r.createElement("p",null,'But what happens with cubic curves? Imagine we have an S curve and we place our circle at the start of the curve, and start sliding it along. For a while we can simply adjust the radius and things will be fine, but once we get to the midpoint of that S, something odd happens: the circle "flips" from one side of the curve to the other side, in order for the curvatures to keep matching. This is called an inflection, and we can find out where those happen relatively easily.'),r.createElement("p",null,"What we need to do is solve a simple equation:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b039194e01b6081628efaf4aa169a4c50fa4aae4.svg",width:"61.599999999999994rem",height:"16.799999999999997rem"}),r.createElement("p",null,"What we're saying here is that given the curvature function ",r.createElement("em",null,"C(t)"),", we want to know for which values of ",r.createElement("em",null,"t"),' this function is zero, meaning there is no "curvature", which will be exactly at the point between our circle being on one side of the curve, and our circle being on the other side of the curve. So what does ',r.createElement("em",null,"C(t)")," look like? Actually something that seems not too hard:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/297d1e13000b19d351e5884a40909652a2ee83e2.svg",width:"404.59999999999997rem",height:"22.4rem"}),r.createElement("p",null,"So the function ",r.createElement("em",null,"C(t)")," is wholly defined by the first and second derivative functions for the parametric dimensions of our curve. And as already shown, derivatives of Bézier curves are just simpler Bézier curves, with very easy to compute new coefficients, so this should be pretty easy."),r.createElement("p",null,"However as we've seen in the section on aligning, aligning lets us simplify things ",r.createElement("em",null,"a lot"),", by completely removing the contributions of the first coordinate from most mathematical evaluations, and removing the last ",r.createElement("em",null,"y")," coordinate as well by virtue of the last point lying on the x-axis. So, while we can evaluate ",r.createElement("em",null,"C(t) = 0")," for our curve, it'll be much easier to first axis-align the curve and ",r.createElement("em",null,"then")," evalutating the curvature function."),r.createElement("div",{ +className:"note"},r.createElement("h3",{id:"let-s-derive-the-full-formula-anyway"},"Let's derive the full formula anyway"),r.createElement("p",null,"Of course, before we do our aligned check, let's see what happens if we compute the curvature function without axis-aligning. We start with the first and second derivatives, given our basis functions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e522d174844a5a31f585cc04cab944a3c4593781.svg",width:"631.4rem",height:"74.19999999999999rem"}),r.createElement("p",null,"And of course the same functions for ",r.createElement("em",null,"y"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/57d857282b8c91da5caf94dcfbe85145dbd760a8.svg",width:"418.59999999999997rem",height:"72.8rem"}),r.createElement("p",null,"Asking a computer to now compose the ",r.createElement("em",null,"C(t)")," function for us (and to expand it to a readable form of simple terms) gives us this rather overly complicated set of arithmetic expressions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e69d797dc67f0bd2d826fcf8c48c22ff5decf23.svg",width:"579.5999999999999rem",height:"102.19999999999999rem"}),r.createElement("p",null,"That is... unwieldy. So, we note that there are a lot of terms that involve multiplications involving x1, y1, and y4, which would all disappear if we axis-align our curve, which is why aligning is a great idea.")),r.createElement("p",null,"Aligning our curve so that three of the eight coefficients become zero, we end up with the following simple term function for ",r.createElement("em",null,"C(t)"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/f61c01094f0de8ca4c7f26a229f0206d54b13930.svg",width:"589.4rem",height:"22.4rem"}),r.createElement("p",null,"That's a lot easier to work with: we see a fair number of terms that we can compute and then cache, giving us the following simplification:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c1e427616a8a2502abf3cf46415971d0df9a273c.svg",width:"534.8rem",height:"77rem"}),r.createElement("p",null,"This is a plain quadratic curve, and we know how to solve ",r.createElement("em",null,"C(t) = 0"),"; we use the quadratic formula:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/368099657b735b0d17becbbe7be915e88e8c04c5.svg",width:"456.4rem",height:"57.4rem"}),r.createElement("p",null,"We can easily compute this value ",r.createElement("em",null,"if")," the descriminator isn't a negative number (because we only want real roots, not complex roots), and ",r.createElement("em",null,"if")," ",r.createElement("em",null,"x")," is not zero, because divisions by zero are rather useless."),r.createElement("p",null,"Taking that into account, we compute ",r.createElement("em",null,"t"),", we disregard any ",r.createElement("em",null,"t")," value that isn't in the Bézier interval [0,1], and we now know at which ",r.createElement("em",null,"t")," value(s) our curve will inflect."),r.createElement(i,{title:"Finding cubic Bézier curve inflections",setup:e.setupCubic,draw:e.draw}))}},canonical:{locale:"en-GB",title:"Canonical form (for cubic curves)",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"canonical",title:"Canonical form (for cubic curves)",number:"20"}),r.createElement("p",null,"While quadratic curves are relatively simple curves to analyze, the same cannot be said of the cubic curve. As a curvature controlled by more than one control points, it exhibits all kinds of features like loops, cusps, odd colinear features, and up to two inflection points because the curvature can change direction up to three times. Now, knowing what kind of curve we're dealing with means that some algorithms can be run more efficiently than if we have to implement them as generic solvers, so is there a way to determine the curve type without lots of work?"),r.createElement("p",null,"As it so happens, the answer is yes and the solution we're going to look at was presented by Maureen C. Stone from Xerox PARC and Tony D. deRose from the University of Washington in their joint paper ",r.createElement("a",{href:"http://graphics.pixar.com/people/derose/publications/CubicClassification/paper.pdf"},'"A Geometric Characterization of Parametric Cubic curves"'),'. It was published in 1989, and defines curves as having a "canonical" form (i.e. a form that all curves can be reduced to) from which we can immediately tell which features a curve will have. So how does it work?'),r.createElement("p",null,'The first observation that makes things work is that if we have a cubic curve with four points, we can apply a linear transformation to these points such that three of the points end up on (0,0), (0,1) and (1,1), with the last point then being "somewhere". After applying that transformation, the location of that last point can then tell us what kind of curve we\'re dealing with. Specifically, we see the following breakdown:'),r.createElement(i,{static:!0,preset:"simple",title:"The canonical curve map",setup:e.setup,draw:e.drawBase}),r.createElement("p",null,"This is a fairly funky image, so let's see how it breaks down. We see the three fixed points at (0,0), (0,1) and (1,1), and then the fourth point is somewhere. Depending on where it is, our curve will have certain features. Namely, if the fourth point is..."),r.createElement("ol",null,r.createElement("li",null,"anywhere on and in the red zone, the curve will be self-intersecting, yielding either a cusp or a loop. Anywhere inside the the red zone, this will be a loop. We won't know ",r.createElement("i",null,"where")," that loop is (in terms of ",r.createElement("i",null,"t")," values), but we are guaranteed that there is one."),r.createElement("li",null,"on the left (red) edge, the curve will have a cusp. We again don't know ",r.createElement("em",null,"where"),", just that it has one. This edge is described by the function:")),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ae5a63e86bb367e6266a394962387344d0a92b10.svg",width:"189rem",height:"39.199999999999996rem"}),r.createElement("ol",null,r.createElement("li",null,"on the lower right (pink) edge, the curve will have a loop at t=1, so we know the end coordinate of the curve also lies ",r.createElement("em",null,"on")," the curve. This edge is described by the function:")),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d389fcde05a773be99f84db5fc9ed7ef043bf406.svg",width:"242.2rem",height:"40.599999999999994rem"}),r.createElement("ol",null,r.createElement("li",null,"on the top (blue) edge, the curve will have a loop at t=0, so we know the start coordinate of the curve also lies ",r.createElement("em",null,"on")," the curve. This edge is described by the function:")),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d97181a9d0ada19862a0ff2cebb08bdee00868d7.svg",width:"161rem",height:"39.199999999999996rem"}),r.createElement("ol",null,r.createElement("li",null,"inside the green zone, the curve will have a single inflection, switching concave/convex once."),r.createElement("li",null,"between the red and green zones, the curve has two inflections, meaning its curvature switches between concave/convex form twice."),r.createElement("li",null,"anywhere on the right of the red zone, the curve will have no inflections. It'll just be a well-behaved arch.")),r.createElement("p",null,"Of course, this map is fairly small, but the regions extend to infinity, with well defined boundaries."),r.createElement("div",{className:"note"},r.createElement("h3",{id:"wait-where-do-those-lines-come-from-"},"Wait, where do those lines come from?"),r.createElement("p",null,'Without repeating the paper mentioned at the top of this section, the loop-boundaries come from rewriting the curve into canonical form, and then solving the formulae for which constraints must hold for which possible curve properties. In the paper these functions yield formulae for where you will find cusp points, or loops where we know t=0 or t=1, but those functions are derived for the full cubic expression, meaning they apply to t=-∞ to t=∞... For Bézier curves we only care about the "clipped interval" t=0 to t=1, so some of the properties that apply when you look at the curve over an infinite interval simply don\'t apply to the Bézier curve interval.'),r.createElement("p",null,'The right bound for the loop region, indicating where the curve switches from "having inflections" to "having a loop", for the general cubic curve, is actually mirrored over x=1, but for Bézier curves this right half doesn\'t apply, so we don\'t need to pay attention to it. Similarly, the boundaries for t=0 and t=1 loops are also nice clean curves but get "cut off" when we only look at what the general curve does over the interval t=0 to t=1.'),r.createElement("p",null,'For the full details, head over to the paper and read through sections 3 and 4. If you still remember your high school precalculus, you can probably follow along with this paper, although you might have to read it a few times before all the bits "click".')),r.createElement("p",null,"So now the question becomes: how do we manipulate our curve so that it fits this canonical form, with three fixed points, and one \"free\" point? Enter linear algerba. Don't worry, I'll be doing all the math for you, as well as show you what the effect is on our curves, but basically we're going to be using linear algebra, rather than calculus, because \"it's way easier\". Sometimes a calculus approach is very hard to work with, when the equivalent geometrical solution is super obvious."),r.createElement("p",null,"The approach is going to start with a curve that doesn't have all-colinear points (so we need to make sure the points don't all fall on a straight line), and then applying four graphics operations that you will probably have heard of: translation (moving all points by some fixed x- and y-distance), scaling (multiplying all points by some x and y scale factor), and shearing (an operation that turns rectangles into parallelograms)."),r.createElement("p",null,"Step 1: we translate any curve by -p1.x and -p1.y, so that the curve starts at (0,0). We're going to make use of an interesting trick here, by pretending our 2D coordinates are 3D, with the ",r.createElement("i",null,"z")," coordinate simply always being 1. This is an old trick in graphics to overcome the limitations of 2D transformations: without it, we can only turn (x,y) coordinates into new coordinates of the form (ax + by, cx + dy), which means we can't do translation, since that requires we end up with some kind of (x + a, y + b). If we add a bogus ",r.createElement("i",null,"z")," coordinate that is always 1, then we can suddenly add arbitrary values. For example:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/00ca2970fccea8f0883af6db4fbc3a60efd2539d.svg",width:"495.59999999999997rem",height:"57.4rem"}),r.createElement("p",null,"Sweet! ",r.createElement("i",null,"z")," stays 1, so we can effectively ignore it entirely, but we added some plain values to our x and y coordinates. So, if we want to subtract p1.x and p1.y, we use:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1a48a27661f19f066ddd591fb4fc0d553b34c944.svg",width:"477.4rem",height:"60.199999999999996rem"}),r.createElement("p",null,"Running all our coordinates through this transformation gives a new set of coordinates, let's call those ",r.createElement("b",null,"U"),", where the first coordinate lies on (0,0), and the rest is still somewhat free. Our next job is to make sure point 2 ends up lying on the ",r.createElement("i",null,"x=0")," line, so what we want is a transformation matrix that, when we run it, subtracts ",r.createElement("i",null,"x")," from whatever ",r.createElement("i",null,"x")," we currently have. This is called ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Shear_matrix"},"shearing"),", and the typical x-shear matrix and its transformation looks like this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/8e98c870c9d5b60bccf196d29e290f9de6657ce7.svg",width:"204.39999999999998rem",height:"56rem"}),r.createElement("p",null,"So we want some shearing value that, when multiplied by ",r.createElement("i",null,"y"),", yields ",r.createElement("i",null,"-x"),", so our x coordinate becomes zero. That value is simpy ",r.createElement("i",null,"-x/y"),", because ",r.createElement("i",null,"-x/y * y = -x"),". Done:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/585fa88864a98008c15225bdbeb0eb26a4653dab.svg",width:"140rem",height:"70rem"}),r.createElement("p",null,"Now, running this on all our points generates a new set of coordinates, let's call those V, which now have point 1 on (0,0) and point 2 on (0, some-value), and we wanted it at (0,1), so we need to ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Scaling_%28geometry%29"},"do some scaling")," to make sure it ends up at (0,1). Additionally, we want point 3 to end up on (1,1), so we can also scale x to make sure its x-coordinate will be 1 after we run the transform. That means we'll be x-scaling by 1/point3",r.createElement("sub",null,"x"),", and y-scaling by point2",r.createElement("sub",null,"y"),". This is really easy:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/bf9c60b59e6247de3fece63638a8333bdcd068a4.svg",width:"144.2rem",height:"74.19999999999999rem"}),r.createElement("p",null,"Then, finally, this generates a new set of coordinates, let's call those W, of which point 1 lies on (0,0), point 2 lies on (0,1), and point three lies on (1, ...) so all that's left is to make sure point 3 ends up at (1,1) - but we can't scale! Point 2 is already in the right place, and y-scaling would move it out of (0,1) again, so our only option is to y-shear point three, just like how we x-sheared point 2 earlier. In this case, we do the same trick, but with ",r.createElement("code",null,"y/x")," rather than ",r.createElement("code",null,"x/y")," because we're not x-shearing but y-shearing. Additionally, we don't actually want to end up at zero (which is what we did before) so we need to shear towards an offset, in this case 1:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/af412fd7df7faf35973314095ec6bf1cb28a8e34.svg",width:"147rem",height:"68.6rem"}),r.createElement("p",null,'And this generates our final set of four coordinates. Of these, we already know that points 1 through 3 are (0,0), (0,1) and (1,1), and only the last coordinate is "free". In fact, given any four starting coordinates, the resulting "transformation mapped" coordinate will be:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/66e084e9ee396b8cc40de3d0df9c4658dcd10e14.svg",width:"477.4rem",height:"95.19999999999999rem"}),r.createElement("p",null,"That looks very complex, but notice that every coordinate value is being offset by the initial translation, and a lot of terms in there repeat: it's pretty easy to calculate this fast, since there's so much we can cache and reuse while we compute this mapped coordinate!"),r.createElement("p",null,"First, let's just do that translation step as a \"preprocessing\" operation so we don't have to subtract the values all the time. What does that leave?"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d2dc58a4a6951ff27e5b83fb9be239e2fbe0f7ce.svg",width:"371rem",height:"61.599999999999994rem"}),r.createElement("p",null,"Suddenly things look a lot simpler: the mapped x is fairly straight forward to compute, and we see that the mapped y actually contains the mapped x in its entirety, so we'll have that part already available when we need to evaluate it. In fact, let's pull out all those common factors to see just how simple this is:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ebaea590e50dfce555e8ad2c63682fe9e6285f06.svg",width:"428.4rem",height:"42rem"}),r.createElement("p",null,"That's kind of super-simple to write out in code, I think you'll agree. Coding math tends to be easier than the formulae initially make it look!"),r.createElement("div",{className:"note"},r.createElement("h3",{id:"how-do-you-track-all-that-"},"How do you track all that?"),r.createElement("p",null,"Doing maths can be a pain, so whenever possible, I like to make computers do the work for me. Especially for things like this, I simply use ",r.createElement("a",{href:"http://www.wolfram.com/mathematica"},"Mathematica"),". Tracking all this math by hand is insane, and we invented computers, literally, to do this for us. I have no reason to use pen and paper when I can write out what I want to do in a program, and have the program do the math for me. And real math, too, with symbols, not with numbers. In fact, ",r.createElement("a",{href:"http://pomax.github.io/gh-weblog/downloads/canonical-curve.nb"},"here's")," the Mathematica notebook if you want to see how this works for yourself."),r.createElement("p",null,"Now, I know, you're thinking \"but Mathematica is super expensive!\" and that's true, it's ",r.createElement("a",{href:"http://www.wolfram.com/mathematica-home-edition"},"$295 for home use"),", but it's ",r.createElement("strong",null,"also")," ",r.createElement("a",{href:"http://www.wolfram.com/raspberry-pi"},"free when you buy a $35 raspberry pi"),". Obviously, I bought a raspberry pi, and I encourage you to do the same. With that, as long as you know what you want to ",r.createElement("em",null,"do"),", Mathematica can just do it for you. And we don't have to be geniusses to work out what the maths looks like. That's what we have computers for.")),r.createElement("p",null,"So, let's write up a sketch that'll show us the canonical form for any curve drawn in blue, overlaid on our canonical map, so that we can immediately tell which features our curve must have, based on where the fourth coordinate is located on the map:"),r.createElement(i,{preset:"simple",title:"A cubic curve mapped to canonical form",setup:e.setup,draw:e.draw}))}},arclength:{locale:"en-GB",title:"Arc length",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"arclength",title:"Arc length",number:"21"}),r.createElement("p",null,"How long is a Bézier curve? As it turns out, that's not actually an easy question, because the answer requires maths that —much like root finding— cannot generally be solved the traditional way. If we have a parametric curve with ",r.createElement("em",null,"f",r.createElement("sub",null,"x"),"(t)")," and ",r.createElement("em",null,"f",r.createElement("sub",null,"y"),"(t)"),", then the length of the curve, measured from start point to some point ",r.createElement("em",null,"t = z"),", is computed using the following seemingly straight forward (if a bit overwhelming) formula:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/16e3f81dfc12c526ca53b477b2aa67ef7b56bfe2.svg",width:"147rem",height:"35rem"}),r.createElement("p",null,"or, more commonly written using Leibnitz notation as:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/8e2857c32b23969bca67b0ead318493a3e61dc4a.svg",width:"257.59999999999997rem",height:"36.4rem"}),r.createElement("p",null,"This formula says that the length of a parametric curve is in fact equal to the ",r.createElement("strong",null,"area")," underneath a function that looks a remarkable amount like Pythagoras' rule for computing the diagonal of a straight angled triangle. This sounds pretty simple, right? Sadly, it's far from simple... cutting straight to after the chase is over: for quadratic curves, this formula generates an ",r.createElement("a",{href:"http://www.wolframalpha.com/input/?i=antiderivative+for+sqrt%28%282*%281-t%29*t*B+%2B+t%5E2*C%29%27%5E2+%2B+%282*%281-t%29*t*E%29%27%5E2%29&incParTime=true"},"unwieldy computation"),", and we're simply not going to implement things that way. For cubic Bézier curves, things get even more fun, because there is no \"closed form\" solution, meaning that due to the way calculus works, there is no generic formula that allows you to calculate the arc length. Let me just repeat this, because it's fairly crucial: ",r.createElement("strong",null,r.createElement("em",null,'for cubic and higher Bézier curves, there is no way to solve this function if you want to use it "for all possible coordinates"')),"."),r.createElement("p",null,"Seriously: ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Abel%E2%80%93Ruffini_theorem"},"It cannot be done"),"."),r.createElement("p",null,"So we turn to numerical approaches again. The method we'll look at here is the ",r.createElement("a",{href:"http://www.youtube.com/watch?v=unWguclP-Ds&feature=BFa&list=PLC8FC40C714F5E60F&index=1"},"Gauss quadrature"),". This approximation is a really neat trick, because for any ",r.createElement("em",null,"n",r.createElement("sup",null,"th"))," degree polynomial it finds approximated values for an integral really efficiently. Explaining this procedure in length is way beyond the scope of this page, so if you're interested in finding out why it works, I can recommend the University of South Florida video lecture on the procedure, linked in this very paragraph. The general solution we're looking for is the following:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e6a8d7d5f1742bb926c0c992d2b89c71090edbf4.svg",width:"576.8rem",height:"74.19999999999999rem"}),r.createElement("p",null,'In plain text: an integral function can always be treated as the sum of an (infinite) number of (infinitely thin) rectangular strips sitting "under" the function\'s plotted graph. To illustrate this idea, the following graph shows the integral for a sinoid function. The more strips we use (and of course the more we use, the thinner they get) the closer we get to the true area under the curve, and thus the better the approximation:'),r.createElement("div",{className:"figure"},r.createElement(i,{inline:!0,static:!0,preset:"empty",title:"A function's approximated integral",setup:e.setup,draw:e.drawCoarseIntegral}),r.createElement(i,{inline:!0,static:!0,preset:"empty",title:"A better approximation",setup:e.setup,draw:e.drawFineIntegral}),r.createElement(i,{inline:!0,static:!0,preset:"empty",title:"An even better approximation",setup:e.setup,draw:e.drawSuperFineIntegral})),r.createElement("p",null,'Now, infinitely many terms to sum and infinitely thin rectangles are not something that computers can work with, so instead we\'re going to approximate the infinite summation by using a sum of a finite number of "just thin" rectangular strips. As long as we use a high enough number of thin enough rectangular strips, this will give us an approximation that is pretty close to what the real value is.'),r.createElement("p",null,"So, the trick is to come up with useful rectangular strips. A naive way is to simply create ",r.createElement("em",null,"n")," strips, all with the same width, but there is a far better way using special values for ",r.createElement("em",null,"C")," and ",r.createElement("em",null,"f(t)")," depending on the value of ",r.createElement("em",null,"n"),", which indicates how many strips we'll use, and it's called the Legendre-Gauss quadrature."),r.createElement("p",null,"This approach uses strips that are ",r.createElement("em",null,"not")," spaced evenly, but instead spaces them in a special way that works remarkably well. If you look at the earlier sinoid graphic, you could imagine that we could probably get a result similar to the one with 99 strips if we used fewer strips, but spaced them so that the steeper the curve is, the thinner we make the strip, and conversely, the flatter the curve is (especially near the tops of the function), the wider we make the strip. That's akin to how the Legendre values work."),r.createElement("div",{className:"note"},r.createElement("p",null,"Note that one requirement for the approach we'll use is that the integral must run from -1 to 1. That's no good, because we're dealing with Bézier curves, and the length of a section of curve applies to values which run from 0 to \"some value smaller than or equal to 1\" (let's call that value ",r.createElement("em",null,"z"),"). Thankfully, we can quite easily transform any integral interval to any other integral interval, by shifting and scaling the inputs. Doing so, we get the following:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/631e6396082d9621472546b87c2e27065990d568.svg",width:"358.4rem",height:"75.6rem"}),r.createElement("p",null,"That may look a bit more complicated, but the fraction involving ",r.createElement("em",null,"z")," is a fixed number, so the summation, and the evaluation of the ",r.createElement("em",null,"f(t)")," values are still pretty simple."),r.createElement("p",null,"So, what do we need to perform this calculation? For one, we'll need an explicit formula for ",r.createElement("em",null,"f(t)"),", because that derivative notation is handy on paper, but not when we have to implement it. We'll also need to know what these ",r.createElement("em",null,"C",r.createElement("sub",null,"i"))," and ",r.createElement("em",null,"t",r.createElement("sub",null,"i"))," values should be. Luckily, that's less work because there are actually many tables available that give these values, for any ",r.createElement("em",null,"n"),", so if we want to approximate our integral with only two terms (which is a bit low, really) then ",r.createElement("a",{href:"legendre-gauss.html"},"these tables")," would tell us that for ",r.createElement("em",null,"n=2")," we must use the following values:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/6dc4299695f03c27c362e7faf47ae4474794809e.svg",width:"65.8rem",height:"98rem"}),r.createElement("p",null,"Which means that in order for us to approximate the integral, we must plug these values into the approximate function, which gives us:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/fe54606651e308caf83a65e53bc4d6104f8a4ee1.svg",width:"499.79999999999995rem",height:"46.199999999999996rem"}),r.createElement("p",null,"We can program that pretty easily, provided we have that ",r.createElement("em",null,"f(t)")," available, which we do, as we know the full description for the Bézier curve functions B",r.createElement("sub",null,"x"),"(t) and B",r.createElement("sub",null,"y"),"(t).")),r.createElement("p",null,"If we use the Legendre-Gauss values for our ",r.createElement("em",null,"C")," values (thickness for each strip) and ",r.createElement("em",null,"t")," values (location of each strip), we can determine the approximate length of a Bézier curve by computing the Legendre-Gauss sum. The following graphic shows a cubic curve, with its computed lengths; Go ahead and change the curve, to see how its length changes. One thing worth trying is to see if you can make a straight line, and see if the length matches what you'd expect. What if you form a line with the control points on the outside, and the start/end points on the inside?"),r.createElement(i,{preset:"simple",title:"Arc length for a Bézier curve",setup:e.setupCurve,draw:e.drawCurve}))}},arclengthapprox:{locale:"en-GB",title:"Approximated arc length",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"arclengthapprox",title:"Approximated arc length",number:"22"}),r.createElement("p",null,"Sometimes, we don't actually need the precision of a true arc length, and we can get away with simply computing the approximate arc length instead. The by far fastest way to do this is to flatten the curve and then simply calculate the linear distance from point to point. This will come with an error, but this can be made arbitrarily small by increasing the segment count."),r.createElement("p",null,"If we combine the work done in the previous sections on curve flattening and arc length computation, we can implement these with minimal effort:"),r.createElement(i,{preset:"twopanel",title:"Approximate quadratic curve arc length",setup:e.setupQuadratic,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement(i,{preset:"twopanel",title:"Approximate cubic curve arc length",setup:e.setupCubic,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"Try clicking on the sketch and using your up and down arrow keys to lower the number of segments for both the quadratic and cubic curve. You may notice that the error in length is actually pretty significant, even if the percentage is fairly low: if the number of segments used yields an error of 0.1% or higher, the flattened curve already looks fairly obviously flattened. And of course, the longer the curve, the more significant the error will be."))}},tracing:{locale:"en-GB",title:"Tracing a curve at fixed distance intervals",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"tracing",title:"Tracing a curve at fixed distance intervals",number:"23"}),r.createElement("p",null,"Say you want to draw a curve with a dashed line, rather than a solid line, or you want to move something along the curve at fixed distance intervals over time, like a train along a track, and you want to use Bézier curves."),r.createElement("p",null,"Now you have a problem."),r.createElement("p",null,"The reason you have a problem is that Bézier curves are parametric functions with non-linear behaviour, whereas moving a train along a track is about as close to a practical example of linear behaviour as you can get. The problem we're faced with is that we can't just pick ",r.createElement("em",null,"t"),' values at some fixed interval and expect the Bézier functions to generate points that are spaced a fixed distance apart. In fact, let\'s look at the relation between "distance long a curve" and "',r.createElement("em",null,"t"),' value", by plotting them against one another.'),r.createElement("p",null,"The following graphic shows a particularly illustrative curve, and it's length-to-t plot. For linear traversal, this line needs to be straight, running from (0,0) to (length,1). This is, it's safe to say, not what we'll see, we'll see something wobbly instead. To make matters even worse, the length-to-",r.createElement("em",null,"t")," function is also of a much higher order than our curve is: while the curve we're using for this exercise is a cubic curve, which can switch concave/convex form once at best, the plot shows that the distance function along the curve is able to switch forms three times (to see this, try creating an S curve with the start/end close together, but the control points far apart)."),r.createElement(i,{preset:"twopanel",title:"The t-for-distance function",setup:e.setup,draw:e.plotOnly}),r.createElement("p",null,"We see a function that might be invertible, but we won't be able to do so, symbolically. You may remember from the section on arc length that we cannot actually compute the true arc length function as an expression of ",r.createElement("em",null,"t"),", which means we also can't compute the true inverted function that gives ",r.createElement("em",null,"t")," as an expression of length. So how do we fix this?"),r.createElement("p",null,"One way is to do what the graphic does: simply run through the curve, determine its ",r.createElement("em",null,"t"),"-for-length values as a set of discrete values at some high resolution (the graphic uses 100 discrete points), and then use those as a basis for finding an appropriate ",r.createElement("em",null,"t")," value, given a distance along the curve. This works quite well, actually, and is fairly fast."),r.createElement("p",null,"We can use some colour to show the difference between distance-based and time based intervals: the following graph is similar to the previous one, except it segments the curve in terms of equal-distance intervals. This shows as regular colour intervals going down the graph, but the mapping to ",r.createElement("em",null,"t")," values is not linear, so there will be (highly) irregular intervals along the horizontal axis. It also shows the curve in an alternating colouring based on the t-for-distance values we find our LUT:"),r.createElement(i,{ +preset:"threepanel",title:"Fixed-interval coloring a curve",setup:e.setup,draw:e.drawColoured,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"Use your up and down arrow keys to increase or decrease the number of equidistant segments used to colour the curve."),r.createElement("p",null,'However, are there better ways? One such way is discussed in "',r.createElement("a",{href:"http://www.geometrictools.com/Documentation/MovingAlongCurveSpecifiedSpeed.pdf"},"Moving Along a Curve with Specified Speed"),"\" by David Eberly of Geometric Tools, LLC, but basically because we have no explicit length function (or rather, one we don't have to constantly compute for different intervals), you may simply be better off with a traditional lookup table (LUT)."))}},intersections:{locale:"en-GB",title:"Intersections",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"intersections",title:"Intersections",number:"24"}),r.createElement("p",null,"Let's look at some more things we will want to do with Bézier curves. Almost immediately after figuring out how to get bounding boxes to work, people tend to run into the problem that even though the minimal bounding box (based on rotation) is tight, it's not sufficient to perform true collision detection. It's a good first step to make sure there ",r.createElement("em",null,"might")," be a collision (if there is no bounding box overlap, there can't be one), but in order to do real collision detection we need to know whether or not there's an intersection on the actual curve."),r.createElement("p",null,"We'll do this in steps, because it's a bit of a journey to get to curve/curve intersection checking. First, let's start simple, by implementing a line-line intersection checker. While we can solve this the traditional calculus way (determine the functions for both lines, then compute the intersection by equating them and solving for two unknowns), linear algebra actually offers a nicer solution."),r.createElement("h3",{id:"line-line-intersections"},"Line-line intersections"),r.createElement("p",null,"if we have two line segments with two coordinates each, segments A-B and C-D, we can find the intersection of the lines these segments are an intervals on by linear algebra, using the procedure outlined in this ",r.createElement("a",{href:"http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=geometry2#line_line_intersection"},"top coder")," article. Of course, we need to make sure that the intersection isn't just on the lines our line segments lie on, but also on our line segments themselves, so after we find the intersection we need to verify it lies without the bounds of our original line segments."),r.createElement("p",null,"The following graphic implements this intersection detection, showing a red point for an intersection on the lines our segments lie on (thus being a virtual intersection point), and a green point for an intersection that lies on both segments (being a real intersection point)."),r.createElement(i,{preset:"simple",title:"Line/line intersections",setup:e.setupLines,draw:e.drawLineIntersection}),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"implementing-line-line-intersections"},"Implementing line-line intersections"),r.createElement("p",null,"Let's have a look at how to implement a line-line intersection checking function. The basics are covered in the article mentioned above, but sometimes you need more function signatures, because you might not want to call your function with eight distinct parameters. Maybe you're using point structs or the line. Let's get coding:"),r.createElement("pre",null,"lli8 = function(x1,y1,x2,y2,x3,y3,x4,y4):\n var nx=(x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4),\n ny=(x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4),\n d=(x1-x2)*(y3-y4)-(y1-y2)*(x3-x4);\n if d=0:\n return false\n return point(nx/d, ny/d)\n\nlli4 = function(p1, p2, p3, p4):\n var x1 = p1.x, y1 = p1.y,\n x2 = p2.x, y2 = p2.y,\n x3 = p3.x, y3 = p3.y,\n x4 = p4.x, y4 = p4.y;\n return lli8(x1,y1,x2,y2,x3,y3,x4,y4)\n\nlli = function(line1, line2):\n return lli4(line1.p1, line1.p2, line2.p1, line2.p2)\n")),r.createElement("h3",{id:"what-about-curve-line-intersections-"},"What about curve-line intersections?"),r.createElement("p",null,"Curve/line intersection is more work, but we've already seen the techniques we need to use in order to perform it: first we translate/rotate both the line and curve together, in such a way that the line coincides with the x-axis. This will position the curve in a way that makes it cross the line at points where its y-function is zero. By doing this, the problem of finding intersections between a curve and a line has now become the problem of performing root finding on our translated/rotated curve, as we already covered in the section on finding extremities."),r.createElement(i,{preset:"simple",title:"Quadratic curve/line intersections",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"simple",title:"Cubic curve/line intersections",setup:e.setupCubic,draw:e.draw}),r.createElement("p",null,"Curve/curve intersection, however, is more complicated. Since we have no straight line to align to, we can't simply align one of the curves and be left with a simple procedure. Instead, we'll need to apply two techniques we've not covered yet: de Casteljau's algorithm, and curve splitting."))}},curveintersection:{locale:"en-GB",title:"Curve/curve intersection",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"curveintersection",title:"Curve/curve intersection",number:"25"}),r.createElement("p",null,'Using de Casteljau\'s algorithm to split the curve we can now implement curve/curve intersection finding using a "divide and conquer" technique:'),r.createElement("ul",null,r.createElement("li",null,"Take two curves ",r.createElement("em",null,"C",r.createElement("sub",null,"1"))," and ",r.createElement("em",null,"C",r.createElement("sub",null,"2")),", and treat them as a pair."),r.createElement("li",null,"If their bounding boxes overlap, split up each curve into two sub-curves"),r.createElement("li",null,"With ",r.createElement("em",null,"C",r.createElement("sub",null,"1.1")),", ",r.createElement("em",null,"C",r.createElement("sub",null,"1.2")),", ",r.createElement("em",null,"C",r.createElement("sub",null,"2.1"))," and ",r.createElement("em",null,"C",r.createElement("sub",null,"2.2")),", form four new pairs (",r.createElement("em",null,"C",r.createElement("sub",null,"1.1")),",",r.createElement("em",null,"C",r.createElement("sub",null,"2.1")),"), (",r.createElement("em",null,"C",r.createElement("sub",null,"1.1")),", ",r.createElement("em",null,"C",r.createElement("sub",null,"2.2")),"), (",r.createElement("em",null,"C",r.createElement("sub",null,"1.2")),",",r.createElement("em",null,"C",r.createElement("sub",null,"2.1")),"), and (",r.createElement("em",null,"C",r.createElement("sub",null,"1.2")),",",r.createElement("em",null,"C",r.createElement("sub",null,"2.2")),")."),r.createElement("li",null,"For each pair, check whether their bounding boxes overlap.",r.createElement("ul",null,r.createElement("li",null,"If their bounding boxes do not overlap, discard the pair, as there is no intersection between this pair of curves."),r.createElement("li",null,"If there ",r.createElement("em",null,"is")," overlap, rerun all steps for this pair."))),r.createElement("li",null,"Once the sub-curves we form are so small that they effectively occupy sub-pixel areas, we consider an intersection found.")),r.createElement("p",null,'This algorithm will start with a single pair, "balloon" until it runs in parallel for a large number of potential sub-pairs, and then taper back down as it homes in on intersection coordinates, ending up with as many pairs as there are intersections.'),r.createElement("p",null,"The following graphic applies this algorithm to a pair of cubic curves, one step at a time, so you can see the algorithm in action. Click the button to run a single step in the algorithm, after setting up your curves in some creative arrangement. The algorithm resets once it's found a solution, so you can try this with lots of different curves (can you find the configuration that yields the maximum number of intersections between two cubic curves? Nine intersections!)"),r.createElement(i,{preset:"clipping",title:"Curve/curve intersections",setup:e.setup,draw:e.draw},"\\t",r.createElement("button",{onClick:e.stepUp},"advance one step")),r.createElement("p",null,"Self-intersection is dealt with in the same way, except we turn a curve into two or more curves first based on the inflection points. We then form all possible curve pairs with the resultant segments, and run exactly the same algorithm. All non-overlapping curve pairs will be removed after the first iteration, and the remaining steps home in on the curve's self-intersection points."))}},abc:{locale:"en-GB",title:"The projection identity",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"abc",title:"The projection identity",number:"26"}),r.createElement("p",null,"De Casteljau's algorithm is the pivotal algorithm when it comes to Bézier curves. You can use it not just to split curves, but also to draw them efficiently (especially for high-order Bézier curves), as well as to come up with curves based on three points and a tangent. Particularly this last thing is really useful because it lets us \"mould\" a curve, by picking it up at some point, and dragging that point around to change the curve's shape."),r.createElement("p",null,"How does that work? Succinctly: we run de Casteljau's algorithm in reverse!"),r.createElement("p",null,"In order to run de Casteljau's algorithm in reverse, we need a few basic things: a start and end point, a point on the curve that want to be moving around, which has an associated ",r.createElement("em",null,"t"),' value, and a point we\'ve not explicitly talked about before, and as far as I know has no explicit name, but lives one iteration higher in the de Casteljau process then our on-curve point does. I like to call it "A" for reasons that will become obvious.'),r.createElement("p",null,'So let\'s use graphics instead of text to see where this "A" is, because text only gets us so far: in the following graphic, click anywhere on the curves to see the identity information that we\'ll be using to run de Casteljau in reverse (you can manipulate the curve even after picking a point. Note the "ratio" value when you do so: does it change?):'),r.createElement("div",{className:"figure"},r.createElement(i,{inline:!0,preset:"abc",title:"Projections in a quadratic Bézier curve",setup:e.setupQuadratic,draw:e.draw,onClick:e.onClick}),r.createElement(i,{inline:!0,preset:"abc",title:"Projections in a cubic Bézier curve",setup:e.setupCubic,draw:e.draw,onClick:e.onClick})),r.createElement("p",null,"Clicking anywhere on the curves shows us three things:"),r.createElement("ol",null,r.createElement("li",null,"our on-curve point; let's call that ",r.createElement("b",null,"B"),","),r.createElement("li",null,"a point at the tip of B's \"hat\", on de Casteljau step up; let's call that ",r.createElement("b",null,"A"),", and"),r.createElement("li",null,"a point that we get by projecting B onto the start--end baseline; let's call that ",r.createElement("b",null,"C"),".")),r.createElement("p",null,"These three values ABC hide an important identity formula for quadratic and cubic Bézier curves: for any point on the curve with some ",r.createElement("em",null,"t")," value, the ratio distance of C along baseline is fixed: if some ",r.createElement("em",null,"t")," value sets up a C that is 20% away from the start and 80% away from the end, then it doesn't matter where the start, end, or control points are: for that ",r.createElement("em",null,"t")," value, C will ",r.createElement("em",null,"always")," lie at 20% from the start and 80% from the end point. Go ahead, pick an on-curve point in either graphic and then move all the other points around: if you only move the control points, start and end won't move, and so neither will C, and if you move either start or end point, C will move but its relative position will not change. The following function stays true:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/f48f095d9c37c079ff6a5f71b3047397aa7dfc6b.svg",width:"207.2rem",height:"16.799999999999997rem"}),r.createElement("p",null,"So that just leaves finding A."),r.createElement("div",{className:"note"},r.createElement("p",null,"While that relation is fixed, the function ",r.createElement("em",null,"u(t)")," differs depending on whether we're working with quadratic or cubic curves:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/cb35e42bf53bfc2b96f959e78256da01f8b91dbc.svg",width:"207.2rem",height:"91rem"}),r.createElement("p",null,"So, if we know the start and end coordinates, and we know the ",r.createElement("em",null,"t")," value, we know C:"),r.createElement("div",{className:"figure"},r.createElement(i,{inline:!0,preset:"abc",title:"Quadratic value of C for t",draw:e.drawQCT,onMouseMove:e.setCT}),r.createElement(i,{inline:!0,preset:"abc",title:"Cubic value of C for t",draw:e.drawCCT,onMouseMove:e.setCT})),r.createElement("p",null,"Mouse-over the graphs to see the expression for C, given the ",r.createElement("em",null,"t")," value at the mouse pointer.")),r.createElement("p",null,"There's also another important bit of information that is inherent to the ABC values: while the distances between A and B, and B and C, are dynamic (based on where we put B), the ",r.createElement("em",null,"ratio")," between the two distances is stable: given some ",r.createElement("em",null,"t")," value, the following always holds:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/6cb3e94fe9164128a25570a32abed15baa726f17.svg",width:"263.2rem",height:"40.599999999999994rem"}),r.createElement("p",null,"This leads to a pretty powerful bit of knowledge: merely by knowing the ",r.createElement("em",null,"t")," value of some on curve point, we know where C has to be (as per the above note), and because we know B and C, and thus have the distance between them, we know where A has to be:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1dffb79b42799c95c899e689b074361f662ec807.svg",width:"228.2rem",height:"39.199999999999996rem"}),r.createElement("p",null,"And that's it, all values found."),r.createElement("div",{className:"note"},r.createElement("p",null,"Much like the ",r.createElement("em",null,"u(t)")," function in the above note, the ",r.createElement("em",null,"ratio(t)")," function depends on whether we're looking at quadratic or cubic curves. Their form is intrinsically related to the ",r.createElement("em",null,"u(t)")," function in that they both come rolling out of the same function evalution, explained over on ",r.createElement("a",{href:"http://mathoverflow.net/questions/122257/finding-the-formula-for-Bézier-curve-ratios-hull-point-point-baseline"},"MathOverflow"),' by Boris Zbarsky and myself. The ratio functions are the "s(t)" functions from the answers there, while the "u(t)" functions have the same name both here and on MathOverflow.'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7ef64890f95db9e48258edb46a3d52d5ed143155.svg",width:"257.59999999999997rem",height:"43.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5f2bb71795c615637d632da70b722938cb103b03.svg",width:"233.79999999999998rem",height:"43.4rem"}),r.createElement("p",null,'Unfortunately, this trick only works for quadratic and cubic curves. Once we hit higher order curves, things become a lot less predictable; the "fixed point ',r.createElement("em",null,"C"),'" is no longer fixed, moving around as we move the control points, and projections of ',r.createElement("em",null,"B")," onto the line between start and end may actually lie on that line before the start, or after the end, and there are no simple ratios that we can exploit.")),r.createElement("p",null,"So: if we know B and its corresponding ",r.createElement("em",null,"t"),' value, then we know all the ABC values, which —together with a start and end coordinate— gives us the necessary information to reconstruct a curve\'s "de Casteljau skeleton", which means that two points and a value between 0 and 1, we can come up with a curve. And that opens up possibilities: curve manipulation by dragging an on-curve point, curve fitting of "a bunch of coordinates", these are useful things, and we\'ll look at both in the next sections.'))}},moulding:{locale:"en-GB",title:"Manipulating a curve",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"moulding",title:"Manipulating a curve",number:"27"}),r.createElement("p",null,'Armed with knowledge of the "ABC" relation, we can now update a curve interactively, by letting people click anywhere on the curve, find the ',r.createElement("em",null,"t"),'-value matching that coordinate, and then letting them drag that point around. With every drag update we\'ll have a new point "B", which we can combine with the fixed point "C" to find our new point A. Once we have those, we can reconstruct the de Casteljau skeleton and thus construct a new curve with the same start/end points as the original curve, passing through the user-selected point B, with correct new control points.'),r.createElement(i,{preset:"moulding",title:"Moulding a quadratic Bézier curve",setup:e.setupQuadratic,draw:e.drawMould,onClick:e.placeMouldPoint,onMouseDown:e.markQB,onMouseDrag:e.dragQB,onMouseUp:e.saveCurve}),r.createElement("p",null,r.createElement("strong",null,"Click-dragging the curve itself")," shows what we're using to compute the new coordinates: while dragging you will see the original points B and its corresponding ",r.createElement("i",null,"t"),"-value, the original point C for that ",r.createElement("i",null,"t"),"-value, as well as the new point B' based on the mouse cursor. Since we know the ",r.createElement("i",null,"t"),"-value for this configuration, we can compute the ABC ratio for this configuration, and we know that our new point A' should like at a distance:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e361e1235c94bbe87e95834c7fcfb6ab96e028b9.svg",width:"226.79999999999998rem",height:"37.8rem"}),r.createElement("p",null,"For quadratic curves, this means we're done, since the new point A' is equivalent to the new quadratic control point. For cubic curves, we need to do a little more work:"),r.createElement(i,{preset:"moulding",title:"Moulding a cubic Bézier curve",setup:e.setupCubic,draw:e.drawMould,onClick:e.placeMouldPoint,onMouseDown:e.markCB,onMouseDrag:e.dragCB,onMouseUp:e.saveCurve}),r.createElement("p",null,"To help understand what's going on, the cubic graphic shows the full de Casteljau construction \"hull\" when repositioning point B. We compute A` in exactly the same way as before, but we also record the final strut line that forms B in the original curve. Given A', B', and the endpoints e1 and e2 of the strut line relative to B', we can now compute where the new control points should be. Remember that B' lies on line e1--e2 at a distance ",r.createElement("i",null,"t"),", because that's how Bézier curves work. In the same manner, we know the distance A--e1 is only line-interval [0,t] of the full segment, and A--e2 is only line-interval [t,1], so constructing the new control points is fairly easy."),r.createElement("p",null,"First, we construct the one-level-of-de-Casteljau-up points:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1833383a4800c495451abcacc2ada34e5601995d.svg",width:"140rem",height:"78.39999999999999rem"}),r.createElement("p",null,"And then we can compute the new control points:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d53cad094fddaacbb047c9d7c465a5011e3bfbfd.svg",width:"163.79999999999998rem",height:"78.39999999999999rem"}),r.createElement("p",null,"And that's cubic curve manipulation."))}},pointcurves:{locale:"en-GB",title:"Creating a curve from three points",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"pointcurves",title:"Creating a curve from three points",number:"28"}),r.createElement("p",null,"Given the preceding section on curve manipulation, we can also generate quadratic and cubic curves from any three points. However, unlike circle-fitting, which requires just three points, Bézier curve fitting requires three points, as well as a ",r.createElement("em",null,"t")," value, so we can figure out where point 'C' needs to be."),r.createElement("p",null,"The following graphic lets you place three points, and will use the preceding sections on the ABC ratio and curve construction to form a quadratic curve through them. You can move the points you've placed around by click-dragging, or try a new curve by drawing new points with pure clicks. (There's some freedom here, so for illustrative purposes we clamped ",r.createElement("em",null,"t")," to simply be 0.5, lets us bypass some maths, since a ",r.createElement("em",null,"t")," value of 0.5 always puts C in the middle of the start--end line segment)"),r.createElement(i,{preset:"generate",title:"Fitting a quadratic Bézier curve",setup:e.setup,draw:e.drawQuadratic,onClick:e.onClick}),r.createElement("p",null,'For cubic curves we also need some values to construct the "de Casteljau line through B" with, and that gives us quite a bit of choice. Since we\'ve clamped ',r.createElement("em",null,"t"),' to 0.5, we\'ll set up a line through B parallel to the line start--end, with a length that is proportional to the length of the line B--C: the further away from the baseline B is, the wider its construction line will be, and so the more "bulby" the curve will look. This still gives us some freedom in terms of exactly how to scale the length of the construction line as we move B closer or further away from the baseline, so I simply picked some values that sort-of-kind-of look right in that if a circle through (start,B,end) forms a perfect hemisphere, the cubic curve constructed forms something close to a hemisphere, too, and if the points lie on a line, then the curve constructed has the control points very close to B, while still lying between B and the correct curve end point:'),r.createElement(i,{preset:"generate",title:"Fitting a cubic Bézier curve",setup:e.setup,draw:e.drawCubic,onClick:e.onClick}),r.createElement("p",null,'In each graphic, the blue parts are the values that we "just have" simply by setting up our three points, combined with our decision on which ',r.createElement("em",null,"t")," value to use (and construction line orientation and length for cubic curves). There are of course many ways to determine a combination of ",r.createElement("em",null,"t"),' and tangent values that lead to a more "æsthetic" curve, but this will be left as an exercise to the reader, since there are many, and æsthetics are often quite personal.'))}},catmullconv:{locale:"en-GB",title:"Bézier curves and Catmull-Rom curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"catmullconv",title:"Bézier curves and Catmull-Rom curves",number:"29"}),r.createElement("p",null,"Taking an excursion to different splines, the other common design curve is the ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull.E2.80.93Rom_spline"},"Catmull-Rom spline"),". Now, a Catmull-Rom spline is a form of cubic Hermite spline, and as it so happens the cubic Bézier curve is also a cubic Hermite spline, so maybe... maybe we can convert one into the other, and back, with some simple substitutions?"),r.createElement("p",null,'Unlike Bézier curves, Catmull-Rom splines pass through each point used to define the curve, except the first and last, which makes sense if you read the "natural language" descriptionfor how a Catmull-Rom spline works: a Catmull-Rom spline is a curve that, at each point P',r.createElement("sub",null,"x"),", has a tangent along the line P",r.createElement("sub",null,"x-1")," to P",r.createElement("sub",null,"x+1"),". The curve runs from points P",r.createElement("sub",null,"2")," to P",r.createElement("sub",null,"n-1"),', and has a "tension" that determines how fast the curve passes through each point. The lower the tension, the faster the curve goes through each point, and the bigger its local tangent is.'),r.createElement("p",null,"I'll be showing the conversion to and from Catmull-Rom curves for the tension that the Processing language uses for its Catmull-Rom algorithm."),r.createElement("p",null,"We start with showing the Catmull-Rom matrix form:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5fc1c44e623f2a9fbeefdaa204557479e3debf5a.svg",width:"429.79999999999995rem",height:"78.39999999999999rem"}),r.createElement("p",null,"However, there's something funny going on here: the coordinate column matrix looks weird. The reason is that Catmull-Rom curves are actually curve segments that are described by two points, and two tangents; the curve leaves a point V1 (if we have four coordinates instead, this is coordinate 2), arriving at a point V2 (coordinate 3), with the curve departing V1 with a tangent vector V'1 (equal to the tangent from coordinate 1 to coordinate 3) and arriving at V2 with tangent vector V'2 (equal to the tangent from coordinate 2 to coordinate 4). So if we want to express this as a matrix form based on four coordinates, we get this representation instead:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/40b9ca9b5755a4be49517ddfa630fef7b8e23067.svg",width:"406rem",height:"86.8rem"}),r.createElement("div",{className:"note"},r.createElement("h2",{id:"where-did-that-2-come-from-"},"Where did that 2 come from?"),r.createElement("p",null,"Catmull-Rom splines are based on the concept of tension: the higher the tensions, the shorter the tangents at the departure and arrival points. The basic Catmull-Rom curve arrives and departs with tangents equal to half the distance between the two adjacent points, so that's where that 2 came from."),r.createElement("p",null,'However, the "real" matrix is this:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7bf9b5e971866babedd991ccdde5c4ab104297e5.svg",width:"351.4rem",height:"88.19999999999999rem"}),r.createElement("p",null,"This bakes in the tension factor τ explicitly.")),r.createElement("p",null,'Plugging this into the "two coordinates and two tangent vectors" matrix form, we get:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/4818f8797c35f23c2b9883aa986b1129b2fa151a.svg",width:"299.59999999999997rem",height:"78.39999999999999rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/08f77989369f664cbc0fb7526791efd4c5299d70.svg",width:"499.79999999999995rem",height:"77rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c7ae769c5370469b16523bab6f34abf0dd6749be.svg",width:"414.4rem",height:"77rem"}),r.createElement("p",null,"So let's find out which transformation matrix we need in order to convert from Catmull-Rom to Bézier:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7250f1c57e2bd66ec4349e4e88db4d5d74401a06.svg",width:"730.8rem",height:"77rem"}),r.createElement("p",null,"The difference is somewhere in the actual hermite matrix, since the ",r.createElement("em",null,"t")," and coordinate values are identical, so let's solve that matrix equasion:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/8a42b24fca3aaf6b8ec08e84b7e91c43e26e8acf.svg",width:"418.59999999999997rem",height:"75.6rem"}),r.createElement("p",null,"We left-multiply both sides by the inverse of the Bézier matrix, to get rid of the Bézier matrix on the right side of the equals sign:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e111d6e846f4d7204dec484005f74993e66c6c9.svg",width:"841.4rem",height:"84rem"}),r.createElement("p",null,"Which gives us:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/f94b80113772d90a4fbc93d4495cb5767e5c8123.svg",width:"183.39999999999998rem",height:"75.6rem"}),r.createElement("p",null,"Multiplying this ",r.createElement("strong",null,r.createElement("em",null,"A"))," with our coordinates will give us a proper Bézier matrix expression again:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d088274e440ceeac2916a0f32176682d776c1c57.svg",width:"448rem",height:"77rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/9e68f80b270d3445d9f9cb28ff2c5aed219aa9d2.svg",width:"365.4rem",height:"85.39999999999999rem"}),r.createElement("p",null,"So a Catmull-Rom to Bézier conversion, based on coordinates, requires turning the Catmull-Rom coordinates on the left into the Bézier coordinates on the right (with τ being our tension factor):"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/92a34d777899da97f1907e6b093db28872f02c3a.svg",width:"261.8rem",height:"89.6rem"}),r.createElement("p",null,"And the other way around, a Bézier to Catmull-Rom conversion requires turning the Bézier coordinates on the left this time into the Catmull-Rom coordinates on the right. Note that there is no tension this time, because Bézier curves don't have any. Converting from Bézier to Catmull-Rom is simply a default-tension Catmull-Rom curve:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ee3d3d219a18596dc403c0392d44bc585d738e6c.svg",width:"309.4rem",height:"81.19999999999999rem"}),r.createElement("p",null,"Done. We can now draw the curves we want using either Bézier curves or Catmull-Rom splines, the choice mostly being which drawing algorithms we have natively available."))}},catmullmoulding:{locale:"en-GB",title:"Creating a Catmull-Rom curve from three points",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"catmullmoulding",title:"Creating a Catmull-Rom curve from three points",number:"30"}),r.createElement("p",null,"Now, we saw how to fit a Bézier curve to three points, but if Catmull-Rom curves go through points, why can't we just use those to do curve fitting, instead?"),r.createElement("p",null,"As a matter of fact, we can, but there's a difference between the kind of curve fitting we did in the previous section, and the kind of curve fitting that we can do with Catmull-Rom curves. In the previous section we came up with a single curve that goes through three points. There was a decent amount of maths and computation involved, and the end result was three or four coordinates that described a single curve, depending on whether we were fitting a quadratic or cubic curve."),r.createElement("p",null,"Using Catmull-Rom curves, we need virtually no computation, but even though we end up with one Catmull-Rom curve of ",r.createElement("i",null,"n")," points, in order to draw the equivalent curve using cubic Bézier curves we need a massive ",r.createElement("i",null,"3n-2")," points (and that's without double-counting points that are shared by consecutive cubic curves)."),r.createElement("p",null,'In the following graphic, on the left we see three points that we want to draw a Catmull-Rom curve through (which we can move around freely, by the way), with in the second panel some of the "interesting" Catmull-Rom information: in black there\'s the baseline start--end, which will act as tangent orientation for the curve at point p2. We also see a virtual point p0 and p4, which are initially just point p2 reflected over the baseline. However, by using the up and down cursor key we can offset these points parallel to the baseline. Why would we want to do this? Because the line p0--p2 acts as departure tangent at p1, and the line p2--p4 acts as arrival tangent at p3. Play around with the graphic a bit to get an idea of what all of that meant:'),r.createElement(i,{ +preset:"threepanel",title:"Catmull-Rom curve fitting",setup:e.setup,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"As should be obvious by now, Catmull-Rom curves are great for \"fitting a curvature to some points\", but if we want to convert that curve to Bézier form we're going to end up with a lot of separate (but visually joined) Bézier curves. Depending on what we want to do, that'll be either unnecessary work, or exactly what we want: which it is depends entirely on you."))}},polybezier:{locale:"en-GB",title:"Forming poly-Bézier curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"polybezier",title:"Forming poly-Bézier curves",number:"31"}),r.createElement("p",null,"Much like lines can be chained together to form polygons, Bézier curves can be chained together to form poly-Béziers, and the only trick required is to make sure that:"),r.createElement("ol",null,r.createElement("li",null,"the end point of each section is the starting point of the following section, and"),r.createElement("li",null,"the derivatives across that dual point line up.")),r.createElement("p",null,"Unless, of course, you want discontinuities; then you don't even need 2."),r.createElement("p",null,"We'll cover three forms of poly-Bézier curves in this section. First, we'll look at the kind that just follows point 1. where the end point of a segment is the same point as the start point of the next segment. This leads to poly-Béziers that are pretty hard to work with, but they're the easiest to implement:"),r.createElement(i,{preset:"poly",title:"Unlinked quadratic poly-Bézier",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"poly",title:"Unlinked cubic poly-Bézier",setup:e.setupCubic,draw:e.draw}),r.createElement("p",null,'Dragging the control points around only affects the curve segments that the control point belongs to, and moving an on-curve point leaves the control points where they are, which is not the most useful for practical modelling purposes. So, let\'s add in the logic we need to make things a little better. We\'ll start by linking up control points by ensuring that the "incoming" derivative at an on-curve point is the same as it\'s "outgoing" derivative:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/37740bb1a0b7b1ff48bf3454e52295fc717cacbb.svg",width:"130.2rem",height:"18.2rem"}),r.createElement("p",null,"We can effect this quite easily, because we know that the vector from a curve's last control point to its last on-curve point is equal to the derivative vector. If we want to ensure that the first control point of the next curve matches that, all we have to do is mirror that last control point through the last on-curve point. And mirroring any point A through any point B is really simple:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ce6e3939608c4ed0598107b06543c2301b91bb7f.svg",width:"319.2rem",height:"42rem"}),r.createElement("p",null,"So let's implement that and see what it gets us. The following two graphics show a quadratic and a cubic poly-Bézier curve again, but this time moving the control points around moves others, too. However, you might see something unexpected going on for quadratic curves..."),r.createElement(i,{preset:"poly",title:"Loosely connected quadratic poly-Bézier",setup:e.setupQuadratic,draw:e.draw,onMouseMove:e.linkDerivatives}),r.createElement(i,{preset:"poly",title:"Loosely connected cubic poly-Bézier",setup:e.setupCubic,draw:e.draw,onMouseMove:e.linkDerivatives}),r.createElement("p",null,"As you can see, quadratic curves are particularly ill-suited for poly-Bézier curves, as all the control points are effectively linked. Move one of them, and you move all of them. Not only that, but if we move the on-curve points, it's possible to get a situation where a control point's positions is different depending on whether it's the reflection of its left or right neighbouring control point: we can't even form a proper rule-conforming curve! This means that we cannot use quadratic poly-Béziers for anything other than really, really simple shapes. And even then, they're probably the wrong choice. Cubic curves are pretty decent, but the fact that the derivatives are linked means we can't manipulate curves as well as we might if we relaxed the constraints a little."),r.createElement("p",null,"So: let's relax the requirement a little."),r.createElement("p",null,"We can change the constraint so that we still preserve the ",r.createElement("em",null,"angle")," of the derivatives across sections (so transitions from one section to the next will still look natural), but give up the requirement that they should also have the same ",r.createElement("em",null,"vector length"),". Doing so will give us a much more useful kind of poly-Bézier curve:"),r.createElement(i,{preset:"poly",title:"Loosely connected quadratic poly-Bézier",setup:e.setupQuadratic,draw:e.draw,onMouseMove:e.linkDirection}),r.createElement(i,{preset:"poly",title:"Loosely connected cubic poly-Bézier",setup:e.setupCubic,draw:e.draw,onMouseMove:e.linkDirection}),r.createElement("p",null,"Cubic curves are now better behaved when it comes to dragging control points around, but the quadratic poly-Bézier still has the problem that moving one control points will move the control points and may ending up defining \"the next\" control point in a way that doesn't work. Quadratic curves really aren't very useful to work with..."),r.createElement("p",null,"Finally, we also want to make sure that moving the on-curve coordinates preserves the relative positions of the associated control points. With that, we get to the kind of curve control that you might be familiar with from applications like Photoshop, Inkscape, Blender, etc."),r.createElement(i,{preset:"poly",title:"Loosely connected quadratic poly-Bézier",setup:e.setupQuadratic,draw:e.draw,onMouseDown:e.bufferPoints,onMouseMove:e.modelCurve}),r.createElement(i,{preset:"poly",title:"Loosely connected cubic poly-Bézier",setup:e.setupCubic,draw:e.draw,onMouseDown:e.bufferPoints,onMouseMove:e.modelCurve}),r.createElement("p",null,'Again, we see that cubic curves are now rather nice to work with, but quadratic curves have a new, very serious problem: we can move an on-curve point in such a way that we can\'t compute what needs to "happen next". Move the top point down, below the left and right points, for instance. There is no way to preserve correct control points without a kink at the bottom point. Quadratic curves: just not that good...'),r.createElement("p",null,'A final improvement is to offer fine-level control over which points behave which, so that you can have "kinks" or individually controlled segments when you need them, with nicely well-behaved curves for the rest of the path. Implementing that, is left as an excercise for the reader.'))}},shapes:{locale:"en-GB",title:"Boolean shape operations",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"shapes",title:"Boolean shape operations",number:"32"}),r.createElement("p",null,"We can apply the topics covered so far in this primer to effect boolean shape operations: getting the union, intersection, or exclusion, between two or more shapes that involve Bézier curves. For simplicity (well.. sort of, more homogeneity), we'll be looking at Poly-Bézier shapes only, but a shape that consists of a mix of lines and Bézier curves is technically a simplification (although it does mean we need to write a definition for the class of shapes that mix lines and Bézier curves. Since poly-Bézier curves are a superset, we'll be using those in the following examples)"),r.createElement("p",null,"The procedure for performing boolean operations consists, broadly, of four steps:"),r.createElement("ol",null,r.createElement("li",null,"Find the intersection points between both shapes,"),r.createElement("li",null,"cut up the shapes into multiple sections between these intersections,"),r.createElement("li",null,"discard any section that isn't part of the desired operation's resultant shape, and"),r.createElement("li",null,"link up the remaining sections to form the new shape.")),r.createElement("p",null,"Finding all intersections between two poly-Bézier curves, or any poly-line-section shape, is similar to the iterative algorithm discussed in the section on curve/curve intersection. For each segment in the poly-Bézier curve we check whether its bounding box overlaps with any of the segment bounding boxes in the other poly-Bézier curve. If so, we run normal intersection detection."),r.createElement("p",null,"After we found all intersection points, we split up our poly-Bézier curves, making sure to record which of the newly formed poly-Bézier curves might potentially link up at the points we split the originals up at. This will let us quickly glue poly-Bézier curves back together after the next step."),r.createElement("p",null,"Once we have all the new poly-Bézier curves, we run the first step of the desired boolean operation."),r.createElement("ul",null,r.createElement("li",null,'Union: discard all poly-Bézier curves that lie "inside" our union of our shapes. E.g. if we want the union of two overlapping circles, the resulting shape is the outline.'),r.createElement("li",null,'Intersection: discard all poly-Bézier curves that lie "outside" the intersection of the two shapes. E.g. if we want the intersection of two overlapping circles, the resulting shape is the tapered ellipse where they overlap.'),r.createElement("li",null,"Exclusion: none of the sections are discarded, but we will need to link the shapes back up in a special way. Flip any section that would qualify for removal under UNION rules.")),r.createElement("table",{className:"sketch"},r.createElement("tbody",null,r.createElement("tr",null,r.createElement("td",{className:"labeled-image"},r.createElement("img",{src:"images/op_base.gif",height:"169px"}),"Two overlapping shapes."),r.createElement("td",{className:"labeled-image"},r.createElement("img",{src:"images/op_union.gif",height:"169px"}),"The unified region."),r.createElement("td",{className:"labeled-image"},r.createElement("img",{src:"images/op_intersection.gif",height:"169px"}),"Their intersection."),r.createElement("td",{className:"labeled-image"},r.createElement("img",{src:"images/op_exclusion.gif",height:"169px"}),"Their exclusion regions.")))),r.createElement("p",null,'The main complication in the outlined procedure here is determining how sections qualify in terms of being "inside" and "outside" of our shapes. For this, we need to be able to perform point-in-shape detection, for which we\'ll use a classic algorithm: getting the "crossing number" by using ray casting, and then testing for "insidedness" by applying the ',r.createElement("a",{href:"http://folk.uio.no/bjornw/doc/bifrost-ref/bifrost-ref-12.html"},"even-odd rule"),': For any point and any shape, we can cast a ray from our point, to some point that we know lies outside of the shape (such as a corner of our drawing surface). We then count how many times that line crosses our shape (remember that we can perform line/curve intersection detection quite easily). If the number of times it crosses the shape\'s outline is even, the point did not actually lie inside our shape. If the number of intersections is odd, our point did lie inside out shape. With that knowledge, we can decide whether to treat a section that such a point lies on "needs removal" (under union rules), "needs preserving" (under intersection rules), or "needs flipping" (under exclusion rules).'),r.createElement("p",null,"These operations are expensive, and implementing your own code for this is generally a bad idea if there is already a geometry package available for your language of choice. In this case, for JavaScript the most excellent ",r.createElement("a",{href:"http://paperjs.org"},"Paper.js")," already comes with all the code in place to perform efficient boolean shape operations, so rather that implement an inferior version here, I can strongly recommend the Paper.js library if you intend to do any boolean shape work."),r.createElement("p",null,"The following graphic shows Paper.js doing its thing for two shapes: one static, and one that is linked to your mouse pointer. If you move the mouse around, you'll see how the shape intersections are resolved. The base shapes are outlined in blue, and the boolean result is coloured red."),r.createElement(i,{preset:"simple",title:"Boolean shape operations with Paper.js",paperjs:!0,setup:e.setup,draw:e.draw,onMouseMove:e.onMouseMove},r.createElement("br",null),e.modes.map(function(t){var n=e.state.mode===t?"selected":null;return r.createElement("button",{className:n,key:t,onClick:function(){return e.setMode(t)}},t)})))}},projections:{locale:"en-GB",title:"Projecting a point onto a Bézier curve",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"projections",title:"Projecting a point onto a Bézier curve",number:"33"}),r.createElement("p",null,"Say we have a Bézier curve and some point, not on the curve, of which we want to know which ",r.createElement("code",null,"t")," value on the curve gives us an on-curve point closest to our off-curve point. Or: say we want to find the projection of a random point onto a curve. How do we do that?"),r.createElement("p",null,"If the Bézier curve is of low enough order, we might be able to ",r.createElement("a",{href:"http://jazzros.blogspot.ca/2011/03/projecting-point-on-bezier-curve.html"},"work out the maths for how to do this"),", and get a perfect ",r.createElement("code",null,"t")," value back, but in general this is an incredibly hard problem and the easiest solution is, really, a numerical approach again. We'll be finding our ideal ",r.createElement("code",null,"t")," value using a ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Binary_search_algorithm"},"binary search"),". First, we do a coarse distance-check based on ",r.createElement("code",null,"t"),' values associated with the curve\'s "to draw" coordinates (using a lookup table, or LUT). This is pretty fast. Then we run this algorithm:'),r.createElement("ol",null,r.createElement("li",null,"with the ",r.createElement("code",null,"t")," value we found, start with some small interval around ",r.createElement("code",null,"t")," (1/length_of_LUT on either side is a reasonable start),"),r.createElement("li",null,"if the distance to ",r.createElement("code",null,"t ± interval/2")," is larger than the distance to ",r.createElement("code",null,"t"),", try again with the interval reduced to half its original length."),r.createElement("li",null,"if the distance to ",r.createElement("code",null,"t ± interval/2")," is smaller than the distance to ",r.createElement("code",null,"t"),", replace ",r.createElement("code",null,"t")," with the smaller-distance value."),r.createElement("li",null,"after reducing the interval, or changing ",r.createElement("code",null,"t"),", go back to step 1.")),r.createElement("p",null,"We keep repeating this process until the interval is small enough to claim the difference in precision found is irrelevant for the purpose we're trying to find ",r.createElement("code",null,"t")," for. In this case, I'm arbitrarily fixing it at 0.0001."),r.createElement("p",null,'The following graphic demonstrates the result of this procedure.Simply move the cursor around, and if it does not lie on top of the curve, you will see a line that projects the cursor onto the curve based on an iteratively found "ideal" ',r.createElement("code",null,"t")," value."),r.createElement(i,{preset:"simple",title:"Projecting a point onto a Bézier curve",setup:e.setup,draw:e.draw,onMouseMove:e.onMouseMove}))}},offsetting:{locale:"en-GB",title:"Curve offsetting",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"offsetting",title:"Curve offsetting",number:"34"}),r.createElement("p",null,"Perhaps you are like me, and you've been writing various small programs that use Bézier curves in some way or another, and at some point you make the step to implementing path extrusion. But you don't want to do it pixel based, you want to stay in the vector world. You find that extruding lines is relatively easy, and tracing outlines is coming along nicely (although junction caps and fillets are a bit of a hassle), and then decide to do things properly and add Bézier curves to the mix. Now you have a problem."),r.createElement("p",null,"Unlike lines, you can't simply extrude a Bézier curve by taking a copy and moving it around, because of the curvatures; rather than a uniform thickness you get an extrusion that looks too thin in places, if you're lucky, but more likely will self-intersect. The trick, then, is to scale the curve, rather than simply copying it. But how do you scale a Bézier curve?"),r.createElement("p",null,"Bottom line: ",r.createElement("strong",null,"you can't"),". So you cheat. We're not going to do true curve scaling, or rather curve offsetting, because that's impossible. Instead we're going to try to generate 'looks good enough' offset curves."),r.createElement("div",{className:"note"},r.createElement("h3",{id:"-what-do-you-mean-you-can-t-prove-it-"},'"What do you mean, you can\'t. Prove it."'),r.createElement("p",null,'First off, when I say "you can\'t" what I really mean is "you can\'t offset a Bézier curve with another Bézier curve". not even by using a really high order curve. You can find the function that describes the offset curve, but it won\'t be a polynomial, and as such it cannot be represented as a Bézier curve, which ',r.createElement("strong",null,"has")," to be a polynomial. Let's look at why this is:"),r.createElement("p",null,"From a mathematical point of view, an offset curve ",r.createElement("code",null,"O(t)")," is a curve such that, given our original curve ",r.createElement("code",null,"B(t)"),", any point on ",r.createElement("code",null,"O(t)")," is a fixed distance ",r.createElement("code",null,"d")," away from coordinate ",r.createElement("code",null,"B(t)"),". So let's math that:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3aff5cef0028337bbb48ae64ad30000c4d5e238f.svg",width:"113.39999999999999rem",height:"16.799999999999997rem"}),r.createElement("p",null,"However, we're working in 2D, and ",r.createElement("code",null,"d")," is a single value, so we want to turn it into a vector. If we want a point distance ",r.createElement("code",null,"d"),' "away" from the curve ',r.createElement("code",null,"B(t)")," then what we really mean is that we want a point at ",r.createElement("code",null,"d"),' times the "normal vector" from point ',r.createElement("code",null,"B(t)"),', where the "normal" is a vector that runs perpendicular ("at a right angle") to the tangent at ',r.createElement("code",null,"B(t)"),". Easy enough:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/2cf48e2f8525258a3fa0fe4f10ec2acef67104b3.svg",width:"158.2rem",height:"16.799999999999997rem"}),r.createElement("p",null,"Now this still isn't very useful unless we know what the formula for ",r.createElement("code",null,"N(t)")," is, so let's find out. ",r.createElement("code",null,"N(t)")," runs perpendicular to the original curve tangent, and we know that the tangent is simply ",r.createElement("code",null,"B'(t)"),", so we could just rotate that 90 degrees and be done with it. However, we need to ensure that ",r.createElement("code",null,"N(t)")," has the same magnitude for every ",r.createElement("code",null,"t"),", or the offset curve won't be at a uniform distance, thus not being an offset curve at all. The easiest way to guarantee this is to make sure ",r.createElement("code",null,"N(t)")," always has length 1, which we can achieve by dividing ",r.createElement("code",null,"B'(t)")," by its magnitude:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/4941ecbff4c50732ba66fec53307456fc605f032.svg",width:"125.99999999999999rem",height:"42rem"}),r.createElement("p",null,"Determining the length requires computing an arc length, and this is where things get Tricky with a capital T. First off, to compute arc length from some start ",r.createElement("code",null,"a")," to end ",r.createElement("code",null,"b"),', we must use the formula we saw earlier. Noting that "length" is usually denoted with double vertical bars:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/f6d8c2965b02363e092acb00bbc1398cfbb170a4.svg",width:"177.79999999999998rem",height:"37.8rem"}),r.createElement("p",null,"So if we want the length of the tangent, we plug in ",r.createElement("code",null,"B'(t)"),", with ",r.createElement("code",null,"t = 0")," as start and",r.createElement("code",null,"t = 1")," as end:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1f024282044316a9e4b3de2c855d2ceb96aff056.svg",width:"219.79999999999998rem",height:"37.8rem"}),r.createElement("p",null,"And that's where things go wrong. It doesn't even really matter what the second derivative for ",r.createElement("code",null,"B(t)")," is, that square root is screwing everything up, because it turns our nice polynomials into things that are no longer polynomials."),r.createElement("p",null,"There is a small class of polynomials where the square root is also a polynomial, but they're utterly useless to us: any polynomial with unweighted binomial coefficients has a square root that is also a polynomial. Now, you might think that Bézier curves are just fine because they do, but they don't; remember that only the ",r.createElement("strong",null,"base")," function has binomial coefficients. That's before we factor in our coordinates, which turn it into a non-binomial polygon. The only way to make sure the functions stay binomial is to make all our coordinates have the same value. And that's not a curve, that's a point. We can already create offset curves for points, we call them circles, and they have much simpler functions than Bézier curves."),r.createElement("p",null,"So, since the tangent length isn't a polynomial, the normalised tangent won't be a polynomial either, which means ",r.createElement("code",null,"N(t)")," won't be a polynomial, which means that ",r.createElement("code",null,"d")," times ",r.createElement("code",null,"N(t)")," won't be a polynomial, which means that, ultimately, ",r.createElement("code",null,"O(t)")," won't be a polynomial, which means that even if we can determine the function for ",r.createElement("code",null,"O(t)")," just fine (and that's far from trivial!), it simply cannot be represented as a Bézier curve."),r.createElement("p",null,"And that's one reason why Bézier curves are tricky: there are actually a ",r.createElement("code",null,"lot")," of curves that cannot be represent as a Bézier curve at all. They can't even model their own offset curves. They're weird that way. So how do all those other programs do it? Well, much like we're about to do, they cheat. We're going to approximate an offset curve in a way that will look relatively close to what the real offset curve would look like, if we could compute it.")),r.createElement("p",null,'So, you cannot offset a Bézier curve perfectly with another Bézier curve, no matter how high-order you make that other Bézier curve. However, we can chop up a curve into "safe" sub-curves (where safe means that all the control points are always on a single side of the baseline, and the midpoint of the curve at ',r.createElement("code",null,"t=0.5")," is roughly in the centre of the polygon defined by the curve coordinates) and then point-scale each sub-curve with respect to its scaling origin (which is the intersection of the point normals at the start and end points)."),r.createElement("p",null,"A good way to do this reduction is to first find the curve's extreme points, as explained in the earlier section on curve extremities, and use these as initial splitting points. After this initial split, we can check each individual segment to see if it's \"safe enough\" based on where the center of the curve is. If the on-curve point for ",r.createElement("code",null,"t=0.5")," is too far off from the center, we simply split the segment down the middle. Generally this is more than enough to end up with safe segments."),r.createElement("p",null,"The following graphics show off curve offsetting, and you can use your up and down arrow keys to control the distance at which the curve gets offset. The curve first gets reduced to safe segments, each of which is then offset at the desired distance. Especially for simple curves, particularly easily set up for quadratic curves, no reduction is necessary, but the more twisty the curve gets, the more the curve needs to be reduced in order to get segments that can safely be scaled."),r.createElement(i,{preset:"simple",title:"Offsetting a quadratic Bézier curve",setup:e.setupQuadratic,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement(i,{preset:"simple",title:"Offsetting a cubic Bézier curve",setup:e.setupCubic,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"You may notice that this may still lead to small 'jumps' in the sub-curves when moving the curve around. This is caused by the fact that we're still performing a naive form of offsetting, moving the control points the same distance as the start and end points. If the curve is large enough, this may still lead to incorrect offsets."))}},graduatedoffset:{locale:"en-GB",title:"Graduated curve offsetting",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"graduatedoffset",title:"Graduated curve offsetting",number:"35"}),r.createElement("p",null,"What if we want to do graduated offsetting, starting at some distance ",r.createElement("code",null,"s")," but ending at some other distance ",r.createElement("code",null,"e"),'? well, if we can compute the length of a curve (which we can if we use the Legendre-Gauss quadrature approach) then we can also determine how far "along the line" any point on the curve is. With that knowledge, we can offset a curve so that its offset curve is not uniformly wide, but graduated between with two different offset widths at the start and end.'),r.createElement("p",null,'Like normal offsetting we cut up our curve in sub-curves, and then check at which distance along the original curve each sub-curve starts and ends, as well as to which point on the curve each of the control points map. This gives us the distance-along-the-curve for each interesting point in the sub-curve. If we call the total length of all sub-curves seen prior to seeing "the current" sub-curve ',r.createElement("code",null,"S")," (and if the current sub-curve is the first one, ",r.createElement("code",null,"S")," is zero), and we call the full length of our original curve ",r.createElement("code",null,"L"),", then we get the following graduation values:"),r.createElement("ul",null,r.createElement("li",null,"start: map ",r.createElement("code",null,"S")," from interval (",r.createElement("code",null,"0,L"),") to interval ",r.createElement("code",null,"(s,e)")),r.createElement("li",null,"c1: ",r.createElement("code",null,"map(<strong>S+d1</strong>, 0,L, s,e)"),", d1 = distance along curve to projection of c1"),r.createElement("li",null,"c2: ",r.createElement("code",null,"map(<strong>S+d2</strong>, 0,L, s,e)"),", d2 = distance along curve to projection of c2"),r.createElement("li",null,"..."),r.createElement("li",null,"end: ",r.createElement("code",null,"map(<strong>S+length(subcurve)</strong>, 0,L, s,e)"))),r.createElement("p",null,"At each of the relevant points (start, end, and the projections of the control points onto the curve) we know the curve's normal, so offsetting is simply a matter of taking our original point, and moving it along the normal vector by the offset distance for each point. Doing so will give us the following result (these have with a starting width of 0, and an end width of 40 pixels, but can be controlled with your up and down arrow keys):"),r.createElement(i,{preset:"simple",title:"Offsetting a quadratic Bézier curve",setup:e.setupQuadratic,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement(i,{preset:"simple",title:"Offsetting a cubic Bézier curve",setup:e.setupCubic,draw:e.draw,onKeyDown:e.props.onKeyDown}))}},circles:{locale:"en-GB",title:"Circles and quadratic Bézier curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"circles",title:"Circles and quadratic Bézier curves",number:"36"}),r.createElement("p",null,"Circles and Bézier curves are very different beasts, and circles are infinitely easier to work with than Bézier curves. Their formula is much simpler, and they can be drawn more efficiently. But, sometimes you don't have the luxury of using circles, or ellipses, or arcs. Sometimes, all you have are Bézier curves. For instance, if you're doing font design, fonts have no concept of geometric shapes, they only know straight lines, and Bézier curves. OpenType fonts with TrueType outlines only know quadratic Bézier curves, and OpenType fonts with Type 2 outlines only know cubic Bézier curves. So how do you draw a circle, or an ellipse, or an arc?"),r.createElement("p",null,"You approximate."),r.createElement("p",null,"We already know that Bézier curves cannot model all curves that we can think of, and this includes perfect circles, as well as ellipses, and their arc counterparts. However, we can certainly approximate them to a degree that is visually acceptable. Quadratic and cubic curves offer us different curvature control, so in order to approximate a circle we will first need to figure out what the error is if we try to approximate arcs of increasing degree with quadratic and cubic curves, and where the coordinates even lie."),r.createElement("p",null,"Since arcs are mid-point-symmetrical, we need the control points to set up a symmetrical curve. For quadratic curves this means that the control point will be somewhere on a line that intersects the baseline at a right angle. And we don't get any choice on where that will be, since the derivatives at the start and end point have to line up, so our control point will lie at the intersection of the tangents at the start and end point."),r.createElement("p",null,"First, let's try to fit the quadratic curve onto a circular arc. In the following sketch you can move the mouse around over a unit circle, to see how well, or poorly, a quadratic curve can approximate the arc from (1,0) to where your mouse cursor is:"),r.createElement(i,{preset:"arcfitting",title:"Quadratic Bézier arc approximation",setup:e.setup,draw:e.draw,onMouseMove:e.onMouseMove}),r.createElement("p",null,"As you can see, things go horribly wrong quite quickly; even trying to approximate a quarter circle using a quadratic curve is a bad idea. An eighth of a turns might look okay, but how okay is okay? Let's apply some maths and find out. What we're interested in is how far off our on-curve coordinates are with respect to a circular arc, given a specific start and end angle. We'll be looking at how much space there is between the circular arc, and the quadratic curve's midpoint."),r.createElement("p",null,"We start out with our start and end point, and for convenience we will place them on a unit circle (a circle around 0,0 with radius 1), at some angle ",r.createElement("em",null,"φ"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ef34ab8f466ed3294895135a346b55ada05d779d.svg",width:"183.39999999999998rem",height:"42rem"}),r.createElement("p",null,"What we want to find is the intersection of the tangents, so we want a point C such that:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5660e8512b07dbac7fcf04633de8002fa25aa962.svg",width:"298.2rem",height:"42rem"}),r.createElement("p",null,"i.e. we want a point that lies on the vertical line through S (at some distance ",r.createElement("em",null,"a")," from S) and also lies on the tangent line through E (at some distance ",r.createElement("em",null,"b")," from E). Solving this gives us:"),r.createElement("img",{ +className:"LaTeX SVG",src:"images/latex/d16e7a1c1e9686e1afb82f4ffcec07078d264565.svg",width:"229.6rem",height:"42rem"}),r.createElement("p",null,"First we solve for ",r.createElement("em",null,"b"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3128b31a874166ebe4479d3002d70f280de375a1.svg",width:"588rem",height:"18.2rem"}),r.createElement("p",null,"which yields:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/02b158f9ef2191b970dc2fe69c0903eba2b1f8b5.svg",width:"106.39999999999999rem",height:"40.599999999999994rem"}),r.createElement("p",null,"which we can then substitute in the expression for ",r.createElement("em",null,"a"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3bd9c2d6740ff530aabcbe60252742032af816e9.svg",width:"242.2rem",height:"204.39999999999998rem"}),r.createElement("p",null,"A quick check shows that plugging these values for ",r.createElement("em",null,"a")," and ",r.createElement("em",null,"b")," into the expressions for C",r.createElement("sub",null,"x")," and C",r.createElement("sub",null,"y"),' give the same x/y coordinates for both "',r.createElement("em",null,"a"),' away from A" and "',r.createElement("em",null,"b")," away from B\", so let's continue: now that we know the coordinate values for C, we know where our on-curve point T for ",r.createElement("em",null,"t=0.5")," (or angle φ/2) is, because we can just evaluate the Bézier polynomial, and we know where the circle arc's actual point P is for angle φ/2:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b80423188012451e0400f473c19729eb2bad654.svg",width:"197.39999999999998rem",height:"33.599999999999994rem"}),r.createElement("p",null,"We compute T, observing that if ",r.createElement("em",null,"t=0.5"),", the polynomial values (1-t)², 2(1-t)t, and t² are 0.25, 0.5, and 0.25 respectively:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/bc50559ff8bd9062694a449aae5f6f85f91de909.svg",width:"264.59999999999997rem",height:"36.4rem"}),r.createElement("p",null,"Which, worked out for the x and y components, gives:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c7fca7664a3acb855eeaaf412aa2331202f41097.svg",width:"428.4rem",height:"81.19999999999999rem"}),r.createElement("p",null,"And the distance between these two is the standard Euclidean distance:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3251cd91a1cffc27a1695ece4c13cc651d7007fb.svg",width:"418.59999999999997rem",height:"161rem"}),r.createElement("p",null,"So, what does this distance function look like when we plot it for a number of ranges for the angle φ, such as a half circle, quarter circle and eighth circle?"),r.createElement("table",null,r.createElement("tbody",null,r.createElement("tr",null,r.createElement("td",null,r.createElement("img",{src:"images/arc-q-pi.gif",height:"190px"}),"plotted for 0 ≤ φ ≤ π:"),r.createElement("td",null,r.createElement("img",{src:"images/arc-q-pi2.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ ½π:"),r.createElement("td",null,e.props.showhref?"http://www.wolframalpha.com/input/?i=plot+sqrt%28%281%2F4+*+%28sin%28x%29+%2B+2tan%28x%2F2%29%29+-+sin%28x%2F2%29%29%5E2+%2B+%282sin%5E4%28x%2F4%29%29%5E2%29+for+0+%3C%3D+x+%3C%3D+pi%2F4":null,r.createElement("img",{src:"images/arc-q-pi4.gif",height:"174px"}),"plotted for 0 ≤ φ ≤ ¼π:")))),r.createElement("p",null,"We now see why the eighth circle arc looks decent, but the quarter circle arc doesn't: an error of roughly 0.06 at ",r.createElement("em",null,"t=0.5")," means we're 6% off the mark... we will already be off by one pixel on a circle with pixel radius 17. Any decent sized quarter circle arc, say with radius 100px, will be way off if approximated by a quadratic curve! For the eighth circle arc, however, the error is only roughly 0.003, or 0.3%, which explains why it looks so close to the actual eighth circle arc. In fact, if we want a truly tiny error, like 0.001, we'll have to contend with an angle of (rounded) 0.593667, which equates to roughly 34 degrees. We'd need 11 quadratic curves to form a full circle with that precision! (technically, 10 and ten seventeenth, but we can't do partial curves, so we have to round up). That's a whole lot of curves just to get a shape that can be drawn using a simple function!"),r.createElement("p",null,"In fact, let's flip the function around, so that if we plug in the precision error, labelled ε, we get back the maximum angle for that precision:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/61a938fa10b77e8c41c3c064ed39bd1145d6bbcc.svg",width:"259rem",height:"56rem"}),r.createElement("p",null,"And frankly, things are starting to look a bit ridiculous at this point, we're doing way more maths than we've ever done, but thankfully this is as far as we need the maths to take us: If we plug in the precisions 0.1, 0.01, 0.001 and 0.0001 we get the radians values 1.748, 1.038, 0.594 and 0.3356; in degrees, that means we can cover roughly 100 degrees (requiring four curves), 59.5 degrees (requiring six curves), 34 degrees (requiring 11 curves), and 19.2 degrees (requiring a whopping nineteen curves)."),r.createElement("p",null,"The bottom line? ",r.createElement("strong",null,"Quadratic curves are kind of lousy")," if you want circular (or elliptical, which are circles that have been squashed in one dimension) curves. We can do better, even if it's just by raising the order of our curve once. So let's try the same thing for cubic curves."))}},circles_cubic:{locale:"en-GB",title:"Circles and cubic Bézier curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"circles_cubic",title:"Circles and cubic Bézier curves",number:"37"}),r.createElement("p",null,"In the previous section we tried to approximate a circular arc with a quadratic curve, and it mostly made us unhappy. Cubic curves are much better suited to this task, so what do we need to do?"),r.createElement("p",null,'For cubic curves, we basically want the curve to pass through three points on the circle: the start point, the mid point at "angle/2", and the end point at "angle". We then also need to make sure the control points are such that the start and end tangent lines line up with the circle\'s tangent lines at the start and end point.'),r.createElement("p",null,'The first thing we can do is "guess" what the curve should look like, based on the previously outlined curve-through-three-points procedure. This will give use a curve with correct start, mid and end points, but possibly incorrect derivatives at the start and end, because the control points might not be in the right spot. We can then slide the control points along the lines that connect them to their respective end point, until they effect the corrected derivative at the start and end points. However, if you look back at the section on fitting curves through three points, the rules used were such that they optimized for a near perfect hemisphere, so using the same guess won\'t be all that useful: guessing the solution based on knowing the solution is not really guessing.'),r.createElement("p",null,'So have a graphical look at a "bad" guess versus the true fit, where we\'ll be using the bad guess and the description in the second paragraph to derive the maths for the true fit:'),r.createElement(i,{preset:"arcfitting",title:"Cubic Bézier arc approximation",setup:e.setup,draw:e.draw,onMouseMove:e.onMouseMove}),r.createElement("p",null,'We see two curves here; in blue, our "guessed" curve and its control points, and in grey/black, the true curve fit, with proper control points that were shifted in, along line between our guessed control points, such that the derivatives at the start and end points are correct.'),r.createElement("p",null,'We can already seethat cubic curves are a lot better than quadratic curves, and don\'t look all that wrong until we go well past a quarter circle; ⅜th starts to hint at problems, and half a circle has an obvious "gap" between the real circle and the cubic approximation. Anything past that just looks plain ridiculous... but quarter curves actually look pretty okay!'),r.createElement("p",null,'So, maths time again: how okay is "okay"? Let\'s apply some more maths to find out.'),r.createElement("p",null,"Unlike for the quadratic curve, we can't use ",r.createElement("i",null,"t=0.5")," as our reference point because by its very nature it's one of the three points that are actually guaranteed to lie on the circular curve. Instead, we need a different ",r.createElement("i",null,"t")," value. If we run some analysis on the curve we find that the actual ",r.createElement("i",null,"t"),' value at which the curve is furthest from what it should be is 0.211325 (rounded), but we don\'t know "why", since finding this value involves root-finding, and is nearly impossible to do symbolically without pages and pages of math just to express one of the possible solutions.'),r.createElement("p",null,"So instead of walking you through the derivation for that value, let's simply take that ",r.createElement("i",null,"t")," value and see what the error is for circular arcs with an angle ranging from 0 to 2π:"),r.createElement("table",null,r.createElement("tbody",null,r.createElement("tr",null,r.createElement("td",null,r.createElement("img",{src:"images/arc-c-2pi.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ 2π:"),r.createElement("td",null,r.createElement("img",{src:"images/arc-c-pi.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ π:"),r.createElement("td",null,r.createElement("img",{src:"images/arc-c-pi2.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ ½π:")))),r.createElement("p",null,"We see that cubic Bézier curves are much better when it comes to approximating circular arcs, with an error of less than 0.027 at the two \"bulge\" points for a quarter circle (which had an error of 0.06 for quadratic curves at the mid point), and an error near 0.001 for an eighth of a circle, so we're getting less than half the error for a quarter circle, or: at a slightly lower error, we're getting twice the arc. This makes cubic curves quite useful!"),r.createElement("p",null,'In fact, the precision of a cubic curve at a quarter circle is considered "good enough" by so many people that it\'s generally considered "just fine" to use four cubic Bézier curves to fake a full circle when no circle primitives are available; generally, people won\'t notice that it\'s not a real circle unless you also happen to overlay an actual circle, so that the difference becomes obvious.'),r.createElement("p",null,'So with the error analysis out of the way, how do we actually compute the coordinates needed to get that "true fit" cubic curve? The first observation is that we already know the start and end points, because they\'re the same as for the quadratic attempt:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ef34ab8f466ed3294895135a346b55ada05d779d.svg",width:"183.39999999999998rem",height:"42rem"}),r.createElement("p",null,"But we now need to find two control points, rather than one. If we want the derivatives at the start and end point to match the circle, then the first control point can only lie somewhere on the vertical line through S, and the second control point can only lie somewhere on the line tangent to point E, which means:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/4df65dae78bc5a0e6c5f23a2faae9a9d7a8b39b3.svg",width:"118.99999999999999rem",height:"42rem"}),r.createElement("p",null,'where "a" is some scaling factor, and:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/cb32f8f9c3ae2b264a48003c237a798d02dc8935.svg",width:"170.79999999999998rem",height:"42rem"}),r.createElement("p",null,'where "b" is also some scaling factor.'),r.createElement("p",null,"Starting with this information, we slowly maths our way to success, but I won't lie: the maths for this is pretty trig-heavy, and it's easy to get lost if you remember (or know!) some of the core trigonoetric identities, so if you just want to see the final result just skip past the next section!"),r.createElement("div",{className:"note"},r.createElement("h2",{id:"let-s-do-this-thing-"},"Let's do this thing."),r.createElement("p",null,"Unlike for the quadratic case, we need some more information in order to compute ",r.createElement("i",null,"a")," and ",r.createElement("i",null,"b"),", since they're no longer dependent variables. First, we observe that the curve is symmetrical, so whatever values we end up finding for C",r.createElement("sub",null,"1")," will apply to C",r.createElement("sub",null,"2")," as well (rotated along its tangent), so we'll focus on finding the location of C",r.createElement("sub",null,"1")," only. So here's where we do something that you might not expect: we're going to ignore for a moment, because we're going to have a much easier time if we just solve this problem with geometry first, then move to calculus to solve a much simpler problem."),r.createElement("p",null,"If we look at the triangle that is formed between our starting point, or initial guess C",r.createElement("sub",null,"1")," and our real C",r.createElement("sub",null,"1"),", there's something funny going on: if we treat the line ","{","start,guess","}"," as our opposite side, the line ","{","guess,real","}"," as our adjacent side, with ","{","start,real","}"," our hypothenuse, then the angle for the corner hypothenuse/adjacent is half that of the arc we're covering. Try it: if you place the end point at a quarter circle (pi/2, or 90 degrees), the angle in our triangle is half a quarter (pi/4, or 45 degrees). With that knowledge, and a knowledge of what the length of any of our lines segments are (as a function), we can determine where our control points are, and thus have everything we need to find the error distance function. Of the three lines, the one we can easiest determine is ","{","start,guess","}",", so let's find out what the guessed control point is. Again geometrically, because we have the benefit of an on-curve ",r.createElement("i",null,"t=0.5")," value."),r.createElement("p",null,"The distance from our guessed point to the start point is exactly the same as the projection distance we looked at earlier. Using ",r.createElement("i",null,"t=0.5"),' as our point "B" in the "A,B,C" projection, then we know the length of the line segment ',"{","C,A","}",", since it's d",r.createElement("sub",null,"1")," = ","{","A,B","}"," + d",r.createElement("sub",null,"2")," = ","{","B,C","}",":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b15a274c1e0a6aeeaf517b5d2c8ee0a7997dd617.svg",width:"417.2rem",height:"42rem"}),r.createElement("p",null,"So that just leaves us to find the distance from ",r.createElement("i",null,"t=0.5")," to the baseline for an arbitrary angle φ, which is the distance from the centre of the circle to our ",r.createElement("i",null,"t=0.5")," point, minus the distance from the centre to the line that runs from start point to end point. The first is the same as the point P we found for the quadratic curve:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b80423188012451e0400f473c19729eb2bad654.svg",width:"197.39999999999998rem",height:"33.599999999999994rem"}),r.createElement("p",null,"And the distance from the origin to the line start/end is another application of angles, since the triangle ","{","origin,start,C","}"," has known angles, and two known sides. We can find the length of the line ","{","origin,C","}",", which lets us trivially compute the coordinate for C:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/9be55fb38d5d30bbc6c7140afb1c7bc097bc044e.svg",width:"274.4rem",height:"70rem"}),r.createElement("p",null,"With the coordinate C, and knowledge of coordinate B, we can determine coordinate A, and get a vector that is identical to the vector ","{","start,guess","}",":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/262f2eca63105779f30a0a5445cf76f60786039a.svg",width:"417.2rem",height:"50.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e83ebbac13a84ef6036bf4be57b3d1b6cb316f8.svg",width:"221.2rem",height:"49rem"}),r.createElement("p",null,"Which means we can now determine the distance ","{","start,guessed","}",", which is the same as the distance ","{","C,A","}",", and use that to determine the vertical distance from our start point to our C",r.createElement("sub",null,"1"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c87e454fb11ef7f15c7386e83ca1ce41a004d8a7.svg",width:"264.59999999999997rem",height:"58.8rem"}),r.createElement("p",null,"And after this tedious detour to find the coordinate for C",r.createElement("sub",null,"1"),", we can find C",r.createElement("sub",null,"2")," fairly simply, since it's lies at distance -C",r.createElement("sub",null,"1y")," along the end point's tangent:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/25f027074b6af8ca7b640e27636e3bf89c28afdb.svg",width:"550.1999999999999rem",height:"82.6rem"}),r.createElement("p",null,"And that's it, we have all four points now for an approximation of an arbitrary circular arc with angle φ.")),r.createElement("p",null,"So, to recap, given an angle φ, the new control coordinates are:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c4d82e44d1c67dda8ba26aa6da0f406d05eba618.svg",width:"215.6rem",height:"42rem"}),r.createElement("p",null,"and"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3a4b1ee00eebb7697e5513ef9df673928913252e.svg",width:"337.4rem",height:"42rem"}),r.createElement("p",null,'And, because the "quarter curve" special case comes up so incredibly often, let\'s look at what these new control points mean for the curve coordinates of a quarter curve, by simply filling in φ = π/2:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/63e0936b4849d4cdbb9a2e0909181259be951e4d.svg",width:"432.59999999999997rem",height:"35rem"}),r.createElement("p",null,"Which, in decimal values, rounded to six significant digits, is:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/fd12e65204a31319b66355c6ff99e6b3d9603b05.svg",width:"432.59999999999997rem",height:"16.799999999999997rem"}),r.createElement("p",null,"Of course, this is for a circle with radius 1, so if you have a different radius circle, simply multiply the coordinate by the radius you need. And then finally, forming a full curve is now a simple a matter of mirroring these coordinates about the origin:"),r.createElement(i,{preset:"simple",title:"Cubic Bézier circle approximation",draw:e.drawCircle,static:!0}))}},arcapproximation:{locale:"en-GB",title:"Approximating Bézier curves with circular arcs",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"arcapproximation",title:"Approximating Bézier curves with circular arcs",number:"38"}),r.createElement("p",null,"Let's look at doing the exact opposite of the previous section: rather than approximating circular arc using Bézier curves, let's approximate Bézier curves using circular arcs."),r.createElement("p",null,"We already saw in the section on circle approximation that this will never yield a perfect equivalent, but sometimes you need circular arcs, such as when you're working with fabrication machinery, or simple vector languages that understand lines and circles, but not much else."),r.createElement("p",null,'The approach is fairly simple: pick a starting point on the curve, and pick two points that are further along the curve. Determine the circle that goes through those three points, and see if it fits the part of the curve we\'re trying to approximate. Decent fit? Try spacing the points further apart. Bad fit? Try spacing the points closer together. Keep doing this until you\'ve found the "good approximation/bad approximation" boundary, record the "good" arc, and then move the starting point up to overlap the end point we previously found. Rinse and repeat until we\'ve covered the entire curve.'),r.createElement("p",null,"So: step 1, how do we find a circle through three points? That part is actually really simple. You may remember (if you ever learned it!) that a line between two points on a circle is called a ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Chord_%28geometry%29"},"chord"),", and one property of chords is that the line from the center of any chord, perpendicular to that chord, passes through the center of the circle."),r.createElement("p",null,"So: if we have have three points, we have three (different) chords, and consequently, three (different) lines that go from those chords through the center of the circle. So we find the centers of the chords, find the perpendicular lines, find the intersection of those lines, and thus find the center of the circle."),r.createElement("p",null,"The following graphic shows this procedure with a different colour for each chord and its associated perpendicular through the center. You can move the points around as much as you like, those lines will always meet!"),r.createElement(i,{preset:"simple",title:"Finding a circle through three points",setup:e.setupCircle,draw:e.drawCircle}),r.createElement("p",null,"So, with the procedure on how to find a circle through three points, finding the arc through those points is straight-forward: pick one of the three points as start point, pick another as an end point, and the arc has to necessarily go from the start point, over the remaining point, to the end point."),r.createElement("p",null,"So how can we convert a Bezier curve into a (sequence of) circular arc(s)?"),r.createElement("ul",null,r.createElement("li",null,"Start at ",r.createElement("em",null,"t=0")),r.createElement("li",null,"Pick two points further down the curve at some value ",r.createElement("em",null,"m = t + n")," and ",r.createElement("em",null,"e = t + 2n")),r.createElement("li",null,"Find the arc that these points define"),r.createElement("li",null,"Determine how close the found arc is to the curve:",r.createElement("ul",null,r.createElement("li",null,"Pick two additional points ",r.createElement("em",null,"e1 = t + n/2")," and ",r.createElement("em",null,"e2 = t + n + n/2"),"."),r.createElement("li",null,"These points, if the arc is a good approximation of the curve interval chosen, should lie ",r.createElement("em",null,"on")," the circle, so their distance to the center of the circle should be the same as the distance from any of the three other points to the center."),r.createElement("li",null,"For point points, determine the (absolute) error between the radius of the circle, and the",r.createElement("em",null,"actual")," distance from the center of the circle to the point on the curve."),r.createElement("li",null,"If this error is too high, we consider the arc bad, and try a smaller interval.")))),r.createElement("p",null,"The result of this is shown in the next graphic: we start at a guaranteed failure: s=0, e=1. That's the entire curve. The midpoint is simply at ",r.createElement("em",null,"t=0.5"),", and then we start performing a ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Binary_search_algorithm"},"Binary Search"),"."),r.createElement("ol",null,r.createElement("li",null,"We start with ",1),r.createElement("li",null,"That'll fail, so we retry with the interval halved: ",.5,r.createElement("ul",null,r.createElement("li",null,"If that arc's good, we move back up by half distance: ",.75,"."),r.createElement("li",null,"However, if the arc was still bad, we move ",r.createElement("em",null,"down")," by half the distance: ",.25,"."))),r.createElement("li",null,"We keep doing this over and over until we have two arcs found in sequence of which the first arc is good, and the second arc is bad. When we find that pair, we've found the boundary between a good approximation and a bad approximation, and we pick the former.")),r.createElement("p",null,"The following graphic shows the result of this approach, with a default error threshold of 0.5, meaning that if an arc is off by a ",r.createElement("em",null,"combined")," half pixel over both verification points, then we treat the arc as bad. This is an extremely simple error policy, but already works really well. Note that the graphic is still interactive, and you can use your up and down arrow keys keys to increase or decrease the error threshold, to see what the effect of a smaller or larger error threshold is."),r.createElement(i,{preset:"simple",title:"Arc approximation of a Bézier curve",setup:e.setupCubic,draw:e.drawSingleArc,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"With that in place, all that's left now is to \"restart\" the procedure by treating the found arc's end point as the new to-be-determined arc's starting point, and using points further down the curve. We keep trying this until the found end point is for ",r.createElement("em",null,"t=1"),", at which point we are done. Again, the following graphic allows for up and down arrow key input to increase or decrease the error threshold, so you can see how picking a different threshold changes the number of arcs that are necessary to reasonably approximate a curve:"),r.createElement(i,{preset:"simple",title:"Arc approximation of a Bézier curve",setup:e.setupCubic,draw:e.drawArcs,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,'So... what is this good for? Obviously, If you\'re working with technologies that can\'t do curves, but can do lines and circles, then the answer is pretty straight-forward, but what else? There are some reasons why you might need this technique: using circular arcs means you can determine whether a coordinate lies "on" your curve really easily: simply compute the distance to each circular arc center, and if any of those are close to the arc radii, at an angle betwee the arc start and end: bingo, this point can be treated as lying "on the curve". Another benefit is that this approximation is "linear": you can almost trivially travel along the arcs at fixed speed. You can also trivially compute the arc length of the approximated curve (it\'s a bit like curve flattening). The only thing to bear in mind is that this is a lossy equivalence: things that you compute based on the approximation are guaranteed "off" by some small value, and depending on how much precision you need, arc approximation is either going to be super useful, or completely useless. It\'s up to you to decide which, based on your application!'))}},bsplines:{locale:"en-GB",title:"B-Splines",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"bsplines",title:"B-Splines",number:"39"}),r.createElement("p",null,"No discussion on Bézier curves is complete without also giving mention of that other beast in the curve design space: B-Splines. Easily confused to mean Bézier splines, that's not actually what they are; they are \"basis function\" splines, which makes a lot of difference, which we'll be looking at in this section. We're not going to dive as deep into B-Splines as we have for Bézier curves (that would be an entire primer on its own) but we'll be looking at how B-Splines work, what kind of maths is involved in computing them, and how to draw them based on a number of parameters that you can pick for individual B-Splines."),r.createElement("p",null,"First off: B-Splines are ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Piecewise"},"piecewise polynomial interpolation curves"),', where the "single curve" is built by performing polynomial interpolation over a set of points, using a sliding window of a fixed number of points. For instance, a "cubic" B-Spline defined by twelve points will have its curve built by evaluating the polynomial interpolation of four points, and the curve can be treated as a lot of different sections, each controlled by four points at a time, such that the full curve consists of smoothly connected sections defined by points ',"{","1,2,3,4","}",", ","{","2,3,4,5","}",", ..., ","{","8,9,10,11","}",", and finally ","{","9,10,11,12","}",", for eight sections."),r.createElement("p",null,"What do they look like? They look like this! .. okay that's an empty graph, but simply click to place some point, with the stipulation that you need at least four point to see any curve. More than four points simply draws a longer B-Spline curve:"),r.createElement(o,{sketch:e.basicSketch}),r.createElement("p",null,"The important part to notice here is that we are ",r.createElement("strong",null,"not"),' doing the same thing with B-Splines that we do for poly-Béziers or Catmull-Rom curves: both of the latter simply define new sections as literally "new sections based on new points", so a 12 point cubic poly-Bézier curve is actually impossible, because we start with a four point curve, and then add three more points for each section that follows, so we can only have 4, 7, 10, 13, 16, etc point Poly-Béziers. Similarly, while Catmull-Rom curves can grow by adding single points, this addition of a single point introduces three implicit Bézier points. Cubic B-Splines, on the other hand, are smooth interpolations of ',r.createElement("em",null,"each possible curve involving four consecutive points"),", such that at any point along the curve except for our start and end points, our on-curve coordinate is defined by four control points."),r.createElement("p",null,"Consider the difference to be this:"),r.createElement("ul",null,r.createElement("li",null,"for Bézier curves, the curve is defined as an interpolation of points, but:"),r.createElement("li",null,"for B-Splines, the curve is defined as an interpolation of ",r.createElement("em",null,"curves"),".")),r.createElement("p",null,"In order to make this interpolation of curves work, the maths is necessarily more complex than the maths for Bézier curves, so let's have a look at how things work."),r.createElement("h2",{id:"how-to-compute-a-b-spline-curve-some-maths"},"How to compute a B-Spline curve: some maths"),r.createElement("p",null,"Given a B-Spline of degree ",r.createElement("code",null,"d")," and thus order ",r.createElement("code",null,"k=d+1")," (so a quadratic B-Spline is degree 2 and order 3, a cubic B-Spline is degree 3 and order 4, etc) and ",r.createElement("code",null,"n")," control points ",r.createElement("code",null,"P<sub>0</sub>")," through ",r.createElement("code",null,"P<sub>n-1</sub>"),", we can compute a point on the curve for some value ",r.createElement("code",null,"t")," in the interval [0,1] (where 0 is the start of the curve, and 1 the end, just like for Bézier curves), by evaluting the following function:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/329da80e737b0005f4dbe4c84ff868bde5dfaee0.svg",width:"177.79999999999998rem",height:"43.4rem"}),r.createElement("p",null,'Which, honestly, doesn\'t tell us all that much. All we can see is that a point on a B-Spline curve is defined as "a mix of all the control points, weighted somehow", where the weighting is achieved through the ',r.createElement("em",null,"N(...)")," function, subscipted with an obvious parameter ",r.createElement("code",null,"i"),", which comes from our summation, and some magical parameter ",r.createElement("code",null,"k"),". So we need to know two things: 1. what does N(t) do, and 2. what is that ",r.createElement("code",null,"k"),"? Let's cover both, in reverse order."),r.createElement("p",null,"The parameter ",r.createElement("code",null,"k"),' represents the "knot interval" over which a section of curve is defined. As we learned earlier, a B-Spline curve is itself an interpoliation of curves, and we can treat each transition where a control point starts or tops influencing the total curvature as a "knot on the curve". Doing so for a degree ',r.createElement("code",null,"d")," B-Spline with ",r.createElement("code",null,"n")," control point gives us ",r.createElement("code",null,"d + n + 1")," knots, defining ",r.createElement("code",null,"d + n")," intervals along the curve, and it is these intervals that the above ",r.createElement("code",null,"k")," subscript to the N() function applies to."),r.createElement("p",null,"Then the N() function itself. What does it look like?"),r.createElement("img",{ +className:"LaTeX SVG",src:"images/latex/c10575fb591062784484357356796a4c0be4f83e.svg",width:"588rem",height:"44.8rem"}),r.createElement("p",null,"So this is where we see the interpolation: N(t) for an (i,k) pair (that is, for a step in the above summation, on a specific knot interval) is a mix between N(t) for (i,k-1) and N(t) for (i+1,k-1), so we see that this is a recursive iteration where ",r.createElement("code",null,"i")," goes up, and ",r.createElement("code",null,"k")," goes down, so it seem reasonable to expect that this recursion has to stop at some point; obviously, it does, and specifically it does so for the following ",r.createElement("code",null,"i"),"/",r.createElement("code",null,"k")," values:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/6664a4fc5832059bbc68eaa8068a4b2577e1d96a.svg",width:"251.99999999999997rem",height:"42rem"}),r.createElement("p",null,"And this function finally has a straight up evaluation: if a ",r.createElement("code",null,"t")," value lies within a knot-specific interval once we reach a ",r.createElement("code",null,"k=1"),' value, it "counts", otherwise it doesn\'t. We did cheat a little, though, because for all these values we need to scale our ',r.createElement("code",null,"t")," value first, so that it lies in the interval bounded by ",r.createElement("code",null,"knots[d]")," and ",r.createElement("code",null,"knots[n]"),", which are the start point and end point where curvature is controlled by exactly ",r.createElement("code",null,"order")," control points. For instance, for degree 3 (=order 4) and 7 control points, with knot vector [1,2,3,4,5,6,7,8,9,10,11], we map ",r.createElement("code",null,"t")," from [the interval 0,1] to the interval [4,8], and then use that value in the functions above, instead."),r.createElement("h2",{id:"can-we-simplify-that-"},"Can we simplify that?"),r.createElement("p",null,"We can, yes."),r.createElement("p",null,"People far smarter than us have looked at this work, and two in particular — ",r.createElement("a",{href:"http://www.npl.co.uk/people/maurice-cox"},"Maurice Cox")," and ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Carl_R._de_Boor"},"Carl de Boor")," — came to a mathematically pleasing solution: to compute a point P(t), we can compute this point by evaluating ",r.createElement("em",null,"d(t)")," on a curve section between knots ",r.createElement("em",null,"i")," and ",r.createElement("em",null,"i+1"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3780a420cd9b1bc59bec2c49bbd29f5e58497a3c.svg",width:"295.4rem",height:"22.4rem"}),r.createElement("p",null,"This is another recursive function, with ",r.createElement("em",null,"k")," values decreasing from the curve order to 1, and the value ",r.createElement("em",null,"α")," (alpha) defined by:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ba3b25cd54993b4601d8f415bc4cde73af4fc460.svg",width:"267.4rem",height:"40.599999999999994rem"}),r.createElement("p",null,'That looks complicated, but it\'s not. Computing alpha is just a fraction involving known, plain numbers and once we have our alpha value, computing (1-alpha) is literally just "computing one minus alpha". Computing this d() function is thus simply a matter of "computing simple arithmetics but with recursion", which might be computationally expensive because we\'re doing "a lot of" steps, but is also computationally cheap because each step only involves very simple maths. Of course as before the recursion has to stop:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1405067abebab73574934e3e69d7a7158106c744.svg",width:"387.79999999999995rem",height:"42rem"}),r.createElement("p",null,"So, we see two stopping conditions: either ",r.createElement("code",null,"i")," becomes 0, in which case d() is zero, or ",r.createElement("code",null,"k"),' becomes zero, in which case we get the same "either 1 or 0" that we saw in the N() function above.'),r.createElement("p",null,"Thanks to Cox and de Boor, we can compute points on a B-Spline pretty easily: we just need to compute a triangle of interconnected values. For instance, d() for i=3, k=3 yields the following triangle:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/a0a1069b001c75a1fab7f40ffa8bc403e1408f0d.svg",width:"438.2rem",height:"242.2rem"}),r.createElement("p",null,"That is, we compute d(3,3) as a mixture of d(2,3) and d(2,2): d(3,3) = a(3,3) x d(2,3) + (1-a(3,3)) x d(2,2)... and we simply keep expanding our triangle until we reach the terminating function parameters. Done deal!"),r.createElement("p",null,"One thing we need to keep in mind is that we're working with a spline that is contrained by its control points, so even though the ",r.createElement("code",null,"d(..., k)")," values are zero or one at the lowest level, they are really \"zero or one, times their respective control point\", so in the next section you'll see the algorithm for running through the computation in a way that starts with a copy of the control point vector and then works its way up to that single point: that's pretty essential!"),r.createElement("p",null,'If we run this computation "down", starting at d(3,3), then without special code in place we would be computing quite a few terms multiple times at each step. On the other hand, we can also start with that last "column", we can generate the terminating d() values first, then compute the a() constants, perform our multiplcations, generate the previous step\'s d() values, compute their a() constants, do the multiplications, etc. until we end up all the way back at the top. If we run our computation this way, we don\'t need any explicit caching, we can just "recycle" the list of numbers we start with and simply update them as we move up the triangle. So, let\'s implement that!'),r.createElement("h2",{id:"cool-cool-but-i-don-t-know-what-to-do-with-that-information"},"Cool, cool... but I don't know what to do with that information"),r.createElement("p",null,"I know, this is pretty mathy, so let's have a look at what happens when we change parameters here. We can't change the maths for the interpolation functions, so that gives us only one way to control what happens here: the knot vector itself. As such, let's look at the graph that shows the interpolation functions for a cubic B-Spline with seven points with a uniform knot vector (so we see seven identical functions), representing how much each point (represented by one function each) influences the total curvature, given our knot values. And, because exploration is the key to discovery, let's make the knot vector a thing we can actually manipulate. Normally a proper knot vector has a constraint that any value is strictly equal to, or larger than the previous ones, but screw it this is programming, let's ignore that hard restriction and just mess with the knots however we like."),r.createElement("div",{className:"two-column"},r.createElement(s,{ref:"interpolation-graph"}),r.createElement(o,{sketch:e.interpolationGraph,controller:function(t,n){return e.bindKnots(t,n,"interpolation-graph")}})),r.createElement("p",null,"Changing the values in the knot vector changes how much each point influences the total curvature (with some clever knot value manipulation, we can even make the influence of certain points disappear entirely!), so we can see that while the control points define the hull inside of which we're going to be drawing a curve, it is actually the knot vector that determines the actual ",r.createElement("em",null,"shape")," of the curve inside that hull."),r.createElement("p",null,"After reading the rest of this section you may want to come back here to try some specific knot vectors, and see if the resulting interpolation landscape makes sense given what you will now think should happen!"),r.createElement("h2",{id:"running-the-computation"},"Running the computation"),r.createElement("p",null,"Unlike the de Casteljau algorithm, where the ",r.createElement("code",null,"t")," value stays the same at every iteration, for B-Splines that is not the case, and so we end having to (for each point we evaluate) run a fairly involving bit of recursive computation. The algorithm is discussed on ",r.createElement("a",{href:"http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/de-Boor.html"},"this Michigan Tech")," page, but an easier to read version is implemented by ",r.createElement("a",{href:"https://github.com/thibauts/b-spline/blob/master/index.js#L59-L71"},"b-spline.js"),", so we'll look at its code."),r.createElement("p",null,"Given an input value ",r.createElement("code",null,"t"),", we first map the input to a value from the domain [0,1] to the domain [knots[degree], knots[knots.length - 1 - degree]. Then, we find the section number ",r.createElement("code",null,"s")," that this mapped ",r.createElement("code",null,"t")," value lies on:"),r.createElement("pre",null,"for(s=domain[0]; s < domain[1]; s++) {\n if(knots[s] <= t && t <= knots[s+1]) break;\n}\n"),r.createElement("p",null,"after running this code, ",r.createElement("code",null,"s")," is the index for the section the point will lie on. We then run the algorithm mentioned on the MU page (updated to use this description's variable names):"),r.createElement("pre",null,"let v = copy of control points\n\nfor(let L = 1; L <= order; L++) {\n for(let i=s; i > s + L - order; i--) {\n let numerator = t - knots[i]\n let denominator = knots[i - L + order] - knots[i]\n let alpha = numerator / denominator\n let v[i] = alpha * v[i] + (1-alpha) * v[i-1]\n }\n}\n"),r.createElement("p",null,'(A nice bit of behaviour in this code is that we work the interpolation "backwards", starting at ',r.createElement("code",null,"i=s")," at each level of the interpolation, and we stop when ",r.createElement("code",null,"i = s - order + level"),", so we always end up with a value for ",r.createElement("code",null,"i")," such that those ",r.createElement("code",null,"v[i-1]")," don't try to use an array index that doesn't exist)"),r.createElement("h2",{id:"open-vs-closed-paths"},"Open vs. closed paths"),r.createElement("p",null,"Much like poly-Béziers, B-Splines can be either open, running from the first point to the last point, or closed, where the first and last point are ",r.createElement("em",null,"the same point"),". However, because B-Splines are an interpolation of curves, not just point, we can't simply make the first and last point the same, we need to link a few point point: for an order ",r.createElement("code",null,"d")," B-Spline, we need to make the last ",r.createElement("code",null,"d")," point the same as the first ",r.createElement("code",null,"d")," points. And the easiest way to do this is to simply append ",r.createElement("code",null,"points.splice(0,d)")," to ",r.createElement("code",null,"points"),". Done!"),r.createElement("p",null,'Of course if we want to manipulate these kind of curves we need to make sure to mark them as "closed" so that we know the coordinate for ',r.createElement("code",null,"points[0]")," and ",r.createElement("code",null,"points[n-k]")," etc. are the same coordinate, and manipulating one will equally manipulate the other, but programming generally makes this really easy by storing references to coordinates (or other linked values such as coordinate weights, discussed in the NURBS section) rather than separate coordinate objects."),r.createElement("h2",{id:"manipulating-the-curve-through-the-knot-vector"},"Manipulating the curve through the knot vector"),r.createElement("p",null,"The most important thing to understand when it comes to B-Splines is that they work ",r.createElement("em",null,"because"),' of the concept of a knot vector. As mentioned above, knots represent "where individual control points start/stop influencing the curve", but we never looked at the ',r.createElement("em",null,"values")," that go in the knot vector. If you look back at the N() and a() functions, you see that interpolations are based on intervals in the knot vector, rather than the actual values in the knot vector, and we can exploit this to do some pretty interesting things with clever manipulation of the knot vector. Specifically there are four things we can do that are worth looking at:"),r.createElement("ol",null,r.createElement("li",null,"we can use a uniform knot vector, with equally spaced intervals,"),r.createElement("li",null,"we can use a non-uniform knot vector, without enforcing equally spaced internvals,"),r.createElement("li",null,'we can collapse sequential knots to the same value, locally lowering curve complexity using "null" intervals, and'),r.createElement("li",null,"we can form a special case non-uniform vector, by combining (1) and (3) to for a vector with collapsed start and end knots, with a uniform vector in between.")),r.createElement("h3",{id:"uniform-b-splines"},"Uniform B-Splines"),r.createElement("p",null,"The most straightforward type of B-Spline is the uniform spline. In a uniform spline, the knots are distributed uniformly over the entire curve interval. For instance, if we have a knot vector of length twelve, then a uniform knot vector would be [0,1,2,3,...,9,10,11]. Or [4,5,6,...,13,14,15], which defines ",r.createElement("em",null,"the same intervals"),", or even [0,2,3,...,18,20,22], which also defines ",r.createElement("em",null,"the same intervals"),", just scaled by a constant factor, which becomes normalised during interpolation and so does not contribute to the curvature."),r.createElement("div",{className:"two-column"},r.createElement(s,{ref:"uniform-spline"}),r.createElement(o,{sketch:e.uniformBSpline,controller:function(t,n){return e.bindKnots(t,n,"uniform-spline")}})),r.createElement("p",null,"This is an important point: the intervals that the knot vector defines are ",r.createElement("em",null,"relative")," intervals, so it doesn't matter if every interval is size 1, or size 100 - the relative differences between the intervals is what shapes any particular curve."),r.createElement("p",null,"The problem with uniform knot vectors is that, as we need ",r.createElement("code",null,"order"),' control points before we have any curve with which we can perform interpolation, the curve does not "start" at the first point, nor "ends" at the last point. Instead there are "gaps". We can get rid of these, by being clever about how we apply the following uniformity-breaking approach instead...'),r.createElement("h3",{id:"reducing-local-curve-complexity-by-collapsing-intervals"},"Reducing local curve complexity by collapsing intervals"),r.createElement("p",null,"By collapsing knot intervals by making two or more consecutive knots have the same value, we can reduce the curve complexity in the sections that are affected by the knots involved. This can have drastic effects: for ever interval collapse, the curve order goes down, and curve continuity goes down, to the point where collapsing ",r.createElement("code",null,"order"),' knots creates a situation where all continuity is lost and the curve "kinks".'),r.createElement("div",{className:"two-column"},r.createElement(s,{ref:"center-cut-bspline"}),r.createElement(o,{sketch:e.centerCutBSpline,controller:function(t,n){return e.bindKnots(t,n,"center-cut-bspline")}})),r.createElement("h3",{id:"open-uniform-b-splines"},"Open-Uniform B-Splines"),r.createElement("p",null,"By combining knot interval collapsing at the start and end of the curve, with uniform knots in between, we can overcome the problem of the curve not starting and ending where we'd kind of like it to:"),r.createElement("p",null,"For any curve of degree ",r.createElement("code",null,"D")," with control points ",r.createElement("code",null,"N"),", we can define a knot vector of length ",r.createElement("code",null,"N+D+1")," in which the values ",r.createElement("code",null,"0 ... D+1")," are the same, the values ",r.createElement("code",null,"D+1 ... N+1"),' follow the "uniform" pattern, and the values ',r.createElement("code",null,"N+1 ... N+D+1"),' are the same again. For example, a cubic B-Spline with 7 control points can have a knot vector [0,0,0,0,1,2,3,4,4,4,4], or it might have the "identical" knot vector [0,0,0,0,2,4,6,8,8,8,8], etc. Again, it is the relative differences that determine the curve shape.'),r.createElement("div",{className:"two-column"},r.createElement(s,{ref:"open-uniform-bspline"}),r.createElement(o,{sketch:e.openUniformBSpline,controller:function(t,n){return e.bindKnots(t,n,"open-uniform-bspline")}})),r.createElement("h3",{id:"non-uniform-b-splines"},"Non-uniform B-Splines"),r.createElement("p",null,'This is essentialy the "free form" version of a B-Spline, and also the least interesting to look at, as without any specific reason to pick specific knot intervals, there is nothing particularly interesting going on. There is one constraint to the knot vector, and that is that any value ',r.createElement("code",null,"knots[k+1]")," should be equal to, or greater than ",r.createElement("code",null,"knots[k]"),"."),r.createElement("h2",{id:"one-last-thing-rational-b-splines"},"One last thing: Rational B-Splines"),r.createElement("p",null,'While it is true that this section on B-Splines is running quite long already, there is one more thing we need to talk about, and that\'s "Rational" splines, where the rationality applies to the "ratio", or relative weights, of the control points themselves. By introducing a ratio vector with weights to apply to each control point, we greatly increase our influence over the final curve shape: the more weight a control point carries, the close to that point the spline curve will lie, a bit like turning up the gravity of a control point.'),r.createElement("div",{className:"two-column"},r.createElement(l,{ref:"rational-uniform-bspline-weights"}),r.createElement(o,{scrolling:!0,sketch:e.rationalUniformBSpline,controller:function(t,n,r,i){e.bindWeights(t,r,i,"rational-uniform-bspline-weights")}})),r.createElement("p",null,'Of course this brings us to the final topic that any text on B-Splines must touch on before calling it a day: the NURBS, or Non-Uniform Rational B-Spline (NURBS is not a plural, the capital S actually just stands for "spline", but a lot of people mistakenly treat it as if it is, so now you know better). NURBS are an important type of curve in computer-facilitated design, used a lot in 3D modelling (as NURBS surfaces) as well as in arbitrary-precision 2D design due to the level of control a NURBS curve offers designers.'),r.createElement("p",null,"While a true non-uniform rational B-Spline would be hard to work with, when we talk about NURBS we typically mean the Open-Uniform Rational B-Spline, or OURBS, but that doesn't roll off the tongue nearly as nicely, and so remember that when people talk about NURBS, they typically mean open-uniform, which has the useful property of starting the curve at the first control point, and ending it at the last."),r.createElement("h2",{id:"extending-our-implementation-to-cover-rational-splines"},"Extending our implementation to cover rational splines"),r.createElement("p",null,"The algorithm for working with Rational B-Splines is virtually identical to the regular algorithm, and the extension to work in the control point weights is fairly simple: we extend each control point from a point in its original number of dimensions (2D, 3D, etc) to one dimension higher, scaling the original dimensions by the control point's weight, and then assigning that weight as its value for the extended dimension."),r.createElement("p",null,"For example, a 2D point ",r.createElement("code",null,"(x,y)")," with weight ",r.createElement("code",null,"w")," becomes a 3D point ",r.createElement("code",null,"(w * x, w * y, w)"),"."),r.createElement("p",null,"We then run the same algorithm as before, which will automatically perform weight interpolation in addition to regular coordinate interpolation, because all we've done is pretended we have coordinates in a higher dimension. The algorithm doesn't really care about how many dimensions it needs to interpolate."),r.createElement("p",null,'In order to recover our "real" curve point, we take the final result of the point generation algorithm, and "unweigh" it: we take the final point\'s derived weight ',r.createElement("code",null,"w'")," and divide all the regular coordinate dimensions by it, then throw away the weight information."),r.createElement("p",null,"Based on our previous example, we take the final 3D point ",r.createElement("code",null,"(x', y', w')"),", which we then turn back into a 2D point by computing ",r.createElement("code",null,"(x'/w', y'/w')"),". And that's it, we're done!"))}},comments:{locale:"en-GB",title:"Comments and questions",getContent:function(e){return r.createElement("section",null,r.createElement("script",null,"/* ----------------------------------------------------------------------------- * * * PLEASE DO NOT LOCALISE THIS FILE * * I can't respond to questions that aren't asked in English, so this is one of * the few cases where there is a content.en-GB.md but you shouldn't change it. * * ----------------------------------------------------------------------------- */"),r.createElement("style",null,"#comments ","{","width: calc(960px + 2em), marginTop: 0, borderTop: 1px solid rgba(255, 0, 0, 0.5), paddingTop: 3em","}"),r.createElement(a,{name:"comments",title:"Comments and questions",number:"40"}),r.createElement("p",null,"If you enjoyed this book, or you simply found it useful for something you were trying to get done, and you were wondering how to let me know you appreciated this book, you can always ",r.createElement("a",{href:"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QPRDLNGDANJSW"},"buy me a coffee"),", however much a coffee is where you live. This work has grown over the years, from a small primer to a 70ish print-page-equivalent reader on the subject of Bézier curves, and a lot of coffee went into the making of it. I don't regret a minute I spent on writing it, but I can always do with some more coffee to keep on writing!"),r.createElement("div",{id:"disqus_thread"}),r.createElement("script",{src:"lib/site/disqus.js",async:!0}))}},"locale-switcher":{locale:"en-GB",title:"locale-switcher",getContent:function(e){return r.createElement("section",null,r.createElement("p",null,"Read this in your own language:"),r.createElement("ul",null,r.createElement("li",null,r.createElement("a",{href:"./en-GB"},"English")),r.createElement("li",null,r.createElement("a",{href:"./ja-JP"},"日本語")),r.createElement("li",null,r.createElement("a",{href:"./zh-CN"},"中文"))),r.createElement("p",null,"Don't see your language listed? ",r.createElement("a",{href:"https://github.com/Pomax/BezierInfo-2/wiki/localize"},"Help translate this content!")))}}}},function(e,t,n){e.exports=n(65)},function(e,t,n){!function(){"use strict";var t=n(66),r=function(e){this.curves=[],this._3d=!1,e&&(this.curves=e,this._3d=this.curves[0]._3d)};r.prototype={valueOf:function(){return this.toString()},toString:function(){return t.pointsToString(this.points)},addCurve:function(e){this.curves.push(e),this._3d=this._3d||e._3d},length:function(){return this.curves.map(function(e){return e.length()}).reduce(function(e,t){return e+t})},curve:function(e){return this.curves[e]},bbox:function(){for(var e=this.curves,n=e[0].bbox(),r=1;r<e.length;r++)t.expandbox(n,e[r].bbox());return n},offset:function(e){var t=[];return this.curves.forEach(function(n){t=t.concat(n.offset(e))}),new r(t)}},e.exports=r}()},function(e,t,n){(function(e){var n,r;/** * @license * * chroma.js - JavaScript library for color conversions @@ -32647,219 +63,7 @@ module.exports = __webpack_require__(70); * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ - -(function() { - var Color, DEG2RAD, LAB_CONSTANTS, PI, PITHIRD, RAD2DEG, TWOPI, _guess_formats, _guess_formats_sorted, _input, _interpolators, abs, atan2, bezier, blend, blend_f, brewer, burn, chroma, clip_rgb, cmyk2rgb, colors, cos, css2rgb, darken, dodge, each, floor, hex2rgb, hsi2rgb, hsl2css, hsl2rgb, hsv2rgb, interpolate, interpolate_hsx, interpolate_lab, interpolate_num, interpolate_rgb, lab2lch, lab2rgb, lab_xyz, lch2lab, lch2rgb, lighten, limit, log, luminance_x, m, max, multiply, normal, num2rgb, overlay, pow, rgb2cmyk, rgb2css, rgb2hex, rgb2hsi, rgb2hsl, rgb2hsv, rgb2lab, rgb2lch, rgb2luminance, rgb2num, rgb2temperature, rgb2xyz, rgb_xyz, rnd, root, round, screen, sin, sqrt, temperature2rgb, type, unpack, w3cx11, xyz_lab, xyz_rgb, - slice = [].slice; - - type = (function() { - - /* - for browser-safe type checking+ - ported from jQuery's $.type - */ - var classToType, len, name, o, ref; - classToType = {}; - ref = "Boolean Number String Function Array Date RegExp Undefined Null".split(" "); - for (o = 0, len = ref.length; o < len; o++) { - name = ref[o]; - classToType["[object " + name + "]"] = name.toLowerCase(); - } - return function(obj) { - var strType; - strType = Object.prototype.toString.call(obj); - return classToType[strType] || "object"; - }; - })(); - - limit = function(x, min, max) { - if (min == null) { - min = 0; - } - if (max == null) { - max = 1; - } - if (x < min) { - x = min; - } - if (x > max) { - x = max; - } - return x; - }; - - unpack = function(args) { - if (args.length >= 3) { - return [].slice.call(args); - } else { - return args[0]; - } - }; - - clip_rgb = function(rgb) { - var i; - for (i in rgb) { - if (i < 3) { - if (rgb[i] < 0) { - rgb[i] = 0; - } - if (rgb[i] > 255) { - rgb[i] = 255; - } - } else if (i === 3) { - if (rgb[i] < 0) { - rgb[i] = 0; - } - if (rgb[i] > 1) { - rgb[i] = 1; - } - } - } - return rgb; - }; - - PI = Math.PI, round = Math.round, cos = Math.cos, floor = Math.floor, pow = Math.pow, log = Math.log, sin = Math.sin, sqrt = Math.sqrt, atan2 = Math.atan2, max = Math.max, abs = Math.abs; - - TWOPI = PI * 2; - - PITHIRD = PI / 3; - - DEG2RAD = PI / 180; - - RAD2DEG = 180 / PI; - - chroma = function() { - if (arguments[0] instanceof Color) { - return arguments[0]; - } - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, arguments, function(){}); - }; - - _interpolators = []; - - if ((typeof module !== "undefined" && module !== null) && (module.exports != null)) { - module.exports = chroma; - } - - if (true) { - !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() { - return chroma; - }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - } else { - root = typeof exports !== "undefined" && exports !== null ? exports : this; - root.chroma = chroma; - } - - chroma.version = '1.1.1'; - - - /** - chroma.js - - Copyright (c) 2011-2013, Gregor Aisch - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * The name Gregor Aisch may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - @source: https://github.com/gka/chroma.js - */ - - _input = {}; - - _guess_formats = []; - - _guess_formats_sorted = false; - - Color = (function() { - function Color() { - var arg, args, chk, len, len1, me, mode, o, w; - me = this; - args = []; - for (o = 0, len = arguments.length; o < len; o++) { - arg = arguments[o]; - if (arg != null) { - args.push(arg); - } - } - mode = args[args.length - 1]; - if (_input[mode] != null) { - me._rgb = clip_rgb(_input[mode](unpack(args.slice(0, -1)))); - } else { - if (!_guess_formats_sorted) { - _guess_formats = _guess_formats.sort(function(a, b) { - return b.p - a.p; - }); - _guess_formats_sorted = true; - } - for (w = 0, len1 = _guess_formats.length; w < len1; w++) { - chk = _guess_formats[w]; - mode = chk.test.apply(chk, args); - if (mode) { - break; - } - } - if (mode) { - me._rgb = clip_rgb(_input[mode].apply(_input, args)); - } - } - if (me._rgb == null) { - console.warn('unknown format: ' + args); - } - if (me._rgb == null) { - me._rgb = [0, 0, 0]; - } - if (me._rgb.length === 3) { - me._rgb.push(1); - } - } - - Color.prototype.alpha = function(alpha) { - if (arguments.length) { - this._rgb[3] = alpha; - return this; - } - return this._rgb[3]; - }; - - Color.prototype.toString = function() { - return this.name(); - }; - - return Color; - - })(); - - chroma._input = _input; - - - /** +(function(){var i,a,o,s,l,c,u,h,d,f,p,m,g,v,w,y,b,_,x,E,C,k,S,P,T,M,N,I,L,A,O,B,z,R,D,j,F,q,V,U,W,G,H,X,K,Q,Y,Z,$,J,ee,te,ne,re,ie,ae,oe,se,le,ce,ue,he,de,fe,pe,me,ge,ve,we,ye,be,_e,xe,Ee,Ce,ke,Se,Pe,Te=[].slice;Ee=function(){var e,t,n,r,i;for(e={},i="Boolean Number String Function Array Date RegExp Undefined Null".split(" "),r=0,t=i.length;r<t;r++)n=i[r],e["[object "+n+"]"]=n.toLowerCase();return function(t){var n;return n=Object.prototype.toString.call(t),e[n]||"object"}}(),K=function(e,t,n){return null==t&&(t=0),null==n&&(n=1),e<t&&(e=t),e>n&&(e=n),e},Ce=function(e){return e.length>=3?[].slice.call(e):e[0]},E=function(e){var t;for(t in e)t<3?(e[t]<0&&(e[t]=0),e[t]>255&&(e[t]=255)):3===t&&(e[t]<0&&(e[t]=0),e[t]>1&&(e[t]=1));return e},s=Math.PI,we=Math.round,S=Math.cos,I=Math.floor,re=Math.pow,Q=Math.log,be=Math.sin,_e=Math.sqrt,g=Math.atan2,$=Math.max,m=Math.abs,u=2*s,l=s/3,a=s/180,c=180/s,x=function(){return arguments[0]instanceof i?arguments[0]:function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,arguments,function(){})},p=[],"undefined"!=typeof e&&null!==e&&null!=e.exports&&(e.exports=x),n=[],r=function(){return x}.apply(t,n),!(void 0!==r&&(e.exports=r)),x.version="1.1.1",f={},h=[],d=!1,i=function(){function e(){var e,t,n,r,i,a,o,s,l;for(a=this,t=[],s=0,r=arguments.length;s<r;s++)e=arguments[s],null!=e&&t.push(e);if(o=t[t.length-1],null!=f[o])a._rgb=E(f[o](Ce(t.slice(0,-1))));else{for(d||(h=h.sort(function(e,t){return t.p-e.p}),d=!0),l=0,i=h.length;l<i&&(n=h[l],!(o=n.test.apply(n,t)));l++);o&&(a._rgb=E(f[o].apply(f,t)))}null==a._rgb&&console.warn("unknown format: "+t),null==a._rgb&&(a._rgb=[0,0,0]),3===a._rgb.length&&a._rgb.push(1)}return e.prototype.alpha=function(e){return arguments.length?(this._rgb[3]=e,this):this._rgb[3]},e.prototype.toString=function(){return this.name()},e}(),x._input=f,/** ColorBrewer colors for chroma.js Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The @@ -32877,16882 +81,8 @@ module.exports = __webpack_require__(70); @preserve */ - - chroma.brewer = brewer = { - OrRd: ['#fff7ec', '#fee8c8', '#fdd49e', '#fdbb84', '#fc8d59', '#ef6548', '#d7301f', '#b30000', '#7f0000'], - PuBu: ['#fff7fb', '#ece7f2', '#d0d1e6', '#a6bddb', '#74a9cf', '#3690c0', '#0570b0', '#045a8d', '#023858'], - BuPu: ['#f7fcfd', '#e0ecf4', '#bfd3e6', '#9ebcda', '#8c96c6', '#8c6bb1', '#88419d', '#810f7c', '#4d004b'], - Oranges: ['#fff5eb', '#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c', '#f16913', '#d94801', '#a63603', '#7f2704'], - BuGn: ['#f7fcfd', '#e5f5f9', '#ccece6', '#99d8c9', '#66c2a4', '#41ae76', '#238b45', '#006d2c', '#00441b'], - YlOrBr: ['#ffffe5', '#fff7bc', '#fee391', '#fec44f', '#fe9929', '#ec7014', '#cc4c02', '#993404', '#662506'], - YlGn: ['#ffffe5', '#f7fcb9', '#d9f0a3', '#addd8e', '#78c679', '#41ab5d', '#238443', '#006837', '#004529'], - Reds: ['#fff5f0', '#fee0d2', '#fcbba1', '#fc9272', '#fb6a4a', '#ef3b2c', '#cb181d', '#a50f15', '#67000d'], - RdPu: ['#fff7f3', '#fde0dd', '#fcc5c0', '#fa9fb5', '#f768a1', '#dd3497', '#ae017e', '#7a0177', '#49006a'], - Greens: ['#f7fcf5', '#e5f5e0', '#c7e9c0', '#a1d99b', '#74c476', '#41ab5d', '#238b45', '#006d2c', '#00441b'], - YlGnBu: ['#ffffd9', '#edf8b1', '#c7e9b4', '#7fcdbb', '#41b6c4', '#1d91c0', '#225ea8', '#253494', '#081d58'], - Purples: ['#fcfbfd', '#efedf5', '#dadaeb', '#bcbddc', '#9e9ac8', '#807dba', '#6a51a3', '#54278f', '#3f007d'], - GnBu: ['#f7fcf0', '#e0f3db', '#ccebc5', '#a8ddb5', '#7bccc4', '#4eb3d3', '#2b8cbe', '#0868ac', '#084081'], - Greys: ['#ffffff', '#f0f0f0', '#d9d9d9', '#bdbdbd', '#969696', '#737373', '#525252', '#252525', '#000000'], - YlOrRd: ['#ffffcc', '#ffeda0', '#fed976', '#feb24c', '#fd8d3c', '#fc4e2a', '#e31a1c', '#bd0026', '#800026'], - PuRd: ['#f7f4f9', '#e7e1ef', '#d4b9da', '#c994c7', '#df65b0', '#e7298a', '#ce1256', '#980043', '#67001f'], - Blues: ['#f7fbff', '#deebf7', '#c6dbef', '#9ecae1', '#6baed6', '#4292c6', '#2171b5', '#08519c', '#08306b'], - PuBuGn: ['#fff7fb', '#ece2f0', '#d0d1e6', '#a6bddb', '#67a9cf', '#3690c0', '#02818a', '#016c59', '#014636'], - Spectral: ['#9e0142', '#d53e4f', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2'], - RdYlGn: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#d9ef8b', '#a6d96a', '#66bd63', '#1a9850', '#006837'], - RdBu: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#f7f7f7', '#d1e5f0', '#92c5de', '#4393c3', '#2166ac', '#053061'], - PiYG: ['#8e0152', '#c51b7d', '#de77ae', '#f1b6da', '#fde0ef', '#f7f7f7', '#e6f5d0', '#b8e186', '#7fbc41', '#4d9221', '#276419'], - PRGn: ['#40004b', '#762a83', '#9970ab', '#c2a5cf', '#e7d4e8', '#f7f7f7', '#d9f0d3', '#a6dba0', '#5aae61', '#1b7837', '#00441b'], - RdYlBu: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee090', '#ffffbf', '#e0f3f8', '#abd9e9', '#74add1', '#4575b4', '#313695'], - BrBG: ['#543005', '#8c510a', '#bf812d', '#dfc27d', '#f6e8c3', '#f5f5f5', '#c7eae5', '#80cdc1', '#35978f', '#01665e', '#003c30'], - RdGy: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#ffffff', '#e0e0e0', '#bababa', '#878787', '#4d4d4d', '#1a1a1a'], - PuOr: ['#7f3b08', '#b35806', '#e08214', '#fdb863', '#fee0b6', '#f7f7f7', '#d8daeb', '#b2abd2', '#8073ac', '#542788', '#2d004b'], - Set2: ['#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', '#e5c494', '#b3b3b3'], - Accent: ['#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666'], - Set1: ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', '#a65628', '#f781bf', '#999999'], - Set3: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f'], - Dark2: ['#1b9e77', '#d95f02', '#7570b3', '#e7298a', '#66a61e', '#e6ab02', '#a6761d', '#666666'], - Paired: ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', '#ffff99', '#b15928'], - Pastel2: ['#b3e2cd', '#fdcdac', '#cbd5e8', '#f4cae4', '#e6f5c9', '#fff2ae', '#f1e2cc', '#cccccc'], - Pastel1: ['#fbb4ae', '#b3cde3', '#ccebc5', '#decbe4', '#fed9a6', '#ffffcc', '#e5d8bd', '#fddaec', '#f2f2f2'] - }; - - - /** - X11 color names - - http://www.w3.org/TR/css3-color/#svg-color - */ - - w3cx11 = { - indigo: "#4b0082", - gold: "#ffd700", - hotpink: "#ff69b4", - firebrick: "#b22222", - indianred: "#cd5c5c", - yellow: "#ffff00", - mistyrose: "#ffe4e1", - darkolivegreen: "#556b2f", - olive: "#808000", - darkseagreen: "#8fbc8f", - pink: "#ffc0cb", - tomato: "#ff6347", - lightcoral: "#f08080", - orangered: "#ff4500", - navajowhite: "#ffdead", - lime: "#00ff00", - palegreen: "#98fb98", - darkslategrey: "#2f4f4f", - greenyellow: "#adff2f", - burlywood: "#deb887", - seashell: "#fff5ee", - mediumspringgreen: "#00fa9a", - fuchsia: "#ff00ff", - papayawhip: "#ffefd5", - blanchedalmond: "#ffebcd", - chartreuse: "#7fff00", - dimgray: "#696969", - black: "#000000", - peachpuff: "#ffdab9", - springgreen: "#00ff7f", - aquamarine: "#7fffd4", - white: "#ffffff", - orange: "#ffa500", - lightsalmon: "#ffa07a", - darkslategray: "#2f4f4f", - brown: "#a52a2a", - ivory: "#fffff0", - dodgerblue: "#1e90ff", - peru: "#cd853f", - lawngreen: "#7cfc00", - chocolate: "#d2691e", - crimson: "#dc143c", - forestgreen: "#228b22", - darkgrey: "#a9a9a9", - lightseagreen: "#20b2aa", - cyan: "#00ffff", - mintcream: "#f5fffa", - silver: "#c0c0c0", - antiquewhite: "#faebd7", - mediumorchid: "#ba55d3", - skyblue: "#87ceeb", - gray: "#808080", - darkturquoise: "#00ced1", - goldenrod: "#daa520", - darkgreen: "#006400", - floralwhite: "#fffaf0", - darkviolet: "#9400d3", - darkgray: "#a9a9a9", - moccasin: "#ffe4b5", - saddlebrown: "#8b4513", - grey: "#808080", - darkslateblue: "#483d8b", - lightskyblue: "#87cefa", - lightpink: "#ffb6c1", - mediumvioletred: "#c71585", - slategrey: "#708090", - red: "#ff0000", - deeppink: "#ff1493", - limegreen: "#32cd32", - darkmagenta: "#8b008b", - palegoldenrod: "#eee8aa", - plum: "#dda0dd", - turquoise: "#40e0d0", - lightgrey: "#d3d3d3", - lightgoldenrodyellow: "#fafad2", - darkgoldenrod: "#b8860b", - lavender: "#e6e6fa", - maroon: "#800000", - yellowgreen: "#9acd32", - sandybrown: "#f4a460", - thistle: "#d8bfd8", - violet: "#ee82ee", - navy: "#000080", - magenta: "#ff00ff", - dimgrey: "#696969", - tan: "#d2b48c", - rosybrown: "#bc8f8f", - olivedrab: "#6b8e23", - blue: "#0000ff", - lightblue: "#add8e6", - ghostwhite: "#f8f8ff", - honeydew: "#f0fff0", - cornflowerblue: "#6495ed", - slateblue: "#6a5acd", - linen: "#faf0e6", - darkblue: "#00008b", - powderblue: "#b0e0e6", - seagreen: "#2e8b57", - darkkhaki: "#bdb76b", - snow: "#fffafa", - sienna: "#a0522d", - mediumblue: "#0000cd", - royalblue: "#4169e1", - lightcyan: "#e0ffff", - green: "#008000", - mediumpurple: "#9370db", - midnightblue: "#191970", - cornsilk: "#fff8dc", - paleturquoise: "#afeeee", - bisque: "#ffe4c4", - slategray: "#708090", - darkcyan: "#008b8b", - khaki: "#f0e68c", - wheat: "#f5deb3", - teal: "#008080", - darkorchid: "#9932cc", - deepskyblue: "#00bfff", - salmon: "#fa8072", - darkred: "#8b0000", - steelblue: "#4682b4", - palevioletred: "#db7093", - lightslategray: "#778899", - aliceblue: "#f0f8ff", - lightslategrey: "#778899", - lightgreen: "#90ee90", - orchid: "#da70d6", - gainsboro: "#dcdcdc", - mediumseagreen: "#3cb371", - lightgray: "#d3d3d3", - mediumturquoise: "#48d1cc", - lemonchiffon: "#fffacd", - cadetblue: "#5f9ea0", - lightyellow: "#ffffe0", - lavenderblush: "#fff0f5", - coral: "#ff7f50", - purple: "#800080", - aqua: "#00ffff", - whitesmoke: "#f5f5f5", - mediumslateblue: "#7b68ee", - darkorange: "#ff8c00", - mediumaquamarine: "#66cdaa", - darksalmon: "#e9967a", - beige: "#f5f5dc", - blueviolet: "#8a2be2", - azure: "#f0ffff", - lightsteelblue: "#b0c4de", - oldlace: "#fdf5e6", - rebeccapurple: "#663399" - }; - - chroma.colors = colors = w3cx11; - - lab2rgb = function() { - var a, args, b, g, l, r, x, y, z; - args = unpack(arguments); - l = args[0], a = args[1], b = args[2]; - y = (l + 16) / 116; - x = isNaN(a) ? y : y + a / 500; - z = isNaN(b) ? y : y - b / 200; - y = LAB_CONSTANTS.Yn * lab_xyz(y); - x = LAB_CONSTANTS.Xn * lab_xyz(x); - z = LAB_CONSTANTS.Zn * lab_xyz(z); - r = xyz_rgb(3.2404542 * x - 1.5371385 * y - 0.4985314 * z); - g = xyz_rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z); - b = xyz_rgb(0.0556434 * x - 0.2040259 * y + 1.0572252 * z); - r = limit(r, 0, 255); - g = limit(g, 0, 255); - b = limit(b, 0, 255); - return [r, g, b, args.length > 3 ? args[3] : 1]; - }; - - xyz_rgb = function(r) { - return round(255 * (r <= 0.00304 ? 12.92 * r : 1.055 * pow(r, 1 / 2.4) - 0.055)); - }; - - lab_xyz = function(t) { - if (t > LAB_CONSTANTS.t1) { - return t * t * t; - } else { - return LAB_CONSTANTS.t2 * (t - LAB_CONSTANTS.t0); - } - }; - - LAB_CONSTANTS = { - Kn: 18, - Xn: 0.950470, - Yn: 1, - Zn: 1.088830, - t0: 0.137931034, - t1: 0.206896552, - t2: 0.12841855, - t3: 0.008856452 - }; - - rgb2lab = function() { - var b, g, r, ref, ref1, x, y, z; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - ref1 = rgb2xyz(r, g, b), x = ref1[0], y = ref1[1], z = ref1[2]; - return [116 * y - 16, 500 * (x - y), 200 * (y - z)]; - }; - - rgb_xyz = function(r) { - if ((r /= 255) <= 0.04045) { - return r / 12.92; - } else { - return pow((r + 0.055) / 1.055, 2.4); - } - }; - - xyz_lab = function(t) { - if (t > LAB_CONSTANTS.t3) { - return pow(t, 1 / 3); - } else { - return t / LAB_CONSTANTS.t2 + LAB_CONSTANTS.t0; - } - }; - - rgb2xyz = function() { - var b, g, r, ref, x, y, z; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - r = rgb_xyz(r); - g = rgb_xyz(g); - b = rgb_xyz(b); - x = xyz_lab((0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / LAB_CONSTANTS.Xn); - y = xyz_lab((0.2126729 * r + 0.7151522 * g + 0.0721750 * b) / LAB_CONSTANTS.Yn); - z = xyz_lab((0.0193339 * r + 0.1191920 * g + 0.9503041 * b) / LAB_CONSTANTS.Zn); - return [x, y, z]; - }; - - chroma.lab = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['lab']), function(){}); - }; - - _input.lab = lab2rgb; - - Color.prototype.lab = function() { - return rgb2lab(this._rgb); - }; - - bezier = function(colors) { - var I, I0, I1, c, lab0, lab1, lab2, lab3, ref, ref1, ref2; - colors = (function() { - var len, o, results; - results = []; - for (o = 0, len = colors.length; o < len; o++) { - c = colors[o]; - results.push(chroma(c)); - } - return results; - })(); - if (colors.length === 2) { - ref = (function() { - var len, o, results; - results = []; - for (o = 0, len = colors.length; o < len; o++) { - c = colors[o]; - results.push(c.lab()); - } - return results; - })(), lab0 = ref[0], lab1 = ref[1]; - I = function(t) { - var i, lab; - lab = (function() { - var o, results; - results = []; - for (i = o = 0; o <= 2; i = ++o) { - results.push(lab0[i] + t * (lab1[i] - lab0[i])); - } - return results; - })(); - return chroma.lab.apply(chroma, lab); - }; - } else if (colors.length === 3) { - ref1 = (function() { - var len, o, results; - results = []; - for (o = 0, len = colors.length; o < len; o++) { - c = colors[o]; - results.push(c.lab()); - } - return results; - })(), lab0 = ref1[0], lab1 = ref1[1], lab2 = ref1[2]; - I = function(t) { - var i, lab; - lab = (function() { - var o, results; - results = []; - for (i = o = 0; o <= 2; i = ++o) { - results.push((1 - t) * (1 - t) * lab0[i] + 2 * (1 - t) * t * lab1[i] + t * t * lab2[i]); - } - return results; - })(); - return chroma.lab.apply(chroma, lab); - }; - } else if (colors.length === 4) { - ref2 = (function() { - var len, o, results; - results = []; - for (o = 0, len = colors.length; o < len; o++) { - c = colors[o]; - results.push(c.lab()); - } - return results; - })(), lab0 = ref2[0], lab1 = ref2[1], lab2 = ref2[2], lab3 = ref2[3]; - I = function(t) { - var i, lab; - lab = (function() { - var o, results; - results = []; - for (i = o = 0; o <= 2; i = ++o) { - results.push((1 - t) * (1 - t) * (1 - t) * lab0[i] + 3 * (1 - t) * (1 - t) * t * lab1[i] + 3 * (1 - t) * t * t * lab2[i] + t * t * t * lab3[i]); - } - return results; - })(); - return chroma.lab.apply(chroma, lab); - }; - } else if (colors.length === 5) { - I0 = bezier(colors.slice(0, 3)); - I1 = bezier(colors.slice(2, 5)); - I = function(t) { - if (t < 0.5) { - return I0(t * 2); - } else { - return I1((t - 0.5) * 2); - } - }; - } - return I; - }; - - chroma.bezier = function(colors) { - var f; - f = bezier(colors); - f.scale = function() { - return chroma.scale(f); - }; - return f; - }; - - - /* - chroma.js - - Copyright (c) 2011-2013, Gregor Aisch - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * The name Gregor Aisch may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - @source: https://github.com/gka/chroma.js - */ - - chroma.cubehelix = function(start, rotations, hue, gamma, lightness) { - var dh, dl, f; - if (start == null) { - start = 300; - } - if (rotations == null) { - rotations = -1.5; - } - if (hue == null) { - hue = 1; - } - if (gamma == null) { - gamma = 1; - } - if (lightness == null) { - lightness = [0, 1]; - } - dl = lightness[1] - lightness[0]; - dh = 0; - f = function(fract) { - var a, amp, b, cos_a, g, h, l, r, sin_a; - a = TWOPI * ((start + 120) / 360 + rotations * fract); - l = pow(lightness[0] + dl * fract, gamma); - h = dh !== 0 ? hue[0] + fract * dh : hue; - amp = h * l * (1 - l) / 2; - cos_a = cos(a); - sin_a = sin(a); - r = l + amp * (-0.14861 * cos_a + 1.78277 * sin_a); - g = l + amp * (-0.29227 * cos_a - 0.90649 * sin_a); - b = l + amp * (+1.97294 * cos_a); - return chroma(clip_rgb([r * 255, g * 255, b * 255])); - }; - f.start = function(s) { - if (s == null) { - return start; - } - start = s; - return f; - }; - f.rotations = function(r) { - if (r == null) { - return rotations; - } - rotations = r; - return f; - }; - f.gamma = function(g) { - if (g == null) { - return gamma; - } - gamma = g; - return f; - }; - f.hue = function(h) { - if (h == null) { - return hue; - } - hue = h; - if (type(hue) === 'array') { - dh = hue[1] - hue[0]; - if (dh === 0) { - hue = hue[1]; - } - } else { - dh = 0; - } - return f; - }; - f.lightness = function(h) { - if (h == null) { - return lightness; - } - lightness = h; - if (type(lightness) === 'array') { - dl = lightness[1] - lightness[0]; - if (dl === 0) { - lightness = lightness[1]; - } - } else { - dl = 0; - } - return f; - }; - f.scale = function() { - return chroma.scale(f); - }; - f.hue(hue); - return f; - }; - - chroma.random = function() { - var code, digits, i, o; - digits = '0123456789abcdef'; - code = '#'; - for (i = o = 0; o < 6; i = ++o) { - code += digits.charAt(floor(Math.random() * 16)); - } - return new Color(code); - }; - - chroma.average = function(colors) { - var a, b, c, g, l, len, o, r, rgba; - r = g = b = a = 0; - l = colors.length; - for (o = 0, len = colors.length; o < len; o++) { - c = colors[o]; - rgba = chroma(c).rgba(); - r += rgba[0]; - g += rgba[1]; - b += rgba[2]; - a += rgba[3]; - } - return new Color(r / l, g / l, b / l, a / l); - }; - - _input.rgb = function() { - var k, ref, results, v; - ref = unpack(arguments); - results = []; - for (k in ref) { - v = ref[k]; - results.push(v); - } - return results; - }; - - chroma.rgb = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['rgb']), function(){}); - }; - - Color.prototype.rgb = function() { - return this._rgb.slice(0, 3); - }; - - Color.prototype.rgba = function() { - return this._rgb; - }; - - _guess_formats.push({ - p: 15, - test: function(n) { - var a; - a = unpack(arguments); - if (type(a) === 'array' && a.length === 3) { - return 'rgb'; - } - if (a.length === 4 && type(a[3]) === "number" && a[3] >= 0 && a[3] <= 1) { - return 'rgb'; - } - } - }); - - hex2rgb = function(hex) { - var a, b, g, r, rgb, u; - if (hex.match(/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)) { - if (hex.length === 4 || hex.length === 7) { - hex = hex.substr(1); - } - if (hex.length === 3) { - hex = hex.split(""); - hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; - } - u = parseInt(hex, 16); - r = u >> 16; - g = u >> 8 & 0xFF; - b = u & 0xFF; - return [r, g, b, 1]; - } - if (hex.match(/^#?([A-Fa-f0-9]{8})$/)) { - if (hex.length === 9) { - hex = hex.substr(1); - } - u = parseInt(hex, 16); - r = u >> 24 & 0xFF; - g = u >> 16 & 0xFF; - b = u >> 8 & 0xFF; - a = round((u & 0xFF) / 0xFF * 100) / 100; - return [r, g, b, a]; - } - if ((_input.css != null) && (rgb = _input.css(hex))) { - return rgb; - } - throw "unknown color: " + hex; - }; - - rgb2hex = function(channels, mode) { - var a, b, g, hxa, r, str, u; - if (mode == null) { - mode = 'rgb'; - } - r = channels[0], g = channels[1], b = channels[2], a = channels[3]; - u = r << 16 | g << 8 | b; - str = "000000" + u.toString(16); - str = str.substr(str.length - 6); - hxa = '0' + round(a * 255).toString(16); - hxa = hxa.substr(hxa.length - 2); - return "#" + (function() { - switch (mode.toLowerCase()) { - case 'rgba': - return str + hxa; - case 'argb': - return hxa + str; - default: - return str; - } - })(); - }; - - _input.hex = function(h) { - return hex2rgb(h); - }; - - chroma.hex = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['hex']), function(){}); - }; - - Color.prototype.hex = function(mode) { - if (mode == null) { - mode = 'rgb'; - } - return rgb2hex(this._rgb, mode); - }; - - _guess_formats.push({ - p: 10, - test: function(n) { - if (arguments.length === 1 && type(n) === "string") { - return 'hex'; - } - } - }); - - hsl2rgb = function() { - var args, b, c, g, h, i, l, o, r, ref, s, t1, t2, t3; - args = unpack(arguments); - h = args[0], s = args[1], l = args[2]; - if (s === 0) { - r = g = b = l * 255; - } else { - t3 = [0, 0, 0]; - c = [0, 0, 0]; - t2 = l < 0.5 ? l * (1 + s) : l + s - l * s; - t1 = 2 * l - t2; - h /= 360; - t3[0] = h + 1 / 3; - t3[1] = h; - t3[2] = h - 1 / 3; - for (i = o = 0; o <= 2; i = ++o) { - if (t3[i] < 0) { - t3[i] += 1; - } - if (t3[i] > 1) { - t3[i] -= 1; - } - if (6 * t3[i] < 1) { - c[i] = t1 + (t2 - t1) * 6 * t3[i]; - } else if (2 * t3[i] < 1) { - c[i] = t2; - } else if (3 * t3[i] < 2) { - c[i] = t1 + (t2 - t1) * ((2 / 3) - t3[i]) * 6; - } else { - c[i] = t1; - } - } - ref = [round(c[0] * 255), round(c[1] * 255), round(c[2] * 255)], r = ref[0], g = ref[1], b = ref[2]; - } - if (args.length > 3) { - return [r, g, b, args[3]]; - } else { - return [r, g, b]; - } - }; - - rgb2hsl = function(r, g, b) { - var h, l, min, ref, s; - if (r !== void 0 && r.length >= 3) { - ref = r, r = ref[0], g = ref[1], b = ref[2]; - } - r /= 255; - g /= 255; - b /= 255; - min = Math.min(r, g, b); - max = Math.max(r, g, b); - l = (max + min) / 2; - if (max === min) { - s = 0; - h = Number.NaN; - } else { - s = l < 0.5 ? (max - min) / (max + min) : (max - min) / (2 - max - min); - } - if (r === max) { - h = (g - b) / (max - min); - } else if (g === max) { - h = 2 + (b - r) / (max - min); - } else if (b === max) { - h = 4 + (r - g) / (max - min); - } - h *= 60; - if (h < 0) { - h += 360; - } - return [h, s, l]; - }; - - chroma.hsl = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['hsl']), function(){}); - }; - - _input.hsl = hsl2rgb; - - Color.prototype.hsl = function() { - return rgb2hsl(this._rgb); - }; - - hsv2rgb = function() { - var args, b, f, g, h, i, p, q, r, ref, ref1, ref2, ref3, ref4, ref5, s, t, v; - args = unpack(arguments); - h = args[0], s = args[1], v = args[2]; - v *= 255; - if (s === 0) { - r = g = b = v; - } else { - if (h === 360) { - h = 0; - } - if (h > 360) { - h -= 360; - } - if (h < 0) { - h += 360; - } - h /= 60; - i = floor(h); - f = h - i; - p = v * (1 - s); - q = v * (1 - s * f); - t = v * (1 - s * (1 - f)); - switch (i) { - case 0: - ref = [v, t, p], r = ref[0], g = ref[1], b = ref[2]; - break; - case 1: - ref1 = [q, v, p], r = ref1[0], g = ref1[1], b = ref1[2]; - break; - case 2: - ref2 = [p, v, t], r = ref2[0], g = ref2[1], b = ref2[2]; - break; - case 3: - ref3 = [p, q, v], r = ref3[0], g = ref3[1], b = ref3[2]; - break; - case 4: - ref4 = [t, p, v], r = ref4[0], g = ref4[1], b = ref4[2]; - break; - case 5: - ref5 = [v, p, q], r = ref5[0], g = ref5[1], b = ref5[2]; - } - } - r = round(r); - g = round(g); - b = round(b); - return [r, g, b, args.length > 3 ? args[3] : 1]; - }; - - rgb2hsv = function() { - var b, delta, g, h, min, r, ref, s, v; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - min = Math.min(r, g, b); - max = Math.max(r, g, b); - delta = max - min; - v = max / 255.0; - if (max === 0) { - h = Number.NaN; - s = 0; - } else { - s = delta / max; - if (r === max) { - h = (g - b) / delta; - } - if (g === max) { - h = 2 + (b - r) / delta; - } - if (b === max) { - h = 4 + (r - g) / delta; - } - h *= 60; - if (h < 0) { - h += 360; - } - } - return [h, s, v]; - }; - - chroma.hsv = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['hsv']), function(){}); - }; - - _input.hsv = hsv2rgb; - - Color.prototype.hsv = function() { - return rgb2hsv(this._rgb); - }; - - num2rgb = function(num) { - var b, g, r; - if (type(num) === "number" && num >= 0 && num <= 0xFFFFFF) { - r = num >> 16; - g = (num >> 8) & 0xFF; - b = num & 0xFF; - return [r, g, b, 1]; - } - console.warn("unknown num color: " + num); - return [0, 0, 0, 1]; - }; - - rgb2num = function() { - var b, g, r, ref; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - return (r << 16) + (g << 8) + b; - }; - - chroma.num = function(num) { - return new Color(num, 'num'); - }; - - Color.prototype.num = function(mode) { - if (mode == null) { - mode = 'rgb'; - } - return rgb2num(this._rgb, mode); - }; - - _input.num = num2rgb; - - _guess_formats.push({ - p: 10, - test: function(n) { - if (arguments.length === 1 && type(n) === "number" && n >= 0 && n <= 0xFFFFFF) { - return 'num'; - } - } - }); - - css2rgb = function(css) { - var aa, ab, hsl, i, m, o, rgb, w; - css = css.toLowerCase(); - if ((chroma.colors != null) && chroma.colors[css]) { - return hex2rgb(chroma.colors[css]); - } - if (m = css.match(/rgb\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*\)/)) { - rgb = m.slice(1, 4); - for (i = o = 0; o <= 2; i = ++o) { - rgb[i] = +rgb[i]; - } - rgb[3] = 1; - } else if (m = css.match(/rgba\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*,\s*([01]|[01]?\.\d+)\)/)) { - rgb = m.slice(1, 5); - for (i = w = 0; w <= 3; i = ++w) { - rgb[i] = +rgb[i]; - } - } else if (m = css.match(/rgb\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/)) { - rgb = m.slice(1, 4); - for (i = aa = 0; aa <= 2; i = ++aa) { - rgb[i] = round(rgb[i] * 2.55); - } - rgb[3] = 1; - } else if (m = css.match(/rgba\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/)) { - rgb = m.slice(1, 5); - for (i = ab = 0; ab <= 2; i = ++ab) { - rgb[i] = round(rgb[i] * 2.55); - } - rgb[3] = +rgb[3]; - } else if (m = css.match(/hsl\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/)) { - hsl = m.slice(1, 4); - hsl[1] *= 0.01; - hsl[2] *= 0.01; - rgb = hsl2rgb(hsl); - rgb[3] = 1; - } else if (m = css.match(/hsla\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/)) { - hsl = m.slice(1, 4); - hsl[1] *= 0.01; - hsl[2] *= 0.01; - rgb = hsl2rgb(hsl); - rgb[3] = +m[4]; - } - return rgb; - }; - - rgb2css = function(rgba) { - var mode; - mode = rgba[3] < 1 ? 'rgba' : 'rgb'; - if (mode === 'rgb') { - return mode + '(' + rgba.slice(0, 3).map(round).join(',') + ')'; - } else if (mode === 'rgba') { - return mode + '(' + rgba.slice(0, 3).map(round).join(',') + ',' + rgba[3] + ')'; - } else { - - } - }; - - rnd = function(a) { - return round(a * 100) / 100; - }; - - hsl2css = function(hsl, alpha) { - var mode; - mode = alpha < 1 ? 'hsla' : 'hsl'; - hsl[0] = rnd(hsl[0] || 0); - hsl[1] = rnd(hsl[1] * 100) + '%'; - hsl[2] = rnd(hsl[2] * 100) + '%'; - if (mode === 'hsla') { - hsl[3] = alpha; - } - return mode + '(' + hsl.join(',') + ')'; - }; - - _input.css = function(h) { - return css2rgb(h); - }; - - chroma.css = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['css']), function(){}); - }; - - Color.prototype.css = function(mode) { - if (mode == null) { - mode = 'rgb'; - } - if (mode.slice(0, 3) === 'rgb') { - return rgb2css(this._rgb); - } else if (mode.slice(0, 3) === 'hsl') { - return hsl2css(this.hsl(), this.alpha()); - } - }; - - _input.named = function(name) { - return hex2rgb(w3cx11[name]); - }; - - _guess_formats.push({ - p: 20, - test: function(n) { - if (arguments.length === 1 && (w3cx11[n] != null)) { - return 'named'; - } - } - }); - - Color.prototype.name = function(n) { - var h, k; - if (arguments.length) { - if (w3cx11[n]) { - this._rgb = hex2rgb(w3cx11[n]); - } - this._rgb[3] = 1; - this; - } - h = this.hex(); - for (k in w3cx11) { - if (h === w3cx11[k]) { - return k; - } - } - return h; - }; - - lch2lab = function() { - - /* - Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel. - These formulas were invented by David Dalrymple to obtain maximum contrast without going - out of gamut if the parameters are in the range 0-1. - - A saturation multiplier was added by Gregor Aisch - */ - var c, h, l, ref; - ref = unpack(arguments), l = ref[0], c = ref[1], h = ref[2]; - h = h * DEG2RAD; - return [l, cos(h) * c, sin(h) * c]; - }; - - lch2rgb = function() { - var L, a, args, b, c, g, h, l, r, ref, ref1; - args = unpack(arguments); - l = args[0], c = args[1], h = args[2]; - ref = lch2lab(l, c, h), L = ref[0], a = ref[1], b = ref[2]; - ref1 = lab2rgb(L, a, b), r = ref1[0], g = ref1[1], b = ref1[2]; - return [limit(r, 0, 255), limit(g, 0, 255), limit(b, 0, 255), args.length > 3 ? args[3] : 1]; - }; - - lab2lch = function() { - var a, b, c, h, l, ref; - ref = unpack(arguments), l = ref[0], a = ref[1], b = ref[2]; - c = sqrt(a * a + b * b); - h = (atan2(b, a) * RAD2DEG + 360) % 360; - if (round(c * 10000) === 0) { - h = Number.NaN; - } - return [l, c, h]; - }; - - rgb2lch = function() { - var a, b, g, l, r, ref, ref1; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - ref1 = rgb2lab(r, g, b), l = ref1[0], a = ref1[1], b = ref1[2]; - return lab2lch(l, a, b); - }; - - chroma.lch = function() { - var args; - args = unpack(arguments); - return new Color(args, 'lch'); - }; - - chroma.hcl = function() { - var args; - args = unpack(arguments); - return new Color(args, 'hcl'); - }; - - _input.lch = lch2rgb; - - _input.hcl = function() { - var c, h, l, ref; - ref = unpack(arguments), h = ref[0], c = ref[1], l = ref[2]; - return lch2rgb([l, c, h]); - }; - - Color.prototype.lch = function() { - return rgb2lch(this._rgb); - }; - - Color.prototype.hcl = function() { - return rgb2lch(this._rgb).reverse(); - }; - - rgb2cmyk = function(mode) { - var b, c, f, g, k, m, r, ref, y; - if (mode == null) { - mode = 'rgb'; - } - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - r = r / 255; - g = g / 255; - b = b / 255; - k = 1 - Math.max(r, Math.max(g, b)); - f = k < 1 ? 1 / (1 - k) : 0; - c = (1 - r - k) * f; - m = (1 - g - k) * f; - y = (1 - b - k) * f; - return [c, m, y, k]; - }; - - cmyk2rgb = function() { - var alpha, args, b, c, g, k, m, r, y; - args = unpack(arguments); - c = args[0], m = args[1], y = args[2], k = args[3]; - alpha = args.length > 4 ? args[4] : 1; - if (k === 1) { - return [0, 0, 0, alpha]; - } - r = c >= 1 ? 0 : round(255 * (1 - c) * (1 - k)); - g = m >= 1 ? 0 : round(255 * (1 - m) * (1 - k)); - b = y >= 1 ? 0 : round(255 * (1 - y) * (1 - k)); - return [r, g, b, alpha]; - }; - - _input.cmyk = function() { - return cmyk2rgb(unpack(arguments)); - }; - - chroma.cmyk = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['cmyk']), function(){}); - }; - - Color.prototype.cmyk = function() { - return rgb2cmyk(this._rgb); - }; - - _input.gl = function() { - var i, k, o, rgb, v; - rgb = (function() { - var ref, results; - ref = unpack(arguments); - results = []; - for (k in ref) { - v = ref[k]; - results.push(v); - } - return results; - }).apply(this, arguments); - for (i = o = 0; o <= 2; i = ++o) { - rgb[i] *= 255; - } - return rgb; - }; - - chroma.gl = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['gl']), function(){}); - }; - - Color.prototype.gl = function() { - var rgb; - rgb = this._rgb; - return [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255, rgb[3]]; - }; - - rgb2luminance = function(r, g, b) { - var ref; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - r = luminance_x(r); - g = luminance_x(g); - b = luminance_x(b); - return 0.2126 * r + 0.7152 * g + 0.0722 * b; - }; - - luminance_x = function(x) { - x /= 255; - if (x <= 0.03928) { - return x / 12.92; - } else { - return pow((x + 0.055) / 1.055, 2.4); - } - }; - - _interpolators = []; - - interpolate = function(col1, col2, f, m) { - var interpol, len, o, res; - if (f == null) { - f = 0.5; - } - if (m == null) { - m = 'rgb'; - } - - /* - interpolates between colors - f = 0 --> me - f = 1 --> col - */ - if (type(col1) !== 'object') { - col1 = chroma(col1); - } - if (type(col2) !== 'object') { - col2 = chroma(col2); - } - for (o = 0, len = _interpolators.length; o < len; o++) { - interpol = _interpolators[o]; - if (m === interpol[0]) { - res = interpol[1](col1, col2, f, m); - break; - } - } - if (res == null) { - throw "color mode " + m + " is not supported"; - } - res.alpha(col1.alpha() + f * (col2.alpha() - col1.alpha())); - return res; - }; - - chroma.interpolate = interpolate; - - Color.prototype.interpolate = function(col2, f, m) { - return interpolate(this, col2, f, m); - }; - - chroma.mix = interpolate; - - Color.prototype.mix = Color.prototype.interpolate; - - interpolate_rgb = function(col1, col2, f, m) { - var xyz0, xyz1; - xyz0 = col1._rgb; - xyz1 = col2._rgb; - return new Color(xyz0[0] + f * (xyz1[0] - xyz0[0]), xyz0[1] + f * (xyz1[1] - xyz0[1]), xyz0[2] + f * (xyz1[2] - xyz0[2]), m); - }; - - _interpolators.push(['rgb', interpolate_rgb]); - - Color.prototype.luminance = function(lum, mode) { - var cur_lum, eps, max_iter, test; - if (mode == null) { - mode = 'rgb'; - } - if (!arguments.length) { - return rgb2luminance(this._rgb); - } - if (lum === 0) { - this._rgb = [0, 0, 0, this._rgb[3]]; - } else if (lum === 1) { - this._rgb = [255, 255, 255, this._rgb[3]]; - } else { - eps = 1e-7; - max_iter = 20; - test = function(l, h) { - var lm, m; - m = l.interpolate(h, 0.5, mode); - lm = m.luminance(); - if (Math.abs(lum - lm) < eps || !max_iter--) { - return m; - } - if (lm > lum) { - return test(l, m); - } - return test(m, h); - }; - cur_lum = rgb2luminance(this._rgb); - this._rgb = (cur_lum > lum ? test(chroma('black'), this) : test(this, chroma('white'))).rgba(); - } - return this; - }; - - temperature2rgb = function(kelvin) { - var b, g, r, temp; - temp = kelvin / 100; - if (temp < 66) { - r = 255; - g = -155.25485562709179 - 0.44596950469579133 * (g = temp - 2) + 104.49216199393888 * log(g); - b = temp < 20 ? 0 : -254.76935184120902 + 0.8274096064007395 * (b = temp - 10) + 115.67994401066147 * log(b); - } else { - r = 351.97690566805693 + 0.114206453784165 * (r = temp - 55) - 40.25366309332127 * log(r); - g = 325.4494125711974 + 0.07943456536662342 * (g = temp - 50) - 28.0852963507957 * log(g); - b = 255; - } - return clip_rgb([r, g, b]); - }; - - rgb2temperature = function() { - var b, eps, g, maxTemp, minTemp, r, ref, rgb, temp; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - minTemp = 1000; - maxTemp = 40000; - eps = 0.4; - while (maxTemp - minTemp > eps) { - temp = (maxTemp + minTemp) * 0.5; - rgb = temperature2rgb(temp); - if ((rgb[2] / rgb[0]) >= (b / r)) { - maxTemp = temp; - } else { - minTemp = temp; - } - } - return round(temp); - }; - - chroma.temperature = chroma.kelvin = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['temperature']), function(){}); - }; - - _input.temperature = _input.kelvin = _input.K = temperature2rgb; - - Color.prototype.temperature = function() { - return rgb2temperature(this._rgb); - }; - - Color.prototype.kelvin = Color.prototype.temperature; - - chroma.contrast = function(a, b) { - var l1, l2, ref, ref1; - if ((ref = type(a)) === 'string' || ref === 'number') { - a = new Color(a); - } - if ((ref1 = type(b)) === 'string' || ref1 === 'number') { - b = new Color(b); - } - l1 = a.luminance(); - l2 = b.luminance(); - if (l1 > l2) { - return (l1 + 0.05) / (l2 + 0.05); - } else { - return (l2 + 0.05) / (l1 + 0.05); - } - }; - - Color.prototype.get = function(modechan) { - var channel, i, me, mode, ref, src; - me = this; - ref = modechan.split('.'), mode = ref[0], channel = ref[1]; - src = me[mode](); - if (channel) { - i = mode.indexOf(channel); - if (i > -1) { - return src[i]; - } else { - return console.warn('unknown channel ' + channel + ' in mode ' + mode); - } - } else { - return src; - } - }; - - Color.prototype.set = function(modechan, value) { - var channel, i, me, mode, ref, src; - me = this; - ref = modechan.split('.'), mode = ref[0], channel = ref[1]; - if (channel) { - src = me[mode](); - i = mode.indexOf(channel); - if (i > -1) { - if (type(value) === 'string') { - switch (value.charAt(0)) { - case '+': - src[i] += +value; - break; - case '-': - src[i] += +value; - break; - case '*': - src[i] *= +(value.substr(1)); - break; - case '/': - src[i] /= +(value.substr(1)); - break; - default: - src[i] = +value; - } - } else { - src[i] = value; - } - } else { - console.warn('unknown channel ' + channel + ' in mode ' + mode); - } - } else { - src = value; - } - me._rgb = chroma(src, mode).alpha(me.alpha())._rgb; - return me; - }; - - Color.prototype.darken = function(amount) { - var lab, me; - if (amount == null) { - amount = 1; - } - me = this; - lab = me.lab(); - lab[0] -= LAB_CONSTANTS.Kn * amount; - return chroma.lab(lab).alpha(me.alpha()); - }; - - Color.prototype.brighten = function(amount) { - if (amount == null) { - amount = 1; - } - return this.darken(-amount); - }; - - Color.prototype.darker = Color.prototype.darken; - - Color.prototype.brighter = Color.prototype.brighten; - - Color.prototype.saturate = function(amount) { - var lch, me; - if (amount == null) { - amount = 1; - } - me = this; - lch = me.lch(); - lch[1] += amount * LAB_CONSTANTS.Kn; - if (lch[1] < 0) { - lch[1] = 0; - } - return chroma.lch(lch).alpha(me.alpha()); - }; - - Color.prototype.desaturate = function(amount) { - if (amount == null) { - amount = 1; - } - return this.saturate(-amount); - }; - - Color.prototype.premultiply = function() { - var a, rgb; - rgb = this.rgb(); - a = this.alpha(); - return chroma(rgb[0] * a, rgb[1] * a, rgb[2] * a, a); - }; - - blend = function(bottom, top, mode) { - if (!blend[mode]) { - throw 'unknown blend mode ' + mode; - } - return blend[mode](bottom, top); - }; - - blend_f = function(f) { - return function(bottom, top) { - var c0, c1; - c0 = chroma(top).rgb(); - c1 = chroma(bottom).rgb(); - return chroma(f(c0, c1), 'rgb'); - }; - }; - - each = function(f) { - return function(c0, c1) { - var i, o, out; - out = []; - for (i = o = 0; o <= 3; i = ++o) { - out[i] = f(c0[i], c1[i]); - } - return out; - }; - }; - - normal = function(a, b) { - return a; - }; - - multiply = function(a, b) { - return a * b / 255; - }; - - darken = function(a, b) { - if (a > b) { - return b; - } else { - return a; - } - }; - - lighten = function(a, b) { - if (a > b) { - return a; - } else { - return b; - } - }; - - screen = function(a, b) { - return 255 * (1 - (1 - a / 255) * (1 - b / 255)); - }; - - overlay = function(a, b) { - if (b < 128) { - return 2 * a * b / 255; - } else { - return 255 * (1 - 2 * (1 - a / 255) * (1 - b / 255)); - } - }; - - burn = function(a, b) { - return 255 * (1 - (1 - b / 255) / (a / 255)); - }; - - dodge = function(a, b) { - if (a === 255) { - return 255; - } - a = 255 * (b / 255) / (1 - a / 255); - if (a > 255) { - return 255; - } else { - return a; - } - }; - - blend.normal = blend_f(each(normal)); - - blend.multiply = blend_f(each(multiply)); - - blend.screen = blend_f(each(screen)); - - blend.overlay = blend_f(each(overlay)); - - blend.darken = blend_f(each(darken)); - - blend.lighten = blend_f(each(lighten)); - - blend.dodge = blend_f(each(dodge)); - - blend.burn = blend_f(each(burn)); - - chroma.blend = blend; - - chroma.analyze = function(data) { - var len, o, r, val; - r = { - min: Number.MAX_VALUE, - max: Number.MAX_VALUE * -1, - sum: 0, - values: [], - count: 0 - }; - for (o = 0, len = data.length; o < len; o++) { - val = data[o]; - if ((val != null) && !isNaN(val)) { - r.values.push(val); - r.sum += val; - if (val < r.min) { - r.min = val; - } - if (val > r.max) { - r.max = val; - } - r.count += 1; - } - } - r.domain = [r.min, r.max]; - r.limits = function(mode, num) { - return chroma.limits(r, mode, num); - }; - return r; - }; - - chroma.scale = function(colors, positions) { - var _classes, _colorCache, _colors, _correctLightness, _domain, _fixed, _max, _min, _mode, _nacol, _out, _padding, _pos, _spread, classifyValue, f, getClass, getColor, resetCache, setColors, tmap; - _mode = 'rgb'; - _nacol = chroma('#ccc'); - _spread = 0; - _fixed = false; - _domain = [0, 1]; - _pos = []; - _padding = [0, 0]; - _classes = false; - _colors = []; - _out = false; - _min = 0; - _max = 1; - _correctLightness = false; - _colorCache = {}; - setColors = function(colors) { - var c, col, o, ref, ref1, ref2, w; - if (colors == null) { - colors = ['#fff', '#000']; - } - if ((colors != null) && type(colors) === 'string' && (((ref = chroma.brewer) != null ? ref[colors] : void 0) != null)) { - colors = chroma.brewer[colors]; - } - if (type(colors) === 'array') { - colors = colors.slice(0); - for (c = o = 0, ref1 = colors.length - 1; 0 <= ref1 ? o <= ref1 : o >= ref1; c = 0 <= ref1 ? ++o : --o) { - col = colors[c]; - if (type(col) === "string") { - colors[c] = chroma(col); - } - } - _pos.length = 0; - for (c = w = 0, ref2 = colors.length - 1; 0 <= ref2 ? w <= ref2 : w >= ref2; c = 0 <= ref2 ? ++w : --w) { - _pos.push(c / (colors.length - 1)); - } - } - resetCache(); - return _colors = colors; - }; - getClass = function(value) { - var i, n; - if (_classes != null) { - n = _classes.length - 1; - i = 0; - while (i < n && value >= _classes[i]) { - i++; - } - return i - 1; - } - return 0; - }; - tmap = function(t) { - return t; - }; - classifyValue = function(value) { - var i, maxc, minc, n, val; - val = value; - if (_classes.length > 2) { - n = _classes.length - 1; - i = getClass(value); - minc = _classes[0] + (_classes[1] - _classes[0]) * (0 + _spread * 0.5); - maxc = _classes[n - 1] + (_classes[n] - _classes[n - 1]) * (1 - _spread * 0.5); - val = _min + ((_classes[i] + (_classes[i + 1] - _classes[i]) * 0.5 - minc) / (maxc - minc)) * (_max - _min); - } - return val; - }; - getColor = function(val, bypassMap) { - var c, col, i, k, o, p, ref, t; - if (bypassMap == null) { - bypassMap = false; - } - if (isNaN(val)) { - return _nacol; - } - if (!bypassMap) { - if (_classes && _classes.length > 2) { - c = getClass(val); - t = c / (_classes.length - 2); - t = _padding[0] + (t * (1 - _padding[0] - _padding[1])); - } else if (_max !== _min) { - t = (val - _min) / (_max - _min); - t = _padding[0] + (t * (1 - _padding[0] - _padding[1])); - t = Math.min(1, Math.max(0, t)); - } else { - t = 1; - } - } else { - t = val; - } - if (!bypassMap) { - t = tmap(t); - } - k = Math.floor(t * 10000); - if (_colorCache[k]) { - col = _colorCache[k]; - } else { - if (type(_colors) === 'array') { - for (i = o = 0, ref = _pos.length - 1; 0 <= ref ? o <= ref : o >= ref; i = 0 <= ref ? ++o : --o) { - p = _pos[i]; - if (t <= p) { - col = _colors[i]; - break; - } - if (t >= p && i === _pos.length - 1) { - col = _colors[i]; - break; - } - if (t > p && t < _pos[i + 1]) { - t = (t - p) / (_pos[i + 1] - p); - col = chroma.interpolate(_colors[i], _colors[i + 1], t, _mode); - break; - } - } - } else if (type(_colors) === 'function') { - col = _colors(t); - } - _colorCache[k] = col; - } - return col; - }; - resetCache = function() { - return _colorCache = {}; - }; - setColors(colors); - f = function(v) { - var c; - c = chroma(getColor(v)); - if (_out && c[_out]) { - return c[_out](); - } else { - return c; - } - }; - f.classes = function(classes) { - var d; - if (classes != null) { - if (type(classes) === 'array') { - _classes = classes; - _domain = [classes[0], classes[classes.length - 1]]; - } else { - d = chroma.analyze(_domain); - if (classes === 0) { - _classes = [d.min, d.max]; - } else { - _classes = chroma.limits(d, 'e', classes); - } - } - return f; - } - return _classes; - }; - f.domain = function(domain) { - var c, d, k, len, o, ref, w; - if (!arguments.length) { - return _domain; - } - _min = domain[0]; - _max = domain[domain.length - 1]; - _pos = []; - k = _colors.length; - if (domain.length === k && _min !== _max) { - for (o = 0, len = domain.length; o < len; o++) { - d = domain[o]; - _pos.push((d - _min) / (_max - _min)); - } - } else { - for (c = w = 0, ref = k - 1; 0 <= ref ? w <= ref : w >= ref; c = 0 <= ref ? ++w : --w) { - _pos.push(c / (k - 1)); - } - } - _domain = [_min, _max]; - return f; - }; - f.mode = function(_m) { - if (!arguments.length) { - return _mode; - } - _mode = _m; - resetCache(); - return f; - }; - f.range = function(colors, _pos) { - setColors(colors, _pos); - return f; - }; - f.out = function(_o) { - _out = _o; - return f; - }; - f.spread = function(val) { - if (!arguments.length) { - return _spread; - } - _spread = val; - return f; - }; - f.correctLightness = function(v) { - if (v == null) { - v = true; - } - _correctLightness = v; - resetCache(); - if (_correctLightness) { - tmap = function(t) { - var L0, L1, L_actual, L_diff, L_ideal, max_iter, pol, t0, t1; - L0 = getColor(0, true).lab()[0]; - L1 = getColor(1, true).lab()[0]; - pol = L0 > L1; - L_actual = getColor(t, true).lab()[0]; - L_ideal = L0 + (L1 - L0) * t; - L_diff = L_actual - L_ideal; - t0 = 0; - t1 = 1; - max_iter = 20; - while (Math.abs(L_diff) > 1e-2 && max_iter-- > 0) { - (function() { - if (pol) { - L_diff *= -1; - } - if (L_diff < 0) { - t0 = t; - t += (t1 - t) * 0.5; - } else { - t1 = t; - t += (t0 - t) * 0.5; - } - L_actual = getColor(t, true).lab()[0]; - return L_diff = L_actual - L_ideal; - })(); - } - return t; - }; - } else { - tmap = function(t) { - return t; - }; - } - return f; - }; - f.padding = function(p) { - if (p != null) { - if (type(p) === 'number') { - p = [p, p]; - } - _padding = p; - return f; - } else { - return _padding; - } - }; - f.colors = function() { - var dd, dm, i, numColors, o, out, ref, results, samples, w; - numColors = 0; - out = 'hex'; - if (arguments.length === 1) { - if (type(arguments[0]) === 'string') { - out = arguments[0]; - } else { - numColors = arguments[0]; - } - } - if (arguments.length === 2) { - numColors = arguments[0], out = arguments[1]; - } - if (numColors) { - dm = _domain[0]; - dd = _domain[1] - dm; - return (function() { - results = []; - for (var o = 0; 0 <= numColors ? o < numColors : o > numColors; 0 <= numColors ? o++ : o--){ results.push(o); } - return results; - }).apply(this).map(function(i) { - return f(dm + i / (numColors - 1) * dd)[out](); - }); - } - colors = []; - samples = []; - if (_classes && _classes.length > 2) { - for (i = w = 1, ref = _classes.length; 1 <= ref ? w < ref : w > ref; i = 1 <= ref ? ++w : --w) { - samples.push((_classes[i - 1] + _classes[i]) * 0.5); - } - } else { - samples = _domain; - } - return samples.map(function(v) { - return f(v)[out](); - }); - }; - return f; - }; - - if (chroma.scales == null) { - chroma.scales = {}; - } - - chroma.scales.cool = function() { - return chroma.scale([chroma.hsl(180, 1, .9), chroma.hsl(250, .7, .4)]); - }; - - chroma.scales.hot = function() { - return chroma.scale(['#000', '#f00', '#ff0', '#fff'], [0, .25, .75, 1]).mode('rgb'); - }; - - chroma.analyze = function(data, key, filter) { - var add, k, len, o, r, val, visit; - r = { - min: Number.MAX_VALUE, - max: Number.MAX_VALUE * -1, - sum: 0, - values: [], - count: 0 - }; - if (filter == null) { - filter = function() { - return true; - }; - } - add = function(val) { - if ((val != null) && !isNaN(val)) { - r.values.push(val); - r.sum += val; - if (val < r.min) { - r.min = val; - } - if (val > r.max) { - r.max = val; - } - r.count += 1; - } - }; - visit = function(val, k) { - if (filter(val, k)) { - if ((key != null) && type(key) === 'function') { - return add(key(val)); - } else if ((key != null) && type(key) === 'string' || type(key) === 'number') { - return add(val[key]); - } else { - return add(val); - } - } - }; - if (type(data) === 'array') { - for (o = 0, len = data.length; o < len; o++) { - val = data[o]; - visit(val); - } - } else { - for (k in data) { - val = data[k]; - visit(val, k); - } - } - r.domain = [r.min, r.max]; - r.limits = function(mode, num) { - return chroma.limits(r, mode, num); - }; - return r; - }; - - chroma.limits = function(data, mode, num) { - var aa, ab, ac, ad, ae, af, ag, ah, ai, aj, ak, al, am, assignments, best, centroids, cluster, clusterSizes, dist, i, j, kClusters, limits, max_log, min, min_log, mindist, n, nb_iters, newCentroids, o, p, pb, pr, ref, ref1, ref10, ref11, ref12, ref13, ref14, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, repeat, sum, tmpKMeansBreaks, value, values, w; - if (mode == null) { - mode = 'equal'; - } - if (num == null) { - num = 7; - } - if (type(data) === 'array') { - data = chroma.analyze(data); - } - min = data.min; - max = data.max; - sum = data.sum; - values = data.values.sort(function(a, b) { - return a - b; - }); - limits = []; - if (mode.substr(0, 1) === 'c') { - limits.push(min); - limits.push(max); - } - if (mode.substr(0, 1) === 'e') { - limits.push(min); - for (i = o = 1, ref = num - 1; 1 <= ref ? o <= ref : o >= ref; i = 1 <= ref ? ++o : --o) { - limits.push(min + (i / num) * (max - min)); - } - limits.push(max); - } else if (mode.substr(0, 1) === 'l') { - if (min <= 0) { - throw 'Logarithmic scales are only possible for values > 0'; - } - min_log = Math.LOG10E * log(min); - max_log = Math.LOG10E * log(max); - limits.push(min); - for (i = w = 1, ref1 = num - 1; 1 <= ref1 ? w <= ref1 : w >= ref1; i = 1 <= ref1 ? ++w : --w) { - limits.push(pow(10, min_log + (i / num) * (max_log - min_log))); - } - limits.push(max); - } else if (mode.substr(0, 1) === 'q') { - limits.push(min); - for (i = aa = 1, ref2 = num - 1; 1 <= ref2 ? aa <= ref2 : aa >= ref2; i = 1 <= ref2 ? ++aa : --aa) { - p = values.length * i / num; - pb = floor(p); - if (pb === p) { - limits.push(values[pb]); - } else { - pr = p - pb; - limits.push(values[pb] * pr + values[pb + 1] * (1 - pr)); - } - } - limits.push(max); - } else if (mode.substr(0, 1) === 'k') { - - /* - implementation based on - http://code.google.com/p/figue/source/browse/trunk/figue.js#336 - simplified for 1-d input values - */ - n = values.length; - assignments = new Array(n); - clusterSizes = new Array(num); - repeat = true; - nb_iters = 0; - centroids = null; - centroids = []; - centroids.push(min); - for (i = ab = 1, ref3 = num - 1; 1 <= ref3 ? ab <= ref3 : ab >= ref3; i = 1 <= ref3 ? ++ab : --ab) { - centroids.push(min + (i / num) * (max - min)); - } - centroids.push(max); - while (repeat) { - for (j = ac = 0, ref4 = num - 1; 0 <= ref4 ? ac <= ref4 : ac >= ref4; j = 0 <= ref4 ? ++ac : --ac) { - clusterSizes[j] = 0; - } - for (i = ad = 0, ref5 = n - 1; 0 <= ref5 ? ad <= ref5 : ad >= ref5; i = 0 <= ref5 ? ++ad : --ad) { - value = values[i]; - mindist = Number.MAX_VALUE; - for (j = ae = 0, ref6 = num - 1; 0 <= ref6 ? ae <= ref6 : ae >= ref6; j = 0 <= ref6 ? ++ae : --ae) { - dist = abs(centroids[j] - value); - if (dist < mindist) { - mindist = dist; - best = j; - } - } - clusterSizes[best]++; - assignments[i] = best; - } - newCentroids = new Array(num); - for (j = af = 0, ref7 = num - 1; 0 <= ref7 ? af <= ref7 : af >= ref7; j = 0 <= ref7 ? ++af : --af) { - newCentroids[j] = null; - } - for (i = ag = 0, ref8 = n - 1; 0 <= ref8 ? ag <= ref8 : ag >= ref8; i = 0 <= ref8 ? ++ag : --ag) { - cluster = assignments[i]; - if (newCentroids[cluster] === null) { - newCentroids[cluster] = values[i]; - } else { - newCentroids[cluster] += values[i]; - } - } - for (j = ah = 0, ref9 = num - 1; 0 <= ref9 ? ah <= ref9 : ah >= ref9; j = 0 <= ref9 ? ++ah : --ah) { - newCentroids[j] *= 1 / clusterSizes[j]; - } - repeat = false; - for (j = ai = 0, ref10 = num - 1; 0 <= ref10 ? ai <= ref10 : ai >= ref10; j = 0 <= ref10 ? ++ai : --ai) { - if (newCentroids[j] !== centroids[i]) { - repeat = true; - break; - } - } - centroids = newCentroids; - nb_iters++; - if (nb_iters > 200) { - repeat = false; - } - } - kClusters = {}; - for (j = aj = 0, ref11 = num - 1; 0 <= ref11 ? aj <= ref11 : aj >= ref11; j = 0 <= ref11 ? ++aj : --aj) { - kClusters[j] = []; - } - for (i = ak = 0, ref12 = n - 1; 0 <= ref12 ? ak <= ref12 : ak >= ref12; i = 0 <= ref12 ? ++ak : --ak) { - cluster = assignments[i]; - kClusters[cluster].push(values[i]); - } - tmpKMeansBreaks = []; - for (j = al = 0, ref13 = num - 1; 0 <= ref13 ? al <= ref13 : al >= ref13; j = 0 <= ref13 ? ++al : --al) { - tmpKMeansBreaks.push(kClusters[j][0]); - tmpKMeansBreaks.push(kClusters[j][kClusters[j].length - 1]); - } - tmpKMeansBreaks = tmpKMeansBreaks.sort(function(a, b) { - return a - b; - }); - limits.push(tmpKMeansBreaks[0]); - for (i = am = 1, ref14 = tmpKMeansBreaks.length - 1; am <= ref14; i = am += 2) { - if (!isNaN(tmpKMeansBreaks[i])) { - limits.push(tmpKMeansBreaks[i]); - } - } - } - return limits; - }; - - hsi2rgb = function(h, s, i) { - - /* - borrowed from here: - http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/hsi2rgb.cpp - */ - var args, b, g, r; - args = unpack(arguments); - h = args[0], s = args[1], i = args[2]; - h /= 360; - if (h < 1 / 3) { - b = (1 - s) / 3; - r = (1 + s * cos(TWOPI * h) / cos(PITHIRD - TWOPI * h)) / 3; - g = 1 - (b + r); - } else if (h < 2 / 3) { - h -= 1 / 3; - r = (1 - s) / 3; - g = (1 + s * cos(TWOPI * h) / cos(PITHIRD - TWOPI * h)) / 3; - b = 1 - (r + g); - } else { - h -= 2 / 3; - g = (1 - s) / 3; - b = (1 + s * cos(TWOPI * h) / cos(PITHIRD - TWOPI * h)) / 3; - r = 1 - (g + b); - } - r = limit(i * r * 3); - g = limit(i * g * 3); - b = limit(i * b * 3); - return [r * 255, g * 255, b * 255, args.length > 3 ? args[3] : 1]; - }; - - rgb2hsi = function() { - - /* - borrowed from here: - http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/rgb2hsi.cpp - */ - var b, g, h, i, min, r, ref, s; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - TWOPI = Math.PI * 2; - r /= 255; - g /= 255; - b /= 255; - min = Math.min(r, g, b); - i = (r + g + b) / 3; - s = 1 - min / i; - if (s === 0) { - h = 0; - } else { - h = ((r - g) + (r - b)) / 2; - h /= Math.sqrt((r - g) * (r - g) + (r - b) * (g - b)); - h = Math.acos(h); - if (b > g) { - h = TWOPI - h; - } - h /= TWOPI; - } - return [h * 360, s, i]; - }; - - chroma.hsi = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['hsi']), function(){}); - }; - - _input.hsi = hsi2rgb; - - Color.prototype.hsi = function() { - return rgb2hsi(this._rgb); - }; - - interpolate_hsx = function(col1, col2, f, m) { - var dh, hue, hue0, hue1, lbv, lbv0, lbv1, res, sat, sat0, sat1, xyz0, xyz1; - if (m === 'hsl') { - xyz0 = col1.hsl(); - xyz1 = col2.hsl(); - } else if (m === 'hsv') { - xyz0 = col1.hsv(); - xyz1 = col2.hsv(); - } else if (m === 'hsi') { - xyz0 = col1.hsi(); - xyz1 = col2.hsi(); - } else if (m === 'lch' || m === 'hcl') { - m = 'hcl'; - xyz0 = col1.hcl(); - xyz1 = col2.hcl(); - } - if (m.substr(0, 1) === 'h') { - hue0 = xyz0[0], sat0 = xyz0[1], lbv0 = xyz0[2]; - hue1 = xyz1[0], sat1 = xyz1[1], lbv1 = xyz1[2]; - } - if (!isNaN(hue0) && !isNaN(hue1)) { - if (hue1 > hue0 && hue1 - hue0 > 180) { - dh = hue1 - (hue0 + 360); - } else if (hue1 < hue0 && hue0 - hue1 > 180) { - dh = hue1 + 360 - hue0; - } else { - dh = hue1 - hue0; - } - hue = hue0 + f * dh; - } else if (!isNaN(hue0)) { - hue = hue0; - if ((lbv1 === 1 || lbv1 === 0) && m !== 'hsv') { - sat = sat0; - } - } else if (!isNaN(hue1)) { - hue = hue1; - if ((lbv0 === 1 || lbv0 === 0) && m !== 'hsv') { - sat = sat1; - } - } else { - hue = Number.NaN; - } - if (sat == null) { - sat = sat0 + f * (sat1 - sat0); - } - lbv = lbv0 + f * (lbv1 - lbv0); - return res = chroma[m](hue, sat, lbv); - }; - - _interpolators = _interpolators.concat((function() { - var len, o, ref, results; - ref = ['hsv', 'hsl', 'hsi', 'hcl', 'lch']; - results = []; - for (o = 0, len = ref.length; o < len; o++) { - m = ref[o]; - results.push([m, interpolate_hsx]); - } - return results; - })()); - - interpolate_num = function(col1, col2, f, m) { - var n1, n2; - n1 = col1.num(); - n2 = col2.num(); - return chroma.num(n1 + (n2 - n1) * f, 'num'); - }; - - _interpolators.push(['num', interpolate_num]); - - interpolate_lab = function(col1, col2, f, m) { - var res, xyz0, xyz1; - xyz0 = col1.lab(); - xyz1 = col2.lab(); - return res = new Color(xyz0[0] + f * (xyz1[0] - xyz0[0]), xyz0[1] + f * (xyz1[1] - xyz0[1]), xyz0[2] + f * (xyz1[2] - xyz0[2]), m); - }; - - _interpolators.push(['lab', interpolate_lab]); - -}).call(this); - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(336)(module))) - -/***/ }), -/* 211 */ -/***/ (function(module, exports, __webpack_require__) { - -var pSlice = Array.prototype.slice; -var objectKeys = __webpack_require__(213); -var isArguments = __webpack_require__(212); - -var deepEqual = module.exports = function (actual, expected, opts) { - if (!opts) opts = {}; - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - - } else if (actual instanceof Date && expected instanceof Date) { - return actual.getTime() === expected.getTime(); - - // 7.3. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if (!actual || !expected || typeof actual != 'object' && typeof expected != 'object') { - return opts.strict ? actual === expected : actual == expected; - - // 7.4. For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected, opts); - } -} - -function isUndefinedOrNull(value) { - return value === null || value === undefined; -} - -function isBuffer (x) { - if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false; - if (typeof x.copy !== 'function' || typeof x.slice !== 'function') { - return false; - } - if (x.length > 0 && typeof x[0] !== 'number') return false; - return true; -} - -function objEquiv(a, b, opts) { - var i, key; - if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) - return false; - // an identical 'prototype' property. - if (a.prototype !== b.prototype) return false; - //~~~I've managed to break Object.keys through screwy arguments passing. - // Converting to array solves the problem. - if (isArguments(a)) { - if (!isArguments(b)) { - return false; - } - a = pSlice.call(a); - b = pSlice.call(b); - return deepEqual(a, b, opts); - } - if (isBuffer(a)) { - if (!isBuffer(b)) { - return false; - } - if (a.length !== b.length) return false; - for (i = 0; i < a.length; i++) { - if (a[i] !== b[i]) return false; - } - return true; - } - try { - var ka = objectKeys(a), - kb = objectKeys(b); - } catch (e) {//happens when one is a string literal and the other isn't - return false; - } - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length != kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] != kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!deepEqual(a[key], b[key], opts)) return false; - } - return typeof a === typeof b; -} - - -/***/ }), -/* 212 */ -/***/ (function(module, exports) { - -var supportsArgumentsClass = (function(){ - return Object.prototype.toString.call(arguments) -})() == '[object Arguments]'; - -exports = module.exports = supportsArgumentsClass ? supported : unsupported; - -exports.supported = supported; -function supported(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -}; - -exports.unsupported = unsupported; -function unsupported(object){ - return object && - typeof object == 'object' && - typeof object.length == 'number' && - Object.prototype.hasOwnProperty.call(object, 'callee') && - !Object.prototype.propertyIsEnumerable.call(object, 'callee') || - false; -}; - - -/***/ }), -/* 213 */ -/***/ (function(module, exports) { - -exports = module.exports = typeof Object.keys === 'function' - ? Object.keys : shim; - -exports.shim = shim; -function shim (obj) { - var keys = []; - for (var key in obj) keys.push(key); - return keys; -} - - -/***/ }), -/* 214 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -var _hyphenPattern = /-(.)/g; - -/** - * Camelcases a hyphenated string, for example: - * - * > camelize('background-color') - * < "backgroundColor" - * - * @param {string} string - * @return {string} - */ -function camelize(string) { - return string.replace(_hyphenPattern, function (_, character) { - return character.toUpperCase(); - }); -} - -module.exports = camelize; - -/***/ }), -/* 215 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - - - -var camelize = __webpack_require__(214); - -var msPattern = /^-ms-/; - -/** - * Camelcases a hyphenated CSS property name, for example: - * - * > camelizeStyleName('background-color') - * < "backgroundColor" - * > camelizeStyleName('-moz-transition') - * < "MozTransition" - * > camelizeStyleName('-ms-transition') - * < "msTransition" - * - * As Andi Smith suggests - * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix - * is converted to lowercase `ms`. - * - * @param {string} string - * @return {string} - */ -function camelizeStyleName(string) { - return camelize(string.replace(msPattern, 'ms-')); -} - -module.exports = camelizeStyleName; - -/***/ }), -/* 216 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - -var isTextNode = __webpack_require__(224); - -/*eslint-disable no-bitwise */ - -/** - * Checks if a given DOM node contains or is another DOM node. - */ -function containsNode(outerNode, innerNode) { - if (!outerNode || !innerNode) { - return false; - } else if (outerNode === innerNode) { - return true; - } else if (isTextNode(outerNode)) { - return false; - } else if (isTextNode(innerNode)) { - return containsNode(outerNode, innerNode.parentNode); - } else if ('contains' in outerNode) { - return outerNode.contains(innerNode); - } else if (outerNode.compareDocumentPosition) { - return !!(outerNode.compareDocumentPosition(innerNode) & 16); - } else { - return false; - } -} - -module.exports = containsNode; - -/***/ }), -/* 217 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -var invariant = __webpack_require__(2); - -/** - * Convert array-like objects to arrays. - * - * This API assumes the caller knows the contents of the data type. For less - * well defined inputs use createArrayFromMixed. - * - * @param {object|function|filelist} obj - * @return {array} - */ -function toArray(obj) { - var length = obj.length; - - // Some browsers builtin objects can report typeof 'function' (e.g. NodeList - // in old versions of Safari). - !(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Array-like object expected') : invariant(false) : void 0; - - !(typeof length === 'number') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object needs a length property') : invariant(false) : void 0; - - !(length === 0 || length - 1 in obj) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object should have keys for indices') : invariant(false) : void 0; - - !(typeof obj.callee !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object can\'t be `arguments`. Use rest params ' + '(function(...args) {}) or Array.from() instead.') : invariant(false) : void 0; - - // Old IE doesn't give collections access to hasOwnProperty. Assume inputs - // without method will throw during the slice call and skip straight to the - // fallback. - if (obj.hasOwnProperty) { - try { - return Array.prototype.slice.call(obj); - } catch (e) { - // IE < 9 does not support Array#slice on collections objects - } - } - - // Fall back to copying key by key. This assumes all keys have a value, - // so will not preserve sparsely populated inputs. - var ret = Array(length); - for (var ii = 0; ii < length; ii++) { - ret[ii] = obj[ii]; - } - return ret; -} - -/** - * Perform a heuristic test to determine if an object is "array-like". - * - * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?" - * Joshu replied: "Mu." - * - * This function determines if its argument has "array nature": it returns - * true if the argument is an actual array, an `arguments' object, or an - * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()). - * - * It will return false for other array-like objects like Filelist. - * - * @param {*} obj - * @return {boolean} - */ -function hasArrayNature(obj) { - return ( - // not null/false - !!obj && ( - // arrays are objects, NodeLists are functions in Safari - typeof obj == 'object' || typeof obj == 'function') && - // quacks like an array - 'length' in obj && - // not window - !('setInterval' in obj) && - // no DOM node should be considered an array-like - // a 'select' element has 'length' and 'item' properties on IE8 - typeof obj.nodeType != 'number' && ( - // a real array - Array.isArray(obj) || - // arguments - 'callee' in obj || - // HTMLCollection/NodeList - 'item' in obj) - ); -} - -/** - * Ensure that the argument is an array by wrapping it in an array if it is not. - * Creates a copy of the argument if it is already an array. - * - * This is mostly useful idiomatically: - * - * var createArrayFromMixed = require('createArrayFromMixed'); - * - * function takesOneOrMoreThings(things) { - * things = createArrayFromMixed(things); - * ... - * } - * - * This allows you to treat `things' as an array, but accept scalars in the API. - * - * If you need to convert an array-like object, like `arguments`, into an array - * use toArray instead. - * - * @param {*} obj - * @return {array} - */ -function createArrayFromMixed(obj) { - if (!hasArrayNature(obj)) { - return [obj]; - } else if (Array.isArray(obj)) { - return obj.slice(); - } else { - return toArray(obj); - } -} - -module.exports = createArrayFromMixed; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 218 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -/*eslint-disable fb-www/unsafe-html*/ - -var ExecutionEnvironment = __webpack_require__(8); - -var createArrayFromMixed = __webpack_require__(217); -var getMarkupWrap = __webpack_require__(219); -var invariant = __webpack_require__(2); - -/** - * Dummy container used to render all markup. - */ -var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; - -/** - * Pattern used by `getNodeName`. - */ -var nodeNamePattern = /^\s*<(\w+)/; - -/** - * Extracts the `nodeName` of the first element in a string of markup. - * - * @param {string} markup String of markup. - * @return {?string} Node name of the supplied markup. - */ -function getNodeName(markup) { - var nodeNameMatch = markup.match(nodeNamePattern); - return nodeNameMatch && nodeNameMatch[1].toLowerCase(); -} - -/** - * Creates an array containing the nodes rendered from the supplied markup. The - * optionally supplied `handleScript` function will be invoked once for each - * <script> element that is rendered. If no `handleScript` function is supplied, - * an exception is thrown if any <script> elements are rendered. - * - * @param {string} markup A string of valid HTML markup. - * @param {?function} handleScript Invoked once for each rendered <script>. - * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes. - */ -function createNodesFromMarkup(markup, handleScript) { - var node = dummyNode; - !!!dummyNode ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createNodesFromMarkup dummy not initialized') : invariant(false) : void 0; - var nodeName = getNodeName(markup); - - var wrap = nodeName && getMarkupWrap(nodeName); - if (wrap) { - node.innerHTML = wrap[1] + markup + wrap[2]; - - var wrapDepth = wrap[0]; - while (wrapDepth--) { - node = node.lastChild; - } - } else { - node.innerHTML = markup; - } - - var scripts = node.getElementsByTagName('script'); - if (scripts.length) { - !handleScript ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createNodesFromMarkup(...): Unexpected <script> element rendered.') : invariant(false) : void 0; - createArrayFromMixed(scripts).forEach(handleScript); - } - - var nodes = Array.from(node.childNodes); - while (node.lastChild) { - node.removeChild(node.lastChild); - } - return nodes; -} - -module.exports = createNodesFromMarkup; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 219 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -/*eslint-disable fb-www/unsafe-html */ - -var ExecutionEnvironment = __webpack_require__(8); - -var invariant = __webpack_require__(2); - -/** - * Dummy container used to detect which wraps are necessary. - */ -var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; - -/** - * Some browsers cannot use `innerHTML` to render certain elements standalone, - * so we wrap them, render the wrapped nodes, then extract the desired node. - * - * In IE8, certain elements cannot render alone, so wrap all elements ('*'). - */ - -var shouldWrap = {}; - -var selectWrap = [1, '<select multiple="true">', '</select>']; -var tableWrap = [1, '<table>', '</table>']; -var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>']; - -var svgWrap = [1, '<svg xmlns="http://www.w3.org/2000/svg">', '</svg>']; - -var markupWrap = { - '*': [1, '?<div>', '</div>'], - - 'area': [1, '<map>', '</map>'], - 'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'], - 'legend': [1, '<fieldset>', '</fieldset>'], - 'param': [1, '<object>', '</object>'], - 'tr': [2, '<table><tbody>', '</tbody></table>'], - - 'optgroup': selectWrap, - 'option': selectWrap, - - 'caption': tableWrap, - 'colgroup': tableWrap, - 'tbody': tableWrap, - 'tfoot': tableWrap, - 'thead': tableWrap, - - 'td': trWrap, - 'th': trWrap -}; - -// Initialize the SVG elements since we know they'll always need to be wrapped -// consistently. If they are created inside a <div> they will be initialized in -// the wrong namespace (and will not display). -var svgElements = ['circle', 'clipPath', 'defs', 'ellipse', 'g', 'image', 'line', 'linearGradient', 'mask', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'text', 'tspan']; -svgElements.forEach(function (nodeName) { - markupWrap[nodeName] = svgWrap; - shouldWrap[nodeName] = true; -}); - -/** - * Gets the markup wrap configuration for the supplied `nodeName`. - * - * NOTE: This lazily detects which wraps are necessary for the current browser. - * - * @param {string} nodeName Lowercase `nodeName`. - * @return {?array} Markup wrap configuration, if applicable. - */ -function getMarkupWrap(nodeName) { - !!!dummyNode ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Markup wrapping node not initialized') : invariant(false) : void 0; - if (!markupWrap.hasOwnProperty(nodeName)) { - nodeName = '*'; - } - if (!shouldWrap.hasOwnProperty(nodeName)) { - if (nodeName === '*') { - dummyNode.innerHTML = '<link />'; - } else { - dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>'; - } - shouldWrap[nodeName] = !dummyNode.firstChild; - } - return shouldWrap[nodeName] ? markupWrap[nodeName] : null; -} - -module.exports = getMarkupWrap; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 220 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - - - -/** - * Gets the scroll position of the supplied element or window. - * - * The return values are unbounded, unlike `getScrollPosition`. This means they - * may be negative or exceed the element boundaries (which is possible using - * inertial scrolling). - * - * @param {DOMWindow|DOMElement} scrollable - * @return {object} Map with `x` and `y` keys. - */ - -function getUnboundedScrollPosition(scrollable) { - if (scrollable === window) { - return { - x: window.pageXOffset || document.documentElement.scrollLeft, - y: window.pageYOffset || document.documentElement.scrollTop - }; - } - return { - x: scrollable.scrollLeft, - y: scrollable.scrollTop - }; -} - -module.exports = getUnboundedScrollPosition; - -/***/ }), -/* 221 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -var _uppercasePattern = /([A-Z])/g; - -/** - * Hyphenates a camelcased string, for example: - * - * > hyphenate('backgroundColor') - * < "background-color" - * - * For CSS style names, use `hyphenateStyleName` instead which works properly - * with all vendor prefixes, including `ms`. - * - * @param {string} string - * @return {string} - */ -function hyphenate(string) { - return string.replace(_uppercasePattern, '-$1').toLowerCase(); -} - -module.exports = hyphenate; - -/***/ }), -/* 222 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - - - -var hyphenate = __webpack_require__(221); - -var msPattern = /^ms-/; - -/** - * Hyphenates a camelcased CSS property name, for example: - * - * > hyphenateStyleName('backgroundColor') - * < "background-color" - * > hyphenateStyleName('MozTransition') - * < "-moz-transition" - * > hyphenateStyleName('msTransition') - * < "-ms-transition" - * - * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix - * is converted to `-ms-`. - * - * @param {string} string - * @return {string} - */ -function hyphenateStyleName(string) { - return hyphenate(string).replace(msPattern, '-ms-'); -} - -module.exports = hyphenateStyleName; - -/***/ }), -/* 223 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -/** - * @param {*} object The object to check. - * @return {boolean} Whether or not the object is a DOM node. - */ -function isNode(object) { - return !!(object && (typeof Node === 'function' ? object instanceof Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string')); -} - -module.exports = isNode; - -/***/ }), -/* 224 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -var isNode = __webpack_require__(223); - -/** - * @param {*} object The object to check. - * @return {boolean} Whether or not the object is a DOM text node. - */ -function isTextNode(object) { - return isNode(object) && object.nodeType == 3; -} - -module.exports = isTextNode; - -/***/ }), -/* 225 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - * @typechecks static-only - */ - - - -/** - * Memoizes the return value of a function that accepts one string argument. - */ - -function memoizeStringOnly(callback) { - var cache = {}; - return function (string) { - if (!cache.hasOwnProperty(string)) { - cache[string] = callback.call(this, string); - } - return cache[string]; - }; -} - -module.exports = memoizeStringOnly; - -/***/ }), -/* 226 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - - - -var ExecutionEnvironment = __webpack_require__(8); - -var performance; - -if (ExecutionEnvironment.canUseDOM) { - performance = window.performance || window.msPerformance || window.webkitPerformance; -} - -module.exports = performance || {}; - -/***/ }), -/* 227 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -var performance = __webpack_require__(226); - -var performanceNow; - -/** - * Detect if we can use `window.performance.now()` and gracefully fallback to - * `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now - * because of Facebook's testing infrastructure. - */ -if (performance.now) { - performanceNow = function performanceNow() { - return performance.now(); - }; -} else { - performanceNow = function performanceNow() { - return Date.now(); - }; -} - -module.exports = performanceNow; - -/***/ }), -/* 228 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.loopAsync = loopAsync; - -function loopAsync(turns, work, callback) { - var currentTurn = 0; - var isDone = false; - - function done() { - isDone = true; - callback.apply(this, arguments); - } - - function next() { - if (isDone) return; - - if (currentTurn < turns) { - work.call(this, currentTurn++, next, done); - } else { - done.apply(this, arguments); - } - } - - next(); -} - -/***/ }), -/* 229 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/*eslint-disable no-empty */ - - -exports.__esModule = true; -exports.saveState = saveState; -exports.readState = readState; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var KeyPrefix = '@@History/'; -var QuotaExceededError = 'QuotaExceededError'; -var SecurityError = 'SecurityError'; - -function createKey(key) { - return KeyPrefix + key; -} - -function saveState(key, state) { - try { - window.sessionStorage.setItem(createKey(key), JSON.stringify(state)); - } catch (error) { - if (error.name === SecurityError) { - // Blocking cookies in Chrome/Firefox/Safari throws SecurityError on any - // attempt to access window.sessionStorage. - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, '[history] Unable to save state; sessionStorage is not available due to security settings') : undefined; - - return; - } - - if (error.name === QuotaExceededError && window.sessionStorage.length === 0) { - // Safari "private mode" throws QuotaExceededError. - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, '[history] Unable to save state; sessionStorage is not available in Safari private mode') : undefined; - - return; - } - - throw error; - } -} - -function readState(key) { - var json = undefined; - try { - json = window.sessionStorage.getItem(createKey(key)); - } catch (error) { - if (error.name === SecurityError) { - // Blocking cookies in Chrome/Firefox/Safari throws SecurityError on any - // attempt to access window.sessionStorage. - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, '[history] Unable to read state; sessionStorage is not available due to security settings') : undefined; - - return null; - } - } - - if (json) { - try { - return JSON.parse(json); - } catch (error) { - // Ignore invalid JSON. - } - } - - return null; -} -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 230 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _ExecutionEnvironment = __webpack_require__(43); - -var _DOMUtils = __webpack_require__(75); - -var _createHistory = __webpack_require__(76); - -var _createHistory2 = _interopRequireDefault(_createHistory); - -function createDOMHistory(options) { - var history = _createHistory2['default'](_extends({ - getUserConfirmation: _DOMUtils.getUserConfirmation - }, options, { - go: _DOMUtils.go - })); - - function listen(listener) { - !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'DOM history needs a DOM') : _invariant2['default'](false) : undefined; - - return history.listen(listener); - } - - return _extends({}, history, { - listen: listen - }); -} - -exports['default'] = createDOMHistory; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 231 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _Actions = __webpack_require__(29); - -var _ExecutionEnvironment = __webpack_require__(43); - -var _DOMUtils = __webpack_require__(75); - -var _DOMStateStorage = __webpack_require__(229); - -var _createDOMHistory = __webpack_require__(230); - -var _createDOMHistory2 = _interopRequireDefault(_createDOMHistory); - -var _parsePath = __webpack_require__(24); - -var _parsePath2 = _interopRequireDefault(_parsePath); - -function isAbsolutePath(path) { - return typeof path === 'string' && path.charAt(0) === '/'; -} - -function ensureSlash() { - var path = _DOMUtils.getHashPath(); - - if (isAbsolutePath(path)) return true; - - _DOMUtils.replaceHashPath('/' + path); - - return false; -} - -function addQueryStringValueToPath(path, key, value) { - return path + (path.indexOf('?') === -1 ? '?' : '&') + (key + '=' + value); -} - -function stripQueryStringValueFromPath(path, key) { - return path.replace(new RegExp('[?&]?' + key + '=[a-zA-Z0-9]+'), ''); -} - -function getQueryStringValueFromPath(path, key) { - var match = path.match(new RegExp('\\?.*?\\b' + key + '=(.+?)\\b')); - return match && match[1]; -} - -var DefaultQueryKey = '_k'; - -function createHashHistory() { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - - !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Hash history needs a DOM') : _invariant2['default'](false) : undefined; - - var queryKey = options.queryKey; - - if (queryKey === undefined || !!queryKey) queryKey = typeof queryKey === 'string' ? queryKey : DefaultQueryKey; - - function getCurrentLocation() { - var path = _DOMUtils.getHashPath(); - - var key = undefined, - state = undefined; - if (queryKey) { - key = getQueryStringValueFromPath(path, queryKey); - path = stripQueryStringValueFromPath(path, queryKey); - - if (key) { - state = _DOMStateStorage.readState(key); - } else { - state = null; - key = history.createKey(); - _DOMUtils.replaceHashPath(addQueryStringValueToPath(path, queryKey, key)); - } - } else { - key = state = null; - } - - var location = _parsePath2['default'](path); - - return history.createLocation(_extends({}, location, { state: state }), undefined, key); - } - - function startHashChangeListener(_ref) { - var transitionTo = _ref.transitionTo; - - function hashChangeListener() { - if (!ensureSlash()) return; // Always make sure hashes are preceeded with a /. - - transitionTo(getCurrentLocation()); - } - - ensureSlash(); - _DOMUtils.addEventListener(window, 'hashchange', hashChangeListener); - - return function () { - _DOMUtils.removeEventListener(window, 'hashchange', hashChangeListener); - }; - } - - function finishTransition(location) { - var basename = location.basename; - var pathname = location.pathname; - var search = location.search; - var state = location.state; - var action = location.action; - var key = location.key; - - if (action === _Actions.POP) return; // Nothing to do. - - var path = (basename || '') + pathname + search; - - if (queryKey) { - path = addQueryStringValueToPath(path, queryKey, key); - _DOMStateStorage.saveState(key, state); - } else { - // Drop key and state. - location.key = location.state = null; - } - - var currentHash = _DOMUtils.getHashPath(); - - if (action === _Actions.PUSH) { - if (currentHash !== path) { - window.location.hash = path; - } else { - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'You cannot PUSH the same path using hash history') : undefined; - } - } else if (currentHash !== path) { - // REPLACE - _DOMUtils.replaceHashPath(path); - } - } - - var history = _createDOMHistory2['default'](_extends({}, options, { - getCurrentLocation: getCurrentLocation, - finishTransition: finishTransition, - saveState: _DOMStateStorage.saveState - })); - - var listenerCount = 0, - stopHashChangeListener = undefined; - - function listenBefore(listener) { - if (++listenerCount === 1) stopHashChangeListener = startHashChangeListener(history); - - var unlisten = history.listenBefore(listener); - - return function () { - unlisten(); - - if (--listenerCount === 0) stopHashChangeListener(); - }; - } - - function listen(listener) { - if (++listenerCount === 1) stopHashChangeListener = startHashChangeListener(history); - - var unlisten = history.listen(listener); - - return function () { - unlisten(); - - if (--listenerCount === 0) stopHashChangeListener(); - }; - } - - function push(location) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](queryKey || location.state == null, 'You cannot use state without a queryKey it will be dropped') : undefined; - - history.push(location); - } - - function replace(location) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](queryKey || location.state == null, 'You cannot use state without a queryKey it will be dropped') : undefined; - - history.replace(location); - } - - var goIsSupportedWithoutReload = _DOMUtils.supportsGoWithoutReloadUsingHash(); - - function go(n) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](goIsSupportedWithoutReload, 'Hash history go(n) causes a full page reload in this browser') : undefined; - - history.go(n); - } - - function createHref(path) { - return '#' + history.createHref(path); - } - - // deprecated - function registerTransitionHook(hook) { - if (++listenerCount === 1) stopHashChangeListener = startHashChangeListener(history); - - history.registerTransitionHook(hook); - } - - // deprecated - function unregisterTransitionHook(hook) { - history.unregisterTransitionHook(hook); - - if (--listenerCount === 0) stopHashChangeListener(); - } - - // deprecated - function pushState(state, path) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](queryKey || state == null, 'You cannot use state without a queryKey it will be dropped') : undefined; - - history.pushState(state, path); - } - - // deprecated - function replaceState(state, path) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](queryKey || state == null, 'You cannot use state without a queryKey it will be dropped') : undefined; - - history.replaceState(state, path); - } - - return _extends({}, history, { - listenBefore: listenBefore, - listen: listen, - push: push, - replace: replace, - go: go, - createHref: createHref, - - registerTransitionHook: registerTransitionHook, // deprecated - warning is in createHistory - unregisterTransitionHook: unregisterTransitionHook, // deprecated - warning is in createHistory - pushState: pushState, // deprecated - warning is in createHistory - replaceState: replaceState // deprecated - warning is in createHistory - }); -} - -exports['default'] = createHashHistory; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 232 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -//import warning from 'warning' - - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _Actions = __webpack_require__(29); - -var _parsePath = __webpack_require__(24); - -var _parsePath2 = _interopRequireDefault(_parsePath); - -function createLocation() { - var location = arguments.length <= 0 || arguments[0] === undefined ? '/' : arguments[0]; - var action = arguments.length <= 1 || arguments[1] === undefined ? _Actions.POP : arguments[1]; - var key = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2]; - - var _fourthArg = arguments.length <= 3 || arguments[3] === undefined ? null : arguments[3]; - - if (typeof location === 'string') location = _parsePath2['default'](location); - - if (typeof action === 'object') { - //warning( - // false, - // 'The state (2nd) argument to createLocation is deprecated; use a ' + - // 'location descriptor instead' - //) - - location = _extends({}, location, { state: action }); - - action = key || _Actions.POP; - key = _fourthArg; - } - - var pathname = location.pathname || '/'; - var search = location.search || ''; - var hash = location.hash || ''; - var state = location.state || null; - - return { - pathname: pathname, - search: search, - hash: hash, - state: state, - action: action, - key: key - }; -} - -exports['default'] = createLocation; -module.exports = exports['default']; - -/***/ }), -/* 233 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _Actions = __webpack_require__(29); - -var _createHistory = __webpack_require__(76); - -var _createHistory2 = _interopRequireDefault(_createHistory); - -var _parsePath = __webpack_require__(24); - -var _parsePath2 = _interopRequireDefault(_parsePath); - -function createStateStorage(entries) { - return entries.filter(function (entry) { - return entry.state; - }).reduce(function (memo, entry) { - memo[entry.key] = entry.state; - return memo; - }, {}); -} - -function createMemoryHistory() { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - - if (Array.isArray(options)) { - options = { entries: options }; - } else if (typeof options === 'string') { - options = { entries: [options] }; - } - - var history = _createHistory2['default'](_extends({}, options, { - getCurrentLocation: getCurrentLocation, - finishTransition: finishTransition, - saveState: saveState, - go: go - })); - - var _options = options; - var entries = _options.entries; - var current = _options.current; - - if (typeof entries === 'string') { - entries = [entries]; - } else if (!Array.isArray(entries)) { - entries = ['/']; - } - - entries = entries.map(function (entry) { - var key = history.createKey(); - - if (typeof entry === 'string') return { pathname: entry, key: key }; - - if (typeof entry === 'object' && entry) return _extends({}, entry, { key: key }); - - true ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Unable to create history entry from %s', entry) : _invariant2['default'](false) : undefined; - }); - - if (current == null) { - current = entries.length - 1; - } else { - !(current >= 0 && current < entries.length) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Current index must be >= 0 and < %s, was %s', entries.length, current) : _invariant2['default'](false) : undefined; - } - - var storage = createStateStorage(entries); - - function saveState(key, state) { - storage[key] = state; - } - - function readState(key) { - return storage[key]; - } - - function getCurrentLocation() { - var entry = entries[current]; - var key = entry.key; - var basename = entry.basename; - var pathname = entry.pathname; - var search = entry.search; - - var path = (basename || '') + pathname + (search || ''); - - var state = undefined; - if (key) { - state = readState(key); - } else { - state = null; - key = history.createKey(); - entry.key = key; - } - - var location = _parsePath2['default'](path); - - return history.createLocation(_extends({}, location, { state: state }), undefined, key); - } - - function canGo(n) { - var index = current + n; - return index >= 0 && index < entries.length; - } - - function go(n) { - if (n) { - if (!canGo(n)) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'Cannot go(%s) there is not enough history', n) : undefined; - return; - } - - current += n; - - var currentLocation = getCurrentLocation(); - - // change action to POP - history.transitionTo(_extends({}, currentLocation, { action: _Actions.POP })); - } - } - - function finishTransition(location) { - switch (location.action) { - case _Actions.PUSH: - current += 1; - - // if we are not on the top of stack - // remove rest and push new - if (current < entries.length) entries.splice(current); - - entries.push(location); - saveState(location.key, location.state); - break; - case _Actions.REPLACE: - entries[current] = location; - saveState(location.key, location.state); - break; - } - } - - return history; -} - -exports['default'] = createMemoryHistory; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 234 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - -var _ExecutionEnvironment = __webpack_require__(43); - -var _runTransitionHook = __webpack_require__(45); - -var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook); - -var _extractPath = __webpack_require__(77); - -var _extractPath2 = _interopRequireDefault(_extractPath); - -var _parsePath = __webpack_require__(24); - -var _parsePath2 = _interopRequireDefault(_parsePath); - -var _deprecate = __webpack_require__(44); - -var _deprecate2 = _interopRequireDefault(_deprecate); - -function useBasename(createHistory) { - return function () { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - var basename = options.basename; - - var historyOptions = _objectWithoutProperties(options, ['basename']); - - var history = createHistory(historyOptions); - - // Automatically use the value of <base href> in HTML - // documents as basename if it's not explicitly given. - if (basename == null && _ExecutionEnvironment.canUseDOM) { - var base = document.getElementsByTagName('base')[0]; - - if (base) basename = _extractPath2['default'](base.href); - } - - function addBasename(location) { - if (basename && location.basename == null) { - if (location.pathname.indexOf(basename) === 0) { - location.pathname = location.pathname.substring(basename.length); - location.basename = basename; - - if (location.pathname === '') location.pathname = '/'; - } else { - location.basename = ''; - } - } - - return location; - } - - function prependBasename(location) { - if (!basename) return location; - - if (typeof location === 'string') location = _parsePath2['default'](location); - - var pname = location.pathname; - var normalizedBasename = basename.slice(-1) === '/' ? basename : basename + '/'; - var normalizedPathname = pname.charAt(0) === '/' ? pname.slice(1) : pname; - var pathname = normalizedBasename + normalizedPathname; - - return _extends({}, location, { - pathname: pathname - }); - } - - // Override all read methods with basename-aware versions. - function listenBefore(hook) { - return history.listenBefore(function (location, callback) { - _runTransitionHook2['default'](hook, addBasename(location), callback); - }); - } - - function listen(listener) { - return history.listen(function (location) { - listener(addBasename(location)); - }); - } - - // Override all write methods with basename-aware versions. - function push(location) { - history.push(prependBasename(location)); - } - - function replace(location) { - history.replace(prependBasename(location)); - } - - function createPath(location) { - return history.createPath(prependBasename(location)); - } - - function createHref(location) { - return history.createHref(prependBasename(location)); - } - - function createLocation() { - return addBasename(history.createLocation.apply(history, arguments)); - } - - // deprecated - function pushState(state, path) { - if (typeof path === 'string') path = _parsePath2['default'](path); - - push(_extends({ state: state }, path)); - } - - // deprecated - function replaceState(state, path) { - if (typeof path === 'string') path = _parsePath2['default'](path); - - replace(_extends({ state: state }, path)); - } - - return _extends({}, history, { - listenBefore: listenBefore, - listen: listen, - push: push, - replace: replace, - createPath: createPath, - createHref: createHref, - createLocation: createLocation, - - pushState: _deprecate2['default'](pushState, 'pushState is deprecated; use push instead'), - replaceState: _deprecate2['default'](replaceState, 'replaceState is deprecated; use replace instead') - }); - }; -} - -exports['default'] = useBasename; -module.exports = exports['default']; - -/***/ }), -/* 235 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _queryString = __webpack_require__(236); - -var _runTransitionHook = __webpack_require__(45); - -var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook); - -var _parsePath = __webpack_require__(24); - -var _parsePath2 = _interopRequireDefault(_parsePath); - -var _deprecate = __webpack_require__(44); - -var _deprecate2 = _interopRequireDefault(_deprecate); - -var SEARCH_BASE_KEY = '$searchBase'; - -function defaultStringifyQuery(query) { - return _queryString.stringify(query).replace(/%20/g, '+'); -} - -var defaultParseQueryString = _queryString.parse; - -function isNestedObject(object) { - for (var p in object) { - if (object.hasOwnProperty(p) && typeof object[p] === 'object' && !Array.isArray(object[p]) && object[p] !== null) return true; - }return false; -} - -/** - * Returns a new createHistory function that may be used to create - * history objects that know how to handle URL queries. - */ -function useQueries(createHistory) { - return function () { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - var stringifyQuery = options.stringifyQuery; - var parseQueryString = options.parseQueryString; - - var historyOptions = _objectWithoutProperties(options, ['stringifyQuery', 'parseQueryString']); - - var history = createHistory(historyOptions); - - if (typeof stringifyQuery !== 'function') stringifyQuery = defaultStringifyQuery; - - if (typeof parseQueryString !== 'function') parseQueryString = defaultParseQueryString; - - function addQuery(location) { - if (location.query == null) { - var search = location.search; - - location.query = parseQueryString(search.substring(1)); - location[SEARCH_BASE_KEY] = { search: search, searchBase: '' }; - } - - // TODO: Instead of all the book-keeping here, this should just strip the - // stringified query from the search. - - return location; - } - - function appendQuery(location, query) { - var _extends2; - - var queryString = undefined; - if (!query || (queryString = stringifyQuery(query)) === '') return location; - - process.env.NODE_ENV !== 'production' ? _warning2['default'](stringifyQuery !== defaultStringifyQuery || !isNestedObject(query), 'useQueries does not stringify nested query objects by default; ' + 'use a custom stringifyQuery function') : undefined; - - if (typeof location === 'string') location = _parsePath2['default'](location); - - var searchBaseSpec = location[SEARCH_BASE_KEY]; - var searchBase = undefined; - if (searchBaseSpec && location.search === searchBaseSpec.search) { - searchBase = searchBaseSpec.searchBase; - } else { - searchBase = location.search || ''; - } - - var search = searchBase + (searchBase ? '&' : '?') + queryString; - - return _extends({}, location, (_extends2 = { - search: search - }, _extends2[SEARCH_BASE_KEY] = { search: search, searchBase: searchBase }, _extends2)); - } - - // Override all read methods with query-aware versions. - function listenBefore(hook) { - return history.listenBefore(function (location, callback) { - _runTransitionHook2['default'](hook, addQuery(location), callback); - }); - } - - function listen(listener) { - return history.listen(function (location) { - listener(addQuery(location)); - }); - } - - // Override all write methods with query-aware versions. - function push(location) { - history.push(appendQuery(location, location.query)); - } - - function replace(location) { - history.replace(appendQuery(location, location.query)); - } - - function createPath(location, query) { - //warning( - // !query, - // 'the query argument to createPath is deprecated; use a location descriptor instead' - //) - return history.createPath(appendQuery(location, query || location.query)); - } - - function createHref(location, query) { - //warning( - // !query, - // 'the query argument to createHref is deprecated; use a location descriptor instead' - //) - return history.createHref(appendQuery(location, query || location.query)); - } - - function createLocation() { - return addQuery(history.createLocation.apply(history, arguments)); - } - - // deprecated - function pushState(state, path, query) { - if (typeof path === 'string') path = _parsePath2['default'](path); - - push(_extends({ state: state }, path, { query: query })); - } - - // deprecated - function replaceState(state, path, query) { - if (typeof path === 'string') path = _parsePath2['default'](path); - - replace(_extends({ state: state }, path, { query: query })); - } - - return _extends({}, history, { - listenBefore: listenBefore, - listen: listen, - push: push, - replace: replace, - createPath: createPath, - createHref: createHref, - createLocation: createLocation, - - pushState: _deprecate2['default'](pushState, 'pushState is deprecated; use push instead'), - replaceState: _deprecate2['default'](replaceState, 'replaceState is deprecated; use replace instead') - }); - }; -} - -exports['default'] = useQueries; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 236 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var strictUriEncode = __webpack_require__(335); - -exports.extract = function (str) { - return str.split('?')[1] || ''; -}; - -exports.parse = function (str) { - if (typeof str !== 'string') { - return {}; - } - - str = str.trim().replace(/^(\?|#|&)/, ''); - - if (!str) { - return {}; - } - - return str.split('&').reduce(function (ret, param) { - var parts = param.replace(/\+/g, ' ').split('='); - // Firefox (pre 40) decodes `%3D` to `=` - // https://github.com/sindresorhus/query-string/pull/37 - var key = parts.shift(); - var val = parts.length > 0 ? parts.join('=') : undefined; - - key = decodeURIComponent(key); - - // missing `=` should be `null`: - // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters - val = val === undefined ? null : decodeURIComponent(val); - - if (!ret.hasOwnProperty(key)) { - ret[key] = val; - } else if (Array.isArray(ret[key])) { - ret[key].push(val); - } else { - ret[key] = [ret[key], val]; - } - - return ret; - }, {}); -}; - -exports.stringify = function (obj) { - return obj ? Object.keys(obj).sort().map(function (key) { - var val = obj[key]; - - if (val === undefined) { - return ''; - } - - if (val === null) { - return key; - } - - if (Array.isArray(val)) { - return val.slice().sort().map(function (val2) { - return strictUriEncode(key) + '=' + strictUriEncode(val2); - }).join('&'); - } - - return strictUriEncode(key) + '=' + strictUriEncode(val); - }).filter(function (x) { - return x.length > 0; - }).join('&') : ''; -}; - - -/***/ }), -/* 237 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = __webpack_require__(251); - - -/***/ }), -/* 238 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ARIADOMPropertyConfig = { - Properties: { - // Global States and Properties - 'aria-current': 0, // state - 'aria-details': 0, - 'aria-disabled': 0, // state - 'aria-hidden': 0, // state - 'aria-invalid': 0, // state - 'aria-keyshortcuts': 0, - 'aria-label': 0, - 'aria-roledescription': 0, - // Widget Attributes - 'aria-autocomplete': 0, - 'aria-checked': 0, - 'aria-expanded': 0, - 'aria-haspopup': 0, - 'aria-level': 0, - 'aria-modal': 0, - 'aria-multiline': 0, - 'aria-multiselectable': 0, - 'aria-orientation': 0, - 'aria-placeholder': 0, - 'aria-pressed': 0, - 'aria-readonly': 0, - 'aria-required': 0, - 'aria-selected': 0, - 'aria-sort': 0, - 'aria-valuemax': 0, - 'aria-valuemin': 0, - 'aria-valuenow': 0, - 'aria-valuetext': 0, - // Live Region Attributes - 'aria-atomic': 0, - 'aria-busy': 0, - 'aria-live': 0, - 'aria-relevant': 0, - // Drag-and-Drop Attributes - 'aria-dropeffect': 0, - 'aria-grabbed': 0, - // Relationship Attributes - 'aria-activedescendant': 0, - 'aria-colcount': 0, - 'aria-colindex': 0, - 'aria-colspan': 0, - 'aria-controls': 0, - 'aria-describedby': 0, - 'aria-errormessage': 0, - 'aria-flowto': 0, - 'aria-labelledby': 0, - 'aria-owns': 0, - 'aria-posinset': 0, - 'aria-rowcount': 0, - 'aria-rowindex': 0, - 'aria-rowspan': 0, - 'aria-setsize': 0 - }, - DOMAttributeNames: {}, - DOMPropertyNames: {} -}; - -module.exports = ARIADOMPropertyConfig; - -/***/ }), -/* 239 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactDOMComponentTree = __webpack_require__(7); - -var focusNode = __webpack_require__(73); - -var AutoFocusUtils = { - focusDOMComponent: function () { - focusNode(ReactDOMComponentTree.getNodeFromInstance(this)); - } -}; - -module.exports = AutoFocusUtils; - -/***/ }), -/* 240 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var EventPropagators = __webpack_require__(31); -var ExecutionEnvironment = __webpack_require__(8); -var FallbackCompositionState = __webpack_require__(246); -var SyntheticCompositionEvent = __webpack_require__(289); -var SyntheticInputEvent = __webpack_require__(292); - -var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space -var START_KEYCODE = 229; - -var canUseCompositionEvent = ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window; - -var documentMode = null; -if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { - documentMode = document.documentMode; -} - -// Webkit offers a very useful `textInput` event that can be used to -// directly represent `beforeInput`. The IE `textinput` event is not as -// useful, so we don't use it. -var canUseTextInputEvent = ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode && !isPresto(); - -// In IE9+, we have access to composition events, but the data supplied -// by the native compositionend event may be incorrect. Japanese ideographic -// spaces, for instance (\u3000) are not recorded correctly. -var useFallbackCompositionData = ExecutionEnvironment.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); - -/** - * Opera <= 12 includes TextEvent in window, but does not fire - * text input events. Rely on keypress instead. - */ -function isPresto() { - var opera = window.opera; - return typeof opera === 'object' && typeof opera.version === 'function' && parseInt(opera.version(), 10) <= 12; -} - -var SPACEBAR_CODE = 32; -var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); - -// Events and their corresponding property names. -var eventTypes = { - beforeInput: { - phasedRegistrationNames: { - bubbled: 'onBeforeInput', - captured: 'onBeforeInputCapture' - }, - dependencies: ['topCompositionEnd', 'topKeyPress', 'topTextInput', 'topPaste'] - }, - compositionEnd: { - phasedRegistrationNames: { - bubbled: 'onCompositionEnd', - captured: 'onCompositionEndCapture' - }, - dependencies: ['topBlur', 'topCompositionEnd', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown'] - }, - compositionStart: { - phasedRegistrationNames: { - bubbled: 'onCompositionStart', - captured: 'onCompositionStartCapture' - }, - dependencies: ['topBlur', 'topCompositionStart', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown'] - }, - compositionUpdate: { - phasedRegistrationNames: { - bubbled: 'onCompositionUpdate', - captured: 'onCompositionUpdateCapture' - }, - dependencies: ['topBlur', 'topCompositionUpdate', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown'] - } -}; - -// Track whether we've ever handled a keypress on the space key. -var hasSpaceKeypress = false; - -/** - * Return whether a native keypress event is assumed to be a command. - * This is required because Firefox fires `keypress` events for key commands - * (cut, copy, select-all, etc.) even though no character is inserted. - */ -function isKeypressCommand(nativeEvent) { - return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && - // ctrlKey && altKey is equivalent to AltGr, and is not a command. - !(nativeEvent.ctrlKey && nativeEvent.altKey); -} - -/** - * Translate native top level events into event types. - * - * @param {string} topLevelType - * @return {object} - */ -function getCompositionEventType(topLevelType) { - switch (topLevelType) { - case 'topCompositionStart': - return eventTypes.compositionStart; - case 'topCompositionEnd': - return eventTypes.compositionEnd; - case 'topCompositionUpdate': - return eventTypes.compositionUpdate; - } -} - -/** - * Does our fallback best-guess model think this event signifies that - * composition has begun? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackCompositionStart(topLevelType, nativeEvent) { - return topLevelType === 'topKeyDown' && nativeEvent.keyCode === START_KEYCODE; -} - -/** - * Does our fallback mode think that this event is the end of composition? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackCompositionEnd(topLevelType, nativeEvent) { - switch (topLevelType) { - case 'topKeyUp': - // Command keys insert or clear IME input. - return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1; - case 'topKeyDown': - // Expect IME keyCode on each keydown. If we get any other - // code we must have exited earlier. - return nativeEvent.keyCode !== START_KEYCODE; - case 'topKeyPress': - case 'topMouseDown': - case 'topBlur': - // Events are not possible without cancelling IME. - return true; - default: - return false; - } -} - -/** - * Google Input Tools provides composition data via a CustomEvent, - * with the `data` property populated in the `detail` object. If this - * is available on the event object, use it. If not, this is a plain - * composition event and we have nothing special to extract. - * - * @param {object} nativeEvent - * @return {?string} - */ -function getDataFromCustomEvent(nativeEvent) { - var detail = nativeEvent.detail; - if (typeof detail === 'object' && 'data' in detail) { - return detail.data; - } - return null; -} - -// Track the current IME composition fallback object, if any. -var currentComposition = null; - -/** - * @return {?object} A SyntheticCompositionEvent. - */ -function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var eventType; - var fallbackData; - - if (canUseCompositionEvent) { - eventType = getCompositionEventType(topLevelType); - } else if (!currentComposition) { - if (isFallbackCompositionStart(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionStart; - } - } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionEnd; - } - - if (!eventType) { - return null; - } - - if (useFallbackCompositionData) { - // The current composition is stored statically and must not be - // overwritten while composition continues. - if (!currentComposition && eventType === eventTypes.compositionStart) { - currentComposition = FallbackCompositionState.getPooled(nativeEventTarget); - } else if (eventType === eventTypes.compositionEnd) { - if (currentComposition) { - fallbackData = currentComposition.getData(); - } - } - } - - var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget); - - if (fallbackData) { - // Inject data generated from fallback path into the synthetic event. - // This matches the property of native CompositionEventInterface. - event.data = fallbackData; - } else { - var customData = getDataFromCustomEvent(nativeEvent); - if (customData !== null) { - event.data = customData; - } - } - - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; -} - -/** - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} nativeEvent Native browser event. - * @return {?string} The string corresponding to this `beforeInput` event. - */ -function getNativeBeforeInputChars(topLevelType, nativeEvent) { - switch (topLevelType) { - case 'topCompositionEnd': - return getDataFromCustomEvent(nativeEvent); - case 'topKeyPress': - /** - * If native `textInput` events are available, our goal is to make - * use of them. However, there is a special case: the spacebar key. - * In Webkit, preventing default on a spacebar `textInput` event - * cancels character insertion, but it *also* causes the browser - * to fall back to its default spacebar behavior of scrolling the - * page. - * - * Tracking at: - * https://code.google.com/p/chromium/issues/detail?id=355103 - * - * To avoid this issue, use the keypress event as if no `textInput` - * event is available. - */ - var which = nativeEvent.which; - if (which !== SPACEBAR_CODE) { - return null; - } - - hasSpaceKeypress = true; - return SPACEBAR_CHAR; - - case 'topTextInput': - // Record the characters to be added to the DOM. - var chars = nativeEvent.data; - - // If it's a spacebar character, assume that we have already handled - // it at the keypress level and bail immediately. Android Chrome - // doesn't give us keycodes, so we need to blacklist it. - if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { - return null; - } - - return chars; - - default: - // For other native event types, do nothing. - return null; - } -} - -/** - * For browsers that do not provide the `textInput` event, extract the - * appropriate string to use for SyntheticInputEvent. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} nativeEvent Native browser event. - * @return {?string} The fallback string for this `beforeInput` event. - */ -function getFallbackBeforeInputChars(topLevelType, nativeEvent) { - // If we are currently composing (IME) and using a fallback to do so, - // try to extract the composed characters from the fallback object. - // If composition event is available, we extract a string only at - // compositionevent, otherwise extract it at fallback events. - if (currentComposition) { - if (topLevelType === 'topCompositionEnd' || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) { - var chars = currentComposition.getData(); - FallbackCompositionState.release(currentComposition); - currentComposition = null; - return chars; - } - return null; - } - - switch (topLevelType) { - case 'topPaste': - // If a paste event occurs after a keypress, throw out the input - // chars. Paste events should not lead to BeforeInput events. - return null; - case 'topKeyPress': - /** - * As of v27, Firefox may fire keypress events even when no character - * will be inserted. A few possibilities: - * - * - `which` is `0`. Arrow keys, Esc key, etc. - * - * - `which` is the pressed key code, but no char is available. - * Ex: 'AltGr + d` in Polish. There is no modified character for - * this key combination and no character is inserted into the - * document, but FF fires the keypress for char code `100` anyway. - * No `input` event will occur. - * - * - `which` is the pressed key code, but a command combination is - * being used. Ex: `Cmd+C`. No character is inserted, and no - * `input` event will occur. - */ - if (nativeEvent.which && !isKeypressCommand(nativeEvent)) { - return String.fromCharCode(nativeEvent.which); - } - return null; - case 'topCompositionEnd': - return useFallbackCompositionData ? null : nativeEvent.data; - default: - return null; - } -} - -/** - * Extract a SyntheticInputEvent for `beforeInput`, based on either native - * `textInput` or fallback behavior. - * - * @return {?object} A SyntheticInputEvent. - */ -function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var chars; - - if (canUseTextInputEvent) { - chars = getNativeBeforeInputChars(topLevelType, nativeEvent); - } else { - chars = getFallbackBeforeInputChars(topLevelType, nativeEvent); - } - - // If no characters are being inserted, no BeforeInput event should - // be fired. - if (!chars) { - return null; - } - - var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget); - - event.data = chars; - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; -} - -/** - * Create an `onBeforeInput` event to match - * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. - * - * This event plugin is based on the native `textInput` event - * available in Chrome, Safari, Opera, and IE. This event fires after - * `onKeyPress` and `onCompositionEnd`, but before `onInput`. - * - * `beforeInput` is spec'd but not implemented in any browsers, and - * the `input` event does not provide any useful information about what has - * actually been added, contrary to the spec. Thus, `textInput` is the best - * available event to identify the characters that have actually been inserted - * into the target node. - * - * This plugin is also responsible for emitting `composition` events, thus - * allowing us to share composition fallback code for both `beforeInput` and - * `composition` event types. - */ -var BeforeInputEventPlugin = { - - eventTypes: eventTypes, - - extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - return [extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget), extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget)]; - } -}; - -module.exports = BeforeInputEventPlugin; - -/***/ }), -/* 241 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var CSSProperty = __webpack_require__(78); -var ExecutionEnvironment = __webpack_require__(8); -var ReactInstrumentation = __webpack_require__(10); - -var camelizeStyleName = __webpack_require__(215); -var dangerousStyleValue = __webpack_require__(299); -var hyphenateStyleName = __webpack_require__(222); -var memoizeStringOnly = __webpack_require__(225); -var warning = __webpack_require__(3); - -var processStyleName = memoizeStringOnly(function (styleName) { - return hyphenateStyleName(styleName); -}); - -var hasShorthandPropertyBug = false; -var styleFloatAccessor = 'cssFloat'; -if (ExecutionEnvironment.canUseDOM) { - var tempStyle = document.createElement('div').style; - try { - // IE8 throws "Invalid argument." if resetting shorthand style properties. - tempStyle.font = ''; - } catch (e) { - hasShorthandPropertyBug = true; - } - // IE8 only supports accessing cssFloat (standard) as styleFloat - if (document.documentElement.style.cssFloat === undefined) { - styleFloatAccessor = 'styleFloat'; - } -} - -if (process.env.NODE_ENV !== 'production') { - // 'msTransform' is correct, but the other prefixes should be capitalized - var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; - - // style values shouldn't contain a semicolon - var badStyleValueWithSemicolonPattern = /;\s*$/; - - var warnedStyleNames = {}; - var warnedStyleValues = {}; - var warnedForNaNValue = false; - - var warnHyphenatedStyleName = function (name, owner) { - if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { - return; - } - - warnedStyleNames[name] = true; - process.env.NODE_ENV !== 'production' ? warning(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName(name), checkRenderMessage(owner)) : void 0; - }; - - var warnBadVendoredStyleName = function (name, owner) { - if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { - return; - } - - warnedStyleNames[name] = true; - process.env.NODE_ENV !== 'production' ? warning(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), checkRenderMessage(owner)) : void 0; - }; - - var warnStyleValueWithSemicolon = function (name, value, owner) { - if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { - return; - } - - warnedStyleValues[value] = true; - process.env.NODE_ENV !== 'production' ? warning(false, 'Style property values shouldn\'t contain a semicolon.%s ' + 'Try "%s: %s" instead.', checkRenderMessage(owner), name, value.replace(badStyleValueWithSemicolonPattern, '')) : void 0; - }; - - var warnStyleValueIsNaN = function (name, value, owner) { - if (warnedForNaNValue) { - return; - } - - warnedForNaNValue = true; - process.env.NODE_ENV !== 'production' ? warning(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, checkRenderMessage(owner)) : void 0; - }; - - var checkRenderMessage = function (owner) { - if (owner) { - var name = owner.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; - }; - - /** - * @param {string} name - * @param {*} value - * @param {ReactDOMComponent} component - */ - var warnValidStyle = function (name, value, component) { - var owner; - if (component) { - owner = component._currentElement._owner; - } - if (name.indexOf('-') > -1) { - warnHyphenatedStyleName(name, owner); - } else if (badVendoredStyleNamePattern.test(name)) { - warnBadVendoredStyleName(name, owner); - } else if (badStyleValueWithSemicolonPattern.test(value)) { - warnStyleValueWithSemicolon(name, value, owner); - } - - if (typeof value === 'number' && isNaN(value)) { - warnStyleValueIsNaN(name, value, owner); - } - }; -} - -/** - * Operations for dealing with CSS properties. - */ -var CSSPropertyOperations = { - - /** - * Serializes a mapping of style properties for use as inline styles: - * - * > createMarkupForStyles({width: '200px', height: 0}) - * "width:200px;height:0;" - * - * Undefined values are ignored so that declarative programming is easier. - * The result should be HTML-escaped before insertion into the DOM. - * - * @param {object} styles - * @param {ReactDOMComponent} component - * @return {?string} - */ - createMarkupForStyles: function (styles, component) { - var serialized = ''; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - var styleValue = styles[styleName]; - if (process.env.NODE_ENV !== 'production') { - warnValidStyle(styleName, styleValue, component); - } - if (styleValue != null) { - serialized += processStyleName(styleName) + ':'; - serialized += dangerousStyleValue(styleName, styleValue, component) + ';'; - } - } - return serialized || null; - }, - - /** - * Sets the value for multiple styles on a node. If a value is specified as - * '' (empty string), the corresponding style property will be unset. - * - * @param {DOMElement} node - * @param {object} styles - * @param {ReactDOMComponent} component - */ - setValueForStyles: function (node, styles, component) { - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: component._debugID, - type: 'update styles', - payload: styles - }); - } - - var style = node.style; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - if (process.env.NODE_ENV !== 'production') { - warnValidStyle(styleName, styles[styleName], component); - } - var styleValue = dangerousStyleValue(styleName, styles[styleName], component); - if (styleName === 'float' || styleName === 'cssFloat') { - styleName = styleFloatAccessor; - } - if (styleValue) { - style[styleName] = styleValue; - } else { - var expansion = hasShorthandPropertyBug && CSSProperty.shorthandPropertyExpansions[styleName]; - if (expansion) { - // Shorthand property that IE8 won't like unsetting, so unset each - // component to placate it - for (var individualStyleName in expansion) { - style[individualStyleName] = ''; - } - } else { - style[styleName] = ''; - } - } - } - } - -}; - -module.exports = CSSPropertyOperations; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 242 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var EventPluginHub = __webpack_require__(30); -var EventPropagators = __webpack_require__(31); -var ExecutionEnvironment = __webpack_require__(8); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactUpdates = __webpack_require__(14); -var SyntheticEvent = __webpack_require__(17); - -var getEventTarget = __webpack_require__(57); -var isEventSupported = __webpack_require__(58); -var isTextInputElement = __webpack_require__(96); - -var eventTypes = { - change: { - phasedRegistrationNames: { - bubbled: 'onChange', - captured: 'onChangeCapture' - }, - dependencies: ['topBlur', 'topChange', 'topClick', 'topFocus', 'topInput', 'topKeyDown', 'topKeyUp', 'topSelectionChange'] - } -}; - -/** - * For IE shims - */ -var activeElement = null; -var activeElementInst = null; -var activeElementValue = null; -var activeElementValueProp = null; - -/** - * SECTION: handle `change` event - */ -function shouldUseChangeEvent(elem) { - var nodeName = elem.nodeName && elem.nodeName.toLowerCase(); - return nodeName === 'select' || nodeName === 'input' && elem.type === 'file'; -} - -var doesChangeEventBubble = false; -if (ExecutionEnvironment.canUseDOM) { - // See `handleChange` comment below - doesChangeEventBubble = isEventSupported('change') && (!document.documentMode || document.documentMode > 8); -} - -function manualDispatchChangeEvent(nativeEvent) { - var event = SyntheticEvent.getPooled(eventTypes.change, activeElementInst, nativeEvent, getEventTarget(nativeEvent)); - EventPropagators.accumulateTwoPhaseDispatches(event); - - // If change and propertychange bubbled, we'd just bind to it like all the - // other events and have it go through ReactBrowserEventEmitter. Since it - // doesn't, we manually listen for the events and so we have to enqueue and - // process the abstract event manually. - // - // Batching is necessary here in order to ensure that all event handlers run - // before the next rerender (including event handlers attached to ancestor - // elements instead of directly on the input). Without this, controlled - // components don't work properly in conjunction with event bubbling because - // the component is rerendered and the value reverted before all the event - // handlers can run. See https://github.com/facebook/react/issues/708. - ReactUpdates.batchedUpdates(runEventInBatch, event); -} - -function runEventInBatch(event) { - EventPluginHub.enqueueEvents(event); - EventPluginHub.processEventQueue(false); -} - -function startWatchingForChangeEventIE8(target, targetInst) { - activeElement = target; - activeElementInst = targetInst; - activeElement.attachEvent('onchange', manualDispatchChangeEvent); -} - -function stopWatchingForChangeEventIE8() { - if (!activeElement) { - return; - } - activeElement.detachEvent('onchange', manualDispatchChangeEvent); - activeElement = null; - activeElementInst = null; -} - -function getTargetInstForChangeEvent(topLevelType, targetInst) { - if (topLevelType === 'topChange') { - return targetInst; - } -} -function handleEventsForChangeEventIE8(topLevelType, target, targetInst) { - if (topLevelType === 'topFocus') { - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForChangeEventIE8(); - startWatchingForChangeEventIE8(target, targetInst); - } else if (topLevelType === 'topBlur') { - stopWatchingForChangeEventIE8(); - } -} - -/** - * SECTION: handle `input` event - */ -var isInputEventSupported = false; -if (ExecutionEnvironment.canUseDOM) { - // IE9 claims to support the input event but fails to trigger it when - // deleting text, so we ignore its input events. - // IE10+ fire input events to often, such when a placeholder - // changes or when an input with a placeholder is focused. - isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 11); -} - -/** - * (For IE <=11) Replacement getter/setter for the `value` property that gets - * set on the active element. - */ -var newValueProp = { - get: function () { - return activeElementValueProp.get.call(this); - }, - set: function (val) { - // Cast to a string so we can do equality checks. - activeElementValue = '' + val; - activeElementValueProp.set.call(this, val); - } -}; - -/** - * (For IE <=11) Starts tracking propertychange events on the passed-in element - * and override the value property so that we can distinguish user events from - * value changes in JS. - */ -function startWatchingForValueChange(target, targetInst) { - activeElement = target; - activeElementInst = targetInst; - activeElementValue = target.value; - activeElementValueProp = Object.getOwnPropertyDescriptor(target.constructor.prototype, 'value'); - - // Not guarded in a canDefineProperty check: IE8 supports defineProperty only - // on DOM elements - Object.defineProperty(activeElement, 'value', newValueProp); - if (activeElement.attachEvent) { - activeElement.attachEvent('onpropertychange', handlePropertyChange); - } else { - activeElement.addEventListener('propertychange', handlePropertyChange, false); - } -} - -/** - * (For IE <=11) Removes the event listeners from the currently-tracked element, - * if any exists. - */ -function stopWatchingForValueChange() { - if (!activeElement) { - return; - } - - // delete restores the original property definition - delete activeElement.value; - - if (activeElement.detachEvent) { - activeElement.detachEvent('onpropertychange', handlePropertyChange); - } else { - activeElement.removeEventListener('propertychange', handlePropertyChange, false); - } - - activeElement = null; - activeElementInst = null; - activeElementValue = null; - activeElementValueProp = null; -} - -/** - * (For IE <=11) Handles a propertychange event, sending a `change` event if - * the value of the active element has changed. - */ -function handlePropertyChange(nativeEvent) { - if (nativeEvent.propertyName !== 'value') { - return; - } - var value = nativeEvent.srcElement.value; - if (value === activeElementValue) { - return; - } - activeElementValue = value; - - manualDispatchChangeEvent(nativeEvent); -} - -/** - * If a `change` event should be fired, returns the target's ID. - */ -function getTargetInstForInputEvent(topLevelType, targetInst) { - if (topLevelType === 'topInput') { - // In modern browsers (i.e., not IE8 or IE9), the input event is exactly - // what we want so fall through here and trigger an abstract event - return targetInst; - } -} - -function handleEventsForInputEventIE(topLevelType, target, targetInst) { - if (topLevelType === 'topFocus') { - // In IE8, we can capture almost all .value changes by adding a - // propertychange handler and looking for events with propertyName - // equal to 'value' - // In IE9-11, propertychange fires for most input events but is buggy and - // doesn't fire when text is deleted, but conveniently, selectionchange - // appears to fire in all of the remaining cases so we catch those and - // forward the event if the value has changed - // In either case, we don't want to call the event handler if the value - // is changed from JS so we redefine a setter for `.value` that updates - // our activeElementValue variable, allowing us to ignore those changes - // - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForValueChange(); - startWatchingForValueChange(target, targetInst); - } else if (topLevelType === 'topBlur') { - stopWatchingForValueChange(); - } -} - -// For IE8 and IE9. -function getTargetInstForInputEventIE(topLevelType, targetInst) { - if (topLevelType === 'topSelectionChange' || topLevelType === 'topKeyUp' || topLevelType === 'topKeyDown') { - // On the selectionchange event, the target is just document which isn't - // helpful for us so just check activeElement instead. - // - // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire - // propertychange on the first input event after setting `value` from a - // script and fires only keydown, keypress, keyup. Catching keyup usually - // gets it and catching keydown lets us fire an event for the first - // keystroke if user does a key repeat (it'll be a little delayed: right - // before the second keystroke). Other input methods (e.g., paste) seem to - // fire selectionchange normally. - if (activeElement && activeElement.value !== activeElementValue) { - activeElementValue = activeElement.value; - return activeElementInst; - } - } -} - -/** - * SECTION: handle `click` event - */ -function shouldUseClickEvent(elem) { - // Use the `click` event to detect changes to checkbox and radio inputs. - // This approach works across all browsers, whereas `change` does not fire - // until `blur` in IE8. - return elem.nodeName && elem.nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio'); -} - -function getTargetInstForClickEvent(topLevelType, targetInst) { - if (topLevelType === 'topClick') { - return targetInst; - } -} - -/** - * This plugin creates an `onChange` event that normalizes change events - * across form elements. This event fires at a time when it's possible to - * change the element's value without seeing a flicker. - * - * Supported elements are: - * - input (see `isTextInputElement`) - * - textarea - * - select - */ -var ChangeEventPlugin = { - - eventTypes: eventTypes, - - extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var targetNode = targetInst ? ReactDOMComponentTree.getNodeFromInstance(targetInst) : window; - - var getTargetInstFunc, handleEventFunc; - if (shouldUseChangeEvent(targetNode)) { - if (doesChangeEventBubble) { - getTargetInstFunc = getTargetInstForChangeEvent; - } else { - handleEventFunc = handleEventsForChangeEventIE8; - } - } else if (isTextInputElement(targetNode)) { - if (isInputEventSupported) { - getTargetInstFunc = getTargetInstForInputEvent; - } else { - getTargetInstFunc = getTargetInstForInputEventIE; - handleEventFunc = handleEventsForInputEventIE; - } - } else if (shouldUseClickEvent(targetNode)) { - getTargetInstFunc = getTargetInstForClickEvent; - } - - if (getTargetInstFunc) { - var inst = getTargetInstFunc(topLevelType, targetInst); - if (inst) { - var event = SyntheticEvent.getPooled(eventTypes.change, inst, nativeEvent, nativeEventTarget); - event.type = 'change'; - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } - } - - if (handleEventFunc) { - handleEventFunc(topLevelType, targetNode, targetInst); - } - } - -}; - -module.exports = ChangeEventPlugin; - -/***/ }), -/* 243 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var DOMLazyTree = __webpack_require__(25); -var ExecutionEnvironment = __webpack_require__(8); - -var createNodesFromMarkup = __webpack_require__(218); -var emptyFunction = __webpack_require__(12); -var invariant = __webpack_require__(2); - -var Danger = { - - /** - * Replaces a node with a string of markup at its current position within its - * parent. The markup must render into a single root node. - * - * @param {DOMElement} oldChild Child node to replace. - * @param {string} markup Markup to render in place of the child node. - * @internal - */ - dangerouslyReplaceNodeWithMarkup: function (oldChild, markup) { - !ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a worker thread. Make sure `window` and `document` are available globally before requiring React when unit testing or use ReactDOMServer.renderToString() for server rendering.') : _prodInvariant('56') : void 0; - !markup ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : _prodInvariant('57') : void 0; - !(oldChild.nodeName !== 'HTML') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the <html> node. This is because browser quirks make this unreliable and/or slow. If you want to render to the root you must use server rendering. See ReactDOMServer.renderToString().') : _prodInvariant('58') : void 0; - - if (typeof markup === 'string') { - var newChild = createNodesFromMarkup(markup, emptyFunction)[0]; - oldChild.parentNode.replaceChild(newChild, oldChild); - } else { - DOMLazyTree.replaceChildWithTree(oldChild, markup); - } - } - -}; - -module.exports = Danger; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 244 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * Module that is injectable into `EventPluginHub`, that specifies a - * deterministic ordering of `EventPlugin`s. A convenient way to reason about - * plugins, without having to package every one of them. This is better than - * having plugins be ordered in the same order that they are injected because - * that ordering would be influenced by the packaging order. - * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that - * preventing default on events is convenient in `SimpleEventPlugin` handlers. - */ - -var DefaultEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'TapEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin']; - -module.exports = DefaultEventPluginOrder; - -/***/ }), -/* 245 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var EventPropagators = __webpack_require__(31); -var ReactDOMComponentTree = __webpack_require__(7); -var SyntheticMouseEvent = __webpack_require__(37); - -var eventTypes = { - mouseEnter: { - registrationName: 'onMouseEnter', - dependencies: ['topMouseOut', 'topMouseOver'] - }, - mouseLeave: { - registrationName: 'onMouseLeave', - dependencies: ['topMouseOut', 'topMouseOver'] - } -}; - -var EnterLeaveEventPlugin = { - - eventTypes: eventTypes, - - /** - * For almost every interaction we care about, there will be both a top-level - * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that - * we do not extract duplicate events. However, moving the mouse into the - * browser from outside will not fire a `mouseout` event. In this case, we use - * the `mouseover` top-level event. - */ - extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - if (topLevelType === 'topMouseOver' && (nativeEvent.relatedTarget || nativeEvent.fromElement)) { - return null; - } - if (topLevelType !== 'topMouseOut' && topLevelType !== 'topMouseOver') { - // Must not be a mouse in or mouse out - ignoring. - return null; - } - - var win; - if (nativeEventTarget.window === nativeEventTarget) { - // `nativeEventTarget` is probably a window object. - win = nativeEventTarget; - } else { - // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. - var doc = nativeEventTarget.ownerDocument; - if (doc) { - win = doc.defaultView || doc.parentWindow; - } else { - win = window; - } - } - - var from; - var to; - if (topLevelType === 'topMouseOut') { - from = targetInst; - var related = nativeEvent.relatedTarget || nativeEvent.toElement; - to = related ? ReactDOMComponentTree.getClosestInstanceFromNode(related) : null; - } else { - // Moving to a node from outside the window. - from = null; - to = targetInst; - } - - if (from === to) { - // Nothing pertains to our managed components. - return null; - } - - var fromNode = from == null ? win : ReactDOMComponentTree.getNodeFromInstance(from); - var toNode = to == null ? win : ReactDOMComponentTree.getNodeFromInstance(to); - - var leave = SyntheticMouseEvent.getPooled(eventTypes.mouseLeave, from, nativeEvent, nativeEventTarget); - leave.type = 'mouseleave'; - leave.target = fromNode; - leave.relatedTarget = toNode; - - var enter = SyntheticMouseEvent.getPooled(eventTypes.mouseEnter, to, nativeEvent, nativeEventTarget); - enter.type = 'mouseenter'; - enter.target = toNode; - enter.relatedTarget = fromNode; - - EventPropagators.accumulateEnterLeaveDispatches(leave, enter, from, to); - - return [leave, enter]; - } - -}; - -module.exports = EnterLeaveEventPlugin; - -/***/ }), -/* 246 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var PooledClass = __webpack_require__(20); - -var getTextContentAccessor = __webpack_require__(94); - -/** - * This helper class stores information about text content of a target node, - * allowing comparison of content before and after a given event. - * - * Identify the node where selection currently begins, then observe - * both its text content and its current position in the DOM. Since the - * browser may natively replace the target node during composition, we can - * use its position to find its replacement. - * - * @param {DOMEventTarget} root - */ -function FallbackCompositionState(root) { - this._root = root; - this._startText = this.getText(); - this._fallbackText = null; -} - -_assign(FallbackCompositionState.prototype, { - destructor: function () { - this._root = null; - this._startText = null; - this._fallbackText = null; - }, - - /** - * Get current text of input. - * - * @return {string} - */ - getText: function () { - if ('value' in this._root) { - return this._root.value; - } - return this._root[getTextContentAccessor()]; - }, - - /** - * Determine the differing substring between the initially stored - * text content and the current content. - * - * @return {string} - */ - getData: function () { - if (this._fallbackText) { - return this._fallbackText; - } - - var start; - var startValue = this._startText; - var startLength = startValue.length; - var end; - var endValue = this.getText(); - var endLength = endValue.length; - - for (start = 0; start < startLength; start++) { - if (startValue[start] !== endValue[start]) { - break; - } - } - - var minEnd = startLength - start; - for (end = 1; end <= minEnd; end++) { - if (startValue[startLength - end] !== endValue[endLength - end]) { - break; - } - } - - var sliceTail = end > 1 ? 1 - end : undefined; - this._fallbackText = endValue.slice(start, sliceTail); - return this._fallbackText; - } -}); - -PooledClass.addPoolingTo(FallbackCompositionState); - -module.exports = FallbackCompositionState; - -/***/ }), -/* 247 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMProperty = __webpack_require__(18); - -var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY; -var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE; -var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE; -var HAS_POSITIVE_NUMERIC_VALUE = DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE; -var HAS_OVERLOADED_BOOLEAN_VALUE = DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE; - -var HTMLDOMPropertyConfig = { - isCustomAttribute: RegExp.prototype.test.bind(new RegExp('^(data|aria)-[' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$')), - Properties: { - /** - * Standard Properties - */ - accept: 0, - acceptCharset: 0, - accessKey: 0, - action: 0, - allowFullScreen: HAS_BOOLEAN_VALUE, - allowTransparency: 0, - alt: 0, - // specifies target context for links with `preload` type - as: 0, - async: HAS_BOOLEAN_VALUE, - autoComplete: 0, - // autoFocus is polyfilled/normalized by AutoFocusUtils - // autoFocus: HAS_BOOLEAN_VALUE, - autoPlay: HAS_BOOLEAN_VALUE, - capture: HAS_BOOLEAN_VALUE, - cellPadding: 0, - cellSpacing: 0, - charSet: 0, - challenge: 0, - checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - cite: 0, - classID: 0, - className: 0, - cols: HAS_POSITIVE_NUMERIC_VALUE, - colSpan: 0, - content: 0, - contentEditable: 0, - contextMenu: 0, - controls: HAS_BOOLEAN_VALUE, - coords: 0, - crossOrigin: 0, - data: 0, // For `<object />` acts as `src`. - dateTime: 0, - 'default': HAS_BOOLEAN_VALUE, - defer: HAS_BOOLEAN_VALUE, - dir: 0, - disabled: HAS_BOOLEAN_VALUE, - download: HAS_OVERLOADED_BOOLEAN_VALUE, - draggable: 0, - encType: 0, - form: 0, - formAction: 0, - formEncType: 0, - formMethod: 0, - formNoValidate: HAS_BOOLEAN_VALUE, - formTarget: 0, - frameBorder: 0, - headers: 0, - height: 0, - hidden: HAS_BOOLEAN_VALUE, - high: 0, - href: 0, - hrefLang: 0, - htmlFor: 0, - httpEquiv: 0, - icon: 0, - id: 0, - inputMode: 0, - integrity: 0, - is: 0, - keyParams: 0, - keyType: 0, - kind: 0, - label: 0, - lang: 0, - list: 0, - loop: HAS_BOOLEAN_VALUE, - low: 0, - manifest: 0, - marginHeight: 0, - marginWidth: 0, - max: 0, - maxLength: 0, - media: 0, - mediaGroup: 0, - method: 0, - min: 0, - minLength: 0, - // Caution; `option.selected` is not updated if `select.multiple` is - // disabled with `removeAttribute`. - multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - name: 0, - nonce: 0, - noValidate: HAS_BOOLEAN_VALUE, - open: HAS_BOOLEAN_VALUE, - optimum: 0, - pattern: 0, - placeholder: 0, - playsInline: HAS_BOOLEAN_VALUE, - poster: 0, - preload: 0, - profile: 0, - radioGroup: 0, - readOnly: HAS_BOOLEAN_VALUE, - referrerPolicy: 0, - rel: 0, - required: HAS_BOOLEAN_VALUE, - reversed: HAS_BOOLEAN_VALUE, - role: 0, - rows: HAS_POSITIVE_NUMERIC_VALUE, - rowSpan: HAS_NUMERIC_VALUE, - sandbox: 0, - scope: 0, - scoped: HAS_BOOLEAN_VALUE, - scrolling: 0, - seamless: HAS_BOOLEAN_VALUE, - selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - shape: 0, - size: HAS_POSITIVE_NUMERIC_VALUE, - sizes: 0, - span: HAS_POSITIVE_NUMERIC_VALUE, - spellCheck: 0, - src: 0, - srcDoc: 0, - srcLang: 0, - srcSet: 0, - start: HAS_NUMERIC_VALUE, - step: 0, - style: 0, - summary: 0, - tabIndex: 0, - target: 0, - title: 0, - // Setting .type throws on non-<input> tags - type: 0, - useMap: 0, - value: 0, - width: 0, - wmode: 0, - wrap: 0, - - /** - * RDFa Properties - */ - about: 0, - datatype: 0, - inlist: 0, - prefix: 0, - // property is also supported for OpenGraph in meta tags. - property: 0, - resource: 0, - 'typeof': 0, - vocab: 0, - - /** - * Non-standard Properties - */ - // autoCapitalize and autoCorrect are supported in Mobile Safari for - // keyboard hints. - autoCapitalize: 0, - autoCorrect: 0, - // autoSave allows WebKit/Blink to persist values of input fields on page reloads - autoSave: 0, - // color is for Safari mask-icon link - color: 0, - // itemProp, itemScope, itemType are for - // Microdata support. See http://schema.org/docs/gs.html - itemProp: 0, - itemScope: HAS_BOOLEAN_VALUE, - itemType: 0, - // itemID and itemRef are for Microdata support as well but - // only specified in the WHATWG spec document. See - // https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api - itemID: 0, - itemRef: 0, - // results show looking glass icon and recent searches on input - // search fields in WebKit/Blink - results: 0, - // IE-only attribute that specifies security restrictions on an iframe - // as an alternative to the sandbox attribute on IE<10 - security: 0, - // IE-only attribute that controls focus behavior - unselectable: 0 - }, - DOMAttributeNames: { - acceptCharset: 'accept-charset', - className: 'class', - htmlFor: 'for', - httpEquiv: 'http-equiv' - }, - DOMPropertyNames: {} -}; - -module.exports = HTMLDOMPropertyConfig; - -/***/ }), -/* 248 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactReconciler = __webpack_require__(26); - -var instantiateReactComponent = __webpack_require__(95); -var KeyEscapeUtils = __webpack_require__(49); -var shouldUpdateReactComponent = __webpack_require__(59); -var traverseAllChildren = __webpack_require__(98); -var warning = __webpack_require__(3); - -var ReactComponentTreeHook; - -if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'test') { - // Temporary hack. - // Inline requires don't work well with Jest: - // https://github.com/facebook/react/issues/7240 - // Remove the inline requires when we don't need them anymore: - // https://github.com/facebook/react/pull/7178 - ReactComponentTreeHook = __webpack_require__(9); -} - -function instantiateChild(childInstances, child, name, selfDebugID) { - // We found a component instance. - var keyUnique = childInstances[name] === undefined; - if (process.env.NODE_ENV !== 'production') { - if (!ReactComponentTreeHook) { - ReactComponentTreeHook = __webpack_require__(9); - } - if (!keyUnique) { - process.env.NODE_ENV !== 'production' ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0; - } - } - if (child != null && keyUnique) { - childInstances[name] = instantiateReactComponent(child, true); - } -} - -/** - * ReactChildReconciler provides helpers for initializing or updating a set of - * children. Its output is suitable for passing it onto ReactMultiChild which - * does diffed reordering and insertion. - */ -var ReactChildReconciler = { - /** - * Generates a "mount image" for each of the supplied children. In the case - * of `ReactDOMComponent`, a mount image is a string of markup. - * - * @param {?object} nestedChildNodes Nested child maps. - * @return {?object} A set of child instances. - * @internal - */ - instantiateChildren: function (nestedChildNodes, transaction, context, selfDebugID // 0 in production and for roots - ) { - if (nestedChildNodes == null) { - return null; - } - var childInstances = {}; - - if (process.env.NODE_ENV !== 'production') { - traverseAllChildren(nestedChildNodes, function (childInsts, child, name) { - return instantiateChild(childInsts, child, name, selfDebugID); - }, childInstances); - } else { - traverseAllChildren(nestedChildNodes, instantiateChild, childInstances); - } - return childInstances; - }, - - /** - * Updates the rendered children and returns a new set of children. - * - * @param {?object} prevChildren Previously initialized set of children. - * @param {?object} nextChildren Flat child element maps. - * @param {ReactReconcileTransaction} transaction - * @param {object} context - * @return {?object} A new set of child instances. - * @internal - */ - updateChildren: function (prevChildren, nextChildren, mountImages, removedNodes, transaction, hostParent, hostContainerInfo, context, selfDebugID // 0 in production and for roots - ) { - // We currently don't have a way to track moves here but if we use iterators - // instead of for..in we can zip the iterators and check if an item has - // moved. - // TODO: If nothing has changed, return the prevChildren object so that we - // can quickly bailout if nothing has changed. - if (!nextChildren && !prevChildren) { - return; - } - var name; - var prevChild; - for (name in nextChildren) { - if (!nextChildren.hasOwnProperty(name)) { - continue; - } - prevChild = prevChildren && prevChildren[name]; - var prevElement = prevChild && prevChild._currentElement; - var nextElement = nextChildren[name]; - if (prevChild != null && shouldUpdateReactComponent(prevElement, nextElement)) { - ReactReconciler.receiveComponent(prevChild, nextElement, transaction, context); - nextChildren[name] = prevChild; - } else { - if (prevChild) { - removedNodes[name] = ReactReconciler.getHostNode(prevChild); - ReactReconciler.unmountComponent(prevChild, false); - } - // The child must be instantiated before it's mounted. - var nextChildInstance = instantiateReactComponent(nextElement, true); - nextChildren[name] = nextChildInstance; - // Creating mount image now ensures refs are resolved in right order - // (see https://github.com/facebook/react/pull/7101 for explanation). - var nextChildMountImage = ReactReconciler.mountComponent(nextChildInstance, transaction, hostParent, hostContainerInfo, context, selfDebugID); - mountImages.push(nextChildMountImage); - } - } - // Unmount children that are no longer present. - for (name in prevChildren) { - if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) { - prevChild = prevChildren[name]; - removedNodes[name] = ReactReconciler.getHostNode(prevChild); - ReactReconciler.unmountComponent(prevChild, false); - } - } - }, - - /** - * Unmounts all rendered children. This should be used to clean up children - * when this component is unmounted. - * - * @param {?object} renderedChildren Previously initialized set of children. - * @internal - */ - unmountChildren: function (renderedChildren, safely) { - for (var name in renderedChildren) { - if (renderedChildren.hasOwnProperty(name)) { - var renderedChild = renderedChildren[name]; - ReactReconciler.unmountComponent(renderedChild, safely); - } - } - } - -}; - -module.exports = ReactChildReconciler; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 249 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMChildrenOperations = __webpack_require__(46); -var ReactDOMIDOperations = __webpack_require__(256); - -/** - * Abstracts away all functionality of the reconciler that requires knowledge of - * the browser context. TODO: These callers should be refactored to avoid the - * need for this injection. - */ -var ReactComponentBrowserEnvironment = { - - processChildrenUpdates: ReactDOMIDOperations.dangerouslyProcessChildrenUpdates, - - replaceNodeWithMarkup: DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup - -}; - -module.exports = ReactComponentBrowserEnvironment; - -/***/ }), -/* 250 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var React = __webpack_require__(27); -var ReactComponentEnvironment = __webpack_require__(51); -var ReactCurrentOwner = __webpack_require__(15); -var ReactErrorUtils = __webpack_require__(52); -var ReactInstanceMap = __webpack_require__(32); -var ReactInstrumentation = __webpack_require__(10); -var ReactNodeTypes = __webpack_require__(88); -var ReactReconciler = __webpack_require__(26); - -if (process.env.NODE_ENV !== 'production') { - var checkReactTypeSpec = __webpack_require__(298); -} - -var emptyObject = __webpack_require__(28); -var invariant = __webpack_require__(2); -var shallowEqual = __webpack_require__(42); -var shouldUpdateReactComponent = __webpack_require__(59); -var warning = __webpack_require__(3); - -var CompositeTypes = { - ImpureClass: 0, - PureClass: 1, - StatelessFunctional: 2 -}; - -function StatelessComponent(Component) {} -StatelessComponent.prototype.render = function () { - var Component = ReactInstanceMap.get(this)._currentElement.type; - var element = Component(this.props, this.context, this.updater); - warnIfInvalidElement(Component, element); - return element; -}; - -function warnIfInvalidElement(Component, element) { - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(element === null || element === false || React.isValidElement(element), '%s(...): A valid React element (or null) must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(!Component.childContextTypes, '%s(...): childContextTypes cannot be defined on a functional component.', Component.displayName || Component.name || 'Component') : void 0; - } -} - -function shouldConstruct(Component) { - return !!(Component.prototype && Component.prototype.isReactComponent); -} - -function isPureComponent(Component) { - return !!(Component.prototype && Component.prototype.isPureReactComponent); -} - -// Separated into a function to contain deoptimizations caused by try/finally. -function measureLifeCyclePerf(fn, debugID, timerType) { - if (debugID === 0) { - // Top-level wrappers (see ReactMount) and empty components (see - // ReactDOMEmptyComponent) are invisible to hooks and devtools. - // Both are implementation details that should go away in the future. - return fn(); - } - - ReactInstrumentation.debugTool.onBeginLifeCycleTimer(debugID, timerType); - try { - return fn(); - } finally { - ReactInstrumentation.debugTool.onEndLifeCycleTimer(debugID, timerType); - } -} - -/** - * ------------------ The Life-Cycle of a Composite Component ------------------ - * - * - constructor: Initialization of state. The instance is now retained. - * - componentWillMount - * - render - * - [children's constructors] - * - [children's componentWillMount and render] - * - [children's componentDidMount] - * - componentDidMount - * - * Update Phases: - * - componentWillReceiveProps (only called if parent updated) - * - shouldComponentUpdate - * - componentWillUpdate - * - render - * - [children's constructors or receive props phases] - * - componentDidUpdate - * - * - componentWillUnmount - * - [children's componentWillUnmount] - * - [children destroyed] - * - (destroyed): The instance is now blank, released by React and ready for GC. - * - * ----------------------------------------------------------------------------- - */ - -/** - * An incrementing ID assigned to each component when it is mounted. This is - * used to enforce the order in which `ReactUpdates` updates dirty components. - * - * @private - */ -var nextMountID = 1; - -/** - * @lends {ReactCompositeComponent.prototype} - */ -var ReactCompositeComponent = { - - /** - * Base constructor for all composite component. - * - * @param {ReactElement} element - * @final - * @internal - */ - construct: function (element) { - this._currentElement = element; - this._rootNodeID = 0; - this._compositeType = null; - this._instance = null; - this._hostParent = null; - this._hostContainerInfo = null; - - // See ReactUpdateQueue - this._updateBatchNumber = null; - this._pendingElement = null; - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - - this._renderedNodeType = null; - this._renderedComponent = null; - this._context = null; - this._mountOrder = 0; - this._topLevelWrapper = null; - - // See ReactUpdates and ReactUpdateQueue. - this._pendingCallbacks = null; - - // ComponentWillUnmount shall only be called once - this._calledComponentWillUnmount = false; - - if (process.env.NODE_ENV !== 'production') { - this._warnedAboutRefsInRender = false; - } - }, - - /** - * Initializes the component, renders markup, and registers event listeners. - * - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {?object} hostParent - * @param {?object} hostContainerInfo - * @param {?object} context - * @return {?string} Rendered markup to be inserted into the DOM. - * @final - * @internal - */ - mountComponent: function (transaction, hostParent, hostContainerInfo, context) { - var _this = this; - - this._context = context; - this._mountOrder = nextMountID++; - this._hostParent = hostParent; - this._hostContainerInfo = hostContainerInfo; - - var publicProps = this._currentElement.props; - var publicContext = this._processContext(context); - - var Component = this._currentElement.type; - - var updateQueue = transaction.getUpdateQueue(); - - // Initialize the public class - var doConstruct = shouldConstruct(Component); - var inst = this._constructComponent(doConstruct, publicProps, publicContext, updateQueue); - var renderedElement; - - // Support functional components - if (!doConstruct && (inst == null || inst.render == null)) { - renderedElement = inst; - warnIfInvalidElement(Component, renderedElement); - !(inst === null || inst === false || React.isValidElement(inst)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component') : _prodInvariant('105', Component.displayName || Component.name || 'Component') : void 0; - inst = new StatelessComponent(Component); - this._compositeType = CompositeTypes.StatelessFunctional; - } else { - if (isPureComponent(Component)) { - this._compositeType = CompositeTypes.PureClass; - } else { - this._compositeType = CompositeTypes.ImpureClass; - } - } - - if (process.env.NODE_ENV !== 'production') { - // This will throw later in _renderValidatedComponent, but add an early - // warning now to help debugging - if (inst.render == null) { - process.env.NODE_ENV !== 'production' ? warning(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', Component.displayName || Component.name || 'Component') : void 0; - } - - var propsMutated = inst.props !== publicProps; - var componentName = Component.displayName || Component.name || 'Component'; - - process.env.NODE_ENV !== 'production' ? warning(inst.props === undefined || !propsMutated, '%s(...): When calling super() in `%s`, make sure to pass ' + 'up the same props that your component\'s constructor was passed.', componentName, componentName) : void 0; - } - - // These should be set up in the constructor, but as a convenience for - // simpler class abstractions, we set them up after the fact. - inst.props = publicProps; - inst.context = publicContext; - inst.refs = emptyObject; - inst.updater = updateQueue; - - this._instance = inst; - - // Store a reference from the instance back to the internal representation - ReactInstanceMap.set(inst, this); - - if (process.env.NODE_ENV !== 'production') { - // Since plain JS classes are defined without any special initialization - // logic, we can not catch common errors early. Therefore, we have to - // catch them here, at initialization time, instead. - process.env.NODE_ENV !== 'production' ? warning(!inst.getInitialState || inst.getInitialState.isReactClassApproved || inst.state, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', this.getName() || 'a component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(!inst.getDefaultProps || inst.getDefaultProps.isReactClassApproved, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', this.getName() || 'a component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(!inst.propTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', this.getName() || 'a component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(!inst.contextTypes, 'contextTypes was defined as an instance property on %s. Use a ' + 'static property to define contextTypes instead.', this.getName() || 'a component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentShouldUpdate !== 'function', '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', this.getName() || 'A component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentDidUnmount !== 'function', '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', this.getName() || 'A component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentWillRecieveProps !== 'function', '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', this.getName() || 'A component') : void 0; - } - - var initialState = inst.state; - if (initialState === undefined) { - inst.state = initialState = null; - } - !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.state: must be set to an object or null', this.getName() || 'ReactCompositeComponent') : _prodInvariant('106', this.getName() || 'ReactCompositeComponent') : void 0; - - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - - var markup; - if (inst.unstable_handleError) { - markup = this.performInitialMountWithErrorHandling(renderedElement, hostParent, hostContainerInfo, transaction, context); - } else { - markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context); - } - - if (inst.componentDidMount) { - if (process.env.NODE_ENV !== 'production') { - transaction.getReactMountReady().enqueue(function () { - measureLifeCyclePerf(function () { - return inst.componentDidMount(); - }, _this._debugID, 'componentDidMount'); - }); - } else { - transaction.getReactMountReady().enqueue(inst.componentDidMount, inst); - } - } - - return markup; - }, - - _constructComponent: function (doConstruct, publicProps, publicContext, updateQueue) { - if (process.env.NODE_ENV !== 'production') { - ReactCurrentOwner.current = this; - try { - return this._constructComponentWithoutOwner(doConstruct, publicProps, publicContext, updateQueue); - } finally { - ReactCurrentOwner.current = null; - } - } else { - return this._constructComponentWithoutOwner(doConstruct, publicProps, publicContext, updateQueue); - } - }, - - _constructComponentWithoutOwner: function (doConstruct, publicProps, publicContext, updateQueue) { - var Component = this._currentElement.type; - - if (doConstruct) { - if (process.env.NODE_ENV !== 'production') { - return measureLifeCyclePerf(function () { - return new Component(publicProps, publicContext, updateQueue); - }, this._debugID, 'ctor'); - } else { - return new Component(publicProps, publicContext, updateQueue); - } - } - - // This can still be an instance in case of factory components - // but we'll count this as time spent rendering as the more common case. - if (process.env.NODE_ENV !== 'production') { - return measureLifeCyclePerf(function () { - return Component(publicProps, publicContext, updateQueue); - }, this._debugID, 'render'); - } else { - return Component(publicProps, publicContext, updateQueue); - } - }, - - performInitialMountWithErrorHandling: function (renderedElement, hostParent, hostContainerInfo, transaction, context) { - var markup; - var checkpoint = transaction.checkpoint(); - try { - markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context); - } catch (e) { - // Roll back to checkpoint, handle error (which may add items to the transaction), and take a new checkpoint - transaction.rollback(checkpoint); - this._instance.unstable_handleError(e); - if (this._pendingStateQueue) { - this._instance.state = this._processPendingState(this._instance.props, this._instance.context); - } - checkpoint = transaction.checkpoint(); - - this._renderedComponent.unmountComponent(true); - transaction.rollback(checkpoint); - - // Try again - we've informed the component about the error, so they can render an error message this time. - // If this throws again, the error will bubble up (and can be caught by a higher error boundary). - markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context); - } - return markup; - }, - - performInitialMount: function (renderedElement, hostParent, hostContainerInfo, transaction, context) { - var inst = this._instance; - - var debugID = 0; - if (process.env.NODE_ENV !== 'production') { - debugID = this._debugID; - } - - if (inst.componentWillMount) { - if (process.env.NODE_ENV !== 'production') { - measureLifeCyclePerf(function () { - return inst.componentWillMount(); - }, debugID, 'componentWillMount'); - } else { - inst.componentWillMount(); - } - // When mounting, calls to `setState` by `componentWillMount` will set - // `this._pendingStateQueue` without triggering a re-render. - if (this._pendingStateQueue) { - inst.state = this._processPendingState(inst.props, inst.context); - } - } - - // If not a stateless component, we now render - if (renderedElement === undefined) { - renderedElement = this._renderValidatedComponent(); - } - - var nodeType = ReactNodeTypes.getType(renderedElement); - this._renderedNodeType = nodeType; - var child = this._instantiateReactComponent(renderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */ - ); - this._renderedComponent = child; - - var markup = ReactReconciler.mountComponent(child, transaction, hostParent, hostContainerInfo, this._processChildContext(context), debugID); - - if (process.env.NODE_ENV !== 'production') { - if (debugID !== 0) { - var childDebugIDs = child._debugID !== 0 ? [child._debugID] : []; - ReactInstrumentation.debugTool.onSetChildren(debugID, childDebugIDs); - } - } - - return markup; - }, - - getHostNode: function () { - return ReactReconciler.getHostNode(this._renderedComponent); - }, - - /** - * Releases any resources allocated by `mountComponent`. - * - * @final - * @internal - */ - unmountComponent: function (safely) { - if (!this._renderedComponent) { - return; - } - - var inst = this._instance; - - if (inst.componentWillUnmount && !inst._calledComponentWillUnmount) { - inst._calledComponentWillUnmount = true; - - if (safely) { - var name = this.getName() + '.componentWillUnmount()'; - ReactErrorUtils.invokeGuardedCallback(name, inst.componentWillUnmount.bind(inst)); - } else { - if (process.env.NODE_ENV !== 'production') { - measureLifeCyclePerf(function () { - return inst.componentWillUnmount(); - }, this._debugID, 'componentWillUnmount'); - } else { - inst.componentWillUnmount(); - } - } - } - - if (this._renderedComponent) { - ReactReconciler.unmountComponent(this._renderedComponent, safely); - this._renderedNodeType = null; - this._renderedComponent = null; - this._instance = null; - } - - // Reset pending fields - // Even if this component is scheduled for another update in ReactUpdates, - // it would still be ignored because these fields are reset. - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - this._pendingCallbacks = null; - this._pendingElement = null; - - // These fields do not really need to be reset since this object is no - // longer accessible. - this._context = null; - this._rootNodeID = 0; - this._topLevelWrapper = null; - - // Delete the reference from the instance to this internal representation - // which allow the internals to be properly cleaned up even if the user - // leaks a reference to the public instance. - ReactInstanceMap.remove(inst); - - // Some existing components rely on inst.props even after they've been - // destroyed (in event handlers). - // TODO: inst.props = null; - // TODO: inst.state = null; - // TODO: inst.context = null; - }, - - /** - * Filters the context object to only contain keys specified in - * `contextTypes` - * - * @param {object} context - * @return {?object} - * @private - */ - _maskContext: function (context) { - var Component = this._currentElement.type; - var contextTypes = Component.contextTypes; - if (!contextTypes) { - return emptyObject; - } - var maskedContext = {}; - for (var contextName in contextTypes) { - maskedContext[contextName] = context[contextName]; - } - return maskedContext; - }, - - /** - * Filters the context object to only contain keys specified in - * `contextTypes`, and asserts that they are valid. - * - * @param {object} context - * @return {?object} - * @private - */ - _processContext: function (context) { - var maskedContext = this._maskContext(context); - if (process.env.NODE_ENV !== 'production') { - var Component = this._currentElement.type; - if (Component.contextTypes) { - this._checkContextTypes(Component.contextTypes, maskedContext, 'context'); - } - } - return maskedContext; - }, - - /** - * @param {object} currentContext - * @return {object} - * @private - */ - _processChildContext: function (currentContext) { - var Component = this._currentElement.type; - var inst = this._instance; - var childContext; - - if (inst.getChildContext) { - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onBeginProcessingChildContext(); - try { - childContext = inst.getChildContext(); - } finally { - ReactInstrumentation.debugTool.onEndProcessingChildContext(); - } - } else { - childContext = inst.getChildContext(); - } - } - - if (childContext) { - !(typeof Component.childContextTypes === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().', this.getName() || 'ReactCompositeComponent') : _prodInvariant('107', this.getName() || 'ReactCompositeComponent') : void 0; - if (process.env.NODE_ENV !== 'production') { - this._checkContextTypes(Component.childContextTypes, childContext, 'childContext'); - } - for (var name in childContext) { - !(name in Component.childContextTypes) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', this.getName() || 'ReactCompositeComponent', name) : _prodInvariant('108', this.getName() || 'ReactCompositeComponent', name) : void 0; - } - return _assign({}, currentContext, childContext); - } - return currentContext; - }, - - /** - * Assert that the context types are valid - * - * @param {object} typeSpecs Map of context field to a ReactPropType - * @param {object} values Runtime values that need to be type-checked - * @param {string} location e.g. "prop", "context", "child context" - * @private - */ - _checkContextTypes: function (typeSpecs, values, location) { - if (process.env.NODE_ENV !== 'production') { - checkReactTypeSpec(typeSpecs, values, location, this.getName(), null, this._debugID); - } - }, - - receiveComponent: function (nextElement, transaction, nextContext) { - var prevElement = this._currentElement; - var prevContext = this._context; - - this._pendingElement = null; - - this.updateComponent(transaction, prevElement, nextElement, prevContext, nextContext); - }, - - /** - * If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate` - * is set, update the component. - * - * @param {ReactReconcileTransaction} transaction - * @internal - */ - performUpdateIfNecessary: function (transaction) { - if (this._pendingElement != null) { - ReactReconciler.receiveComponent(this, this._pendingElement, transaction, this._context); - } else if (this._pendingStateQueue !== null || this._pendingForceUpdate) { - this.updateComponent(transaction, this._currentElement, this._currentElement, this._context, this._context); - } else { - this._updateBatchNumber = null; - } - }, - - /** - * Perform an update to a mounted component. The componentWillReceiveProps and - * shouldComponentUpdate methods are called, then (assuming the update isn't - * skipped) the remaining update lifecycle methods are called and the DOM - * representation is updated. - * - * By default, this implements React's rendering and reconciliation algorithm. - * Sophisticated clients may wish to override this. - * - * @param {ReactReconcileTransaction} transaction - * @param {ReactElement} prevParentElement - * @param {ReactElement} nextParentElement - * @internal - * @overridable - */ - updateComponent: function (transaction, prevParentElement, nextParentElement, prevUnmaskedContext, nextUnmaskedContext) { - var inst = this._instance; - !(inst != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Attempted to update component `%s` that has already been unmounted (or failed to mount).', this.getName() || 'ReactCompositeComponent') : _prodInvariant('136', this.getName() || 'ReactCompositeComponent') : void 0; - - var willReceive = false; - var nextContext; - - // Determine if the context has changed or not - if (this._context === nextUnmaskedContext) { - nextContext = inst.context; - } else { - nextContext = this._processContext(nextUnmaskedContext); - willReceive = true; - } - - var prevProps = prevParentElement.props; - var nextProps = nextParentElement.props; - - // Not a simple state update but a props update - if (prevParentElement !== nextParentElement) { - willReceive = true; - } - - // An update here will schedule an update but immediately set - // _pendingStateQueue which will ensure that any state updates gets - // immediately reconciled instead of waiting for the next batch. - if (willReceive && inst.componentWillReceiveProps) { - if (process.env.NODE_ENV !== 'production') { - measureLifeCyclePerf(function () { - return inst.componentWillReceiveProps(nextProps, nextContext); - }, this._debugID, 'componentWillReceiveProps'); - } else { - inst.componentWillReceiveProps(nextProps, nextContext); - } - } - - var nextState = this._processPendingState(nextProps, nextContext); - var shouldUpdate = true; - - if (!this._pendingForceUpdate) { - if (inst.shouldComponentUpdate) { - if (process.env.NODE_ENV !== 'production') { - shouldUpdate = measureLifeCyclePerf(function () { - return inst.shouldComponentUpdate(nextProps, nextState, nextContext); - }, this._debugID, 'shouldComponentUpdate'); - } else { - shouldUpdate = inst.shouldComponentUpdate(nextProps, nextState, nextContext); - } - } else { - if (this._compositeType === CompositeTypes.PureClass) { - shouldUpdate = !shallowEqual(prevProps, nextProps) || !shallowEqual(inst.state, nextState); - } - } - } - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(shouldUpdate !== undefined, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', this.getName() || 'ReactCompositeComponent') : void 0; - } - - this._updateBatchNumber = null; - if (shouldUpdate) { - this._pendingForceUpdate = false; - // Will set `this.props`, `this.state` and `this.context`. - this._performComponentUpdate(nextParentElement, nextProps, nextState, nextContext, transaction, nextUnmaskedContext); - } else { - // If it's determined that a component should not update, we still want - // to set props and state but we shortcut the rest of the update. - this._currentElement = nextParentElement; - this._context = nextUnmaskedContext; - inst.props = nextProps; - inst.state = nextState; - inst.context = nextContext; - } - }, - - _processPendingState: function (props, context) { - var inst = this._instance; - var queue = this._pendingStateQueue; - var replace = this._pendingReplaceState; - this._pendingReplaceState = false; - this._pendingStateQueue = null; - - if (!queue) { - return inst.state; - } - - if (replace && queue.length === 1) { - return queue[0]; - } - - var nextState = _assign({}, replace ? queue[0] : inst.state); - for (var i = replace ? 1 : 0; i < queue.length; i++) { - var partial = queue[i]; - _assign(nextState, typeof partial === 'function' ? partial.call(inst, nextState, props, context) : partial); - } - - return nextState; - }, - - /** - * Merges new props and state, notifies delegate methods of update and - * performs update. - * - * @param {ReactElement} nextElement Next element - * @param {object} nextProps Next public object to set as properties. - * @param {?object} nextState Next object to set as state. - * @param {?object} nextContext Next public object to set as context. - * @param {ReactReconcileTransaction} transaction - * @param {?object} unmaskedContext - * @private - */ - _performComponentUpdate: function (nextElement, nextProps, nextState, nextContext, transaction, unmaskedContext) { - var _this2 = this; - - var inst = this._instance; - - var hasComponentDidUpdate = Boolean(inst.componentDidUpdate); - var prevProps; - var prevState; - var prevContext; - if (hasComponentDidUpdate) { - prevProps = inst.props; - prevState = inst.state; - prevContext = inst.context; - } - - if (inst.componentWillUpdate) { - if (process.env.NODE_ENV !== 'production') { - measureLifeCyclePerf(function () { - return inst.componentWillUpdate(nextProps, nextState, nextContext); - }, this._debugID, 'componentWillUpdate'); - } else { - inst.componentWillUpdate(nextProps, nextState, nextContext); - } - } - - this._currentElement = nextElement; - this._context = unmaskedContext; - inst.props = nextProps; - inst.state = nextState; - inst.context = nextContext; - - this._updateRenderedComponent(transaction, unmaskedContext); - - if (hasComponentDidUpdate) { - if (process.env.NODE_ENV !== 'production') { - transaction.getReactMountReady().enqueue(function () { - measureLifeCyclePerf(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), _this2._debugID, 'componentDidUpdate'); - }); - } else { - transaction.getReactMountReady().enqueue(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), inst); - } - } - }, - - /** - * Call the component's `render` method and update the DOM accordingly. - * - * @param {ReactReconcileTransaction} transaction - * @internal - */ - _updateRenderedComponent: function (transaction, context) { - var prevComponentInstance = this._renderedComponent; - var prevRenderedElement = prevComponentInstance._currentElement; - var nextRenderedElement = this._renderValidatedComponent(); - - var debugID = 0; - if (process.env.NODE_ENV !== 'production') { - debugID = this._debugID; - } - - if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { - ReactReconciler.receiveComponent(prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context)); - } else { - var oldHostNode = ReactReconciler.getHostNode(prevComponentInstance); - ReactReconciler.unmountComponent(prevComponentInstance, false); - - var nodeType = ReactNodeTypes.getType(nextRenderedElement); - this._renderedNodeType = nodeType; - var child = this._instantiateReactComponent(nextRenderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */ - ); - this._renderedComponent = child; - - var nextMarkup = ReactReconciler.mountComponent(child, transaction, this._hostParent, this._hostContainerInfo, this._processChildContext(context), debugID); - - if (process.env.NODE_ENV !== 'production') { - if (debugID !== 0) { - var childDebugIDs = child._debugID !== 0 ? [child._debugID] : []; - ReactInstrumentation.debugTool.onSetChildren(debugID, childDebugIDs); - } - } - - this._replaceNodeWithMarkup(oldHostNode, nextMarkup, prevComponentInstance); - } - }, - - /** - * Overridden in shallow rendering. - * - * @protected - */ - _replaceNodeWithMarkup: function (oldHostNode, nextMarkup, prevInstance) { - ReactComponentEnvironment.replaceNodeWithMarkup(oldHostNode, nextMarkup, prevInstance); - }, - - /** - * @protected - */ - _renderValidatedComponentWithoutOwnerOrContext: function () { - var inst = this._instance; - var renderedElement; - - if (process.env.NODE_ENV !== 'production') { - renderedElement = measureLifeCyclePerf(function () { - return inst.render(); - }, this._debugID, 'render'); - } else { - renderedElement = inst.render(); - } - - if (process.env.NODE_ENV !== 'production') { - // We allow auto-mocks to proceed as if they're returning null. - if (renderedElement === undefined && inst.render._isMockFunction) { - // This is probably bad practice. Consider warning here and - // deprecating this convenience. - renderedElement = null; - } - } - - return renderedElement; - }, - - /** - * @private - */ - _renderValidatedComponent: function () { - var renderedElement; - if (process.env.NODE_ENV !== 'production' || this._compositeType !== CompositeTypes.StatelessFunctional) { - ReactCurrentOwner.current = this; - try { - renderedElement = this._renderValidatedComponentWithoutOwnerOrContext(); - } finally { - ReactCurrentOwner.current = null; - } - } else { - renderedElement = this._renderValidatedComponentWithoutOwnerOrContext(); - } - !( - // TODO: An `isValidNode` function would probably be more appropriate - renderedElement === null || renderedElement === false || React.isValidElement(renderedElement)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.', this.getName() || 'ReactCompositeComponent') : _prodInvariant('109', this.getName() || 'ReactCompositeComponent') : void 0; - - return renderedElement; - }, - - /** - * Lazily allocates the refs object and stores `component` as `ref`. - * - * @param {string} ref Reference name. - * @param {component} component Component to store as `ref`. - * @final - * @private - */ - attachRef: function (ref, component) { - var inst = this.getPublicInstance(); - !(inst != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Stateless function components cannot have refs.') : _prodInvariant('110') : void 0; - var publicComponentInstance = component.getPublicInstance(); - if (process.env.NODE_ENV !== 'production') { - var componentName = component && component.getName ? component.getName() : 'a component'; - process.env.NODE_ENV !== 'production' ? warning(publicComponentInstance != null || component._compositeType !== CompositeTypes.StatelessFunctional, 'Stateless function components cannot be given refs ' + '(See ref "%s" in %s created by %s). ' + 'Attempts to access this ref will fail.', ref, componentName, this.getName()) : void 0; - } - var refs = inst.refs === emptyObject ? inst.refs = {} : inst.refs; - refs[ref] = publicComponentInstance; - }, - - /** - * Detaches a reference name. - * - * @param {string} ref Name to dereference. - * @final - * @private - */ - detachRef: function (ref) { - var refs = this.getPublicInstance().refs; - delete refs[ref]; - }, - - /** - * Get a text description of the component that can be used to identify it - * in error messages. - * @return {string} The name or null. - * @internal - */ - getName: function () { - var type = this._currentElement.type; - var constructor = this._instance && this._instance.constructor; - return type.displayName || constructor && constructor.displayName || type.name || constructor && constructor.name || null; - }, - - /** - * Get the publicly accessible representation of this component - i.e. what - * is exposed by refs and returned by render. Can be null for stateless - * components. - * - * @return {ReactComponent} the public component instance. - * @internal - */ - getPublicInstance: function () { - var inst = this._instance; - if (this._compositeType === CompositeTypes.StatelessFunctional) { - return null; - } - return inst; - }, - - // Stub - _instantiateReactComponent: null - -}; - -module.exports = ReactCompositeComponent; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 251 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/ - - - -var ReactDOMComponentTree = __webpack_require__(7); -var ReactDefaultInjection = __webpack_require__(268); -var ReactMount = __webpack_require__(87); -var ReactReconciler = __webpack_require__(26); -var ReactUpdates = __webpack_require__(14); -var ReactVersion = __webpack_require__(283); - -var findDOMNode = __webpack_require__(300); -var getHostComponentFromComposite = __webpack_require__(93); -var renderSubtreeIntoContainer = __webpack_require__(308); -var warning = __webpack_require__(3); - -ReactDefaultInjection.inject(); - -var ReactDOM = { - findDOMNode: findDOMNode, - render: ReactMount.render, - unmountComponentAtNode: ReactMount.unmountComponentAtNode, - version: ReactVersion, - - /* eslint-disable camelcase */ - unstable_batchedUpdates: ReactUpdates.batchedUpdates, - unstable_renderSubtreeIntoContainer: renderSubtreeIntoContainer -}; - -// Inject the runtime into a devtools global hook regardless of browser. -// Allows for debugging when the hook is injected on the page. -if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') { - __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ - ComponentTree: { - getClosestInstanceFromNode: ReactDOMComponentTree.getClosestInstanceFromNode, - getNodeFromInstance: function (inst) { - // inst is an internal instance (but could be a composite) - if (inst._renderedComponent) { - inst = getHostComponentFromComposite(inst); - } - if (inst) { - return ReactDOMComponentTree.getNodeFromInstance(inst); - } else { - return null; - } - } - }, - Mount: ReactMount, - Reconciler: ReactReconciler - }); -} - -if (process.env.NODE_ENV !== 'production') { - var ExecutionEnvironment = __webpack_require__(8); - if (ExecutionEnvironment.canUseDOM && window.top === window.self) { - - // First check if devtools is not installed - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { - // If we're in Chrome or Firefox, provide a download link if not installed. - if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) { - // Firefox does not have the issue with devtools loaded over file:// - var showFileUrlMessage = window.location.protocol.indexOf('http') === -1 && navigator.userAgent.indexOf('Firefox') === -1; - console.debug('Download the React DevTools ' + (showFileUrlMessage ? 'and use an HTTP server (instead of a file: URL) ' : '') + 'for a better development experience: ' + 'https://fb.me/react-devtools'); - } - } - - var testFunc = function testFn() {}; - process.env.NODE_ENV !== 'production' ? warning((testFunc.name || testFunc.toString()).indexOf('testFn') !== -1, 'It looks like you\'re using a minified copy of the development build ' + 'of React. When deploying React apps to production, make sure to use ' + 'the production build which skips development warnings and is faster. ' + 'See https://fb.me/react-minification for more details.') : void 0; - - // If we're in IE8, check to see if we are in compatibility mode and provide - // information on preventing compatibility mode - var ieCompatibilityMode = document.documentMode && document.documentMode < 8; - - process.env.NODE_ENV !== 'production' ? warning(!ieCompatibilityMode, 'Internet Explorer is running in compatibility mode; please add the ' + 'following tag to your HTML to prevent this from happening: ' + '<meta http-equiv="X-UA-Compatible" content="IE=edge" />') : void 0; - - var expectedFeatures = [ - // shims - Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.trim]; - - for (var i = 0; i < expectedFeatures.length; i++) { - if (!expectedFeatures[i]) { - process.env.NODE_ENV !== 'production' ? warning(false, 'One or more ES5 shims expected by React are not available: ' + 'https://fb.me/react-warning-polyfills') : void 0; - break; - } - } - } -} - -if (process.env.NODE_ENV !== 'production') { - var ReactInstrumentation = __webpack_require__(10); - var ReactDOMUnknownPropertyHook = __webpack_require__(265); - var ReactDOMNullInputValuePropHook = __webpack_require__(259); - var ReactDOMInvalidARIAHook = __webpack_require__(258); - - ReactInstrumentation.debugTool.addHook(ReactDOMUnknownPropertyHook); - ReactInstrumentation.debugTool.addHook(ReactDOMNullInputValuePropHook); - ReactInstrumentation.debugTool.addHook(ReactDOMInvalidARIAHook); -} - -module.exports = ReactDOM; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 252 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -/* global hasOwnProperty:true */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var AutoFocusUtils = __webpack_require__(239); -var CSSPropertyOperations = __webpack_require__(241); -var DOMLazyTree = __webpack_require__(25); -var DOMNamespaces = __webpack_require__(47); -var DOMProperty = __webpack_require__(18); -var DOMPropertyOperations = __webpack_require__(80); -var EventPluginHub = __webpack_require__(30); -var EventPluginRegistry = __webpack_require__(35); -var ReactBrowserEventEmitter = __webpack_require__(36); -var ReactDOMComponentFlags = __webpack_require__(81); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactDOMInput = __webpack_require__(257); -var ReactDOMOption = __webpack_require__(260); -var ReactDOMSelect = __webpack_require__(82); -var ReactDOMTextarea = __webpack_require__(263); -var ReactInstrumentation = __webpack_require__(10); -var ReactMultiChild = __webpack_require__(276); -var ReactServerRenderingTransaction = __webpack_require__(281); - -var emptyFunction = __webpack_require__(12); -var escapeTextContentForBrowser = __webpack_require__(39); -var invariant = __webpack_require__(2); -var isEventSupported = __webpack_require__(58); -var shallowEqual = __webpack_require__(42); -var validateDOMNesting = __webpack_require__(60); -var warning = __webpack_require__(3); - -var Flags = ReactDOMComponentFlags; -var deleteListener = EventPluginHub.deleteListener; -var getNode = ReactDOMComponentTree.getNodeFromInstance; -var listenTo = ReactBrowserEventEmitter.listenTo; -var registrationNameModules = EventPluginRegistry.registrationNameModules; - -// For quickly matching children type, to test if can be treated as content. -var CONTENT_TYPES = { 'string': true, 'number': true }; - -var STYLE = 'style'; -var HTML = '__html'; -var RESERVED_PROPS = { - children: null, - dangerouslySetInnerHTML: null, - suppressContentEditableWarning: null -}; - -// Node type for document fragments (Node.DOCUMENT_FRAGMENT_NODE). -var DOC_FRAGMENT_TYPE = 11; - -function getDeclarationErrorAddendum(internalInstance) { - if (internalInstance) { - var owner = internalInstance._currentElement._owner || null; - if (owner) { - var name = owner.getName(); - if (name) { - return ' This DOM node was rendered by `' + name + '`.'; - } - } - } - return ''; -} - -function friendlyStringify(obj) { - if (typeof obj === 'object') { - if (Array.isArray(obj)) { - return '[' + obj.map(friendlyStringify).join(', ') + ']'; - } else { - var pairs = []; - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - var keyEscaped = /^[a-z$_][\w$_]*$/i.test(key) ? key : JSON.stringify(key); - pairs.push(keyEscaped + ': ' + friendlyStringify(obj[key])); - } - } - return '{' + pairs.join(', ') + '}'; - } - } else if (typeof obj === 'string') { - return JSON.stringify(obj); - } else if (typeof obj === 'function') { - return '[function object]'; - } - // Differs from JSON.stringify in that undefined because undefined and that - // inf and nan don't become null - return String(obj); -} - -var styleMutationWarning = {}; - -function checkAndWarnForMutatedStyle(style1, style2, component) { - if (style1 == null || style2 == null) { - return; - } - if (shallowEqual(style1, style2)) { - return; - } - - var componentName = component._tag; - var owner = component._currentElement._owner; - var ownerName; - if (owner) { - ownerName = owner.getName(); - } - - var hash = ownerName + '|' + componentName; - - if (styleMutationWarning.hasOwnProperty(hash)) { - return; - } - - styleMutationWarning[hash] = true; - - process.env.NODE_ENV !== 'production' ? warning(false, '`%s` was passed a style object that has previously been mutated. ' + 'Mutating `style` is deprecated. Consider cloning it beforehand. Check ' + 'the `render` %s. Previous style: %s. Mutated style: %s.', componentName, owner ? 'of `' + ownerName + '`' : 'using <' + componentName + '>', friendlyStringify(style1), friendlyStringify(style2)) : void 0; -} - -/** - * @param {object} component - * @param {?object} props - */ -function assertValidProps(component, props) { - if (!props) { - return; - } - // Note the use of `==` which checks for null or undefined. - if (voidElementTags[component._tag]) { - !(props.children == null && props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : _prodInvariant('137', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : void 0; - } - if (props.dangerouslySetInnerHTML != null) { - !(props.children == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : _prodInvariant('60') : void 0; - !(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.') : _prodInvariant('61') : void 0; - } - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : void 0; - process.env.NODE_ENV !== 'production' ? warning(props.suppressContentEditableWarning || !props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : void 0; - process.env.NODE_ENV !== 'production' ? warning(props.onFocusIn == null && props.onFocusOut == null, 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.') : void 0; - } - !(props.style == null || typeof props.style === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + \'em\'}} when using JSX.%s', getDeclarationErrorAddendum(component)) : _prodInvariant('62', getDeclarationErrorAddendum(component)) : void 0; -} - -function enqueuePutListener(inst, registrationName, listener, transaction) { - if (transaction instanceof ReactServerRenderingTransaction) { - return; - } - if (process.env.NODE_ENV !== 'production') { - // IE8 has no API for event capturing and the `onScroll` event doesn't - // bubble. - process.env.NODE_ENV !== 'production' ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\'t support the `onScroll` event') : void 0; - } - var containerInfo = inst._hostContainerInfo; - var isDocumentFragment = containerInfo._node && containerInfo._node.nodeType === DOC_FRAGMENT_TYPE; - var doc = isDocumentFragment ? containerInfo._node : containerInfo._ownerDocument; - listenTo(registrationName, doc); - transaction.getReactMountReady().enqueue(putListener, { - inst: inst, - registrationName: registrationName, - listener: listener - }); -} - -function putListener() { - var listenerToPut = this; - EventPluginHub.putListener(listenerToPut.inst, listenerToPut.registrationName, listenerToPut.listener); -} - -function inputPostMount() { - var inst = this; - ReactDOMInput.postMountWrapper(inst); -} - -function textareaPostMount() { - var inst = this; - ReactDOMTextarea.postMountWrapper(inst); -} - -function optionPostMount() { - var inst = this; - ReactDOMOption.postMountWrapper(inst); -} - -var setAndValidateContentChildDev = emptyFunction; -if (process.env.NODE_ENV !== 'production') { - setAndValidateContentChildDev = function (content) { - var hasExistingContent = this._contentDebugID != null; - var debugID = this._debugID; - // This ID represents the inlined child that has no backing instance: - var contentDebugID = -debugID; - - if (content == null) { - if (hasExistingContent) { - ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID); - } - this._contentDebugID = null; - return; - } - - validateDOMNesting(null, String(content), this, this._ancestorInfo); - this._contentDebugID = contentDebugID; - if (hasExistingContent) { - ReactInstrumentation.debugTool.onBeforeUpdateComponent(contentDebugID, content); - ReactInstrumentation.debugTool.onUpdateComponent(contentDebugID); - } else { - ReactInstrumentation.debugTool.onBeforeMountComponent(contentDebugID, content, debugID); - ReactInstrumentation.debugTool.onMountComponent(contentDebugID); - ReactInstrumentation.debugTool.onSetChildren(debugID, [contentDebugID]); - } - }; -} - -// There are so many media events, it makes sense to just -// maintain a list rather than create a `trapBubbledEvent` for each -var mediaEvents = { - topAbort: 'abort', - topCanPlay: 'canplay', - topCanPlayThrough: 'canplaythrough', - topDurationChange: 'durationchange', - topEmptied: 'emptied', - topEncrypted: 'encrypted', - topEnded: 'ended', - topError: 'error', - topLoadedData: 'loadeddata', - topLoadedMetadata: 'loadedmetadata', - topLoadStart: 'loadstart', - topPause: 'pause', - topPlay: 'play', - topPlaying: 'playing', - topProgress: 'progress', - topRateChange: 'ratechange', - topSeeked: 'seeked', - topSeeking: 'seeking', - topStalled: 'stalled', - topSuspend: 'suspend', - topTimeUpdate: 'timeupdate', - topVolumeChange: 'volumechange', - topWaiting: 'waiting' -}; - -function trapBubbledEventsLocal() { - var inst = this; - // If a component renders to null or if another component fatals and causes - // the state of the tree to be corrupted, `node` here can be null. - !inst._rootNodeID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Must be mounted to trap events') : _prodInvariant('63') : void 0; - var node = getNode(inst); - !node ? process.env.NODE_ENV !== 'production' ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : _prodInvariant('64') : void 0; - - switch (inst._tag) { - case 'iframe': - case 'object': - inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topLoad', 'load', node)]; - break; - case 'video': - case 'audio': - - inst._wrapperState.listeners = []; - // Create listener for each media event - for (var event in mediaEvents) { - if (mediaEvents.hasOwnProperty(event)) { - inst._wrapperState.listeners.push(ReactBrowserEventEmitter.trapBubbledEvent(event, mediaEvents[event], node)); - } - } - break; - case 'source': - inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topError', 'error', node)]; - break; - case 'img': - inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topError', 'error', node), ReactBrowserEventEmitter.trapBubbledEvent('topLoad', 'load', node)]; - break; - case 'form': - inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topReset', 'reset', node), ReactBrowserEventEmitter.trapBubbledEvent('topSubmit', 'submit', node)]; - break; - case 'input': - case 'select': - case 'textarea': - inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topInvalid', 'invalid', node)]; - break; - } -} - -function postUpdateSelectWrapper() { - ReactDOMSelect.postUpdateWrapper(this); -} - -// For HTML, certain tags should omit their close tag. We keep a whitelist for -// those special-case tags. - -var omittedCloseTags = { - 'area': true, - 'base': true, - 'br': true, - 'col': true, - 'embed': true, - 'hr': true, - 'img': true, - 'input': true, - 'keygen': true, - 'link': true, - 'meta': true, - 'param': true, - 'source': true, - 'track': true, - 'wbr': true -}; - -var newlineEatingTags = { - 'listing': true, - 'pre': true, - 'textarea': true -}; - -// For HTML, certain tags cannot have children. This has the same purpose as -// `omittedCloseTags` except that `menuitem` should still have its closing tag. - -var voidElementTags = _assign({ - 'menuitem': true -}, omittedCloseTags); - -// We accept any tag to be rendered but since this gets injected into arbitrary -// HTML, we want to make sure that it's a safe tag. -// http://www.w3.org/TR/REC-xml/#NT-Name - -var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset -var validatedTagCache = {}; -var hasOwnProperty = {}.hasOwnProperty; - -function validateDangerousTag(tag) { - if (!hasOwnProperty.call(validatedTagCache, tag)) { - !VALID_TAG_REGEX.test(tag) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Invalid tag: %s', tag) : _prodInvariant('65', tag) : void 0; - validatedTagCache[tag] = true; - } -} - -function isCustomComponent(tagName, props) { - return tagName.indexOf('-') >= 0 || props.is != null; -} - -var globalIdCounter = 1; - -/** - * Creates a new React class that is idempotent and capable of containing other - * React components. It accepts event listeners and DOM properties that are - * valid according to `DOMProperty`. - * - * - Event listeners: `onClick`, `onMouseDown`, etc. - * - DOM properties: `className`, `name`, `title`, etc. - * - * The `style` property functions differently from the DOM API. It accepts an - * object mapping of style properties to values. - * - * @constructor ReactDOMComponent - * @extends ReactMultiChild - */ -function ReactDOMComponent(element) { - var tag = element.type; - validateDangerousTag(tag); - this._currentElement = element; - this._tag = tag.toLowerCase(); - this._namespaceURI = null; - this._renderedChildren = null; - this._previousStyle = null; - this._previousStyleCopy = null; - this._hostNode = null; - this._hostParent = null; - this._rootNodeID = 0; - this._domID = 0; - this._hostContainerInfo = null; - this._wrapperState = null; - this._topLevelWrapper = null; - this._flags = 0; - if (process.env.NODE_ENV !== 'production') { - this._ancestorInfo = null; - setAndValidateContentChildDev.call(this, null); - } -} - -ReactDOMComponent.displayName = 'ReactDOMComponent'; - -ReactDOMComponent.Mixin = { - - /** - * Generates root tag markup then recurses. This method has side effects and - * is not idempotent. - * - * @internal - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {?ReactDOMComponent} the parent component instance - * @param {?object} info about the host container - * @param {object} context - * @return {string} The computed markup. - */ - mountComponent: function (transaction, hostParent, hostContainerInfo, context) { - this._rootNodeID = globalIdCounter++; - this._domID = hostContainerInfo._idCounter++; - this._hostParent = hostParent; - this._hostContainerInfo = hostContainerInfo; - - var props = this._currentElement.props; - - switch (this._tag) { - case 'audio': - case 'form': - case 'iframe': - case 'img': - case 'link': - case 'object': - case 'source': - case 'video': - this._wrapperState = { - listeners: null - }; - transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); - break; - case 'input': - ReactDOMInput.mountWrapper(this, props, hostParent); - props = ReactDOMInput.getHostProps(this, props); - transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); - break; - case 'option': - ReactDOMOption.mountWrapper(this, props, hostParent); - props = ReactDOMOption.getHostProps(this, props); - break; - case 'select': - ReactDOMSelect.mountWrapper(this, props, hostParent); - props = ReactDOMSelect.getHostProps(this, props); - transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); - break; - case 'textarea': - ReactDOMTextarea.mountWrapper(this, props, hostParent); - props = ReactDOMTextarea.getHostProps(this, props); - transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); - break; - } - - assertValidProps(this, props); - - // We create tags in the namespace of their parent container, except HTML - // tags get no namespace. - var namespaceURI; - var parentTag; - if (hostParent != null) { - namespaceURI = hostParent._namespaceURI; - parentTag = hostParent._tag; - } else if (hostContainerInfo._tag) { - namespaceURI = hostContainerInfo._namespaceURI; - parentTag = hostContainerInfo._tag; - } - if (namespaceURI == null || namespaceURI === DOMNamespaces.svg && parentTag === 'foreignobject') { - namespaceURI = DOMNamespaces.html; - } - if (namespaceURI === DOMNamespaces.html) { - if (this._tag === 'svg') { - namespaceURI = DOMNamespaces.svg; - } else if (this._tag === 'math') { - namespaceURI = DOMNamespaces.mathml; - } - } - this._namespaceURI = namespaceURI; - - if (process.env.NODE_ENV !== 'production') { - var parentInfo; - if (hostParent != null) { - parentInfo = hostParent._ancestorInfo; - } else if (hostContainerInfo._tag) { - parentInfo = hostContainerInfo._ancestorInfo; - } - if (parentInfo) { - // parentInfo should always be present except for the top-level - // component when server rendering - validateDOMNesting(this._tag, null, this, parentInfo); - } - this._ancestorInfo = validateDOMNesting.updatedAncestorInfo(parentInfo, this._tag, this); - } - - var mountImage; - if (transaction.useCreateElement) { - var ownerDocument = hostContainerInfo._ownerDocument; - var el; - if (namespaceURI === DOMNamespaces.html) { - if (this._tag === 'script') { - // Create the script via .innerHTML so its "parser-inserted" flag is - // set to true and it does not execute - var div = ownerDocument.createElement('div'); - var type = this._currentElement.type; - div.innerHTML = '<' + type + '></' + type + '>'; - el = div.removeChild(div.firstChild); - } else if (props.is) { - el = ownerDocument.createElement(this._currentElement.type, props.is); - } else { - // Separate else branch instead of using `props.is || undefined` above becuase of a Firefox bug. - // See discussion in https://github.com/facebook/react/pull/6896 - // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240 - el = ownerDocument.createElement(this._currentElement.type); - } - } else { - el = ownerDocument.createElementNS(namespaceURI, this._currentElement.type); - } - ReactDOMComponentTree.precacheNode(this, el); - this._flags |= Flags.hasCachedChildNodes; - if (!this._hostParent) { - DOMPropertyOperations.setAttributeForRoot(el); - } - this._updateDOMProperties(null, props, transaction); - var lazyTree = DOMLazyTree(el); - this._createInitialChildren(transaction, props, context, lazyTree); - mountImage = lazyTree; - } else { - var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction, props); - var tagContent = this._createContentMarkup(transaction, props, context); - if (!tagContent && omittedCloseTags[this._tag]) { - mountImage = tagOpen + '/>'; - } else { - mountImage = tagOpen + '>' + tagContent + '</' + this._currentElement.type + '>'; - } - } - - switch (this._tag) { - case 'input': - transaction.getReactMountReady().enqueue(inputPostMount, this); - if (props.autoFocus) { - transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); - } - break; - case 'textarea': - transaction.getReactMountReady().enqueue(textareaPostMount, this); - if (props.autoFocus) { - transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); - } - break; - case 'select': - if (props.autoFocus) { - transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); - } - break; - case 'button': - if (props.autoFocus) { - transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); - } - break; - case 'option': - transaction.getReactMountReady().enqueue(optionPostMount, this); - break; - } - - return mountImage; - }, - - /** - * Creates markup for the open tag and all attributes. - * - * This method has side effects because events get registered. - * - * Iterating over object properties is faster than iterating over arrays. - * @see http://jsperf.com/obj-vs-arr-iteration - * - * @private - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {object} props - * @return {string} Markup of opening tag. - */ - _createOpenTagMarkupAndPutListeners: function (transaction, props) { - var ret = '<' + this._currentElement.type; - - for (var propKey in props) { - if (!props.hasOwnProperty(propKey)) { - continue; - } - var propValue = props[propKey]; - if (propValue == null) { - continue; - } - if (registrationNameModules.hasOwnProperty(propKey)) { - if (propValue) { - enqueuePutListener(this, propKey, propValue, transaction); - } - } else { - if (propKey === STYLE) { - if (propValue) { - if (process.env.NODE_ENV !== 'production') { - // See `_updateDOMProperties`. style block - this._previousStyle = propValue; - } - propValue = this._previousStyleCopy = _assign({}, props.style); - } - propValue = CSSPropertyOperations.createMarkupForStyles(propValue, this); - } - var markup = null; - if (this._tag != null && isCustomComponent(this._tag, props)) { - if (!RESERVED_PROPS.hasOwnProperty(propKey)) { - markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue); - } - } else { - markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue); - } - if (markup) { - ret += ' ' + markup; - } - } - } - - // For static pages, no need to put React ID and checksum. Saves lots of - // bytes. - if (transaction.renderToStaticMarkup) { - return ret; - } - - if (!this._hostParent) { - ret += ' ' + DOMPropertyOperations.createMarkupForRoot(); - } - ret += ' ' + DOMPropertyOperations.createMarkupForID(this._domID); - return ret; - }, - - /** - * Creates markup for the content between the tags. - * - * @private - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {object} props - * @param {object} context - * @return {string} Content markup. - */ - _createContentMarkup: function (transaction, props, context) { - var ret = ''; - - // Intentional use of != to avoid catching zero/false. - var innerHTML = props.dangerouslySetInnerHTML; - if (innerHTML != null) { - if (innerHTML.__html != null) { - ret = innerHTML.__html; - } - } else { - var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null; - var childrenToUse = contentToUse != null ? null : props.children; - if (contentToUse != null) { - // TODO: Validate that text is allowed as a child of this node - ret = escapeTextContentForBrowser(contentToUse); - if (process.env.NODE_ENV !== 'production') { - setAndValidateContentChildDev.call(this, contentToUse); - } - } else if (childrenToUse != null) { - var mountImages = this.mountChildren(childrenToUse, transaction, context); - ret = mountImages.join(''); - } - } - if (newlineEatingTags[this._tag] && ret.charAt(0) === '\n') { - // text/html ignores the first character in these tags if it's a newline - // Prefer to break application/xml over text/html (for now) by adding - // a newline specifically to get eaten by the parser. (Alternately for - // textareas, replacing "^\n" with "\r\n" doesn't get eaten, and the first - // \r is normalized out by HTMLTextAreaElement#value.) - // See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre> - // See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions> - // See: <http://www.w3.org/TR/html5/syntax.html#newlines> - // See: Parsing of "textarea" "listing" and "pre" elements - // from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody> - return '\n' + ret; - } else { - return ret; - } - }, - - _createInitialChildren: function (transaction, props, context, lazyTree) { - // Intentional use of != to avoid catching zero/false. - var innerHTML = props.dangerouslySetInnerHTML; - if (innerHTML != null) { - if (innerHTML.__html != null) { - DOMLazyTree.queueHTML(lazyTree, innerHTML.__html); - } - } else { - var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null; - var childrenToUse = contentToUse != null ? null : props.children; - // TODO: Validate that text is allowed as a child of this node - if (contentToUse != null) { - // Avoid setting textContent when the text is empty. In IE11 setting - // textContent on a text area will cause the placeholder to not - // show within the textarea until it has been focused and blurred again. - // https://github.com/facebook/react/issues/6731#issuecomment-254874553 - if (contentToUse !== '') { - if (process.env.NODE_ENV !== 'production') { - setAndValidateContentChildDev.call(this, contentToUse); - } - DOMLazyTree.queueText(lazyTree, contentToUse); - } - } else if (childrenToUse != null) { - var mountImages = this.mountChildren(childrenToUse, transaction, context); - for (var i = 0; i < mountImages.length; i++) { - DOMLazyTree.queueChild(lazyTree, mountImages[i]); - } - } - } - }, - - /** - * Receives a next element and updates the component. - * - * @internal - * @param {ReactElement} nextElement - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {object} context - */ - receiveComponent: function (nextElement, transaction, context) { - var prevElement = this._currentElement; - this._currentElement = nextElement; - this.updateComponent(transaction, prevElement, nextElement, context); - }, - - /** - * Updates a DOM component after it has already been allocated and - * attached to the DOM. Reconciles the root DOM node, then recurses. - * - * @param {ReactReconcileTransaction} transaction - * @param {ReactElement} prevElement - * @param {ReactElement} nextElement - * @internal - * @overridable - */ - updateComponent: function (transaction, prevElement, nextElement, context) { - var lastProps = prevElement.props; - var nextProps = this._currentElement.props; - - switch (this._tag) { - case 'input': - lastProps = ReactDOMInput.getHostProps(this, lastProps); - nextProps = ReactDOMInput.getHostProps(this, nextProps); - break; - case 'option': - lastProps = ReactDOMOption.getHostProps(this, lastProps); - nextProps = ReactDOMOption.getHostProps(this, nextProps); - break; - case 'select': - lastProps = ReactDOMSelect.getHostProps(this, lastProps); - nextProps = ReactDOMSelect.getHostProps(this, nextProps); - break; - case 'textarea': - lastProps = ReactDOMTextarea.getHostProps(this, lastProps); - nextProps = ReactDOMTextarea.getHostProps(this, nextProps); - break; - } - - assertValidProps(this, nextProps); - this._updateDOMProperties(lastProps, nextProps, transaction); - this._updateDOMChildren(lastProps, nextProps, transaction, context); - - switch (this._tag) { - case 'input': - // Update the wrapper around inputs *after* updating props. This has to - // happen after `_updateDOMProperties`. Otherwise HTML5 input validations - // raise warnings and prevent the new value from being assigned. - ReactDOMInput.updateWrapper(this); - break; - case 'textarea': - ReactDOMTextarea.updateWrapper(this); - break; - case 'select': - // <select> value update needs to occur after <option> children - // reconciliation - transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this); - break; - } - }, - - /** - * Reconciles the properties by detecting differences in property values and - * updating the DOM as necessary. This function is probably the single most - * critical path for performance optimization. - * - * TODO: Benchmark whether checking for changed values in memory actually - * improves performance (especially statically positioned elements). - * TODO: Benchmark the effects of putting this at the top since 99% of props - * do not change for a given reconciliation. - * TODO: Benchmark areas that can be improved with caching. - * - * @private - * @param {object} lastProps - * @param {object} nextProps - * @param {?DOMElement} node - */ - _updateDOMProperties: function (lastProps, nextProps, transaction) { - var propKey; - var styleName; - var styleUpdates; - for (propKey in lastProps) { - if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) { - continue; - } - if (propKey === STYLE) { - var lastStyle = this._previousStyleCopy; - for (styleName in lastStyle) { - if (lastStyle.hasOwnProperty(styleName)) { - styleUpdates = styleUpdates || {}; - styleUpdates[styleName] = ''; - } - } - this._previousStyleCopy = null; - } else if (registrationNameModules.hasOwnProperty(propKey)) { - if (lastProps[propKey]) { - // Only call deleteListener if there was a listener previously or - // else willDeleteListener gets called when there wasn't actually a - // listener (e.g., onClick={null}) - deleteListener(this, propKey); - } - } else if (isCustomComponent(this._tag, lastProps)) { - if (!RESERVED_PROPS.hasOwnProperty(propKey)) { - DOMPropertyOperations.deleteValueForAttribute(getNode(this), propKey); - } - } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) { - DOMPropertyOperations.deleteValueForProperty(getNode(this), propKey); - } - } - for (propKey in nextProps) { - var nextProp = nextProps[propKey]; - var lastProp = propKey === STYLE ? this._previousStyleCopy : lastProps != null ? lastProps[propKey] : undefined; - if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) { - continue; - } - if (propKey === STYLE) { - if (nextProp) { - if (process.env.NODE_ENV !== 'production') { - checkAndWarnForMutatedStyle(this._previousStyleCopy, this._previousStyle, this); - this._previousStyle = nextProp; - } - nextProp = this._previousStyleCopy = _assign({}, nextProp); - } else { - this._previousStyleCopy = null; - } - if (lastProp) { - // Unset styles on `lastProp` but not on `nextProp`. - for (styleName in lastProp) { - if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) { - styleUpdates = styleUpdates || {}; - styleUpdates[styleName] = ''; - } - } - // Update styles that changed since `lastProp`. - for (styleName in nextProp) { - if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) { - styleUpdates = styleUpdates || {}; - styleUpdates[styleName] = nextProp[styleName]; - } - } - } else { - // Relies on `updateStylesByID` not mutating `styleUpdates`. - styleUpdates = nextProp; - } - } else if (registrationNameModules.hasOwnProperty(propKey)) { - if (nextProp) { - enqueuePutListener(this, propKey, nextProp, transaction); - } else if (lastProp) { - deleteListener(this, propKey); - } - } else if (isCustomComponent(this._tag, nextProps)) { - if (!RESERVED_PROPS.hasOwnProperty(propKey)) { - DOMPropertyOperations.setValueForAttribute(getNode(this), propKey, nextProp); - } - } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) { - var node = getNode(this); - // If we're updating to null or undefined, we should remove the property - // from the DOM node instead of inadvertently setting to a string. This - // brings us in line with the same behavior we have on initial render. - if (nextProp != null) { - DOMPropertyOperations.setValueForProperty(node, propKey, nextProp); - } else { - DOMPropertyOperations.deleteValueForProperty(node, propKey); - } - } - } - if (styleUpdates) { - CSSPropertyOperations.setValueForStyles(getNode(this), styleUpdates, this); - } - }, - - /** - * Reconciles the children with the various properties that affect the - * children content. - * - * @param {object} lastProps - * @param {object} nextProps - * @param {ReactReconcileTransaction} transaction - * @param {object} context - */ - _updateDOMChildren: function (lastProps, nextProps, transaction, context) { - var lastContent = CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null; - var nextContent = CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null; - - var lastHtml = lastProps.dangerouslySetInnerHTML && lastProps.dangerouslySetInnerHTML.__html; - var nextHtml = nextProps.dangerouslySetInnerHTML && nextProps.dangerouslySetInnerHTML.__html; - - // Note the use of `!=` which checks for null or undefined. - var lastChildren = lastContent != null ? null : lastProps.children; - var nextChildren = nextContent != null ? null : nextProps.children; - - // If we're switching from children to content/html or vice versa, remove - // the old content - var lastHasContentOrHtml = lastContent != null || lastHtml != null; - var nextHasContentOrHtml = nextContent != null || nextHtml != null; - if (lastChildren != null && nextChildren == null) { - this.updateChildren(null, transaction, context); - } else if (lastHasContentOrHtml && !nextHasContentOrHtml) { - this.updateTextContent(''); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onSetChildren(this._debugID, []); - } - } - - if (nextContent != null) { - if (lastContent !== nextContent) { - this.updateTextContent('' + nextContent); - if (process.env.NODE_ENV !== 'production') { - setAndValidateContentChildDev.call(this, nextContent); - } - } - } else if (nextHtml != null) { - if (lastHtml !== nextHtml) { - this.updateMarkup('' + nextHtml); - } - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onSetChildren(this._debugID, []); - } - } else if (nextChildren != null) { - if (process.env.NODE_ENV !== 'production') { - setAndValidateContentChildDev.call(this, null); - } - - this.updateChildren(nextChildren, transaction, context); - } - }, - - getHostNode: function () { - return getNode(this); - }, - - /** - * Destroys all event registrations for this instance. Does not remove from - * the DOM. That must be done by the parent. - * - * @internal - */ - unmountComponent: function (safely) { - switch (this._tag) { - case 'audio': - case 'form': - case 'iframe': - case 'img': - case 'link': - case 'object': - case 'source': - case 'video': - var listeners = this._wrapperState.listeners; - if (listeners) { - for (var i = 0; i < listeners.length; i++) { - listeners[i].remove(); - } - } - break; - case 'html': - case 'head': - case 'body': - /** - * Components like <html> <head> and <body> can't be removed or added - * easily in a cross-browser way, however it's valuable to be able to - * take advantage of React's reconciliation for styling and <title> - * management. So we just document it and throw in dangerous cases. - */ - true ? process.env.NODE_ENV !== 'production' ? invariant(false, '<%s> tried to unmount. Because of cross-browser quirks it is impossible to unmount some top-level components (eg <html>, <head>, and <body>) reliably and efficiently. To fix this, have a single top-level component that never unmounts render these elements.', this._tag) : _prodInvariant('66', this._tag) : void 0; - break; - } - - this.unmountChildren(safely); - ReactDOMComponentTree.uncacheNode(this); - EventPluginHub.deleteAllListeners(this); - this._rootNodeID = 0; - this._domID = 0; - this._wrapperState = null; - - if (process.env.NODE_ENV !== 'production') { - setAndValidateContentChildDev.call(this, null); - } - }, - - getPublicInstance: function () { - return getNode(this); - } - -}; - -_assign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild.Mixin); - -module.exports = ReactDOMComponent; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 253 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var validateDOMNesting = __webpack_require__(60); - -var DOC_NODE_TYPE = 9; - -function ReactDOMContainerInfo(topLevelWrapper, node) { - var info = { - _topLevelWrapper: topLevelWrapper, - _idCounter: 1, - _ownerDocument: node ? node.nodeType === DOC_NODE_TYPE ? node : node.ownerDocument : null, - _node: node, - _tag: node ? node.nodeName.toLowerCase() : null, - _namespaceURI: node ? node.namespaceURI : null - }; - if (process.env.NODE_ENV !== 'production') { - info._ancestorInfo = node ? validateDOMNesting.updatedAncestorInfo(null, info._tag, null) : null; - } - return info; -} - -module.exports = ReactDOMContainerInfo; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 254 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var DOMLazyTree = __webpack_require__(25); -var ReactDOMComponentTree = __webpack_require__(7); - -var ReactDOMEmptyComponent = function (instantiate) { - // ReactCompositeComponent uses this: - this._currentElement = null; - // ReactDOMComponentTree uses these: - this._hostNode = null; - this._hostParent = null; - this._hostContainerInfo = null; - this._domID = 0; -}; -_assign(ReactDOMEmptyComponent.prototype, { - mountComponent: function (transaction, hostParent, hostContainerInfo, context) { - var domID = hostContainerInfo._idCounter++; - this._domID = domID; - this._hostParent = hostParent; - this._hostContainerInfo = hostContainerInfo; - - var nodeValue = ' react-empty: ' + this._domID + ' '; - if (transaction.useCreateElement) { - var ownerDocument = hostContainerInfo._ownerDocument; - var node = ownerDocument.createComment(nodeValue); - ReactDOMComponentTree.precacheNode(this, node); - return DOMLazyTree(node); - } else { - if (transaction.renderToStaticMarkup) { - // Normally we'd insert a comment node, but since this is a situation - // where React won't take over (static pages), we can simply return - // nothing. - return ''; - } - return '<!--' + nodeValue + '-->'; - } - }, - receiveComponent: function () {}, - getHostNode: function () { - return ReactDOMComponentTree.getNodeFromInstance(this); - }, - unmountComponent: function () { - ReactDOMComponentTree.uncacheNode(this); - } -}); - -module.exports = ReactDOMEmptyComponent; - -/***/ }), -/* 255 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactDOMFeatureFlags = { - useCreateElement: true, - useFiber: false -}; - -module.exports = ReactDOMFeatureFlags; - -/***/ }), -/* 256 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMChildrenOperations = __webpack_require__(46); -var ReactDOMComponentTree = __webpack_require__(7); - -/** - * Operations used to process updates to DOM nodes. - */ -var ReactDOMIDOperations = { - - /** - * Updates a component's children by processing a series of updates. - * - * @param {array<object>} updates List of update configurations. - * @internal - */ - dangerouslyProcessChildrenUpdates: function (parentInst, updates) { - var node = ReactDOMComponentTree.getNodeFromInstance(parentInst); - DOMChildrenOperations.processUpdates(node, updates); - } -}; - -module.exports = ReactDOMIDOperations; - -/***/ }), -/* 257 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var DOMPropertyOperations = __webpack_require__(80); -var LinkedValueUtils = __webpack_require__(50); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactUpdates = __webpack_require__(14); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -var didWarnValueLink = false; -var didWarnCheckedLink = false; -var didWarnValueDefaultValue = false; -var didWarnCheckedDefaultChecked = false; -var didWarnControlledToUncontrolled = false; -var didWarnUncontrolledToControlled = false; - -function forceUpdateIfMounted() { - if (this._rootNodeID) { - // DOM component is still mounted; update - ReactDOMInput.updateWrapper(this); - } -} - -function isControlled(props) { - var usesChecked = props.type === 'checkbox' || props.type === 'radio'; - return usesChecked ? props.checked != null : props.value != null; -} - -/** - * Implements an <input> host component that allows setting these optional - * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. - * - * If `checked` or `value` are not supplied (or null/undefined), user actions - * that affect the checked state or value will trigger updates to the element. - * - * If they are supplied (and not null/undefined), the rendered element will not - * trigger updates to the element. Instead, the props must change in order for - * the rendered element to be updated. - * - * The rendered element will be initialized as unchecked (or `defaultChecked`) - * with an empty value (or `defaultValue`). - * - * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html - */ -var ReactDOMInput = { - getHostProps: function (inst, props) { - var value = LinkedValueUtils.getValue(props); - var checked = LinkedValueUtils.getChecked(props); - - var hostProps = _assign({ - // Make sure we set .type before any other properties (setting .value - // before .type means .value is lost in IE11 and below) - type: undefined, - // Make sure we set .step before .value (setting .value before .step - // means .value is rounded on mount, based upon step precision) - step: undefined, - // Make sure we set .min & .max before .value (to ensure proper order - // in corner cases such as min or max deriving from value, e.g. Issue #7170) - min: undefined, - max: undefined - }, props, { - defaultChecked: undefined, - defaultValue: undefined, - value: value != null ? value : inst._wrapperState.initialValue, - checked: checked != null ? checked : inst._wrapperState.initialChecked, - onChange: inst._wrapperState.onChange - }); - - return hostProps; - }, - - mountWrapper: function (inst, props) { - if (process.env.NODE_ENV !== 'production') { - LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner); - - var owner = inst._currentElement._owner; - - if (props.valueLink !== undefined && !didWarnValueLink) { - process.env.NODE_ENV !== 'production' ? warning(false, '`valueLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0; - didWarnValueLink = true; - } - if (props.checkedLink !== undefined && !didWarnCheckedLink) { - process.env.NODE_ENV !== 'production' ? warning(false, '`checkedLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0; - didWarnCheckedLink = true; - } - if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { - process.env.NODE_ENV !== 'production' ? warning(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; - didWarnCheckedDefaultChecked = true; - } - if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { - process.env.NODE_ENV !== 'production' ? warning(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; - didWarnValueDefaultValue = true; - } - } - - var defaultValue = props.defaultValue; - inst._wrapperState = { - initialChecked: props.checked != null ? props.checked : props.defaultChecked, - initialValue: props.value != null ? props.value : defaultValue, - listeners: null, - onChange: _handleChange.bind(inst) - }; - - if (process.env.NODE_ENV !== 'production') { - inst._wrapperState.controlled = isControlled(props); - } - }, - - updateWrapper: function (inst) { - var props = inst._currentElement.props; - - if (process.env.NODE_ENV !== 'production') { - var controlled = isControlled(props); - var owner = inst._currentElement._owner; - - if (!inst._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) { - process.env.NODE_ENV !== 'production' ? warning(false, '%s is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; - didWarnUncontrolledToControlled = true; - } - if (inst._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) { - process.env.NODE_ENV !== 'production' ? warning(false, '%s is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; - didWarnControlledToUncontrolled = true; - } - } - - // TODO: Shouldn't this be getChecked(props)? - var checked = props.checked; - if (checked != null) { - DOMPropertyOperations.setValueForProperty(ReactDOMComponentTree.getNodeFromInstance(inst), 'checked', checked || false); - } - - var node = ReactDOMComponentTree.getNodeFromInstance(inst); - var value = LinkedValueUtils.getValue(props); - if (value != null) { - - // Cast `value` to a string to ensure the value is set correctly. While - // browsers typically do this as necessary, jsdom doesn't. - var newValue = '' + value; - - // To avoid side effects (such as losing text selection), only set value if changed - if (newValue !== node.value) { - node.value = newValue; - } - } else { - if (props.value == null && props.defaultValue != null) { - // In Chrome, assigning defaultValue to certain input types triggers input validation. - // For number inputs, the display value loses trailing decimal points. For email inputs, - // Chrome raises "The specified value <x> is not a valid email address". - // - // Here we check to see if the defaultValue has actually changed, avoiding these problems - // when the user is inputting text - // - // https://github.com/facebook/react/issues/7253 - if (node.defaultValue !== '' + props.defaultValue) { - node.defaultValue = '' + props.defaultValue; - } - } - if (props.checked == null && props.defaultChecked != null) { - node.defaultChecked = !!props.defaultChecked; - } - } - }, - - postMountWrapper: function (inst) { - var props = inst._currentElement.props; - - // This is in postMount because we need access to the DOM node, which is not - // available until after the component has mounted. - var node = ReactDOMComponentTree.getNodeFromInstance(inst); - - // Detach value from defaultValue. We won't do anything if we're working on - // submit or reset inputs as those values & defaultValues are linked. They - // are not resetable nodes so this operation doesn't matter and actually - // removes browser-default values (eg "Submit Query") when no value is - // provided. - - switch (props.type) { - case 'submit': - case 'reset': - break; - case 'color': - case 'date': - case 'datetime': - case 'datetime-local': - case 'month': - case 'time': - case 'week': - // This fixes the no-show issue on iOS Safari and Android Chrome: - // https://github.com/facebook/react/issues/7233 - node.value = ''; - node.value = node.defaultValue; - break; - default: - node.value = node.value; - break; - } - - // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug - // this is needed to work around a chrome bug where setting defaultChecked - // will sometimes influence the value of checked (even after detachment). - // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416 - // We need to temporarily unset name to avoid disrupting radio button groups. - var name = node.name; - if (name !== '') { - node.name = ''; - } - node.defaultChecked = !node.defaultChecked; - node.defaultChecked = !node.defaultChecked; - if (name !== '') { - node.name = name; - } - } -}; - -function _handleChange(event) { - var props = this._currentElement.props; - - var returnValue = LinkedValueUtils.executeOnChange(props, event); - - // Here we use asap to wait until all updates have propagated, which - // is important when using controlled components within layers: - // https://github.com/facebook/react/issues/1698 - ReactUpdates.asap(forceUpdateIfMounted, this); - - var name = props.name; - if (props.type === 'radio' && name != null) { - var rootNode = ReactDOMComponentTree.getNodeFromInstance(this); - var queryRoot = rootNode; - - while (queryRoot.parentNode) { - queryRoot = queryRoot.parentNode; - } - - // If `rootNode.form` was non-null, then we could try `form.elements`, - // but that sometimes behaves strangely in IE8. We could also try using - // `form.getElementsByName`, but that will only return direct children - // and won't include inputs that use the HTML5 `form=` attribute. Since - // the input might not even be in a form, let's just use the global - // `querySelectorAll` to ensure we don't miss anything. - var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]'); - - for (var i = 0; i < group.length; i++) { - var otherNode = group[i]; - if (otherNode === rootNode || otherNode.form !== rootNode.form) { - continue; - } - // This will throw if radio buttons rendered by different copies of React - // and the same name are rendered into the same form (same as #1939). - // That's probably okay; we don't support it just as we don't support - // mixing React radio buttons with non-React ones. - var otherInstance = ReactDOMComponentTree.getInstanceFromNode(otherNode); - !otherInstance ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : _prodInvariant('90') : void 0; - // If this is a controlled radio button group, forcing the input that - // was previously checked to update will cause it to be come re-checked - // as appropriate. - ReactUpdates.asap(forceUpdateIfMounted, otherInstance); - } - } - - return returnValue; -} - -module.exports = ReactDOMInput; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 258 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMProperty = __webpack_require__(18); -var ReactComponentTreeHook = __webpack_require__(9); - -var warning = __webpack_require__(3); - -var warnedProperties = {}; -var rARIA = new RegExp('^(aria)-[' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$'); - -function validateProperty(tagName, name, debugID) { - if (warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { - return true; - } - - if (rARIA.test(name)) { - var lowerCasedName = name.toLowerCase(); - var standardName = DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null; - - // If this is an aria-* attribute, but is not listed in the known DOM - // DOM properties, then it is an invalid aria-* attribute. - if (standardName == null) { - warnedProperties[name] = true; - return false; - } - // aria-* attributes should be lowercase; suggest the lowercase version. - if (name !== standardName) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Unknown ARIA attribute %s. Did you mean %s?%s', name, standardName, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - warnedProperties[name] = true; - return true; - } - } - - return true; -} - -function warnInvalidARIAProps(debugID, element) { - var invalidProps = []; - - for (var key in element.props) { - var isValid = validateProperty(element.type, key, debugID); - if (!isValid) { - invalidProps.push(key); - } - } - - var unknownPropString = invalidProps.map(function (prop) { - return '`' + prop + '`'; - }).join(', '); - - if (invalidProps.length === 1) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - } else if (invalidProps.length > 1) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - } -} - -function handleElement(debugID, element) { - if (element == null || typeof element.type !== 'string') { - return; - } - if (element.type.indexOf('-') >= 0 || element.props.is) { - return; - } - - warnInvalidARIAProps(debugID, element); -} - -var ReactDOMInvalidARIAHook = { - onBeforeMountComponent: function (debugID, element) { - if (process.env.NODE_ENV !== 'production') { - handleElement(debugID, element); - } - }, - onBeforeUpdateComponent: function (debugID, element) { - if (process.env.NODE_ENV !== 'production') { - handleElement(debugID, element); - } - } -}; - -module.exports = ReactDOMInvalidARIAHook; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 259 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactComponentTreeHook = __webpack_require__(9); - -var warning = __webpack_require__(3); - -var didWarnValueNull = false; - -function handleElement(debugID, element) { - if (element == null) { - return; - } - if (element.type !== 'input' && element.type !== 'textarea' && element.type !== 'select') { - return; - } - if (element.props != null && element.props.value === null && !didWarnValueNull) { - process.env.NODE_ENV !== 'production' ? warning(false, '`value` prop on `%s` should not be null. ' + 'Consider using the empty string to clear the component or `undefined` ' + 'for uncontrolled components.%s', element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - - didWarnValueNull = true; - } -} - -var ReactDOMNullInputValuePropHook = { - onBeforeMountComponent: function (debugID, element) { - handleElement(debugID, element); - }, - onBeforeUpdateComponent: function (debugID, element) { - handleElement(debugID, element); - } -}; - -module.exports = ReactDOMNullInputValuePropHook; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 260 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var React = __webpack_require__(27); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactDOMSelect = __webpack_require__(82); - -var warning = __webpack_require__(3); -var didWarnInvalidOptionChildren = false; - -function flattenChildren(children) { - var content = ''; - - // Flatten children and warn if they aren't strings or numbers; - // invalid types are ignored. - React.Children.forEach(children, function (child) { - if (child == null) { - return; - } - if (typeof child === 'string' || typeof child === 'number') { - content += child; - } else if (!didWarnInvalidOptionChildren) { - didWarnInvalidOptionChildren = true; - process.env.NODE_ENV !== 'production' ? warning(false, 'Only strings and numbers are supported as <option> children.') : void 0; - } - }); - - return content; -} - -/** - * Implements an <option> host component that warns when `selected` is set. - */ -var ReactDOMOption = { - mountWrapper: function (inst, props, hostParent) { - // TODO (yungsters): Remove support for `selected` in <option>. - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.') : void 0; - } - - // Look up whether this option is 'selected' - var selectValue = null; - if (hostParent != null) { - var selectParent = hostParent; - - if (selectParent._tag === 'optgroup') { - selectParent = selectParent._hostParent; - } - - if (selectParent != null && selectParent._tag === 'select') { - selectValue = ReactDOMSelect.getSelectValueContext(selectParent); - } - } - - // If the value is null (e.g., no specified value or after initial mount) - // or missing (e.g., for <datalist>), we don't change props.selected - var selected = null; - if (selectValue != null) { - var value; - if (props.value != null) { - value = props.value + ''; - } else { - value = flattenChildren(props.children); - } - selected = false; - if (Array.isArray(selectValue)) { - // multiple - for (var i = 0; i < selectValue.length; i++) { - if ('' + selectValue[i] === value) { - selected = true; - break; - } - } - } else { - selected = '' + selectValue === value; - } - } - - inst._wrapperState = { selected: selected }; - }, - - postMountWrapper: function (inst) { - // value="" should make a value attribute (#6219) - var props = inst._currentElement.props; - if (props.value != null) { - var node = ReactDOMComponentTree.getNodeFromInstance(inst); - node.setAttribute('value', props.value); - } - }, - - getHostProps: function (inst, props) { - var hostProps = _assign({ selected: undefined, children: undefined }, props); - - // Read state only from initial mount because <select> updates value - // manually; we need the initial state only for server rendering - if (inst._wrapperState.selected != null) { - hostProps.selected = inst._wrapperState.selected; - } - - var content = flattenChildren(props.children); - - if (content) { - hostProps.children = content; - } - - return hostProps; - } - -}; - -module.exports = ReactDOMOption; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 261 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ExecutionEnvironment = __webpack_require__(8); - -var getNodeForCharacterOffset = __webpack_require__(305); -var getTextContentAccessor = __webpack_require__(94); - -/** - * While `isCollapsed` is available on the Selection object and `collapsed` - * is available on the Range object, IE11 sometimes gets them wrong. - * If the anchor/focus nodes and offsets are the same, the range is collapsed. - */ -function isCollapsed(anchorNode, anchorOffset, focusNode, focusOffset) { - return anchorNode === focusNode && anchorOffset === focusOffset; -} - -/** - * Get the appropriate anchor and focus node/offset pairs for IE. - * - * The catch here is that IE's selection API doesn't provide information - * about whether the selection is forward or backward, so we have to - * behave as though it's always forward. - * - * IE text differs from modern selection in that it behaves as though - * block elements end with a new line. This means character offsets will - * differ between the two APIs. - * - * @param {DOMElement} node - * @return {object} - */ -function getIEOffsets(node) { - var selection = document.selection; - var selectedRange = selection.createRange(); - var selectedLength = selectedRange.text.length; - - // Duplicate selection so we can move range without breaking user selection. - var fromStart = selectedRange.duplicate(); - fromStart.moveToElementText(node); - fromStart.setEndPoint('EndToStart', selectedRange); - - var startOffset = fromStart.text.length; - var endOffset = startOffset + selectedLength; - - return { - start: startOffset, - end: endOffset - }; -} - -/** - * @param {DOMElement} node - * @return {?object} - */ -function getModernOffsets(node) { - var selection = window.getSelection && window.getSelection(); - - if (!selection || selection.rangeCount === 0) { - return null; - } - - var anchorNode = selection.anchorNode; - var anchorOffset = selection.anchorOffset; - var focusNode = selection.focusNode; - var focusOffset = selection.focusOffset; - - var currentRange = selection.getRangeAt(0); - - // In Firefox, range.startContainer and range.endContainer can be "anonymous - // divs", e.g. the up/down buttons on an <input type="number">. Anonymous - // divs do not seem to expose properties, triggering a "Permission denied - // error" if any of its properties are accessed. The only seemingly possible - // way to avoid erroring is to access a property that typically works for - // non-anonymous divs and catch any error that may otherwise arise. See - // https://bugzilla.mozilla.org/show_bug.cgi?id=208427 - try { - /* eslint-disable no-unused-expressions */ - currentRange.startContainer.nodeType; - currentRange.endContainer.nodeType; - /* eslint-enable no-unused-expressions */ - } catch (e) { - return null; - } - - // If the node and offset values are the same, the selection is collapsed. - // `Selection.isCollapsed` is available natively, but IE sometimes gets - // this value wrong. - var isSelectionCollapsed = isCollapsed(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset); - - var rangeLength = isSelectionCollapsed ? 0 : currentRange.toString().length; - - var tempRange = currentRange.cloneRange(); - tempRange.selectNodeContents(node); - tempRange.setEnd(currentRange.startContainer, currentRange.startOffset); - - var isTempRangeCollapsed = isCollapsed(tempRange.startContainer, tempRange.startOffset, tempRange.endContainer, tempRange.endOffset); - - var start = isTempRangeCollapsed ? 0 : tempRange.toString().length; - var end = start + rangeLength; - - // Detect whether the selection is backward. - var detectionRange = document.createRange(); - detectionRange.setStart(anchorNode, anchorOffset); - detectionRange.setEnd(focusNode, focusOffset); - var isBackward = detectionRange.collapsed; - - return { - start: isBackward ? end : start, - end: isBackward ? start : end - }; -} - -/** - * @param {DOMElement|DOMTextNode} node - * @param {object} offsets - */ -function setIEOffsets(node, offsets) { - var range = document.selection.createRange().duplicate(); - var start, end; - - if (offsets.end === undefined) { - start = offsets.start; - end = start; - } else if (offsets.start > offsets.end) { - start = offsets.end; - end = offsets.start; - } else { - start = offsets.start; - end = offsets.end; - } - - range.moveToElementText(node); - range.moveStart('character', start); - range.setEndPoint('EndToStart', range); - range.moveEnd('character', end - start); - range.select(); -} - -/** - * In modern non-IE browsers, we can support both forward and backward - * selections. - * - * Note: IE10+ supports the Selection object, but it does not support - * the `extend` method, which means that even in modern IE, it's not possible - * to programmatically create a backward selection. Thus, for all IE - * versions, we use the old IE API to create our selections. - * - * @param {DOMElement|DOMTextNode} node - * @param {object} offsets - */ -function setModernOffsets(node, offsets) { - if (!window.getSelection) { - return; - } - - var selection = window.getSelection(); - var length = node[getTextContentAccessor()].length; - var start = Math.min(offsets.start, length); - var end = offsets.end === undefined ? start : Math.min(offsets.end, length); - - // IE 11 uses modern selection, but doesn't support the extend method. - // Flip backward selections, so we can set with a single range. - if (!selection.extend && start > end) { - var temp = end; - end = start; - start = temp; - } - - var startMarker = getNodeForCharacterOffset(node, start); - var endMarker = getNodeForCharacterOffset(node, end); - - if (startMarker && endMarker) { - var range = document.createRange(); - range.setStart(startMarker.node, startMarker.offset); - selection.removeAllRanges(); - - if (start > end) { - selection.addRange(range); - selection.extend(endMarker.node, endMarker.offset); - } else { - range.setEnd(endMarker.node, endMarker.offset); - selection.addRange(range); - } - } -} - -var useIEOffsets = ExecutionEnvironment.canUseDOM && 'selection' in document && !('getSelection' in window); - -var ReactDOMSelection = { - /** - * @param {DOMElement} node - */ - getOffsets: useIEOffsets ? getIEOffsets : getModernOffsets, - - /** - * @param {DOMElement|DOMTextNode} node - * @param {object} offsets - */ - setOffsets: useIEOffsets ? setIEOffsets : setModernOffsets -}; - -module.exports = ReactDOMSelection; - -/***/ }), -/* 262 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var DOMChildrenOperations = __webpack_require__(46); -var DOMLazyTree = __webpack_require__(25); -var ReactDOMComponentTree = __webpack_require__(7); - -var escapeTextContentForBrowser = __webpack_require__(39); -var invariant = __webpack_require__(2); -var validateDOMNesting = __webpack_require__(60); - -/** - * Text nodes violate a couple assumptions that React makes about components: - * - * - When mounting text into the DOM, adjacent text nodes are merged. - * - Text nodes cannot be assigned a React root ID. - * - * This component is used to wrap strings between comment nodes so that they - * can undergo the same reconciliation that is applied to elements. - * - * TODO: Investigate representing React components in the DOM with text nodes. - * - * @class ReactDOMTextComponent - * @extends ReactComponent - * @internal - */ -var ReactDOMTextComponent = function (text) { - // TODO: This is really a ReactText (ReactNode), not a ReactElement - this._currentElement = text; - this._stringText = '' + text; - // ReactDOMComponentTree uses these: - this._hostNode = null; - this._hostParent = null; - - // Properties - this._domID = 0; - this._mountIndex = 0; - this._closingComment = null; - this._commentNodes = null; -}; - -_assign(ReactDOMTextComponent.prototype, { - - /** - * Creates the markup for this text node. This node is not intended to have - * any features besides containing text content. - * - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {string} Markup for this text node. - * @internal - */ - mountComponent: function (transaction, hostParent, hostContainerInfo, context) { - if (process.env.NODE_ENV !== 'production') { - var parentInfo; - if (hostParent != null) { - parentInfo = hostParent._ancestorInfo; - } else if (hostContainerInfo != null) { - parentInfo = hostContainerInfo._ancestorInfo; - } - if (parentInfo) { - // parentInfo should always be present except for the top-level - // component when server rendering - validateDOMNesting(null, this._stringText, this, parentInfo); - } - } - - var domID = hostContainerInfo._idCounter++; - var openingValue = ' react-text: ' + domID + ' '; - var closingValue = ' /react-text '; - this._domID = domID; - this._hostParent = hostParent; - if (transaction.useCreateElement) { - var ownerDocument = hostContainerInfo._ownerDocument; - var openingComment = ownerDocument.createComment(openingValue); - var closingComment = ownerDocument.createComment(closingValue); - var lazyTree = DOMLazyTree(ownerDocument.createDocumentFragment()); - DOMLazyTree.queueChild(lazyTree, DOMLazyTree(openingComment)); - if (this._stringText) { - DOMLazyTree.queueChild(lazyTree, DOMLazyTree(ownerDocument.createTextNode(this._stringText))); - } - DOMLazyTree.queueChild(lazyTree, DOMLazyTree(closingComment)); - ReactDOMComponentTree.precacheNode(this, openingComment); - this._closingComment = closingComment; - return lazyTree; - } else { - var escapedText = escapeTextContentForBrowser(this._stringText); - - if (transaction.renderToStaticMarkup) { - // Normally we'd wrap this between comment nodes for the reasons stated - // above, but since this is a situation where React won't take over - // (static pages), we can simply return the text as it is. - return escapedText; - } - - return '<!--' + openingValue + '-->' + escapedText + '<!--' + closingValue + '-->'; - } - }, - - /** - * Updates this component by updating the text content. - * - * @param {ReactText} nextText The next text content - * @param {ReactReconcileTransaction} transaction - * @internal - */ - receiveComponent: function (nextText, transaction) { - if (nextText !== this._currentElement) { - this._currentElement = nextText; - var nextStringText = '' + nextText; - if (nextStringText !== this._stringText) { - // TODO: Save this as pending props and use performUpdateIfNecessary - // and/or updateComponent to do the actual update for consistency with - // other component types? - this._stringText = nextStringText; - var commentNodes = this.getHostNode(); - DOMChildrenOperations.replaceDelimitedText(commentNodes[0], commentNodes[1], nextStringText); - } - } - }, - - getHostNode: function () { - var hostNode = this._commentNodes; - if (hostNode) { - return hostNode; - } - if (!this._closingComment) { - var openingComment = ReactDOMComponentTree.getNodeFromInstance(this); - var node = openingComment.nextSibling; - while (true) { - !(node != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Missing closing comment for text component %s', this._domID) : _prodInvariant('67', this._domID) : void 0; - if (node.nodeType === 8 && node.nodeValue === ' /react-text ') { - this._closingComment = node; - break; - } - node = node.nextSibling; - } - } - hostNode = [this._hostNode, this._closingComment]; - this._commentNodes = hostNode; - return hostNode; - }, - - unmountComponent: function () { - this._closingComment = null; - this._commentNodes = null; - ReactDOMComponentTree.uncacheNode(this); - } - -}); - -module.exports = ReactDOMTextComponent; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 263 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var LinkedValueUtils = __webpack_require__(50); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactUpdates = __webpack_require__(14); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -var didWarnValueLink = false; -var didWarnValDefaultVal = false; - -function forceUpdateIfMounted() { - if (this._rootNodeID) { - // DOM component is still mounted; update - ReactDOMTextarea.updateWrapper(this); - } -} - -/** - * Implements a <textarea> host component that allows setting `value`, and - * `defaultValue`. This differs from the traditional DOM API because value is - * usually set as PCDATA children. - * - * If `value` is not supplied (or null/undefined), user actions that affect the - * value will trigger updates to the element. - * - * If `value` is supplied (and not null/undefined), the rendered element will - * not trigger updates to the element. Instead, the `value` prop must change in - * order for the rendered element to be updated. - * - * The rendered element will be initialized with an empty value, the prop - * `defaultValue` if specified, or the children content (deprecated). - */ -var ReactDOMTextarea = { - getHostProps: function (inst, props) { - !(props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : _prodInvariant('91') : void 0; - - // Always set children to the same thing. In IE9, the selection range will - // get reset if `textContent` is mutated. We could add a check in setTextContent - // to only set the value if/when the value differs from the node value (which would - // completely solve this IE9 bug), but Sebastian+Ben seemed to like this solution. - // The value can be a boolean or object so that's why it's forced to be a string. - var hostProps = _assign({}, props, { - value: undefined, - defaultValue: undefined, - children: '' + inst._wrapperState.initialValue, - onChange: inst._wrapperState.onChange - }); - - return hostProps; - }, - - mountWrapper: function (inst, props) { - if (process.env.NODE_ENV !== 'production') { - LinkedValueUtils.checkPropTypes('textarea', props, inst._currentElement._owner); - if (props.valueLink !== undefined && !didWarnValueLink) { - process.env.NODE_ENV !== 'production' ? warning(false, '`valueLink` prop on `textarea` is deprecated; set `value` and `onChange` instead.') : void 0; - didWarnValueLink = true; - } - if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0; - didWarnValDefaultVal = true; - } - } - - var value = LinkedValueUtils.getValue(props); - var initialValue = value; - - // Only bother fetching default value if we're going to use it - if (value == null) { - var defaultValue = props.defaultValue; - // TODO (yungsters): Remove support for children content in <textarea>. - var children = props.children; - if (children != null) { - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.') : void 0; - } - !(defaultValue == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : _prodInvariant('92') : void 0; - if (Array.isArray(children)) { - !(children.length <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, '<textarea> can only have at most one child.') : _prodInvariant('93') : void 0; - children = children[0]; - } - - defaultValue = '' + children; - } - if (defaultValue == null) { - defaultValue = ''; - } - initialValue = defaultValue; - } - - inst._wrapperState = { - initialValue: '' + initialValue, - listeners: null, - onChange: _handleChange.bind(inst) - }; - }, - - updateWrapper: function (inst) { - var props = inst._currentElement.props; - - var node = ReactDOMComponentTree.getNodeFromInstance(inst); - var value = LinkedValueUtils.getValue(props); - if (value != null) { - // Cast `value` to a string to ensure the value is set correctly. While - // browsers typically do this as necessary, jsdom doesn't. - var newValue = '' + value; - - // To avoid side effects (such as losing text selection), only set value if changed - if (newValue !== node.value) { - node.value = newValue; - } - if (props.defaultValue == null) { - node.defaultValue = newValue; - } - } - if (props.defaultValue != null) { - node.defaultValue = props.defaultValue; - } - }, - - postMountWrapper: function (inst) { - // This is in postMount because we need access to the DOM node, which is not - // available until after the component has mounted. - var node = ReactDOMComponentTree.getNodeFromInstance(inst); - var textContent = node.textContent; - - // Only set node.value if textContent is equal to the expected - // initial value. In IE10/IE11 there is a bug where the placeholder attribute - // will populate textContent as well. - // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/ - if (textContent === inst._wrapperState.initialValue) { - node.value = textContent; - } - } -}; - -function _handleChange(event) { - var props = this._currentElement.props; - var returnValue = LinkedValueUtils.executeOnChange(props, event); - ReactUpdates.asap(forceUpdateIfMounted, this); - return returnValue; -} - -module.exports = ReactDOMTextarea; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 264 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -/** - * Return the lowest common ancestor of A and B, or null if they are in - * different trees. - */ -function getLowestCommonAncestor(instA, instB) { - !('_hostNode' in instA) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0; - !('_hostNode' in instB) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0; - - var depthA = 0; - for (var tempA = instA; tempA; tempA = tempA._hostParent) { - depthA++; - } - var depthB = 0; - for (var tempB = instB; tempB; tempB = tempB._hostParent) { - depthB++; - } - - // If A is deeper, crawl up. - while (depthA - depthB > 0) { - instA = instA._hostParent; - depthA--; - } - - // If B is deeper, crawl up. - while (depthB - depthA > 0) { - instB = instB._hostParent; - depthB--; - } - - // Walk in lockstep until we find a match. - var depth = depthA; - while (depth--) { - if (instA === instB) { - return instA; - } - instA = instA._hostParent; - instB = instB._hostParent; - } - return null; -} - -/** - * Return if A is an ancestor of B. - */ -function isAncestor(instA, instB) { - !('_hostNode' in instA) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'isAncestor: Invalid argument.') : _prodInvariant('35') : void 0; - !('_hostNode' in instB) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'isAncestor: Invalid argument.') : _prodInvariant('35') : void 0; - - while (instB) { - if (instB === instA) { - return true; - } - instB = instB._hostParent; - } - return false; -} - -/** - * Return the parent instance of the passed-in instance. - */ -function getParentInstance(inst) { - !('_hostNode' in inst) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getParentInstance: Invalid argument.') : _prodInvariant('36') : void 0; - - return inst._hostParent; -} - -/** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. - */ -function traverseTwoPhase(inst, fn, arg) { - var path = []; - while (inst) { - path.push(inst); - inst = inst._hostParent; - } - var i; - for (i = path.length; i-- > 0;) { - fn(path[i], 'captured', arg); - } - for (i = 0; i < path.length; i++) { - fn(path[i], 'bubbled', arg); - } -} - -/** - * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that - * should would receive a `mouseEnter` or `mouseLeave` event. - * - * Does not invoke the callback on the nearest common ancestor because nothing - * "entered" or "left" that element. - */ -function traverseEnterLeave(from, to, fn, argFrom, argTo) { - var common = from && to ? getLowestCommonAncestor(from, to) : null; - var pathFrom = []; - while (from && from !== common) { - pathFrom.push(from); - from = from._hostParent; - } - var pathTo = []; - while (to && to !== common) { - pathTo.push(to); - to = to._hostParent; - } - var i; - for (i = 0; i < pathFrom.length; i++) { - fn(pathFrom[i], 'bubbled', argFrom); - } - for (i = pathTo.length; i-- > 0;) { - fn(pathTo[i], 'captured', argTo); - } -} - -module.exports = { - isAncestor: isAncestor, - getLowestCommonAncestor: getLowestCommonAncestor, - getParentInstance: getParentInstance, - traverseTwoPhase: traverseTwoPhase, - traverseEnterLeave: traverseEnterLeave -}; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 265 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMProperty = __webpack_require__(18); -var EventPluginRegistry = __webpack_require__(35); -var ReactComponentTreeHook = __webpack_require__(9); - -var warning = __webpack_require__(3); - -if (process.env.NODE_ENV !== 'production') { - var reactProps = { - children: true, - dangerouslySetInnerHTML: true, - key: true, - ref: true, - - autoFocus: true, - defaultValue: true, - valueLink: true, - defaultChecked: true, - checkedLink: true, - innerHTML: true, - suppressContentEditableWarning: true, - onFocusIn: true, - onFocusOut: true - }; - var warnedProperties = {}; - - var validateProperty = function (tagName, name, debugID) { - if (DOMProperty.properties.hasOwnProperty(name) || DOMProperty.isCustomAttribute(name)) { - return true; - } - if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { - return true; - } - if (EventPluginRegistry.registrationNameModules.hasOwnProperty(name)) { - return true; - } - warnedProperties[name] = true; - var lowerCasedName = name.toLowerCase(); - - // data-* attributes should be lowercase; suggest the lowercase version - var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null; - - var registrationName = EventPluginRegistry.possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? EventPluginRegistry.possibleRegistrationNames[lowerCasedName] : null; - - if (standardName != null) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Unknown DOM property %s. Did you mean %s?%s', name, standardName, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - return true; - } else if (registrationName != null) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Unknown event handler property %s. Did you mean `%s`?%s', name, registrationName, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - return true; - } else { - // We were unable to guess which prop the user intended. - // It is likely that the user was just blindly spreading/forwarding props - // Components should be careful to only render valid props/attributes. - // Warning will be invoked in warnUnknownProperties to allow grouping. - return false; - } - }; -} - -var warnUnknownProperties = function (debugID, element) { - var unknownProps = []; - for (var key in element.props) { - var isValid = validateProperty(element.type, key, debugID); - if (!isValid) { - unknownProps.push(key); - } - } - - var unknownPropString = unknownProps.map(function (prop) { - return '`' + prop + '`'; - }).join(', '); - - if (unknownProps.length === 1) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Unknown prop %s on <%s> tag. Remove this prop from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - } else if (unknownProps.length > 1) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Unknown props %s on <%s> tag. Remove these props from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - } -}; - -function handleElement(debugID, element) { - if (element == null || typeof element.type !== 'string') { - return; - } - if (element.type.indexOf('-') >= 0 || element.props.is) { - return; - } - warnUnknownProperties(debugID, element); -} - -var ReactDOMUnknownPropertyHook = { - onBeforeMountComponent: function (debugID, element) { - handleElement(debugID, element); - }, - onBeforeUpdateComponent: function (debugID, element) { - handleElement(debugID, element); - } -}; - -module.exports = ReactDOMUnknownPropertyHook; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 266 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactInvalidSetStateWarningHook = __webpack_require__(274); -var ReactHostOperationHistoryHook = __webpack_require__(272); -var ReactComponentTreeHook = __webpack_require__(9); -var ExecutionEnvironment = __webpack_require__(8); - -var performanceNow = __webpack_require__(227); -var warning = __webpack_require__(3); - -var hooks = []; -var didHookThrowForEvent = {}; - -function callHook(event, fn, context, arg1, arg2, arg3, arg4, arg5) { - try { - fn.call(context, arg1, arg2, arg3, arg4, arg5); - } catch (e) { - process.env.NODE_ENV !== 'production' ? warning(didHookThrowForEvent[event], 'Exception thrown by hook while handling %s: %s', event, e + '\n' + e.stack) : void 0; - didHookThrowForEvent[event] = true; - } -} - -function emitEvent(event, arg1, arg2, arg3, arg4, arg5) { - for (var i = 0; i < hooks.length; i++) { - var hook = hooks[i]; - var fn = hook[event]; - if (fn) { - callHook(event, fn, hook, arg1, arg2, arg3, arg4, arg5); - } - } -} - -var isProfiling = false; -var flushHistory = []; -var lifeCycleTimerStack = []; -var currentFlushNesting = 0; -var currentFlushMeasurements = []; -var currentFlushStartTime = 0; -var currentTimerDebugID = null; -var currentTimerStartTime = 0; -var currentTimerNestedFlushDuration = 0; -var currentTimerType = null; - -var lifeCycleTimerHasWarned = false; - -function clearHistory() { - ReactComponentTreeHook.purgeUnmountedComponents(); - ReactHostOperationHistoryHook.clearHistory(); -} - -function getTreeSnapshot(registeredIDs) { - return registeredIDs.reduce(function (tree, id) { - var ownerID = ReactComponentTreeHook.getOwnerID(id); - var parentID = ReactComponentTreeHook.getParentID(id); - tree[id] = { - displayName: ReactComponentTreeHook.getDisplayName(id), - text: ReactComponentTreeHook.getText(id), - updateCount: ReactComponentTreeHook.getUpdateCount(id), - childIDs: ReactComponentTreeHook.getChildIDs(id), - // Text nodes don't have owners but this is close enough. - ownerID: ownerID || parentID && ReactComponentTreeHook.getOwnerID(parentID) || 0, - parentID: parentID - }; - return tree; - }, {}); -} - -function resetMeasurements() { - var previousStartTime = currentFlushStartTime; - var previousMeasurements = currentFlushMeasurements; - var previousOperations = ReactHostOperationHistoryHook.getHistory(); - - if (currentFlushNesting === 0) { - currentFlushStartTime = 0; - currentFlushMeasurements = []; - clearHistory(); - return; - } - - if (previousMeasurements.length || previousOperations.length) { - var registeredIDs = ReactComponentTreeHook.getRegisteredIDs(); - flushHistory.push({ - duration: performanceNow() - previousStartTime, - measurements: previousMeasurements || [], - operations: previousOperations || [], - treeSnapshot: getTreeSnapshot(registeredIDs) - }); - } - - clearHistory(); - currentFlushStartTime = performanceNow(); - currentFlushMeasurements = []; -} - -function checkDebugID(debugID) { - var allowRoot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - if (allowRoot && debugID === 0) { - return; - } - if (!debugID) { - process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDebugTool: debugID may not be empty.') : void 0; - } -} - -function beginLifeCycleTimer(debugID, timerType) { - if (currentFlushNesting === 0) { - return; - } - if (currentTimerType && !lifeCycleTimerHasWarned) { - process.env.NODE_ENV !== 'production' ? warning(false, 'There is an internal error in the React performance measurement code. ' + 'Did not expect %s timer to start while %s timer is still in ' + 'progress for %s instance.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0; - lifeCycleTimerHasWarned = true; - } - currentTimerStartTime = performanceNow(); - currentTimerNestedFlushDuration = 0; - currentTimerDebugID = debugID; - currentTimerType = timerType; -} - -function endLifeCycleTimer(debugID, timerType) { - if (currentFlushNesting === 0) { - return; - } - if (currentTimerType !== timerType && !lifeCycleTimerHasWarned) { - process.env.NODE_ENV !== 'production' ? warning(false, 'There is an internal error in the React performance measurement code. ' + 'We did not expect %s timer to stop while %s timer is still in ' + 'progress for %s instance. Please report this as a bug in React.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0; - lifeCycleTimerHasWarned = true; - } - if (isProfiling) { - currentFlushMeasurements.push({ - timerType: timerType, - instanceID: debugID, - duration: performanceNow() - currentTimerStartTime - currentTimerNestedFlushDuration - }); - } - currentTimerStartTime = 0; - currentTimerNestedFlushDuration = 0; - currentTimerDebugID = null; - currentTimerType = null; -} - -function pauseCurrentLifeCycleTimer() { - var currentTimer = { - startTime: currentTimerStartTime, - nestedFlushStartTime: performanceNow(), - debugID: currentTimerDebugID, - timerType: currentTimerType - }; - lifeCycleTimerStack.push(currentTimer); - currentTimerStartTime = 0; - currentTimerNestedFlushDuration = 0; - currentTimerDebugID = null; - currentTimerType = null; -} - -function resumeCurrentLifeCycleTimer() { - var _lifeCycleTimerStack$ = lifeCycleTimerStack.pop(), - startTime = _lifeCycleTimerStack$.startTime, - nestedFlushStartTime = _lifeCycleTimerStack$.nestedFlushStartTime, - debugID = _lifeCycleTimerStack$.debugID, - timerType = _lifeCycleTimerStack$.timerType; - - var nestedFlushDuration = performanceNow() - nestedFlushStartTime; - currentTimerStartTime = startTime; - currentTimerNestedFlushDuration += nestedFlushDuration; - currentTimerDebugID = debugID; - currentTimerType = timerType; -} - -var lastMarkTimeStamp = 0; -var canUsePerformanceMeasure = -// $FlowFixMe https://github.com/facebook/flow/issues/2345 -typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; - -function shouldMark(debugID) { - if (!isProfiling || !canUsePerformanceMeasure) { - return false; - } - var element = ReactComponentTreeHook.getElement(debugID); - if (element == null || typeof element !== 'object') { - return false; - } - var isHostElement = typeof element.type === 'string'; - if (isHostElement) { - return false; - } - return true; -} - -function markBegin(debugID, markType) { - if (!shouldMark(debugID)) { - return; - } - - var markName = debugID + '::' + markType; - lastMarkTimeStamp = performanceNow(); - performance.mark(markName); -} - -function markEnd(debugID, markType) { - if (!shouldMark(debugID)) { - return; - } - - var markName = debugID + '::' + markType; - var displayName = ReactComponentTreeHook.getDisplayName(debugID) || 'Unknown'; - - // Chrome has an issue of dropping markers recorded too fast: - // https://bugs.chromium.org/p/chromium/issues/detail?id=640652 - // To work around this, we will not report very small measurements. - // I determined the magic number by tweaking it back and forth. - // 0.05ms was enough to prevent the issue, but I set it to 0.1ms to be safe. - // When the bug is fixed, we can `measure()` unconditionally if we want to. - var timeStamp = performanceNow(); - if (timeStamp - lastMarkTimeStamp > 0.1) { - var measurementName = displayName + ' [' + markType + ']'; - performance.measure(measurementName, markName); - } - - performance.clearMarks(markName); - performance.clearMeasures(measurementName); -} - -var ReactDebugTool = { - addHook: function (hook) { - hooks.push(hook); - }, - removeHook: function (hook) { - for (var i = 0; i < hooks.length; i++) { - if (hooks[i] === hook) { - hooks.splice(i, 1); - i--; - } - } - }, - isProfiling: function () { - return isProfiling; - }, - beginProfiling: function () { - if (isProfiling) { - return; - } - - isProfiling = true; - flushHistory.length = 0; - resetMeasurements(); - ReactDebugTool.addHook(ReactHostOperationHistoryHook); - }, - endProfiling: function () { - if (!isProfiling) { - return; - } - - isProfiling = false; - resetMeasurements(); - ReactDebugTool.removeHook(ReactHostOperationHistoryHook); - }, - getFlushHistory: function () { - return flushHistory; - }, - onBeginFlush: function () { - currentFlushNesting++; - resetMeasurements(); - pauseCurrentLifeCycleTimer(); - emitEvent('onBeginFlush'); - }, - onEndFlush: function () { - resetMeasurements(); - currentFlushNesting--; - resumeCurrentLifeCycleTimer(); - emitEvent('onEndFlush'); - }, - onBeginLifeCycleTimer: function (debugID, timerType) { - checkDebugID(debugID); - emitEvent('onBeginLifeCycleTimer', debugID, timerType); - markBegin(debugID, timerType); - beginLifeCycleTimer(debugID, timerType); - }, - onEndLifeCycleTimer: function (debugID, timerType) { - checkDebugID(debugID); - endLifeCycleTimer(debugID, timerType); - markEnd(debugID, timerType); - emitEvent('onEndLifeCycleTimer', debugID, timerType); - }, - onBeginProcessingChildContext: function () { - emitEvent('onBeginProcessingChildContext'); - }, - onEndProcessingChildContext: function () { - emitEvent('onEndProcessingChildContext'); - }, - onHostOperation: function (operation) { - checkDebugID(operation.instanceID); - emitEvent('onHostOperation', operation); - }, - onSetState: function () { - emitEvent('onSetState'); - }, - onSetChildren: function (debugID, childDebugIDs) { - checkDebugID(debugID); - childDebugIDs.forEach(checkDebugID); - emitEvent('onSetChildren', debugID, childDebugIDs); - }, - onBeforeMountComponent: function (debugID, element, parentDebugID) { - checkDebugID(debugID); - checkDebugID(parentDebugID, true); - emitEvent('onBeforeMountComponent', debugID, element, parentDebugID); - markBegin(debugID, 'mount'); - }, - onMountComponent: function (debugID) { - checkDebugID(debugID); - markEnd(debugID, 'mount'); - emitEvent('onMountComponent', debugID); - }, - onBeforeUpdateComponent: function (debugID, element) { - checkDebugID(debugID); - emitEvent('onBeforeUpdateComponent', debugID, element); - markBegin(debugID, 'update'); - }, - onUpdateComponent: function (debugID) { - checkDebugID(debugID); - markEnd(debugID, 'update'); - emitEvent('onUpdateComponent', debugID); - }, - onBeforeUnmountComponent: function (debugID) { - checkDebugID(debugID); - emitEvent('onBeforeUnmountComponent', debugID); - markBegin(debugID, 'unmount'); - }, - onUnmountComponent: function (debugID) { - checkDebugID(debugID); - markEnd(debugID, 'unmount'); - emitEvent('onUnmountComponent', debugID); - }, - onTestEvent: function () { - emitEvent('onTestEvent'); - } -}; - -// TODO remove these when RN/www gets updated -ReactDebugTool.addDevtool = ReactDebugTool.addHook; -ReactDebugTool.removeDevtool = ReactDebugTool.removeHook; - -ReactDebugTool.addHook(ReactInvalidSetStateWarningHook); -ReactDebugTool.addHook(ReactComponentTreeHook); -var url = ExecutionEnvironment.canUseDOM && window.location.href || ''; -if (/[?&]react_perf\b/.test(url)) { - ReactDebugTool.beginProfiling(); -} - -module.exports = ReactDebugTool; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 267 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var ReactUpdates = __webpack_require__(14); -var Transaction = __webpack_require__(38); - -var emptyFunction = __webpack_require__(12); - -var RESET_BATCHED_UPDATES = { - initialize: emptyFunction, - close: function () { - ReactDefaultBatchingStrategy.isBatchingUpdates = false; - } -}; - -var FLUSH_BATCHED_UPDATES = { - initialize: emptyFunction, - close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates) -}; - -var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES]; - -function ReactDefaultBatchingStrategyTransaction() { - this.reinitializeTransaction(); -} - -_assign(ReactDefaultBatchingStrategyTransaction.prototype, Transaction, { - getTransactionWrappers: function () { - return TRANSACTION_WRAPPERS; - } -}); - -var transaction = new ReactDefaultBatchingStrategyTransaction(); - -var ReactDefaultBatchingStrategy = { - isBatchingUpdates: false, - - /** - * Call the provided function in a context within which calls to `setState` - * and friends are batched such that components aren't updated unnecessarily. - */ - batchedUpdates: function (callback, a, b, c, d, e) { - var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates; - - ReactDefaultBatchingStrategy.isBatchingUpdates = true; - - // The code is written this way to avoid extra allocations - if (alreadyBatchingUpdates) { - return callback(a, b, c, d, e); - } else { - return transaction.perform(callback, null, a, b, c, d, e); - } - } -}; - -module.exports = ReactDefaultBatchingStrategy; - -/***/ }), -/* 268 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ARIADOMPropertyConfig = __webpack_require__(238); -var BeforeInputEventPlugin = __webpack_require__(240); -var ChangeEventPlugin = __webpack_require__(242); -var DefaultEventPluginOrder = __webpack_require__(244); -var EnterLeaveEventPlugin = __webpack_require__(245); -var HTMLDOMPropertyConfig = __webpack_require__(247); -var ReactComponentBrowserEnvironment = __webpack_require__(249); -var ReactDOMComponent = __webpack_require__(252); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactDOMEmptyComponent = __webpack_require__(254); -var ReactDOMTreeTraversal = __webpack_require__(264); -var ReactDOMTextComponent = __webpack_require__(262); -var ReactDefaultBatchingStrategy = __webpack_require__(267); -var ReactEventListener = __webpack_require__(271); -var ReactInjection = __webpack_require__(273); -var ReactReconcileTransaction = __webpack_require__(279); -var SVGDOMPropertyConfig = __webpack_require__(284); -var SelectEventPlugin = __webpack_require__(285); -var SimpleEventPlugin = __webpack_require__(286); - -var alreadyInjected = false; - -function inject() { - if (alreadyInjected) { - // TODO: This is currently true because these injections are shared between - // the client and the server package. They should be built independently - // and not share any injection state. Then this problem will be solved. - return; - } - alreadyInjected = true; - - ReactInjection.EventEmitter.injectReactEventListener(ReactEventListener); - - /** - * Inject modules for resolving DOM hierarchy and plugin ordering. - */ - ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder); - ReactInjection.EventPluginUtils.injectComponentTree(ReactDOMComponentTree); - ReactInjection.EventPluginUtils.injectTreeTraversal(ReactDOMTreeTraversal); - - /** - * Some important event plugins included by default (without having to require - * them). - */ - ReactInjection.EventPluginHub.injectEventPluginsByName({ - SimpleEventPlugin: SimpleEventPlugin, - EnterLeaveEventPlugin: EnterLeaveEventPlugin, - ChangeEventPlugin: ChangeEventPlugin, - SelectEventPlugin: SelectEventPlugin, - BeforeInputEventPlugin: BeforeInputEventPlugin - }); - - ReactInjection.HostComponent.injectGenericComponentClass(ReactDOMComponent); - - ReactInjection.HostComponent.injectTextComponentClass(ReactDOMTextComponent); - - ReactInjection.DOMProperty.injectDOMPropertyConfig(ARIADOMPropertyConfig); - ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig); - ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig); - - ReactInjection.EmptyComponent.injectEmptyComponentFactory(function (instantiate) { - return new ReactDOMEmptyComponent(instantiate); - }); - - ReactInjection.Updates.injectReconcileTransaction(ReactReconcileTransaction); - ReactInjection.Updates.injectBatchingStrategy(ReactDefaultBatchingStrategy); - - ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment); -} - -module.exports = { - inject: inject -}; - -/***/ }), -/* 269 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -// The Symbol used to tag the ReactElement type. If there is no native Symbol -// nor polyfill, then a plain number is used for performance. - -var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7; - -module.exports = REACT_ELEMENT_TYPE; - -/***/ }), -/* 270 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var EventPluginHub = __webpack_require__(30); - -function runEventQueueInBatch(events) { - EventPluginHub.enqueueEvents(events); - EventPluginHub.processEventQueue(false); -} - -var ReactEventEmitterMixin = { - - /** - * Streams a fired top-level event to `EventPluginHub` where plugins have the - * opportunity to create `ReactEvent`s to be dispatched. - */ - handleTopLevel: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var events = EventPluginHub.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); - runEventQueueInBatch(events); - } -}; - -module.exports = ReactEventEmitterMixin; - -/***/ }), -/* 271 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var EventListener = __webpack_require__(72); -var ExecutionEnvironment = __webpack_require__(8); -var PooledClass = __webpack_require__(20); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactUpdates = __webpack_require__(14); - -var getEventTarget = __webpack_require__(57); -var getUnboundedScrollPosition = __webpack_require__(220); - -/** - * Find the deepest React component completely containing the root of the - * passed-in instance (for use when entire React trees are nested within each - * other). If React trees are not nested, returns null. - */ -function findParent(inst) { - // TODO: It may be a good idea to cache this to prevent unnecessary DOM - // traversal, but caching is difficult to do correctly without using a - // mutation observer to listen for all DOM changes. - while (inst._hostParent) { - inst = inst._hostParent; - } - var rootNode = ReactDOMComponentTree.getNodeFromInstance(inst); - var container = rootNode.parentNode; - return ReactDOMComponentTree.getClosestInstanceFromNode(container); -} - -// Used to store ancestor hierarchy in top level callback -function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) { - this.topLevelType = topLevelType; - this.nativeEvent = nativeEvent; - this.ancestors = []; -} -_assign(TopLevelCallbackBookKeeping.prototype, { - destructor: function () { - this.topLevelType = null; - this.nativeEvent = null; - this.ancestors.length = 0; - } -}); -PooledClass.addPoolingTo(TopLevelCallbackBookKeeping, PooledClass.twoArgumentPooler); - -function handleTopLevelImpl(bookKeeping) { - var nativeEventTarget = getEventTarget(bookKeeping.nativeEvent); - var targetInst = ReactDOMComponentTree.getClosestInstanceFromNode(nativeEventTarget); - - // Loop through the hierarchy, in case there's any nested components. - // It's important that we build the array of ancestors before calling any - // event handlers, because event handlers can modify the DOM, leading to - // inconsistencies with ReactMount's node cache. See #1105. - var ancestor = targetInst; - do { - bookKeeping.ancestors.push(ancestor); - ancestor = ancestor && findParent(ancestor); - } while (ancestor); - - for (var i = 0; i < bookKeeping.ancestors.length; i++) { - targetInst = bookKeeping.ancestors[i]; - ReactEventListener._handleTopLevel(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent)); - } -} - -function scrollValueMonitor(cb) { - var scrollPosition = getUnboundedScrollPosition(window); - cb(scrollPosition); -} - -var ReactEventListener = { - _enabled: true, - _handleTopLevel: null, - - WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null, - - setHandleTopLevel: function (handleTopLevel) { - ReactEventListener._handleTopLevel = handleTopLevel; - }, - - setEnabled: function (enabled) { - ReactEventListener._enabled = !!enabled; - }, - - isEnabled: function () { - return ReactEventListener._enabled; - }, - - /** - * Traps top-level events by using event bubbling. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {string} handlerBaseName Event name (e.g. "click"). - * @param {object} element Element on which to attach listener. - * @return {?object} An object with a remove function which will forcefully - * remove the listener. - * @internal - */ - trapBubbledEvent: function (topLevelType, handlerBaseName, element) { - if (!element) { - return null; - } - return EventListener.listen(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType)); - }, - - /** - * Traps a top-level event by using event capturing. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {string} handlerBaseName Event name (e.g. "click"). - * @param {object} element Element on which to attach listener. - * @return {?object} An object with a remove function which will forcefully - * remove the listener. - * @internal - */ - trapCapturedEvent: function (topLevelType, handlerBaseName, element) { - if (!element) { - return null; - } - return EventListener.capture(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType)); - }, - - monitorScrollValue: function (refresh) { - var callback = scrollValueMonitor.bind(null, refresh); - EventListener.listen(window, 'scroll', callback); - }, - - dispatchEvent: function (topLevelType, nativeEvent) { - if (!ReactEventListener._enabled) { - return; - } - - var bookKeeping = TopLevelCallbackBookKeeping.getPooled(topLevelType, nativeEvent); - try { - // Event queue being processed in the same cycle allows - // `preventDefault`. - ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping); - } finally { - TopLevelCallbackBookKeeping.release(bookKeeping); - } - } -}; - -module.exports = ReactEventListener; - -/***/ }), -/* 272 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var history = []; - -var ReactHostOperationHistoryHook = { - onHostOperation: function (operation) { - history.push(operation); - }, - clearHistory: function () { - if (ReactHostOperationHistoryHook._preventClearing) { - // Should only be used for tests. - return; - } - - history = []; - }, - getHistory: function () { - return history; - } -}; - -module.exports = ReactHostOperationHistoryHook; - -/***/ }), -/* 273 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMProperty = __webpack_require__(18); -var EventPluginHub = __webpack_require__(30); -var EventPluginUtils = __webpack_require__(48); -var ReactComponentEnvironment = __webpack_require__(51); -var ReactEmptyComponent = __webpack_require__(83); -var ReactBrowserEventEmitter = __webpack_require__(36); -var ReactHostComponent = __webpack_require__(85); -var ReactUpdates = __webpack_require__(14); - -var ReactInjection = { - Component: ReactComponentEnvironment.injection, - DOMProperty: DOMProperty.injection, - EmptyComponent: ReactEmptyComponent.injection, - EventPluginHub: EventPluginHub.injection, - EventPluginUtils: EventPluginUtils.injection, - EventEmitter: ReactBrowserEventEmitter.injection, - HostComponent: ReactHostComponent.injection, - Updates: ReactUpdates.injection -}; - -module.exports = ReactInjection; - -/***/ }), -/* 274 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var warning = __webpack_require__(3); - -if (process.env.NODE_ENV !== 'production') { - var processingChildContext = false; - - var warnInvalidSetState = function () { - process.env.NODE_ENV !== 'production' ? warning(!processingChildContext, 'setState(...): Cannot call setState() inside getChildContext()') : void 0; - }; -} - -var ReactInvalidSetStateWarningHook = { - onBeginProcessingChildContext: function () { - processingChildContext = true; - }, - onEndProcessingChildContext: function () { - processingChildContext = false; - }, - onSetState: function () { - warnInvalidSetState(); - } -}; - -module.exports = ReactInvalidSetStateWarningHook; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 275 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var adler32 = __webpack_require__(297); - -var TAG_END = /\/?>/; -var COMMENT_START = /^<\!\-\-/; - -var ReactMarkupChecksum = { - CHECKSUM_ATTR_NAME: 'data-react-checksum', - - /** - * @param {string} markup Markup string - * @return {string} Markup string with checksum attribute attached - */ - addChecksumToMarkup: function (markup) { - var checksum = adler32(markup); - - // Add checksum (handle both parent tags, comments and self-closing tags) - if (COMMENT_START.test(markup)) { - return markup; - } else { - return markup.replace(TAG_END, ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '"$&'); - } - }, - - /** - * @param {string} markup to use - * @param {DOMElement} element root React element - * @returns {boolean} whether or not the markup is the same - */ - canReuseMarkup: function (markup, element) { - var existingChecksum = element.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); - existingChecksum = existingChecksum && parseInt(existingChecksum, 10); - var markupChecksum = adler32(markup); - return markupChecksum === existingChecksum; - } -}; - -module.exports = ReactMarkupChecksum; - -/***/ }), -/* 276 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var ReactComponentEnvironment = __webpack_require__(51); -var ReactInstanceMap = __webpack_require__(32); -var ReactInstrumentation = __webpack_require__(10); - -var ReactCurrentOwner = __webpack_require__(15); -var ReactReconciler = __webpack_require__(26); -var ReactChildReconciler = __webpack_require__(248); - -var emptyFunction = __webpack_require__(12); -var flattenChildren = __webpack_require__(301); -var invariant = __webpack_require__(2); - -/** - * Make an update for markup to be rendered and inserted at a supplied index. - * - * @param {string} markup Markup that renders into an element. - * @param {number} toIndex Destination index. - * @private - */ -function makeInsertMarkup(markup, afterNode, toIndex) { - // NOTE: Null values reduce hidden classes. - return { - type: 'INSERT_MARKUP', - content: markup, - fromIndex: null, - fromNode: null, - toIndex: toIndex, - afterNode: afterNode - }; -} - -/** - * Make an update for moving an existing element to another index. - * - * @param {number} fromIndex Source index of the existing element. - * @param {number} toIndex Destination index of the element. - * @private - */ -function makeMove(child, afterNode, toIndex) { - // NOTE: Null values reduce hidden classes. - return { - type: 'MOVE_EXISTING', - content: null, - fromIndex: child._mountIndex, - fromNode: ReactReconciler.getHostNode(child), - toIndex: toIndex, - afterNode: afterNode - }; -} - -/** - * Make an update for removing an element at an index. - * - * @param {number} fromIndex Index of the element to remove. - * @private - */ -function makeRemove(child, node) { - // NOTE: Null values reduce hidden classes. - return { - type: 'REMOVE_NODE', - content: null, - fromIndex: child._mountIndex, - fromNode: node, - toIndex: null, - afterNode: null - }; -} - -/** - * Make an update for setting the markup of a node. - * - * @param {string} markup Markup that renders into an element. - * @private - */ -function makeSetMarkup(markup) { - // NOTE: Null values reduce hidden classes. - return { - type: 'SET_MARKUP', - content: markup, - fromIndex: null, - fromNode: null, - toIndex: null, - afterNode: null - }; -} - -/** - * Make an update for setting the text content. - * - * @param {string} textContent Text content to set. - * @private - */ -function makeTextContent(textContent) { - // NOTE: Null values reduce hidden classes. - return { - type: 'TEXT_CONTENT', - content: textContent, - fromIndex: null, - fromNode: null, - toIndex: null, - afterNode: null - }; -} - -/** - * Push an update, if any, onto the queue. Creates a new queue if none is - * passed and always returns the queue. Mutative. - */ -function enqueue(queue, update) { - if (update) { - queue = queue || []; - queue.push(update); - } - return queue; -} - -/** - * Processes any enqueued updates. - * - * @private - */ -function processQueue(inst, updateQueue) { - ReactComponentEnvironment.processChildrenUpdates(inst, updateQueue); -} - -var setChildrenForInstrumentation = emptyFunction; -if (process.env.NODE_ENV !== 'production') { - var getDebugID = function (inst) { - if (!inst._debugID) { - // Check for ART-like instances. TODO: This is silly/gross. - var internal; - if (internal = ReactInstanceMap.get(inst)) { - inst = internal; - } - } - return inst._debugID; - }; - setChildrenForInstrumentation = function (children) { - var debugID = getDebugID(this); - // TODO: React Native empty components are also multichild. - // This means they still get into this method but don't have _debugID. - if (debugID !== 0) { - ReactInstrumentation.debugTool.onSetChildren(debugID, children ? Object.keys(children).map(function (key) { - return children[key]._debugID; - }) : []); - } - }; -} - -/** - * ReactMultiChild are capable of reconciling multiple children. - * - * @class ReactMultiChild - * @internal - */ -var ReactMultiChild = { - - /** - * Provides common functionality for components that must reconcile multiple - * children. This is used by `ReactDOMComponent` to mount, update, and - * unmount child components. - * - * @lends {ReactMultiChild.prototype} - */ - Mixin: { - - _reconcilerInstantiateChildren: function (nestedChildren, transaction, context) { - if (process.env.NODE_ENV !== 'production') { - var selfDebugID = getDebugID(this); - if (this._currentElement) { - try { - ReactCurrentOwner.current = this._currentElement._owner; - return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context, selfDebugID); - } finally { - ReactCurrentOwner.current = null; - } - } - } - return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context); - }, - - _reconcilerUpdateChildren: function (prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context) { - var nextChildren; - var selfDebugID = 0; - if (process.env.NODE_ENV !== 'production') { - selfDebugID = getDebugID(this); - if (this._currentElement) { - try { - ReactCurrentOwner.current = this._currentElement._owner; - nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID); - } finally { - ReactCurrentOwner.current = null; - } - ReactChildReconciler.updateChildren(prevChildren, nextChildren, mountImages, removedNodes, transaction, this, this._hostContainerInfo, context, selfDebugID); - return nextChildren; - } - } - nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID); - ReactChildReconciler.updateChildren(prevChildren, nextChildren, mountImages, removedNodes, transaction, this, this._hostContainerInfo, context, selfDebugID); - return nextChildren; - }, - - /** - * Generates a "mount image" for each of the supplied children. In the case - * of `ReactDOMComponent`, a mount image is a string of markup. - * - * @param {?object} nestedChildren Nested child maps. - * @return {array} An array of mounted representations. - * @internal - */ - mountChildren: function (nestedChildren, transaction, context) { - var children = this._reconcilerInstantiateChildren(nestedChildren, transaction, context); - this._renderedChildren = children; - - var mountImages = []; - var index = 0; - for (var name in children) { - if (children.hasOwnProperty(name)) { - var child = children[name]; - var selfDebugID = 0; - if (process.env.NODE_ENV !== 'production') { - selfDebugID = getDebugID(this); - } - var mountImage = ReactReconciler.mountComponent(child, transaction, this, this._hostContainerInfo, context, selfDebugID); - child._mountIndex = index++; - mountImages.push(mountImage); - } - } - - if (process.env.NODE_ENV !== 'production') { - setChildrenForInstrumentation.call(this, children); - } - - return mountImages; - }, - - /** - * Replaces any rendered children with a text content string. - * - * @param {string} nextContent String of content. - * @internal - */ - updateTextContent: function (nextContent) { - var prevChildren = this._renderedChildren; - // Remove any rendered children. - ReactChildReconciler.unmountChildren(prevChildren, false); - for (var name in prevChildren) { - if (prevChildren.hasOwnProperty(name)) { - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'updateTextContent called on non-empty component.') : _prodInvariant('118') : void 0; - } - } - // Set new text content. - var updates = [makeTextContent(nextContent)]; - processQueue(this, updates); - }, - - /** - * Replaces any rendered children with a markup string. - * - * @param {string} nextMarkup String of markup. - * @internal - */ - updateMarkup: function (nextMarkup) { - var prevChildren = this._renderedChildren; - // Remove any rendered children. - ReactChildReconciler.unmountChildren(prevChildren, false); - for (var name in prevChildren) { - if (prevChildren.hasOwnProperty(name)) { - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'updateTextContent called on non-empty component.') : _prodInvariant('118') : void 0; - } - } - var updates = [makeSetMarkup(nextMarkup)]; - processQueue(this, updates); - }, - - /** - * Updates the rendered children with new children. - * - * @param {?object} nextNestedChildrenElements Nested child element maps. - * @param {ReactReconcileTransaction} transaction - * @internal - */ - updateChildren: function (nextNestedChildrenElements, transaction, context) { - // Hook used by React ART - this._updateChildren(nextNestedChildrenElements, transaction, context); - }, - - /** - * @param {?object} nextNestedChildrenElements Nested child element maps. - * @param {ReactReconcileTransaction} transaction - * @final - * @protected - */ - _updateChildren: function (nextNestedChildrenElements, transaction, context) { - var prevChildren = this._renderedChildren; - var removedNodes = {}; - var mountImages = []; - var nextChildren = this._reconcilerUpdateChildren(prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context); - if (!nextChildren && !prevChildren) { - return; - } - var updates = null; - var name; - // `nextIndex` will increment for each child in `nextChildren`, but - // `lastIndex` will be the last index visited in `prevChildren`. - var nextIndex = 0; - var lastIndex = 0; - // `nextMountIndex` will increment for each newly mounted child. - var nextMountIndex = 0; - var lastPlacedNode = null; - for (name in nextChildren) { - if (!nextChildren.hasOwnProperty(name)) { - continue; - } - var prevChild = prevChildren && prevChildren[name]; - var nextChild = nextChildren[name]; - if (prevChild === nextChild) { - updates = enqueue(updates, this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex)); - lastIndex = Math.max(prevChild._mountIndex, lastIndex); - prevChild._mountIndex = nextIndex; - } else { - if (prevChild) { - // Update `lastIndex` before `_mountIndex` gets unset by unmounting. - lastIndex = Math.max(prevChild._mountIndex, lastIndex); - // The `removedNodes` loop below will actually remove the child. - } - // The child must be instantiated before it's mounted. - updates = enqueue(updates, this._mountChildAtIndex(nextChild, mountImages[nextMountIndex], lastPlacedNode, nextIndex, transaction, context)); - nextMountIndex++; - } - nextIndex++; - lastPlacedNode = ReactReconciler.getHostNode(nextChild); - } - // Remove children that are no longer present. - for (name in removedNodes) { - if (removedNodes.hasOwnProperty(name)) { - updates = enqueue(updates, this._unmountChild(prevChildren[name], removedNodes[name])); - } - } - if (updates) { - processQueue(this, updates); - } - this._renderedChildren = nextChildren; - - if (process.env.NODE_ENV !== 'production') { - setChildrenForInstrumentation.call(this, nextChildren); - } - }, - - /** - * Unmounts all rendered children. This should be used to clean up children - * when this component is unmounted. It does not actually perform any - * backend operations. - * - * @internal - */ - unmountChildren: function (safely) { - var renderedChildren = this._renderedChildren; - ReactChildReconciler.unmountChildren(renderedChildren, safely); - this._renderedChildren = null; - }, - - /** - * Moves a child component to the supplied index. - * - * @param {ReactComponent} child Component to move. - * @param {number} toIndex Destination index of the element. - * @param {number} lastIndex Last index visited of the siblings of `child`. - * @protected - */ - moveChild: function (child, afterNode, toIndex, lastIndex) { - // If the index of `child` is less than `lastIndex`, then it needs to - // be moved. Otherwise, we do not need to move it because a child will be - // inserted or moved before `child`. - if (child._mountIndex < lastIndex) { - return makeMove(child, afterNode, toIndex); - } - }, - - /** - * Creates a child component. - * - * @param {ReactComponent} child Component to create. - * @param {string} mountImage Markup to insert. - * @protected - */ - createChild: function (child, afterNode, mountImage) { - return makeInsertMarkup(mountImage, afterNode, child._mountIndex); - }, - - /** - * Removes a child component. - * - * @param {ReactComponent} child Child to remove. - * @protected - */ - removeChild: function (child, node) { - return makeRemove(child, node); - }, - - /** - * Mounts a child with the supplied name. - * - * NOTE: This is part of `updateChildren` and is here for readability. - * - * @param {ReactComponent} child Component to mount. - * @param {string} name Name of the child. - * @param {number} index Index at which to insert the child. - * @param {ReactReconcileTransaction} transaction - * @private - */ - _mountChildAtIndex: function (child, mountImage, afterNode, index, transaction, context) { - child._mountIndex = index; - return this.createChild(child, afterNode, mountImage); - }, - - /** - * Unmounts a rendered child. - * - * NOTE: This is part of `updateChildren` and is here for readability. - * - * @param {ReactComponent} child Component to unmount. - * @private - */ - _unmountChild: function (child, node) { - var update = this.removeChild(child, node); - child._mountIndex = null; - return update; - } - - } - -}; - -module.exports = ReactMultiChild; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 277 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -/** - * @param {?object} object - * @return {boolean} True if `object` is a valid owner. - * @final - */ -function isValidOwner(object) { - return !!(object && typeof object.attachRef === 'function' && typeof object.detachRef === 'function'); -} - -/** - * ReactOwners are capable of storing references to owned components. - * - * All components are capable of //being// referenced by owner components, but - * only ReactOwner components are capable of //referencing// owned components. - * The named reference is known as a "ref". - * - * Refs are available when mounted and updated during reconciliation. - * - * var MyComponent = React.createClass({ - * render: function() { - * return ( - * <div onClick={this.handleClick}> - * <CustomComponent ref="custom" /> - * </div> - * ); - * }, - * handleClick: function() { - * this.refs.custom.handleClick(); - * }, - * componentDidMount: function() { - * this.refs.custom.initialize(); - * } - * }); - * - * Refs should rarely be used. When refs are used, they should only be done to - * control data that is not handled by React's data flow. - * - * @class ReactOwner - */ -var ReactOwner = { - /** - * Adds a component by ref to an owner component. - * - * @param {ReactComponent} component Component to reference. - * @param {string} ref Name by which to refer to the component. - * @param {ReactOwner} owner Component on which to record the ref. - * @final - * @internal - */ - addComponentAsRefTo: function (component, ref, owner) { - !isValidOwner(owner) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component\'s `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).') : _prodInvariant('119') : void 0; - owner.attachRef(ref, component); - }, - - /** - * Removes a component by ref from an owner component. - * - * @param {ReactComponent} component Component to dereference. - * @param {string} ref Name of the ref to remove. - * @param {ReactOwner} owner Component on which the ref is recorded. - * @final - * @internal - */ - removeComponentAsRefFrom: function (component, ref, owner) { - !isValidOwner(owner) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might be removing a ref to a component that was not created inside a component\'s `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).') : _prodInvariant('120') : void 0; - var ownerPublicInstance = owner.getPublicInstance(); - // Check that `component`'s owner is still alive and that `component` is still the current ref - // because we do not want to detach the ref if another component stole it. - if (ownerPublicInstance && ownerPublicInstance.refs[ref] === component.getPublicInstance()) { - owner.detachRef(ref); - } - } - -}; - -module.exports = ReactOwner; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 278 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactPropTypeLocationNames = {}; - -if (process.env.NODE_ENV !== 'production') { - ReactPropTypeLocationNames = { - prop: 'prop', - context: 'context', - childContext: 'child context' - }; -} - -module.exports = ReactPropTypeLocationNames; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 279 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var CallbackQueue = __webpack_require__(79); -var PooledClass = __webpack_require__(20); -var ReactBrowserEventEmitter = __webpack_require__(36); -var ReactInputSelection = __webpack_require__(86); -var ReactInstrumentation = __webpack_require__(10); -var Transaction = __webpack_require__(38); -var ReactUpdateQueue = __webpack_require__(53); - -/** - * Ensures that, when possible, the selection range (currently selected text - * input) is not disturbed by performing the transaction. - */ -var SELECTION_RESTORATION = { - /** - * @return {Selection} Selection information. - */ - initialize: ReactInputSelection.getSelectionInformation, - /** - * @param {Selection} sel Selection information returned from `initialize`. - */ - close: ReactInputSelection.restoreSelection -}; - -/** - * Suppresses events (blur/focus) that could be inadvertently dispatched due to - * high level DOM manipulations (like temporarily removing a text input from the - * DOM). - */ -var EVENT_SUPPRESSION = { - /** - * @return {boolean} The enabled status of `ReactBrowserEventEmitter` before - * the reconciliation. - */ - initialize: function () { - var currentlyEnabled = ReactBrowserEventEmitter.isEnabled(); - ReactBrowserEventEmitter.setEnabled(false); - return currentlyEnabled; - }, - - /** - * @param {boolean} previouslyEnabled Enabled status of - * `ReactBrowserEventEmitter` before the reconciliation occurred. `close` - * restores the previous value. - */ - close: function (previouslyEnabled) { - ReactBrowserEventEmitter.setEnabled(previouslyEnabled); - } -}; - -/** - * Provides a queue for collecting `componentDidMount` and - * `componentDidUpdate` callbacks during the transaction. - */ -var ON_DOM_READY_QUEUEING = { - /** - * Initializes the internal `onDOMReady` queue. - */ - initialize: function () { - this.reactMountReady.reset(); - }, - - /** - * After DOM is flushed, invoke all registered `onDOMReady` callbacks. - */ - close: function () { - this.reactMountReady.notifyAll(); - } -}; - -/** - * Executed within the scope of the `Transaction` instance. Consider these as - * being member methods, but with an implied ordering while being isolated from - * each other. - */ -var TRANSACTION_WRAPPERS = [SELECTION_RESTORATION, EVENT_SUPPRESSION, ON_DOM_READY_QUEUEING]; - -if (process.env.NODE_ENV !== 'production') { - TRANSACTION_WRAPPERS.push({ - initialize: ReactInstrumentation.debugTool.onBeginFlush, - close: ReactInstrumentation.debugTool.onEndFlush - }); -} - -/** - * Currently: - * - The order that these are listed in the transaction is critical: - * - Suppresses events. - * - Restores selection range. - * - * Future: - * - Restore document/overflow scroll positions that were unintentionally - * modified via DOM insertions above the top viewport boundary. - * - Implement/integrate with customized constraint based layout system and keep - * track of which dimensions must be remeasured. - * - * @class ReactReconcileTransaction - */ -function ReactReconcileTransaction(useCreateElement) { - this.reinitializeTransaction(); - // Only server-side rendering really needs this option (see - // `ReactServerRendering`), but server-side uses - // `ReactServerRenderingTransaction` instead. This option is here so that it's - // accessible and defaults to false when `ReactDOMComponent` and - // `ReactDOMTextComponent` checks it in `mountComponent`.` - this.renderToStaticMarkup = false; - this.reactMountReady = CallbackQueue.getPooled(null); - this.useCreateElement = useCreateElement; -} - -var Mixin = { - /** - * @see Transaction - * @abstract - * @final - * @return {array<object>} List of operation wrap procedures. - * TODO: convert to array<TransactionWrapper> - */ - getTransactionWrappers: function () { - return TRANSACTION_WRAPPERS; - }, - - /** - * @return {object} The queue to collect `onDOMReady` callbacks with. - */ - getReactMountReady: function () { - return this.reactMountReady; - }, - - /** - * @return {object} The queue to collect React async events. - */ - getUpdateQueue: function () { - return ReactUpdateQueue; - }, - - /** - * Save current transaction state -- if the return value from this method is - * passed to `rollback`, the transaction will be reset to that state. - */ - checkpoint: function () { - // reactMountReady is the our only stateful wrapper - return this.reactMountReady.checkpoint(); - }, - - rollback: function (checkpoint) { - this.reactMountReady.rollback(checkpoint); - }, - - /** - * `PooledClass` looks for this, and will invoke this before allowing this - * instance to be reused. - */ - destructor: function () { - CallbackQueue.release(this.reactMountReady); - this.reactMountReady = null; - } -}; - -_assign(ReactReconcileTransaction.prototype, Transaction, Mixin); - -PooledClass.addPoolingTo(ReactReconcileTransaction); - -module.exports = ReactReconcileTransaction; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 280 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactOwner = __webpack_require__(277); - -var ReactRef = {}; - -function attachRef(ref, component, owner) { - if (typeof ref === 'function') { - ref(component.getPublicInstance()); - } else { - // Legacy ref - ReactOwner.addComponentAsRefTo(component, ref, owner); - } -} - -function detachRef(ref, component, owner) { - if (typeof ref === 'function') { - ref(null); - } else { - // Legacy ref - ReactOwner.removeComponentAsRefFrom(component, ref, owner); - } -} - -ReactRef.attachRefs = function (instance, element) { - if (element === null || typeof element !== 'object') { - return; - } - var ref = element.ref; - if (ref != null) { - attachRef(ref, instance, element._owner); - } -}; - -ReactRef.shouldUpdateRefs = function (prevElement, nextElement) { - // If either the owner or a `ref` has changed, make sure the newest owner - // has stored a reference to `this`, and the previous owner (if different) - // has forgotten the reference to `this`. We use the element instead - // of the public this.props because the post processing cannot determine - // a ref. The ref conceptually lives on the element. - - // TODO: Should this even be possible? The owner cannot change because - // it's forbidden by shouldUpdateReactComponent. The ref can change - // if you swap the keys of but not the refs. Reconsider where this check - // is made. It probably belongs where the key checking and - // instantiateReactComponent is done. - - var prevRef = null; - var prevOwner = null; - if (prevElement !== null && typeof prevElement === 'object') { - prevRef = prevElement.ref; - prevOwner = prevElement._owner; - } - - var nextRef = null; - var nextOwner = null; - if (nextElement !== null && typeof nextElement === 'object') { - nextRef = nextElement.ref; - nextOwner = nextElement._owner; - } - - return prevRef !== nextRef || - // If owner changes but we have an unchanged function ref, don't update refs - typeof nextRef === 'string' && nextOwner !== prevOwner; -}; - -ReactRef.detachRefs = function (instance, element) { - if (element === null || typeof element !== 'object') { - return; - } - var ref = element.ref; - if (ref != null) { - detachRef(ref, instance, element._owner); - } -}; - -module.exports = ReactRef; - -/***/ }), -/* 281 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var PooledClass = __webpack_require__(20); -var Transaction = __webpack_require__(38); -var ReactInstrumentation = __webpack_require__(10); -var ReactServerUpdateQueue = __webpack_require__(282); - -/** - * Executed within the scope of the `Transaction` instance. Consider these as - * being member methods, but with an implied ordering while being isolated from - * each other. - */ -var TRANSACTION_WRAPPERS = []; - -if (process.env.NODE_ENV !== 'production') { - TRANSACTION_WRAPPERS.push({ - initialize: ReactInstrumentation.debugTool.onBeginFlush, - close: ReactInstrumentation.debugTool.onEndFlush - }); -} - -var noopCallbackQueue = { - enqueue: function () {} -}; - -/** - * @class ReactServerRenderingTransaction - * @param {boolean} renderToStaticMarkup - */ -function ReactServerRenderingTransaction(renderToStaticMarkup) { - this.reinitializeTransaction(); - this.renderToStaticMarkup = renderToStaticMarkup; - this.useCreateElement = false; - this.updateQueue = new ReactServerUpdateQueue(this); -} - -var Mixin = { - /** - * @see Transaction - * @abstract - * @final - * @return {array} Empty list of operation wrap procedures. - */ - getTransactionWrappers: function () { - return TRANSACTION_WRAPPERS; - }, - - /** - * @return {object} The queue to collect `onDOMReady` callbacks with. - */ - getReactMountReady: function () { - return noopCallbackQueue; - }, - - /** - * @return {object} The queue to collect React async events. - */ - getUpdateQueue: function () { - return this.updateQueue; - }, - - /** - * `PooledClass` looks for this, and will invoke this before allowing this - * instance to be reused. - */ - destructor: function () {}, - - checkpoint: function () {}, - - rollback: function () {} -}; - -_assign(ReactServerRenderingTransaction.prototype, Transaction, Mixin); - -PooledClass.addPoolingTo(ReactServerRenderingTransaction); - -module.exports = ReactServerRenderingTransaction; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 282 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var ReactUpdateQueue = __webpack_require__(53); - -var warning = __webpack_require__(3); - -function warnNoop(publicInstance, callerName) { - if (process.env.NODE_ENV !== 'production') { - var constructor = publicInstance.constructor; - process.env.NODE_ENV !== 'production' ? warning(false, '%s(...): Can only update a mounting component. ' + 'This usually means you called %s() outside componentWillMount() on the server. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, constructor && (constructor.displayName || constructor.name) || 'ReactClass') : void 0; - } -} - -/** - * This is the update queue used for server rendering. - * It delegates to ReactUpdateQueue while server rendering is in progress and - * switches to ReactNoopUpdateQueue after the transaction has completed. - * @class ReactServerUpdateQueue - * @param {Transaction} transaction - */ - -var ReactServerUpdateQueue = function () { - function ReactServerUpdateQueue(transaction) { - _classCallCheck(this, ReactServerUpdateQueue); - - this.transaction = transaction; - } - - /** - * Checks whether or not this composite component is mounted. - * @param {ReactClass} publicInstance The instance we want to test. - * @return {boolean} True if mounted, false otherwise. - * @protected - * @final - */ - - - ReactServerUpdateQueue.prototype.isMounted = function isMounted(publicInstance) { - return false; - }; - - /** - * Enqueue a callback that will be executed after all the pending updates - * have processed. - * - * @param {ReactClass} publicInstance The instance to use as `this` context. - * @param {?function} callback Called after state is updated. - * @internal - */ - - - ReactServerUpdateQueue.prototype.enqueueCallback = function enqueueCallback(publicInstance, callback, callerName) { - if (this.transaction.isInTransaction()) { - ReactUpdateQueue.enqueueCallback(publicInstance, callback, callerName); - } - }; - - /** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldComponentUpdate`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @internal - */ - - - ReactServerUpdateQueue.prototype.enqueueForceUpdate = function enqueueForceUpdate(publicInstance) { - if (this.transaction.isInTransaction()) { - ReactUpdateQueue.enqueueForceUpdate(publicInstance); - } else { - warnNoop(publicInstance, 'forceUpdate'); - } - }; - - /** - * Replaces all of the state. Always use this or `setState` to mutate state. - * You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object|function} completeState Next state. - * @internal - */ - - - ReactServerUpdateQueue.prototype.enqueueReplaceState = function enqueueReplaceState(publicInstance, completeState) { - if (this.transaction.isInTransaction()) { - ReactUpdateQueue.enqueueReplaceState(publicInstance, completeState); - } else { - warnNoop(publicInstance, 'replaceState'); - } - }; - - /** - * Sets a subset of the state. This only exists because _pendingState is - * internal. This provides a merging strategy that is not available to deep - * properties which is confusing. TODO: Expose pendingState or don't use it - * during the merge. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object|function} partialState Next partial state to be merged with state. - * @internal - */ - - - ReactServerUpdateQueue.prototype.enqueueSetState = function enqueueSetState(publicInstance, partialState) { - if (this.transaction.isInTransaction()) { - ReactUpdateQueue.enqueueSetState(publicInstance, partialState); - } else { - warnNoop(publicInstance, 'setState'); - } - }; - - return ReactServerUpdateQueue; -}(); - -module.exports = ReactServerUpdateQueue; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 283 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -module.exports = '15.4.2'; - -/***/ }), -/* 284 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var NS = { - xlink: 'http://www.w3.org/1999/xlink', - xml: 'http://www.w3.org/XML/1998/namespace' -}; - -// We use attributes for everything SVG so let's avoid some duplication and run -// code instead. -// The following are all specified in the HTML config already so we exclude here. -// - class (as className) -// - color -// - height -// - id -// - lang -// - max -// - media -// - method -// - min -// - name -// - style -// - target -// - type -// - width -var ATTRS = { - accentHeight: 'accent-height', - accumulate: 0, - additive: 0, - alignmentBaseline: 'alignment-baseline', - allowReorder: 'allowReorder', - alphabetic: 0, - amplitude: 0, - arabicForm: 'arabic-form', - ascent: 0, - attributeName: 'attributeName', - attributeType: 'attributeType', - autoReverse: 'autoReverse', - azimuth: 0, - baseFrequency: 'baseFrequency', - baseProfile: 'baseProfile', - baselineShift: 'baseline-shift', - bbox: 0, - begin: 0, - bias: 0, - by: 0, - calcMode: 'calcMode', - capHeight: 'cap-height', - clip: 0, - clipPath: 'clip-path', - clipRule: 'clip-rule', - clipPathUnits: 'clipPathUnits', - colorInterpolation: 'color-interpolation', - colorInterpolationFilters: 'color-interpolation-filters', - colorProfile: 'color-profile', - colorRendering: 'color-rendering', - contentScriptType: 'contentScriptType', - contentStyleType: 'contentStyleType', - cursor: 0, - cx: 0, - cy: 0, - d: 0, - decelerate: 0, - descent: 0, - diffuseConstant: 'diffuseConstant', - direction: 0, - display: 0, - divisor: 0, - dominantBaseline: 'dominant-baseline', - dur: 0, - dx: 0, - dy: 0, - edgeMode: 'edgeMode', - elevation: 0, - enableBackground: 'enable-background', - end: 0, - exponent: 0, - externalResourcesRequired: 'externalResourcesRequired', - fill: 0, - fillOpacity: 'fill-opacity', - fillRule: 'fill-rule', - filter: 0, - filterRes: 'filterRes', - filterUnits: 'filterUnits', - floodColor: 'flood-color', - floodOpacity: 'flood-opacity', - focusable: 0, - fontFamily: 'font-family', - fontSize: 'font-size', - fontSizeAdjust: 'font-size-adjust', - fontStretch: 'font-stretch', - fontStyle: 'font-style', - fontVariant: 'font-variant', - fontWeight: 'font-weight', - format: 0, - from: 0, - fx: 0, - fy: 0, - g1: 0, - g2: 0, - glyphName: 'glyph-name', - glyphOrientationHorizontal: 'glyph-orientation-horizontal', - glyphOrientationVertical: 'glyph-orientation-vertical', - glyphRef: 'glyphRef', - gradientTransform: 'gradientTransform', - gradientUnits: 'gradientUnits', - hanging: 0, - horizAdvX: 'horiz-adv-x', - horizOriginX: 'horiz-origin-x', - ideographic: 0, - imageRendering: 'image-rendering', - 'in': 0, - in2: 0, - intercept: 0, - k: 0, - k1: 0, - k2: 0, - k3: 0, - k4: 0, - kernelMatrix: 'kernelMatrix', - kernelUnitLength: 'kernelUnitLength', - kerning: 0, - keyPoints: 'keyPoints', - keySplines: 'keySplines', - keyTimes: 'keyTimes', - lengthAdjust: 'lengthAdjust', - letterSpacing: 'letter-spacing', - lightingColor: 'lighting-color', - limitingConeAngle: 'limitingConeAngle', - local: 0, - markerEnd: 'marker-end', - markerMid: 'marker-mid', - markerStart: 'marker-start', - markerHeight: 'markerHeight', - markerUnits: 'markerUnits', - markerWidth: 'markerWidth', - mask: 0, - maskContentUnits: 'maskContentUnits', - maskUnits: 'maskUnits', - mathematical: 0, - mode: 0, - numOctaves: 'numOctaves', - offset: 0, - opacity: 0, - operator: 0, - order: 0, - orient: 0, - orientation: 0, - origin: 0, - overflow: 0, - overlinePosition: 'overline-position', - overlineThickness: 'overline-thickness', - paintOrder: 'paint-order', - panose1: 'panose-1', - pathLength: 'pathLength', - patternContentUnits: 'patternContentUnits', - patternTransform: 'patternTransform', - patternUnits: 'patternUnits', - pointerEvents: 'pointer-events', - points: 0, - pointsAtX: 'pointsAtX', - pointsAtY: 'pointsAtY', - pointsAtZ: 'pointsAtZ', - preserveAlpha: 'preserveAlpha', - preserveAspectRatio: 'preserveAspectRatio', - primitiveUnits: 'primitiveUnits', - r: 0, - radius: 0, - refX: 'refX', - refY: 'refY', - renderingIntent: 'rendering-intent', - repeatCount: 'repeatCount', - repeatDur: 'repeatDur', - requiredExtensions: 'requiredExtensions', - requiredFeatures: 'requiredFeatures', - restart: 0, - result: 0, - rotate: 0, - rx: 0, - ry: 0, - scale: 0, - seed: 0, - shapeRendering: 'shape-rendering', - slope: 0, - spacing: 0, - specularConstant: 'specularConstant', - specularExponent: 'specularExponent', - speed: 0, - spreadMethod: 'spreadMethod', - startOffset: 'startOffset', - stdDeviation: 'stdDeviation', - stemh: 0, - stemv: 0, - stitchTiles: 'stitchTiles', - stopColor: 'stop-color', - stopOpacity: 'stop-opacity', - strikethroughPosition: 'strikethrough-position', - strikethroughThickness: 'strikethrough-thickness', - string: 0, - stroke: 0, - strokeDasharray: 'stroke-dasharray', - strokeDashoffset: 'stroke-dashoffset', - strokeLinecap: 'stroke-linecap', - strokeLinejoin: 'stroke-linejoin', - strokeMiterlimit: 'stroke-miterlimit', - strokeOpacity: 'stroke-opacity', - strokeWidth: 'stroke-width', - surfaceScale: 'surfaceScale', - systemLanguage: 'systemLanguage', - tableValues: 'tableValues', - targetX: 'targetX', - targetY: 'targetY', - textAnchor: 'text-anchor', - textDecoration: 'text-decoration', - textRendering: 'text-rendering', - textLength: 'textLength', - to: 0, - transform: 0, - u1: 0, - u2: 0, - underlinePosition: 'underline-position', - underlineThickness: 'underline-thickness', - unicode: 0, - unicodeBidi: 'unicode-bidi', - unicodeRange: 'unicode-range', - unitsPerEm: 'units-per-em', - vAlphabetic: 'v-alphabetic', - vHanging: 'v-hanging', - vIdeographic: 'v-ideographic', - vMathematical: 'v-mathematical', - values: 0, - vectorEffect: 'vector-effect', - version: 0, - vertAdvY: 'vert-adv-y', - vertOriginX: 'vert-origin-x', - vertOriginY: 'vert-origin-y', - viewBox: 'viewBox', - viewTarget: 'viewTarget', - visibility: 0, - widths: 0, - wordSpacing: 'word-spacing', - writingMode: 'writing-mode', - x: 0, - xHeight: 'x-height', - x1: 0, - x2: 0, - xChannelSelector: 'xChannelSelector', - xlinkActuate: 'xlink:actuate', - xlinkArcrole: 'xlink:arcrole', - xlinkHref: 'xlink:href', - xlinkRole: 'xlink:role', - xlinkShow: 'xlink:show', - xlinkTitle: 'xlink:title', - xlinkType: 'xlink:type', - xmlBase: 'xml:base', - xmlns: 0, - xmlnsXlink: 'xmlns:xlink', - xmlLang: 'xml:lang', - xmlSpace: 'xml:space', - y: 0, - y1: 0, - y2: 0, - yChannelSelector: 'yChannelSelector', - z: 0, - zoomAndPan: 'zoomAndPan' -}; - -var SVGDOMPropertyConfig = { - Properties: {}, - DOMAttributeNamespaces: { - xlinkActuate: NS.xlink, - xlinkArcrole: NS.xlink, - xlinkHref: NS.xlink, - xlinkRole: NS.xlink, - xlinkShow: NS.xlink, - xlinkTitle: NS.xlink, - xlinkType: NS.xlink, - xmlBase: NS.xml, - xmlLang: NS.xml, - xmlSpace: NS.xml - }, - DOMAttributeNames: {} -}; - -Object.keys(ATTRS).forEach(function (key) { - SVGDOMPropertyConfig.Properties[key] = 0; - if (ATTRS[key]) { - SVGDOMPropertyConfig.DOMAttributeNames[key] = ATTRS[key]; - } -}); - -module.exports = SVGDOMPropertyConfig; - -/***/ }), -/* 285 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var EventPropagators = __webpack_require__(31); -var ExecutionEnvironment = __webpack_require__(8); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactInputSelection = __webpack_require__(86); -var SyntheticEvent = __webpack_require__(17); - -var getActiveElement = __webpack_require__(74); -var isTextInputElement = __webpack_require__(96); -var shallowEqual = __webpack_require__(42); - -var skipSelectionChangeEvent = ExecutionEnvironment.canUseDOM && 'documentMode' in document && document.documentMode <= 11; - -var eventTypes = { - select: { - phasedRegistrationNames: { - bubbled: 'onSelect', - captured: 'onSelectCapture' - }, - dependencies: ['topBlur', 'topContextMenu', 'topFocus', 'topKeyDown', 'topKeyUp', 'topMouseDown', 'topMouseUp', 'topSelectionChange'] - } -}; - -var activeElement = null; -var activeElementInst = null; -var lastSelection = null; -var mouseDown = false; - -// Track whether a listener exists for this plugin. If none exist, we do -// not extract events. See #3639. -var hasListener = false; - -/** - * Get an object which is a unique representation of the current selection. - * - * The return value will not be consistent across nodes or browsers, but - * two identical selections on the same node will return identical objects. - * - * @param {DOMElement} node - * @return {object} - */ -function getSelection(node) { - if ('selectionStart' in node && ReactInputSelection.hasSelectionCapabilities(node)) { - return { - start: node.selectionStart, - end: node.selectionEnd - }; - } else if (window.getSelection) { - var selection = window.getSelection(); - return { - anchorNode: selection.anchorNode, - anchorOffset: selection.anchorOffset, - focusNode: selection.focusNode, - focusOffset: selection.focusOffset - }; - } else if (document.selection) { - var range = document.selection.createRange(); - return { - parentElement: range.parentElement(), - text: range.text, - top: range.boundingTop, - left: range.boundingLeft - }; - } -} - -/** - * Poll selection to see whether it's changed. - * - * @param {object} nativeEvent - * @return {?SyntheticEvent} - */ -function constructSelectEvent(nativeEvent, nativeEventTarget) { - // Ensure we have the right element, and that the user is not dragging a - // selection (this matches native `select` event behavior). In HTML5, select - // fires only on input and textarea thus if there's no focused element we - // won't dispatch. - if (mouseDown || activeElement == null || activeElement !== getActiveElement()) { - return null; - } - - // Only fire when selection has actually changed. - var currentSelection = getSelection(activeElement); - if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { - lastSelection = currentSelection; - - var syntheticEvent = SyntheticEvent.getPooled(eventTypes.select, activeElementInst, nativeEvent, nativeEventTarget); - - syntheticEvent.type = 'select'; - syntheticEvent.target = activeElement; - - EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent); - - return syntheticEvent; - } - - return null; -} - -/** - * This plugin creates an `onSelect` event that normalizes select events - * across form elements. - * - * Supported elements are: - * - input (see `isTextInputElement`) - * - textarea - * - contentEditable - * - * This differs from native browser implementations in the following ways: - * - Fires on contentEditable fields as well as inputs. - * - Fires for collapsed selection. - * - Fires after user input. - */ -var SelectEventPlugin = { - - eventTypes: eventTypes, - - extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - if (!hasListener) { - return null; - } - - var targetNode = targetInst ? ReactDOMComponentTree.getNodeFromInstance(targetInst) : window; - - switch (topLevelType) { - // Track the input node that has focus. - case 'topFocus': - if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') { - activeElement = targetNode; - activeElementInst = targetInst; - lastSelection = null; - } - break; - case 'topBlur': - activeElement = null; - activeElementInst = null; - lastSelection = null; - break; - - // Don't fire the event while the user is dragging. This matches the - // semantics of the native select event. - case 'topMouseDown': - mouseDown = true; - break; - case 'topContextMenu': - case 'topMouseUp': - mouseDown = false; - return constructSelectEvent(nativeEvent, nativeEventTarget); - - // Chrome and IE fire non-standard event when selection is changed (and - // sometimes when it hasn't). IE's event fires out of order with respect - // to key and input events on deletion, so we discard it. - // - // Firefox doesn't support selectionchange, so check selection status - // after each key entry. The selection changes after keydown and before - // keyup, but we check on keydown as well in the case of holding down a - // key, when multiple keydown events are fired but only one keyup is. - // This is also our approach for IE handling, for the reason above. - case 'topSelectionChange': - if (skipSelectionChangeEvent) { - break; - } - // falls through - case 'topKeyDown': - case 'topKeyUp': - return constructSelectEvent(nativeEvent, nativeEventTarget); - } - - return null; - }, - - didPutListener: function (inst, registrationName, listener) { - if (registrationName === 'onSelect') { - hasListener = true; - } - } -}; - -module.exports = SelectEventPlugin; - -/***/ }), -/* 286 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var EventListener = __webpack_require__(72); -var EventPropagators = __webpack_require__(31); -var ReactDOMComponentTree = __webpack_require__(7); -var SyntheticAnimationEvent = __webpack_require__(287); -var SyntheticClipboardEvent = __webpack_require__(288); -var SyntheticEvent = __webpack_require__(17); -var SyntheticFocusEvent = __webpack_require__(291); -var SyntheticKeyboardEvent = __webpack_require__(293); -var SyntheticMouseEvent = __webpack_require__(37); -var SyntheticDragEvent = __webpack_require__(290); -var SyntheticTouchEvent = __webpack_require__(294); -var SyntheticTransitionEvent = __webpack_require__(295); -var SyntheticUIEvent = __webpack_require__(33); -var SyntheticWheelEvent = __webpack_require__(296); - -var emptyFunction = __webpack_require__(12); -var getEventCharCode = __webpack_require__(55); -var invariant = __webpack_require__(2); - -/** - * Turns - * ['abort', ...] - * into - * eventTypes = { - * 'abort': { - * phasedRegistrationNames: { - * bubbled: 'onAbort', - * captured: 'onAbortCapture', - * }, - * dependencies: ['topAbort'], - * }, - * ... - * }; - * topLevelEventsToDispatchConfig = { - * 'topAbort': { sameConfig } - * }; - */ -var eventTypes = {}; -var topLevelEventsToDispatchConfig = {}; -['abort', 'animationEnd', 'animationIteration', 'animationStart', 'blur', 'canPlay', 'canPlayThrough', 'click', 'contextMenu', 'copy', 'cut', 'doubleClick', 'drag', 'dragEnd', 'dragEnter', 'dragExit', 'dragLeave', 'dragOver', 'dragStart', 'drop', 'durationChange', 'emptied', 'encrypted', 'ended', 'error', 'focus', 'input', 'invalid', 'keyDown', 'keyPress', 'keyUp', 'load', 'loadedData', 'loadedMetadata', 'loadStart', 'mouseDown', 'mouseMove', 'mouseOut', 'mouseOver', 'mouseUp', 'paste', 'pause', 'play', 'playing', 'progress', 'rateChange', 'reset', 'scroll', 'seeked', 'seeking', 'stalled', 'submit', 'suspend', 'timeUpdate', 'touchCancel', 'touchEnd', 'touchMove', 'touchStart', 'transitionEnd', 'volumeChange', 'waiting', 'wheel'].forEach(function (event) { - var capitalizedEvent = event[0].toUpperCase() + event.slice(1); - var onEvent = 'on' + capitalizedEvent; - var topEvent = 'top' + capitalizedEvent; - - var type = { - phasedRegistrationNames: { - bubbled: onEvent, - captured: onEvent + 'Capture' - }, - dependencies: [topEvent] - }; - eventTypes[event] = type; - topLevelEventsToDispatchConfig[topEvent] = type; -}); - -var onClickListeners = {}; - -function getDictionaryKey(inst) { - // Prevents V8 performance issue: - // https://github.com/facebook/react/pull/7232 - return '.' + inst._rootNodeID; -} - -function isInteractive(tag) { - return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; -} - -var SimpleEventPlugin = { - - eventTypes: eventTypes, - - extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType]; - if (!dispatchConfig) { - return null; - } - var EventConstructor; - switch (topLevelType) { - case 'topAbort': - case 'topCanPlay': - case 'topCanPlayThrough': - case 'topDurationChange': - case 'topEmptied': - case 'topEncrypted': - case 'topEnded': - case 'topError': - case 'topInput': - case 'topInvalid': - case 'topLoad': - case 'topLoadedData': - case 'topLoadedMetadata': - case 'topLoadStart': - case 'topPause': - case 'topPlay': - case 'topPlaying': - case 'topProgress': - case 'topRateChange': - case 'topReset': - case 'topSeeked': - case 'topSeeking': - case 'topStalled': - case 'topSubmit': - case 'topSuspend': - case 'topTimeUpdate': - case 'topVolumeChange': - case 'topWaiting': - // HTML Events - // @see http://www.w3.org/TR/html5/index.html#events-0 - EventConstructor = SyntheticEvent; - break; - case 'topKeyPress': - // Firefox creates a keypress event for function keys too. This removes - // the unwanted keypress events. Enter is however both printable and - // non-printable. One would expect Tab to be as well (but it isn't). - if (getEventCharCode(nativeEvent) === 0) { - return null; - } - /* falls through */ - case 'topKeyDown': - case 'topKeyUp': - EventConstructor = SyntheticKeyboardEvent; - break; - case 'topBlur': - case 'topFocus': - EventConstructor = SyntheticFocusEvent; - break; - case 'topClick': - // Firefox creates a click event on right mouse clicks. This removes the - // unwanted click events. - if (nativeEvent.button === 2) { - return null; - } - /* falls through */ - case 'topDoubleClick': - case 'topMouseDown': - case 'topMouseMove': - case 'topMouseUp': - // TODO: Disabled elements should not respond to mouse events - /* falls through */ - case 'topMouseOut': - case 'topMouseOver': - case 'topContextMenu': - EventConstructor = SyntheticMouseEvent; - break; - case 'topDrag': - case 'topDragEnd': - case 'topDragEnter': - case 'topDragExit': - case 'topDragLeave': - case 'topDragOver': - case 'topDragStart': - case 'topDrop': - EventConstructor = SyntheticDragEvent; - break; - case 'topTouchCancel': - case 'topTouchEnd': - case 'topTouchMove': - case 'topTouchStart': - EventConstructor = SyntheticTouchEvent; - break; - case 'topAnimationEnd': - case 'topAnimationIteration': - case 'topAnimationStart': - EventConstructor = SyntheticAnimationEvent; - break; - case 'topTransitionEnd': - EventConstructor = SyntheticTransitionEvent; - break; - case 'topScroll': - EventConstructor = SyntheticUIEvent; - break; - case 'topWheel': - EventConstructor = SyntheticWheelEvent; - break; - case 'topCopy': - case 'topCut': - case 'topPaste': - EventConstructor = SyntheticClipboardEvent; - break; - } - !EventConstructor ? process.env.NODE_ENV !== 'production' ? invariant(false, 'SimpleEventPlugin: Unhandled event type, `%s`.', topLevelType) : _prodInvariant('86', topLevelType) : void 0; - var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget); - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - }, - - didPutListener: function (inst, registrationName, listener) { - // Mobile Safari does not fire properly bubble click events on - // non-interactive elements, which means delegated click listeners do not - // fire. The workaround for this bug involves attaching an empty click - // listener on the target node. - // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html - if (registrationName === 'onClick' && !isInteractive(inst._tag)) { - var key = getDictionaryKey(inst); - var node = ReactDOMComponentTree.getNodeFromInstance(inst); - if (!onClickListeners[key]) { - onClickListeners[key] = EventListener.listen(node, 'click', emptyFunction); - } - } - }, - - willDeleteListener: function (inst, registrationName) { - if (registrationName === 'onClick' && !isInteractive(inst._tag)) { - var key = getDictionaryKey(inst); - onClickListeners[key].remove(); - delete onClickListeners[key]; - } - } - -}; - -module.exports = SimpleEventPlugin; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 287 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticEvent = __webpack_require__(17); - -/** - * @interface Event - * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface - * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent - */ -var AnimationEventInterface = { - animationName: null, - elapsedTime: null, - pseudoElement: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticEvent} - */ -function SyntheticAnimationEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticEvent.augmentClass(SyntheticAnimationEvent, AnimationEventInterface); - -module.exports = SyntheticAnimationEvent; - -/***/ }), -/* 288 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticEvent = __webpack_require__(17); - -/** - * @interface Event - * @see http://www.w3.org/TR/clipboard-apis/ - */ -var ClipboardEventInterface = { - clipboardData: function (event) { - return 'clipboardData' in event ? event.clipboardData : window.clipboardData; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface); - -module.exports = SyntheticClipboardEvent; - -/***/ }), -/* 289 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticEvent = __webpack_require__(17); - -/** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents - */ -var CompositionEventInterface = { - data: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticCompositionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticEvent.augmentClass(SyntheticCompositionEvent, CompositionEventInterface); - -module.exports = SyntheticCompositionEvent; - -/***/ }), -/* 290 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticMouseEvent = __webpack_require__(37); - -/** - * @interface DragEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var DragEventInterface = { - dataTransfer: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface); - -module.exports = SyntheticDragEvent; - -/***/ }), -/* 291 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticUIEvent = __webpack_require__(33); - -/** - * @interface FocusEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var FocusEventInterface = { - relatedTarget: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface); - -module.exports = SyntheticFocusEvent; - -/***/ }), -/* 292 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticEvent = __webpack_require__(17); - -/** - * @interface Event - * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105 - * /#events-inputevents - */ -var InputEventInterface = { - data: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticInputEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticEvent.augmentClass(SyntheticInputEvent, InputEventInterface); - -module.exports = SyntheticInputEvent; - -/***/ }), -/* 293 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticUIEvent = __webpack_require__(33); - -var getEventCharCode = __webpack_require__(55); -var getEventKey = __webpack_require__(302); -var getEventModifierState = __webpack_require__(56); - -/** - * @interface KeyboardEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var KeyboardEventInterface = { - key: getEventKey, - location: null, - ctrlKey: null, - shiftKey: null, - altKey: null, - metaKey: null, - repeat: null, - locale: null, - getModifierState: getEventModifierState, - // Legacy Interface - charCode: function (event) { - // `charCode` is the result of a KeyPress event and represents the value of - // the actual printable character. - - // KeyPress is deprecated, but its replacement is not yet final and not - // implemented in any major browser. Only KeyPress has charCode. - if (event.type === 'keypress') { - return getEventCharCode(event); - } - return 0; - }, - keyCode: function (event) { - // `keyCode` is the result of a KeyDown/Up event and represents the value of - // physical keyboard key. - - // The actual meaning of the value depends on the users' keyboard layout - // which cannot be detected. Assuming that it is a US keyboard layout - // provides a surprisingly accurate mapping for US and European users. - // Due to this, it is left to the user to implement at this time. - if (event.type === 'keydown' || event.type === 'keyup') { - return event.keyCode; - } - return 0; - }, - which: function (event) { - // `which` is an alias for either `keyCode` or `charCode` depending on the - // type of the event. - if (event.type === 'keypress') { - return getEventCharCode(event); - } - if (event.type === 'keydown' || event.type === 'keyup') { - return event.keyCode; - } - return 0; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface); - -module.exports = SyntheticKeyboardEvent; - -/***/ }), -/* 294 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticUIEvent = __webpack_require__(33); - -var getEventModifierState = __webpack_require__(56); - -/** - * @interface TouchEvent - * @see http://www.w3.org/TR/touch-events/ - */ -var TouchEventInterface = { - touches: null, - targetTouches: null, - changedTouches: null, - altKey: null, - metaKey: null, - ctrlKey: null, - shiftKey: null, - getModifierState: getEventModifierState -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface); - -module.exports = SyntheticTouchEvent; - -/***/ }), -/* 295 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticEvent = __webpack_require__(17); - -/** - * @interface Event - * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events- - * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent - */ -var TransitionEventInterface = { - propertyName: null, - elapsedTime: null, - pseudoElement: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticEvent} - */ -function SyntheticTransitionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticEvent.augmentClass(SyntheticTransitionEvent, TransitionEventInterface); - -module.exports = SyntheticTransitionEvent; - -/***/ }), -/* 296 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticMouseEvent = __webpack_require__(37); - -/** - * @interface WheelEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var WheelEventInterface = { - deltaX: function (event) { - return 'deltaX' in event ? event.deltaX : - // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). - 'wheelDeltaX' in event ? -event.wheelDeltaX : 0; - }, - deltaY: function (event) { - return 'deltaY' in event ? event.deltaY : - // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). - 'wheelDeltaY' in event ? -event.wheelDeltaY : - // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). - 'wheelDelta' in event ? -event.wheelDelta : 0; - }, - deltaZ: null, - - // Browsers without "deltaMode" is reporting in raw wheel delta where one - // notch on the scroll is always +/- 120, roughly equivalent to pixels. - // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or - // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size. - deltaMode: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticMouseEvent} - */ -function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface); - -module.exports = SyntheticWheelEvent; - -/***/ }), -/* 297 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var MOD = 65521; - -// adler32 is not cryptographically strong, and is only used to sanity check that -// markup generated on the server matches the markup generated on the client. -// This implementation (a modified version of the SheetJS version) has been optimized -// for our use case, at the expense of conforming to the adler32 specification -// for non-ascii inputs. -function adler32(data) { - var a = 1; - var b = 0; - var i = 0; - var l = data.length; - var m = l & ~0x3; - while (i < m) { - var n = Math.min(i + 4096, m); - for (; i < n; i += 4) { - b += (a += data.charCodeAt(i)) + (a += data.charCodeAt(i + 1)) + (a += data.charCodeAt(i + 2)) + (a += data.charCodeAt(i + 3)); - } - a %= MOD; - b %= MOD; - } - for (; i < l; i++) { - b += a += data.charCodeAt(i); - } - a %= MOD; - b %= MOD; - return a | b << 16; -} - -module.exports = adler32; - -/***/ }), -/* 298 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var ReactPropTypeLocationNames = __webpack_require__(278); -var ReactPropTypesSecret = __webpack_require__(89); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -var ReactComponentTreeHook; - -if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'test') { - // Temporary hack. - // Inline requires don't work well with Jest: - // https://github.com/facebook/react/issues/7240 - // Remove the inline requires when we don't need them anymore: - // https://github.com/facebook/react/pull/7178 - ReactComponentTreeHook = __webpack_require__(9); -} - -var loggedTypeFailures = {}; - -/** - * Assert that the values match with the type specs. - * Error messages are memorized and will only be shown once. - * - * @param {object} typeSpecs Map of name to a ReactPropType - * @param {object} values Runtime values that need to be type-checked - * @param {string} location e.g. "prop", "context", "child context" - * @param {string} componentName Name of the component for error messages. - * @param {?object} element The React element that is being type-checked - * @param {?number} debugID The React component instance that is being type-checked - * @private - */ -function checkReactTypeSpec(typeSpecs, values, location, componentName, element, debugID) { - for (var typeSpecName in typeSpecs) { - if (typeSpecs.hasOwnProperty(typeSpecName)) { - var error; - // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - !(typeof typeSpecs[typeSpecName] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : _prodInvariant('84', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : void 0; - error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); - } catch (ex) { - error = ex; - } - process.env.NODE_ENV !== 'production' ? warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName, typeof error) : void 0; - if (error instanceof Error && !(error.message in loggedTypeFailures)) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error.message] = true; - - var componentStackInfo = ''; - - if (process.env.NODE_ENV !== 'production') { - if (!ReactComponentTreeHook) { - ReactComponentTreeHook = __webpack_require__(9); - } - if (debugID !== null) { - componentStackInfo = ReactComponentTreeHook.getStackAddendumByID(debugID); - } else if (element !== null) { - componentStackInfo = ReactComponentTreeHook.getCurrentStackAddendum(element); - } - } - - process.env.NODE_ENV !== 'production' ? warning(false, 'Failed %s type: %s%s', location, error.message, componentStackInfo) : void 0; - } - } - } -} - -module.exports = checkReactTypeSpec; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 299 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var CSSProperty = __webpack_require__(78); -var warning = __webpack_require__(3); - -var isUnitlessNumber = CSSProperty.isUnitlessNumber; -var styleWarnings = {}; - -/** - * Convert a value into the proper css writable value. The style name `name` - * should be logical (no hyphens), as specified - * in `CSSProperty.isUnitlessNumber`. - * - * @param {string} name CSS property name such as `topMargin`. - * @param {*} value CSS property value such as `10px`. - * @param {ReactDOMComponent} component - * @return {string} Normalized style value with dimensions applied. - */ -function dangerousStyleValue(name, value, component) { - // Note that we've removed escapeTextForBrowser() calls here since the - // whole string will be escaped when the attribute is injected into - // the markup. If you provide unsafe user data here they can inject - // arbitrary CSS which may be problematic (I couldn't repro this): - // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet - // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ - // This is not an XSS hole but instead a potential CSS injection issue - // which has lead to a greater discussion about how we're going to - // trust URLs moving forward. See #2115901 - - var isEmpty = value == null || typeof value === 'boolean' || value === ''; - if (isEmpty) { - return ''; - } - - var isNonNumeric = isNaN(value); - if (isNonNumeric || value === 0 || isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) { - return '' + value; // cast to string - } - - if (typeof value === 'string') { - if (process.env.NODE_ENV !== 'production') { - // Allow '0' to pass through without warning. 0 is already special and - // doesn't require units, so we don't need to warn about it. - if (component && value !== '0') { - var owner = component._currentElement._owner; - var ownerName = owner ? owner.getName() : null; - if (ownerName && !styleWarnings[ownerName]) { - styleWarnings[ownerName] = {}; - } - var warned = false; - if (ownerName) { - var warnings = styleWarnings[ownerName]; - warned = warnings[name]; - if (!warned) { - warnings[name] = true; - } - } - if (!warned) { - process.env.NODE_ENV !== 'production' ? warning(false, 'a `%s` tag (owner: `%s`) was passed a numeric string value ' + 'for CSS property `%s` (value: `%s`) which will be treated ' + 'as a unitless number in a future version of React.', component._currentElement.type, ownerName || 'unknown', name, value) : void 0; - } - } - } - value = value.trim(); - } - return value + 'px'; -} - -module.exports = dangerousStyleValue; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 300 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var ReactCurrentOwner = __webpack_require__(15); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactInstanceMap = __webpack_require__(32); - -var getHostComponentFromComposite = __webpack_require__(93); -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -/** - * Returns the DOM node rendered by this element. - * - * See https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode - * - * @param {ReactComponent|DOMElement} componentOrElement - * @return {?DOMElement} The root node of this element. - */ -function findDOMNode(componentOrElement) { - if (process.env.NODE_ENV !== 'production') { - var owner = ReactCurrentOwner.current; - if (owner !== null) { - process.env.NODE_ENV !== 'production' ? warning(owner._warnedAboutRefsInRender, '%s is accessing findDOMNode inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : void 0; - owner._warnedAboutRefsInRender = true; - } - } - if (componentOrElement == null) { - return null; - } - if (componentOrElement.nodeType === 1) { - return componentOrElement; - } - - var inst = ReactInstanceMap.get(componentOrElement); - if (inst) { - inst = getHostComponentFromComposite(inst); - return inst ? ReactDOMComponentTree.getNodeFromInstance(inst) : null; - } - - if (typeof componentOrElement.render === 'function') { - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'findDOMNode was called on an unmounted component.') : _prodInvariant('44') : void 0; - } else { - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Element appears to be neither ReactComponent nor DOMNode (keys: %s)', Object.keys(componentOrElement)) : _prodInvariant('45', Object.keys(componentOrElement)) : void 0; - } -} - -module.exports = findDOMNode; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 301 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var KeyEscapeUtils = __webpack_require__(49); -var traverseAllChildren = __webpack_require__(98); -var warning = __webpack_require__(3); - -var ReactComponentTreeHook; - -if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'test') { - // Temporary hack. - // Inline requires don't work well with Jest: - // https://github.com/facebook/react/issues/7240 - // Remove the inline requires when we don't need them anymore: - // https://github.com/facebook/react/pull/7178 - ReactComponentTreeHook = __webpack_require__(9); -} - -/** - * @param {function} traverseContext Context passed through traversal. - * @param {?ReactComponent} child React child component. - * @param {!string} name String name of key path to child. - * @param {number=} selfDebugID Optional debugID of the current internal instance. - */ -function flattenSingleChildIntoContext(traverseContext, child, name, selfDebugID) { - // We found a component instance. - if (traverseContext && typeof traverseContext === 'object') { - var result = traverseContext; - var keyUnique = result[name] === undefined; - if (process.env.NODE_ENV !== 'production') { - if (!ReactComponentTreeHook) { - ReactComponentTreeHook = __webpack_require__(9); - } - if (!keyUnique) { - process.env.NODE_ENV !== 'production' ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0; - } - } - if (keyUnique && child != null) { - result[name] = child; - } - } -} - -/** - * Flattens children that are typically specified as `props.children`. Any null - * children will not be included in the resulting object. - * @return {!object} flattened children keyed by name. - */ -function flattenChildren(children, selfDebugID) { - if (children == null) { - return children; - } - var result = {}; - - if (process.env.NODE_ENV !== 'production') { - traverseAllChildren(children, function (traverseContext, child, name) { - return flattenSingleChildIntoContext(traverseContext, child, name, selfDebugID); - }, result); - } else { - traverseAllChildren(children, flattenSingleChildIntoContext, result); - } - return result; -} - -module.exports = flattenChildren; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 302 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var getEventCharCode = __webpack_require__(55); - -/** - * Normalization of deprecated HTML5 `key` values - * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names - */ -var normalizeKey = { - 'Esc': 'Escape', - 'Spacebar': ' ', - 'Left': 'ArrowLeft', - 'Up': 'ArrowUp', - 'Right': 'ArrowRight', - 'Down': 'ArrowDown', - 'Del': 'Delete', - 'Win': 'OS', - 'Menu': 'ContextMenu', - 'Apps': 'ContextMenu', - 'Scroll': 'ScrollLock', - 'MozPrintableKey': 'Unidentified' -}; - -/** - * Translation from legacy `keyCode` to HTML5 `key` - * Only special keys supported, all others depend on keyboard layout or browser - * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names - */ -var translateToKey = { - 8: 'Backspace', - 9: 'Tab', - 12: 'Clear', - 13: 'Enter', - 16: 'Shift', - 17: 'Control', - 18: 'Alt', - 19: 'Pause', - 20: 'CapsLock', - 27: 'Escape', - 32: ' ', - 33: 'PageUp', - 34: 'PageDown', - 35: 'End', - 36: 'Home', - 37: 'ArrowLeft', - 38: 'ArrowUp', - 39: 'ArrowRight', - 40: 'ArrowDown', - 45: 'Insert', - 46: 'Delete', - 112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6', - 118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12', - 144: 'NumLock', - 145: 'ScrollLock', - 224: 'Meta' -}; - -/** - * @param {object} nativeEvent Native browser event. - * @return {string} Normalized `key` property. - */ -function getEventKey(nativeEvent) { - if (nativeEvent.key) { - // Normalize inconsistent values reported by browsers due to - // implementations of a working draft specification. - - // FireFox implements `key` but returns `MozPrintableKey` for all - // printable characters (normalized to `Unidentified`), ignore it. - var key = normalizeKey[nativeEvent.key] || nativeEvent.key; - if (key !== 'Unidentified') { - return key; - } - } - - // Browser does not implement `key`, polyfill as much of it as we can. - if (nativeEvent.type === 'keypress') { - var charCode = getEventCharCode(nativeEvent); - - // The enter-key is technically both printable and non-printable and can - // thus be captured by `keypress`, no other non-printable key should. - return charCode === 13 ? 'Enter' : String.fromCharCode(charCode); - } - if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') { - // While user keyboard layout determines the actual meaning of each - // `keyCode` value, almost all function keys have a universal value. - return translateToKey[nativeEvent.keyCode] || 'Unidentified'; - } - return ''; -} - -module.exports = getEventKey; - -/***/ }), -/* 303 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/* global Symbol */ - -var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; -var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. - -/** - * Returns the iterator method function contained on the iterable object. - * - * Be sure to invoke the function with the iterable as context: - * - * var iteratorFn = getIteratorFn(myIterable); - * if (iteratorFn) { - * var iterator = iteratorFn.call(myIterable); - * ... - * } - * - * @param {?object} maybeIterable - * @return {?function} - */ -function getIteratorFn(maybeIterable) { - var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); - if (typeof iteratorFn === 'function') { - return iteratorFn; - } -} - -module.exports = getIteratorFn; - -/***/ }), -/* 304 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var nextDebugID = 1; - -function getNextDebugID() { - return nextDebugID++; -} - -module.exports = getNextDebugID; - -/***/ }), -/* 305 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * Given any node return the first leaf node without children. - * - * @param {DOMElement|DOMTextNode} node - * @return {DOMElement|DOMTextNode} - */ - -function getLeafNode(node) { - while (node && node.firstChild) { - node = node.firstChild; - } - return node; -} - -/** - * Get the next sibling within a container. This will walk up the - * DOM if a node's siblings have been exhausted. - * - * @param {DOMElement|DOMTextNode} node - * @return {?DOMElement|DOMTextNode} - */ -function getSiblingNode(node) { - while (node) { - if (node.nextSibling) { - return node.nextSibling; - } - node = node.parentNode; - } -} - -/** - * Get object describing the nodes which contain characters at offset. - * - * @param {DOMElement|DOMTextNode} root - * @param {number} offset - * @return {?object} - */ -function getNodeForCharacterOffset(root, offset) { - var node = getLeafNode(root); - var nodeStart = 0; - var nodeEnd = 0; - - while (node) { - if (node.nodeType === 3) { - nodeEnd = nodeStart + node.textContent.length; - - if (nodeStart <= offset && nodeEnd >= offset) { - return { - node: node, - offset: offset - nodeStart - }; - } - - nodeStart = nodeEnd; - } - - node = getLeafNode(getSiblingNode(node)); - } -} - -module.exports = getNodeForCharacterOffset; - -/***/ }), -/* 306 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ExecutionEnvironment = __webpack_require__(8); - -/** - * Generate a mapping of standard vendor prefixes using the defined style property and event name. - * - * @param {string} styleProp - * @param {string} eventName - * @returns {object} - */ -function makePrefixMap(styleProp, eventName) { - var prefixes = {}; - - prefixes[styleProp.toLowerCase()] = eventName.toLowerCase(); - prefixes['Webkit' + styleProp] = 'webkit' + eventName; - prefixes['Moz' + styleProp] = 'moz' + eventName; - prefixes['ms' + styleProp] = 'MS' + eventName; - prefixes['O' + styleProp] = 'o' + eventName.toLowerCase(); - - return prefixes; -} - -/** - * A list of event names to a configurable list of vendor prefixes. - */ -var vendorPrefixes = { - animationend: makePrefixMap('Animation', 'AnimationEnd'), - animationiteration: makePrefixMap('Animation', 'AnimationIteration'), - animationstart: makePrefixMap('Animation', 'AnimationStart'), - transitionend: makePrefixMap('Transition', 'TransitionEnd') -}; - -/** - * Event names that have already been detected and prefixed (if applicable). - */ -var prefixedEventNames = {}; - -/** - * Element to check for prefixes on. - */ -var style = {}; - -/** - * Bootstrap if a DOM exists. - */ -if (ExecutionEnvironment.canUseDOM) { - style = document.createElement('div').style; - - // On some platforms, in particular some releases of Android 4.x, - // the un-prefixed "animation" and "transition" properties are defined on the - // style object but the events that fire will still be prefixed, so we need - // to check if the un-prefixed events are usable, and if not remove them from the map. - if (!('AnimationEvent' in window)) { - delete vendorPrefixes.animationend.animation; - delete vendorPrefixes.animationiteration.animation; - delete vendorPrefixes.animationstart.animation; - } - - // Same as above - if (!('TransitionEvent' in window)) { - delete vendorPrefixes.transitionend.transition; - } -} - -/** - * Attempts to determine the correct vendor prefixed event name. - * - * @param {string} eventName - * @returns {string} - */ -function getVendorPrefixedEventName(eventName) { - if (prefixedEventNames[eventName]) { - return prefixedEventNames[eventName]; - } else if (!vendorPrefixes[eventName]) { - return eventName; - } - - var prefixMap = vendorPrefixes[eventName]; - - for (var styleProp in prefixMap) { - if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) { - return prefixedEventNames[eventName] = prefixMap[styleProp]; - } - } - - return ''; -} - -module.exports = getVendorPrefixedEventName; - -/***/ }), -/* 307 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var escapeTextContentForBrowser = __webpack_require__(39); - -/** - * Escapes attribute value to prevent scripting attacks. - * - * @param {*} value Value to escape. - * @return {string} An escaped string. - */ -function quoteAttributeValueForBrowser(value) { - return '"' + escapeTextContentForBrowser(value) + '"'; -} - -module.exports = quoteAttributeValueForBrowser; - -/***/ }), -/* 308 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactMount = __webpack_require__(87); - -module.exports = ReactMount.renderSubtreeIntoContainer; - -/***/ }), -/* 309 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _PropTypes = __webpack_require__(21); - -/** - * A mixin that adds the "history" instance variable to components. - */ -var History = { - - contextTypes: { - history: _PropTypes.history - }, - - componentWillMount: function componentWillMount() { - this.history = this.context.history; - } - -}; - -exports['default'] = History; -module.exports = exports['default']; - -/***/ }), -/* 310 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _Link = __webpack_require__(99); - -var _Link2 = _interopRequireDefault(_Link); - -/** - * An <IndexLink> is used to link to an <IndexRoute>. - */ - -var IndexLink = (function (_Component) { - _inherits(IndexLink, _Component); - - function IndexLink() { - _classCallCheck(this, IndexLink); - - _Component.apply(this, arguments); - } - - IndexLink.prototype.render = function render() { - return _react2['default'].createElement(_Link2['default'], _extends({}, this.props, { onlyActiveOnIndex: true })); - }; - - return IndexLink; -})(_react.Component); - -exports['default'] = IndexLink; -module.exports = exports['default']; - -/***/ }), -/* 311 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _Redirect = __webpack_require__(100); - -var _Redirect2 = _interopRequireDefault(_Redirect); - -var _PropTypes = __webpack_require__(21); - -var _React$PropTypes = _react2['default'].PropTypes; -var string = _React$PropTypes.string; -var object = _React$PropTypes.object; - -/** - * An <IndexRedirect> is used to redirect from an indexRoute. - */ - -var IndexRedirect = (function (_Component) { - _inherits(IndexRedirect, _Component); - - function IndexRedirect() { - _classCallCheck(this, IndexRedirect); - - _Component.apply(this, arguments); - } - - /* istanbul ignore next: sanity check */ - - IndexRedirect.prototype.render = function render() { - true ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, '<IndexRedirect> elements are for router configuration only and should not be rendered') : _invariant2['default'](false) : undefined; - }; - - return IndexRedirect; -})(_react.Component); - -IndexRedirect.propTypes = { - to: string.isRequired, - query: object, - state: object, - onEnter: _PropTypes.falsy, - children: _PropTypes.falsy -}; - -IndexRedirect.createRouteFromReactElement = function (element, parentRoute) { - /* istanbul ignore else: sanity check */ - if (parentRoute) { - parentRoute.indexRoute = _Redirect2['default'].createRouteFromReactElement(element); - } else { - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'An <IndexRedirect> does not make sense at the root of your route config') : undefined; - } -}; - -exports['default'] = IndexRedirect; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 312 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _RouteUtils = __webpack_require__(19); - -var _PropTypes = __webpack_require__(21); - -var func = _react2['default'].PropTypes.func; - -/** - * An <IndexRoute> is used to specify its parent's <Route indexRoute> in - * a JSX route config. - */ - -var IndexRoute = (function (_Component) { - _inherits(IndexRoute, _Component); - - function IndexRoute() { - _classCallCheck(this, IndexRoute); - - _Component.apply(this, arguments); - } - - /* istanbul ignore next: sanity check */ - - IndexRoute.prototype.render = function render() { - true ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, '<IndexRoute> elements are for router configuration only and should not be rendered') : _invariant2['default'](false) : undefined; - }; - - return IndexRoute; -})(_react.Component); - -IndexRoute.propTypes = { - path: _PropTypes.falsy, - component: _PropTypes.component, - components: _PropTypes.components, - getComponent: func, - getComponents: func -}; - -IndexRoute.createRouteFromReactElement = function (element, parentRoute) { - /* istanbul ignore else: sanity check */ - if (parentRoute) { - parentRoute.indexRoute = _RouteUtils.createRouteFromReactElement(element); - } else { - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'An <IndexRoute> does not make sense at the root of your route config') : undefined; - } -}; - -exports['default'] = IndexRoute; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 313 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var object = _react2['default'].PropTypes.object; - -/** - * The Lifecycle mixin adds the routerWillLeave lifecycle method to a - * component that may be used to cancel a transition or prompt the user - * for confirmation. - * - * On standard transitions, routerWillLeave receives a single argument: the - * location we're transitioning to. To cancel the transition, return false. - * To prompt the user for confirmation, return a prompt message (string). - * - * During the beforeunload event (assuming you're using the useBeforeUnload - * history enhancer), routerWillLeave does not receive a location object - * because it isn't possible for us to know the location we're transitioning - * to. In this case routerWillLeave must return a prompt message to prevent - * the user from closing the window/tab. - */ -var Lifecycle = { - - contextTypes: { - history: object.isRequired, - // Nested children receive the route as context, either - // set by the route component using the RouteContext mixin - // or by some other ancestor. - route: object - }, - - propTypes: { - // Route components receive the route object as a prop. - route: object - }, - - componentDidMount: function componentDidMount() { - !this.routerWillLeave ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'The Lifecycle mixin requires you to define a routerWillLeave method') : _invariant2['default'](false) : undefined; - - var route = this.props.route || this.context.route; - - !route ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'The Lifecycle mixin must be used on either a) a <Route component> or ' + 'b) a descendant of a <Route component> that uses the RouteContext mixin') : _invariant2['default'](false) : undefined; - - this._unlistenBeforeLeavingRoute = this.context.history.listenBeforeLeavingRoute(route, this.routerWillLeave); - }, - - componentWillUnmount: function componentWillUnmount() { - if (this._unlistenBeforeLeavingRoute) this._unlistenBeforeLeavingRoute(); - } - -}; - -exports['default'] = Lifecycle; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 314 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _RouteUtils = __webpack_require__(19); - -var _PropTypes = __webpack_require__(21); - -var _React$PropTypes = _react2['default'].PropTypes; -var string = _React$PropTypes.string; -var func = _React$PropTypes.func; - -/** - * A <Route> is used to declare which components are rendered to the - * page when the URL matches a given pattern. - * - * Routes are arranged in a nested tree structure. When a new URL is - * requested, the tree is searched depth-first to find a route whose - * path matches the URL. When one is found, all routes in the tree - * that lead to it are considered "active" and their components are - * rendered into the DOM, nested in the same order as in the tree. - */ - -var Route = (function (_Component) { - _inherits(Route, _Component); - - function Route() { - _classCallCheck(this, Route); - - _Component.apply(this, arguments); - } - - /* istanbul ignore next: sanity check */ - - Route.prototype.render = function render() { - true ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, '<Route> elements are for router configuration only and should not be rendered') : _invariant2['default'](false) : undefined; - }; - - return Route; -})(_react.Component); - -Route.createRouteFromReactElement = _RouteUtils.createRouteFromReactElement; - -Route.propTypes = { - path: string, - component: _PropTypes.component, - components: _PropTypes.components, - getComponent: func, - getComponents: func -}; - -exports['default'] = Route; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 315 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var object = _react2['default'].PropTypes.object; - -/** - * The RouteContext mixin provides a convenient way for route - * components to set the route in context. This is needed for - * routes that render elements that want to use the Lifecycle - * mixin to prevent transitions. - */ -var RouteContext = { - - propTypes: { - route: object.isRequired - }, - - childContextTypes: { - route: object.isRequired - }, - - getChildContext: function getChildContext() { - return { - route: this.props.route - }; - } - -}; - -exports['default'] = RouteContext; -module.exports = exports['default']; - -/***/ }), -/* 316 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _historyLibCreateHashHistory = __webpack_require__(231); - -var _historyLibCreateHashHistory2 = _interopRequireDefault(_historyLibCreateHashHistory); - -var _RouteUtils = __webpack_require__(19); - -var _RoutingContext = __webpack_require__(101); - -var _RoutingContext2 = _interopRequireDefault(_RoutingContext); - -var _useRoutes = __webpack_require__(62); - -var _useRoutes2 = _interopRequireDefault(_useRoutes); - -var _PropTypes = __webpack_require__(21); - -var _React$PropTypes = _react2['default'].PropTypes; -var func = _React$PropTypes.func; -var object = _React$PropTypes.object; - -/** - * A <Router> is a high-level API for automatically setting up - * a router that renders a <RoutingContext> with all the props - * it needs each time the URL changes. - */ - -var Router = (function (_Component) { - _inherits(Router, _Component); - - function Router(props, context) { - _classCallCheck(this, Router); - - _Component.call(this, props, context); - - this.state = { - location: null, - routes: null, - params: null, - components: null - }; - } - - Router.prototype.handleError = function handleError(error) { - if (this.props.onError) { - this.props.onError.call(this, error); - } else { - // Throw errors by default so we don't silently swallow them! - throw error; // This error probably occurred in getChildRoutes or getComponents. - } - }; - - Router.prototype.componentWillMount = function componentWillMount() { - var _this = this; - - var _props = this.props; - var history = _props.history; - var children = _props.children; - var routes = _props.routes; - var parseQueryString = _props.parseQueryString; - var stringifyQuery = _props.stringifyQuery; - - var createHistory = history ? function () { - return history; - } : _historyLibCreateHashHistory2['default']; - - this.history = _useRoutes2['default'](createHistory)({ - routes: _RouteUtils.createRoutes(routes || children), - parseQueryString: parseQueryString, - stringifyQuery: stringifyQuery - }); - - this._unlisten = this.history.listen(function (error, state) { - if (error) { - _this.handleError(error); - } else { - _this.setState(state, _this.props.onUpdate); - } - }); - }; - - /* istanbul ignore next: sanity check */ - - Router.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](nextProps.history === this.props.history, 'You cannot change <Router history>; it will be ignored') : undefined; - - process.env.NODE_ENV !== 'production' ? _warning2['default']((nextProps.routes || nextProps.children) === (this.props.routes || this.props.children), 'You cannot change <Router routes>; it will be ignored') : undefined; - }; - - Router.prototype.componentWillUnmount = function componentWillUnmount() { - if (this._unlisten) this._unlisten(); - }; - - Router.prototype.render = function render() { - var _state = this.state; - var location = _state.location; - var routes = _state.routes; - var params = _state.params; - var components = _state.components; - var _props2 = this.props; - var RoutingContext = _props2.RoutingContext; - var createElement = _props2.createElement; - - var props = _objectWithoutProperties(_props2, ['RoutingContext', 'createElement']); - - if (location == null) return null; // Async match - - // Only forward non-Router-specific props to routing context, as those are - // the only ones that might be custom routing context props. - Object.keys(Router.propTypes).forEach(function (propType) { - return delete props[propType]; - }); - - return _react2['default'].createElement(RoutingContext, _extends({}, props, { - history: this.history, - createElement: createElement, - location: location, - routes: routes, - params: params, - components: components - })); - }; - - return Router; -})(_react.Component); - -Router.propTypes = { - history: object, - children: _PropTypes.routes, - routes: _PropTypes.routes, // alias for children - RoutingContext: func.isRequired, - createElement: func, - onError: func, - onUpdate: func, - parseQueryString: func, - stringifyQuery: func -}; - -Router.defaultProps = { - RoutingContext: _RoutingContext2['default'] -}; - -exports['default'] = Router; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 317 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.runEnterHooks = runEnterHooks; -exports.runLeaveHooks = runLeaveHooks; - -var _AsyncUtils = __webpack_require__(61); - -function createEnterHook(hook, route) { - return function (a, b, callback) { - hook.apply(route, arguments); - - if (hook.length < 3) { - // Assume hook executes synchronously and - // automatically call the callback. - callback(); - } - }; -} - -function getEnterHooks(routes) { - return routes.reduce(function (hooks, route) { - if (route.onEnter) hooks.push(createEnterHook(route.onEnter, route)); - - return hooks; - }, []); -} - -/** - * Runs all onEnter hooks in the given array of routes in order - * with onEnter(nextState, replaceState, callback) and calls - * callback(error, redirectInfo) when finished. The first hook - * to use replaceState short-circuits the loop. - * - * If a hook needs to run asynchronously, it may use the callback - * function. However, doing so will cause the transition to pause, - * which could lead to a non-responsive UI if the hook is slow. - */ - -function runEnterHooks(routes, nextState, callback) { - var hooks = getEnterHooks(routes); - - if (!hooks.length) { - callback(); - return; - } - - var redirectInfo = undefined; - function replaceState(state, pathname, query) { - redirectInfo = { pathname: pathname, query: query, state: state }; - } - - _AsyncUtils.loopAsync(hooks.length, function (index, next, done) { - hooks[index](nextState, replaceState, function (error) { - if (error || redirectInfo) { - done(error, redirectInfo); // No need to continue. - } else { - next(); - } - }); - }, callback); -} - -/** - * Runs all onLeave hooks in the given array of routes in order. - */ - -function runLeaveHooks(routes) { - for (var i = 0, len = routes.length; i < len; ++i) { - if (routes[i].onLeave) routes[i].onLeave.call(routes[i]); - } -} - -/***/ }), -/* 318 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _PatternUtils = __webpack_require__(34); - -function routeParamsChanged(route, prevState, nextState) { - if (!route.path) return false; - - var paramNames = _PatternUtils.getParamNames(route.path); - - return paramNames.some(function (paramName) { - return prevState.params[paramName] !== nextState.params[paramName]; - }); -} - -/** - * Returns an object of { leaveRoutes, enterRoutes } determined by - * the change from prevState to nextState. We leave routes if either - * 1) they are not in the next state or 2) they are in the next state - * but their params have changed (i.e. /users/123 => /users/456). - * - * leaveRoutes are ordered starting at the leaf route of the tree - * we're leaving up to the common parent route. enterRoutes are ordered - * from the top of the tree we're entering down to the leaf route. - */ -function computeChangedRoutes(prevState, nextState) { - var prevRoutes = prevState && prevState.routes; - var nextRoutes = nextState.routes; - - var leaveRoutes = undefined, - enterRoutes = undefined; - if (prevRoutes) { - leaveRoutes = prevRoutes.filter(function (route) { - return nextRoutes.indexOf(route) === -1 || routeParamsChanged(route, prevState, nextState); - }); - - // onLeave hooks start at the leaf route. - leaveRoutes.reverse(); - - enterRoutes = nextRoutes.filter(function (route) { - return prevRoutes.indexOf(route) === -1 || leaveRoutes.indexOf(route) !== -1; - }); - } else { - leaveRoutes = []; - enterRoutes = nextRoutes; - } - - return { - leaveRoutes: leaveRoutes, - enterRoutes: enterRoutes - }; -} - -exports['default'] = computeChangedRoutes; -module.exports = exports['default']; - -/***/ }), -/* 319 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _AsyncUtils = __webpack_require__(61); - -function getComponentsForRoute(location, route, callback) { - if (route.component || route.components) { - callback(null, route.component || route.components); - } else if (route.getComponent) { - route.getComponent(location, callback); - } else if (route.getComponents) { - route.getComponents(location, callback); - } else { - callback(); - } -} - -/** - * Asynchronously fetches all components needed for the given router - * state and calls callback(error, components) when finished. - * - * Note: This operation may finish synchronously if no routes have an - * asynchronous getComponents method. - */ -function getComponents(nextState, callback) { - _AsyncUtils.mapAsync(nextState.routes, function (route, index, callback) { - getComponentsForRoute(nextState.location, route, callback); - }, callback); -} - -exports['default'] = getComponents; -module.exports = exports['default']; - -/***/ }), -/* 320 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _PatternUtils = __webpack_require__(34); - -/** - * Extracts an object of params the given route cares about from - * the given params object. - */ -function getRouteParams(route, params) { - var routeParams = {}; - - if (!route.path) return routeParams; - - var paramNames = _PatternUtils.getParamNames(route.path); - - for (var p in params) { - if (params.hasOwnProperty(p) && paramNames.indexOf(p) !== -1) routeParams[p] = params[p]; - }return routeParams; -} - -exports['default'] = getRouteParams; -module.exports = exports['default']; - -/***/ }), -/* 321 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _PatternUtils = __webpack_require__(34); - -function deepEqual(a, b) { - if (a == b) return true; - - if (a == null || b == null) return false; - - if (Array.isArray(a)) { - return Array.isArray(b) && a.length === b.length && a.every(function (item, index) { - return deepEqual(item, b[index]); - }); - } - - if (typeof a === 'object') { - for (var p in a) { - if (!a.hasOwnProperty(p)) { - continue; - } - - if (a[p] === undefined) { - if (b[p] !== undefined) { - return false; - } - } else if (!b.hasOwnProperty(p)) { - return false; - } else if (!deepEqual(a[p], b[p])) { - return false; - } - } - - return true; - } - - return String(a) === String(b); -} - -function paramsAreActive(paramNames, paramValues, activeParams) { - // FIXME: This doesn't work on repeated params in activeParams. - return paramNames.every(function (paramName, index) { - return String(paramValues[index]) === String(activeParams[paramName]); - }); -} - -function getMatchingRouteIndex(pathname, activeRoutes, activeParams) { - var remainingPathname = pathname, - paramNames = [], - paramValues = []; - - for (var i = 0, len = activeRoutes.length; i < len; ++i) { - var route = activeRoutes[i]; - var pattern = route.path || ''; - - if (pattern.charAt(0) === '/') { - remainingPathname = pathname; - paramNames = []; - paramValues = []; - } - - if (remainingPathname !== null) { - var matched = _PatternUtils.matchPattern(pattern, remainingPathname); - remainingPathname = matched.remainingPathname; - paramNames = [].concat(paramNames, matched.paramNames); - paramValues = [].concat(paramValues, matched.paramValues); - } - - if (remainingPathname === '' && route.path && paramsAreActive(paramNames, paramValues, activeParams)) return i; - } - - return null; -} - -/** - * Returns true if the given pathname matches the active routes - * and params. - */ -function routeIsActive(pathname, routes, params, indexOnly) { - var i = getMatchingRouteIndex(pathname, routes, params); - - if (i === null) { - // No match. - return false; - } else if (!indexOnly) { - // Any match is good enough. - return true; - } - - // If any remaining routes past the match index have paths, then we can't - // be on the index route. - return routes.slice(i + 1).every(function (route) { - return !route.path; - }); -} - -/** - * Returns true if all key/value pairs in the given query are - * currently active. - */ -function queryIsActive(query, activeQuery) { - if (activeQuery == null) return query == null; - - if (query == null) return true; - - return deepEqual(query, activeQuery); -} - -/** - * Returns true if a <Link> to the given pathname/query combination is - * currently active. - */ -function isActive(pathname, query, indexOnly, location, routes, params) { - if (location == null) return false; - - if (!routeIsActive(pathname, routes, params, indexOnly)) return false; - - return queryIsActive(query, location.query); -} - -exports['default'] = isActive; -module.exports = exports['default']; - -/***/ }), -/* 322 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _historyLibCreateMemoryHistory = __webpack_require__(233); - -var _historyLibCreateMemoryHistory2 = _interopRequireDefault(_historyLibCreateMemoryHistory); - -var _historyLibUseBasename = __webpack_require__(234); - -var _historyLibUseBasename2 = _interopRequireDefault(_historyLibUseBasename); - -var _RouteUtils = __webpack_require__(19); - -var _useRoutes = __webpack_require__(62); - -var _useRoutes2 = _interopRequireDefault(_useRoutes); - -var createHistory = _useRoutes2['default'](_historyLibUseBasename2['default'](_historyLibCreateMemoryHistory2['default'])); - -/** - * A high-level API to be used for server-side rendering. - * - * This function matches a location to a set of routes and calls - * callback(error, redirectLocation, renderProps) when finished. - * - * Note: You probably don't want to use this in a browser. Use - * the history.listen API instead. - */ -function match(_ref, callback) { - var routes = _ref.routes; - var location = _ref.location; - var parseQueryString = _ref.parseQueryString; - var stringifyQuery = _ref.stringifyQuery; - var basename = _ref.basename; - - !location ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'match needs a location') : _invariant2['default'](false) : undefined; - - var history = createHistory({ - routes: _RouteUtils.createRoutes(routes), - parseQueryString: parseQueryString, - stringifyQuery: stringifyQuery, - basename: basename - }); - - // Allow match({ location: '/the/path', ... }) - if (typeof location === 'string') location = history.createLocation(location); - - history.match(location, function (error, redirectLocation, nextState) { - callback(error, redirectLocation, nextState && _extends({}, nextState, { history: history })); - }); -} - -exports['default'] = match; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 323 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _AsyncUtils = __webpack_require__(61); - -var _PatternUtils = __webpack_require__(34); - -var _RouteUtils = __webpack_require__(19); - -function getChildRoutes(route, location, callback) { - if (route.childRoutes) { - callback(null, route.childRoutes); - } else if (route.getChildRoutes) { - route.getChildRoutes(location, function (error, childRoutes) { - callback(error, !error && _RouteUtils.createRoutes(childRoutes)); - }); - } else { - callback(); - } -} - -function getIndexRoute(route, location, callback) { - if (route.indexRoute) { - callback(null, route.indexRoute); - } else if (route.getIndexRoute) { - route.getIndexRoute(location, function (error, indexRoute) { - callback(error, !error && _RouteUtils.createRoutes(indexRoute)[0]); - }); - } else if (route.childRoutes) { - (function () { - var pathless = route.childRoutes.filter(function (obj) { - return !obj.hasOwnProperty('path'); - }); - - _AsyncUtils.loopAsync(pathless.length, function (index, next, done) { - getIndexRoute(pathless[index], location, function (error, indexRoute) { - if (error || indexRoute) { - var routes = [pathless[index]].concat(Array.isArray(indexRoute) ? indexRoute : [indexRoute]); - done(error, routes); - } else { - next(); - } - }); - }, function (err, routes) { - callback(null, routes); - }); - })(); - } else { - callback(); - } -} - -function assignParams(params, paramNames, paramValues) { - return paramNames.reduce(function (params, paramName, index) { - var paramValue = paramValues && paramValues[index]; - - if (Array.isArray(params[paramName])) { - params[paramName].push(paramValue); - } else if (paramName in params) { - params[paramName] = [params[paramName], paramValue]; - } else { - params[paramName] = paramValue; - } - - return params; - }, params); -} - -function createParams(paramNames, paramValues) { - return assignParams({}, paramNames, paramValues); -} - -function matchRouteDeep(route, location, remainingPathname, paramNames, paramValues, callback) { - var pattern = route.path || ''; - - if (pattern.charAt(0) === '/') { - remainingPathname = location.pathname; - paramNames = []; - paramValues = []; - } - - if (remainingPathname !== null) { - var matched = _PatternUtils.matchPattern(pattern, remainingPathname); - remainingPathname = matched.remainingPathname; - paramNames = [].concat(paramNames, matched.paramNames); - paramValues = [].concat(paramValues, matched.paramValues); - - if (remainingPathname === '' && route.path) { - var _ret2 = (function () { - var match = { - routes: [route], - params: createParams(paramNames, paramValues) - }; - - getIndexRoute(route, location, function (error, indexRoute) { - if (error) { - callback(error); - } else { - if (Array.isArray(indexRoute)) { - var _match$routes; - - process.env.NODE_ENV !== 'production' ? _warning2['default'](indexRoute.every(function (route) { - return !route.path; - }), 'Index routes should not have paths') : undefined; - (_match$routes = match.routes).push.apply(_match$routes, indexRoute); - } else if (indexRoute) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](!indexRoute.path, 'Index routes should not have paths') : undefined; - match.routes.push(indexRoute); - } - - callback(null, match); - } - }); - return { - v: undefined - }; - })(); - - if (typeof _ret2 === 'object') return _ret2.v; - } - } - - if (remainingPathname != null || route.childRoutes) { - // Either a) this route matched at least some of the path or b) - // we don't have to load this route's children asynchronously. In - // either case continue checking for matches in the subtree. - getChildRoutes(route, location, function (error, childRoutes) { - if (error) { - callback(error); - } else if (childRoutes) { - // Check the child routes to see if any of them match. - matchRoutes(childRoutes, location, function (error, match) { - if (error) { - callback(error); - } else if (match) { - // A child route matched! Augment the match and pass it up the stack. - match.routes.unshift(route); - callback(null, match); - } else { - callback(); - } - }, remainingPathname, paramNames, paramValues); - } else { - callback(); - } - }); - } else { - callback(); - } -} - -/** - * Asynchronously matches the given location to a set of routes and calls - * callback(error, state) when finished. The state object will have the - * following properties: - * - * - routes An array of routes that matched, in hierarchical order - * - params An object of URL parameters - * - * Note: This operation may finish synchronously if no routes have an - * asynchronous getChildRoutes method. - */ -function matchRoutes(routes, location, callback) { - var remainingPathname = arguments.length <= 3 || arguments[3] === undefined ? location.pathname : arguments[3]; - var paramNames = arguments.length <= 4 || arguments[4] === undefined ? [] : arguments[4]; - var paramValues = arguments.length <= 5 || arguments[5] === undefined ? [] : arguments[5]; - return (function () { - _AsyncUtils.loopAsync(routes.length, function (index, next, done) { - matchRouteDeep(routes[index], location, remainingPathname, paramNames, paramValues, function (error, match) { - if (error || match) { - done(error, match); - } else { - next(); - } - }); - }, callback); - })(); -} - -exports['default'] = matchRoutes; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 324 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/** - * Escape and wrap key so it is safe to use as a reactid - * - * @param {string} key to be escaped. - * @return {string} the escaped key. - */ - -function escape(key) { - var escapeRegex = /[=:]/g; - var escaperLookup = { - '=': '=0', - ':': '=2' - }; - var escapedString = ('' + key).replace(escapeRegex, function (match) { - return escaperLookup[match]; - }); - - return '$' + escapedString; -} - -/** - * Unescape and unwrap key for human-readable display - * - * @param {string} key to unescape. - * @return {string} the unescaped key. - */ -function unescape(key) { - var unescapeRegex = /(=0|=2)/g; - var unescaperLookup = { - '=0': '=', - '=2': ':' - }; - var keySubstring = key[0] === '.' && key[1] === '$' ? key.substring(2) : key.substring(1); - - return ('' + keySubstring).replace(unescapeRegex, function (match) { - return unescaperLookup[match]; - }); -} - -var KeyEscapeUtils = { - escape: escape, - unescape: unescape -}; - -module.exports = KeyEscapeUtils; - -/***/ }), -/* 325 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(23); - -var invariant = __webpack_require__(2); - -/** - * Static poolers. Several custom versions for each potential number of - * arguments. A completely generic pooler is easy to implement, but would - * require accessing the `arguments` object. In each of these, `this` refers to - * the Class itself, not an instance. If any others are needed, simply add them - * here, or in their own files. - */ -var oneArgumentPooler = function (copyFieldsFrom) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, copyFieldsFrom); - return instance; - } else { - return new Klass(copyFieldsFrom); - } -}; - -var twoArgumentPooler = function (a1, a2) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2); - return instance; - } else { - return new Klass(a1, a2); - } -}; - -var threeArgumentPooler = function (a1, a2, a3) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3); - return instance; - } else { - return new Klass(a1, a2, a3); - } -}; - -var fourArgumentPooler = function (a1, a2, a3, a4) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3, a4); - return instance; - } else { - return new Klass(a1, a2, a3, a4); - } -}; - -var standardReleaser = function (instance) { - var Klass = this; - !(instance instanceof Klass) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : _prodInvariant('25') : void 0; - instance.destructor(); - if (Klass.instancePool.length < Klass.poolSize) { - Klass.instancePool.push(instance); - } -}; - -var DEFAULT_POOL_SIZE = 10; -var DEFAULT_POOLER = oneArgumentPooler; - -/** - * Augments `CopyConstructor` to be a poolable class, augmenting only the class - * itself (statically) not adding any prototypical fields. Any CopyConstructor - * you give this may have a `poolSize` property, and will look for a - * prototypical `destructor` on instances. - * - * @param {Function} CopyConstructor Constructor that can be used to reset. - * @param {Function} pooler Customizable pooler. - */ -var addPoolingTo = function (CopyConstructor, pooler) { - // Casting as any so that flow ignores the actual implementation and trusts - // it to match the type we declared - var NewKlass = CopyConstructor; - NewKlass.instancePool = []; - NewKlass.getPooled = pooler || DEFAULT_POOLER; - if (!NewKlass.poolSize) { - NewKlass.poolSize = DEFAULT_POOL_SIZE; - } - NewKlass.release = standardReleaser; - return NewKlass; -}; - -var PooledClass = { - addPoolingTo: addPoolingTo, - oneArgumentPooler: oneArgumentPooler, - twoArgumentPooler: twoArgumentPooler, - threeArgumentPooler: threeArgumentPooler, - fourArgumentPooler: fourArgumentPooler -}; - -module.exports = PooledClass; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 326 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var PooledClass = __webpack_require__(325); -var ReactElement = __webpack_require__(22); - -var emptyFunction = __webpack_require__(12); -var traverseAllChildren = __webpack_require__(334); - -var twoArgumentPooler = PooledClass.twoArgumentPooler; -var fourArgumentPooler = PooledClass.fourArgumentPooler; - -var userProvidedKeyEscapeRegex = /\/+/g; -function escapeUserProvidedKey(text) { - return ('' + text).replace(userProvidedKeyEscapeRegex, '$&/'); -} - -/** - * PooledClass representing the bookkeeping associated with performing a child - * traversal. Allows avoiding binding callbacks. - * - * @constructor ForEachBookKeeping - * @param {!function} forEachFunction Function to perform traversal with. - * @param {?*} forEachContext Context to perform context with. - */ -function ForEachBookKeeping(forEachFunction, forEachContext) { - this.func = forEachFunction; - this.context = forEachContext; - this.count = 0; -} -ForEachBookKeeping.prototype.destructor = function () { - this.func = null; - this.context = null; - this.count = 0; -}; -PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler); - -function forEachSingleChild(bookKeeping, child, name) { - var func = bookKeeping.func, - context = bookKeeping.context; - - func.call(context, child, bookKeeping.count++); -} - -/** - * Iterates through children that are typically specified as `props.children`. - * - * See https://facebook.github.io/react/docs/top-level-api.html#react.children.foreach - * - * The provided forEachFunc(child, index) will be called for each - * leaf child. - * - * @param {?*} children Children tree container. - * @param {function(*, int)} forEachFunc - * @param {*} forEachContext Context for forEachContext. - */ -function forEachChildren(children, forEachFunc, forEachContext) { - if (children == null) { - return children; - } - var traverseContext = ForEachBookKeeping.getPooled(forEachFunc, forEachContext); - traverseAllChildren(children, forEachSingleChild, traverseContext); - ForEachBookKeeping.release(traverseContext); -} - -/** - * PooledClass representing the bookkeeping associated with performing a child - * mapping. Allows avoiding binding callbacks. - * - * @constructor MapBookKeeping - * @param {!*} mapResult Object containing the ordered map of results. - * @param {!function} mapFunction Function to perform mapping with. - * @param {?*} mapContext Context to perform mapping with. - */ -function MapBookKeeping(mapResult, keyPrefix, mapFunction, mapContext) { - this.result = mapResult; - this.keyPrefix = keyPrefix; - this.func = mapFunction; - this.context = mapContext; - this.count = 0; -} -MapBookKeeping.prototype.destructor = function () { - this.result = null; - this.keyPrefix = null; - this.func = null; - this.context = null; - this.count = 0; -}; -PooledClass.addPoolingTo(MapBookKeeping, fourArgumentPooler); - -function mapSingleChildIntoContext(bookKeeping, child, childKey) { - var result = bookKeeping.result, - keyPrefix = bookKeeping.keyPrefix, - func = bookKeeping.func, - context = bookKeeping.context; - - - var mappedChild = func.call(context, child, bookKeeping.count++); - if (Array.isArray(mappedChild)) { - mapIntoWithKeyPrefixInternal(mappedChild, result, childKey, emptyFunction.thatReturnsArgument); - } else if (mappedChild != null) { - if (ReactElement.isValidElement(mappedChild)) { - mappedChild = ReactElement.cloneAndReplaceKey(mappedChild, - // Keep both the (mapped) and old keys if they differ, just as - // traverseAllChildren used to do for objects as children - keyPrefix + (mappedChild.key && (!child || child.key !== mappedChild.key) ? escapeUserProvidedKey(mappedChild.key) + '/' : '') + childKey); - } - result.push(mappedChild); - } -} - -function mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) { - var escapedPrefix = ''; - if (prefix != null) { - escapedPrefix = escapeUserProvidedKey(prefix) + '/'; - } - var traverseContext = MapBookKeeping.getPooled(array, escapedPrefix, func, context); - traverseAllChildren(children, mapSingleChildIntoContext, traverseContext); - MapBookKeeping.release(traverseContext); -} - -/** - * Maps children that are typically specified as `props.children`. - * - * See https://facebook.github.io/react/docs/top-level-api.html#react.children.map - * - * The provided mapFunction(child, key, index) will be called for each - * leaf child. - * - * @param {?*} children Children tree container. - * @param {function(*, int)} func The map function. - * @param {*} context Context for mapFunction. - * @return {object} Object containing the ordered map of results. - */ -function mapChildren(children, func, context) { - if (children == null) { - return children; - } - var result = []; - mapIntoWithKeyPrefixInternal(children, result, null, func, context); - return result; -} - -function forEachSingleChildDummy(traverseContext, child, name) { - return null; -} - -/** - * Count the number of children that are typically specified as - * `props.children`. - * - * See https://facebook.github.io/react/docs/top-level-api.html#react.children.count - * - * @param {?*} children Children tree container. - * @return {number} The number of children. - */ -function countChildren(children, context) { - return traverseAllChildren(children, forEachSingleChildDummy, null); -} - -/** - * Flatten a children object (typically specified as `props.children`) and - * return an array with appropriately re-keyed children. - * - * See https://facebook.github.io/react/docs/top-level-api.html#react.children.toarray - */ -function toArray(children) { - var result = []; - mapIntoWithKeyPrefixInternal(children, result, null, emptyFunction.thatReturnsArgument); - return result; -} - -var ReactChildren = { - forEach: forEachChildren, - map: mapChildren, - mapIntoWithKeyPrefixInternal: mapIntoWithKeyPrefixInternal, - count: countChildren, - toArray: toArray -}; - -module.exports = ReactChildren; - -/***/ }), -/* 327 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(23), - _assign = __webpack_require__(6); - -var ReactComponent = __webpack_require__(63); -var ReactElement = __webpack_require__(22); -var ReactPropTypeLocationNames = __webpack_require__(65); -var ReactNoopUpdateQueue = __webpack_require__(64); - -var emptyObject = __webpack_require__(28); -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -var MIXINS_KEY = 'mixins'; - -// Helper function to allow the creation of anonymous functions which do not -// have .name set to the name of the variable being assigned to. -function identity(fn) { - return fn; -} - -/** - * Policies that describe methods in `ReactClassInterface`. - */ - - -var injectedMixins = []; - -/** - * Composite components are higher-level components that compose other composite - * or host components. - * - * To create a new type of `ReactClass`, pass a specification of - * your new class to `React.createClass`. The only requirement of your class - * specification is that you implement a `render` method. - * - * var MyComponent = React.createClass({ - * render: function() { - * return <div>Hello World</div>; - * } - * }); - * - * The class specification supports a specific protocol of methods that have - * special meaning (e.g. `render`). See `ReactClassInterface` for - * more the comprehensive protocol. Any other properties and methods in the - * class specification will be available on the prototype. - * - * @interface ReactClassInterface - * @internal - */ -var ReactClassInterface = { - - /** - * An array of Mixin objects to include when defining your component. - * - * @type {array} - * @optional - */ - mixins: 'DEFINE_MANY', - - /** - * An object containing properties and methods that should be defined on - * the component's constructor instead of its prototype (static methods). - * - * @type {object} - * @optional - */ - statics: 'DEFINE_MANY', - - /** - * Definition of prop types for this component. - * - * @type {object} - * @optional - */ - propTypes: 'DEFINE_MANY', - - /** - * Definition of context types for this component. - * - * @type {object} - * @optional - */ - contextTypes: 'DEFINE_MANY', - - /** - * Definition of context types this component sets for its children. - * - * @type {object} - * @optional - */ - childContextTypes: 'DEFINE_MANY', - - // ==== Definition methods ==== - - /** - * Invoked when the component is mounted. Values in the mapping will be set on - * `this.props` if that prop is not specified (i.e. using an `in` check). - * - * This method is invoked before `getInitialState` and therefore cannot rely - * on `this.state` or use `this.setState`. - * - * @return {object} - * @optional - */ - getDefaultProps: 'DEFINE_MANY_MERGED', - - /** - * Invoked once before the component is mounted. The return value will be used - * as the initial value of `this.state`. - * - * getInitialState: function() { - * return { - * isOn: false, - * fooBaz: new BazFoo() - * } - * } - * - * @return {object} - * @optional - */ - getInitialState: 'DEFINE_MANY_MERGED', - - /** - * @return {object} - * @optional - */ - getChildContext: 'DEFINE_MANY_MERGED', - - /** - * Uses props from `this.props` and state from `this.state` to render the - * structure of the component. - * - * No guarantees are made about when or how often this method is invoked, so - * it must not have side effects. - * - * render: function() { - * var name = this.props.name; - * return <div>Hello, {name}!</div>; - * } - * - * @return {ReactComponent} - * @nosideeffects - * @required - */ - render: 'DEFINE_ONCE', - - // ==== Delegate methods ==== - - /** - * Invoked when the component is initially created and about to be mounted. - * This may have side effects, but any external subscriptions or data created - * by this method must be cleaned up in `componentWillUnmount`. - * - * @optional - */ - componentWillMount: 'DEFINE_MANY', - - /** - * Invoked when the component has been mounted and has a DOM representation. - * However, there is no guarantee that the DOM node is in the document. - * - * Use this as an opportunity to operate on the DOM when the component has - * been mounted (initialized and rendered) for the first time. - * - * @param {DOMElement} rootNode DOM element representing the component. - * @optional - */ - componentDidMount: 'DEFINE_MANY', - - /** - * Invoked before the component receives new props. - * - * Use this as an opportunity to react to a prop transition by updating the - * state using `this.setState`. Current props are accessed via `this.props`. - * - * componentWillReceiveProps: function(nextProps, nextContext) { - * this.setState({ - * likesIncreasing: nextProps.likeCount > this.props.likeCount - * }); - * } - * - * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop - * transition may cause a state change, but the opposite is not true. If you - * need it, you are probably looking for `componentWillUpdate`. - * - * @param {object} nextProps - * @optional - */ - componentWillReceiveProps: 'DEFINE_MANY', - - /** - * Invoked while deciding if the component should be updated as a result of - * receiving new props, state and/or context. - * - * Use this as an opportunity to `return false` when you're certain that the - * transition to the new props/state/context will not require a component - * update. - * - * shouldComponentUpdate: function(nextProps, nextState, nextContext) { - * return !equal(nextProps, this.props) || - * !equal(nextState, this.state) || - * !equal(nextContext, this.context); - * } - * - * @param {object} nextProps - * @param {?object} nextState - * @param {?object} nextContext - * @return {boolean} True if the component should update. - * @optional - */ - shouldComponentUpdate: 'DEFINE_ONCE', - - /** - * Invoked when the component is about to update due to a transition from - * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` - * and `nextContext`. - * - * Use this as an opportunity to perform preparation before an update occurs. - * - * NOTE: You **cannot** use `this.setState()` in this method. - * - * @param {object} nextProps - * @param {?object} nextState - * @param {?object} nextContext - * @param {ReactReconcileTransaction} transaction - * @optional - */ - componentWillUpdate: 'DEFINE_MANY', - - /** - * Invoked when the component's DOM representation has been updated. - * - * Use this as an opportunity to operate on the DOM when the component has - * been updated. - * - * @param {object} prevProps - * @param {?object} prevState - * @param {?object} prevContext - * @param {DOMElement} rootNode DOM element representing the component. - * @optional - */ - componentDidUpdate: 'DEFINE_MANY', - - /** - * Invoked when the component is about to be removed from its parent and have - * its DOM representation destroyed. - * - * Use this as an opportunity to deallocate any external resources. - * - * NOTE: There is no `componentDidUnmount` since your component will have been - * destroyed by that point. - * - * @optional - */ - componentWillUnmount: 'DEFINE_MANY', - - // ==== Advanced methods ==== - - /** - * Updates the component's currently mounted DOM representation. - * - * By default, this implements React's rendering and reconciliation algorithm. - * Sophisticated clients may wish to override this. - * - * @param {ReactReconcileTransaction} transaction - * @internal - * @overridable - */ - updateComponent: 'OVERRIDE_BASE' - -}; - -/** - * Mapping from class specification keys to special processing functions. - * - * Although these are declared like instance properties in the specification - * when defining classes using `React.createClass`, they are actually static - * and are accessible on the constructor instead of the prototype. Despite - * being static, they must be defined outside of the "statics" key under - * which all other static methods are defined. - */ -var RESERVED_SPEC_KEYS = { - displayName: function (Constructor, displayName) { - Constructor.displayName = displayName; - }, - mixins: function (Constructor, mixins) { - if (mixins) { - for (var i = 0; i < mixins.length; i++) { - mixSpecIntoComponent(Constructor, mixins[i]); - } - } - }, - childContextTypes: function (Constructor, childContextTypes) { - if (process.env.NODE_ENV !== 'production') { - validateTypeDef(Constructor, childContextTypes, 'childContext'); - } - Constructor.childContextTypes = _assign({}, Constructor.childContextTypes, childContextTypes); - }, - contextTypes: function (Constructor, contextTypes) { - if (process.env.NODE_ENV !== 'production') { - validateTypeDef(Constructor, contextTypes, 'context'); - } - Constructor.contextTypes = _assign({}, Constructor.contextTypes, contextTypes); - }, - /** - * Special case getDefaultProps which should move into statics but requires - * automatic merging. - */ - getDefaultProps: function (Constructor, getDefaultProps) { - if (Constructor.getDefaultProps) { - Constructor.getDefaultProps = createMergedResultFunction(Constructor.getDefaultProps, getDefaultProps); - } else { - Constructor.getDefaultProps = getDefaultProps; - } - }, - propTypes: function (Constructor, propTypes) { - if (process.env.NODE_ENV !== 'production') { - validateTypeDef(Constructor, propTypes, 'prop'); - } - Constructor.propTypes = _assign({}, Constructor.propTypes, propTypes); - }, - statics: function (Constructor, statics) { - mixStaticSpecIntoComponent(Constructor, statics); - }, - autobind: function () {} }; - -function validateTypeDef(Constructor, typeDef, location) { - for (var propName in typeDef) { - if (typeDef.hasOwnProperty(propName)) { - // use a warning instead of an invariant so components - // don't show up in prod but only in __DEV__ - process.env.NODE_ENV !== 'production' ? warning(typeof typeDef[propName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', Constructor.displayName || 'ReactClass', ReactPropTypeLocationNames[location], propName) : void 0; - } - } -} - -function validateMethodOverride(isAlreadyDefined, name) { - var specPolicy = ReactClassInterface.hasOwnProperty(name) ? ReactClassInterface[name] : null; - - // Disallow overriding of base class methods unless explicitly allowed. - if (ReactClassMixin.hasOwnProperty(name)) { - !(specPolicy === 'OVERRIDE_BASE') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to override `%s` from your class specification. Ensure that your method names do not overlap with React methods.', name) : _prodInvariant('73', name) : void 0; - } - - // Disallow defining methods more than once unless explicitly allowed. - if (isAlreadyDefined) { - !(specPolicy === 'DEFINE_MANY' || specPolicy === 'DEFINE_MANY_MERGED') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to define `%s` on your component more than once. This conflict may be due to a mixin.', name) : _prodInvariant('74', name) : void 0; - } -} - -/** - * Mixin helper which handles policy validation and reserved - * specification keys when building React classes. - */ -function mixSpecIntoComponent(Constructor, spec) { - if (!spec) { - if (process.env.NODE_ENV !== 'production') { - var typeofSpec = typeof spec; - var isMixinValid = typeofSpec === 'object' && spec !== null; - - process.env.NODE_ENV !== 'production' ? warning(isMixinValid, '%s: You\'re attempting to include a mixin that is either null ' + 'or not an object. Check the mixins included by the component, ' + 'as well as any mixins they include themselves. ' + 'Expected object but got %s.', Constructor.displayName || 'ReactClass', spec === null ? null : typeofSpec) : void 0; - } - - return; - } - - !(typeof spec !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You\'re attempting to use a component class or function as a mixin. Instead, just use a regular object.') : _prodInvariant('75') : void 0; - !!ReactElement.isValidElement(spec) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You\'re attempting to use a component as a mixin. Instead, just use a regular object.') : _prodInvariant('76') : void 0; - - var proto = Constructor.prototype; - var autoBindPairs = proto.__reactAutoBindPairs; - - // By handling mixins before any other properties, we ensure the same - // chaining order is applied to methods with DEFINE_MANY policy, whether - // mixins are listed before or after these methods in the spec. - if (spec.hasOwnProperty(MIXINS_KEY)) { - RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins); - } - - for (var name in spec) { - if (!spec.hasOwnProperty(name)) { - continue; - } - - if (name === MIXINS_KEY) { - // We have already handled mixins in a special case above. - continue; - } - - var property = spec[name]; - var isAlreadyDefined = proto.hasOwnProperty(name); - validateMethodOverride(isAlreadyDefined, name); - - if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { - RESERVED_SPEC_KEYS[name](Constructor, property); - } else { - // Setup methods on prototype: - // The following member methods should not be automatically bound: - // 1. Expected ReactClass methods (in the "interface"). - // 2. Overridden methods (that were mixed in). - var isReactClassMethod = ReactClassInterface.hasOwnProperty(name); - var isFunction = typeof property === 'function'; - var shouldAutoBind = isFunction && !isReactClassMethod && !isAlreadyDefined && spec.autobind !== false; - - if (shouldAutoBind) { - autoBindPairs.push(name, property); - proto[name] = property; - } else { - if (isAlreadyDefined) { - var specPolicy = ReactClassInterface[name]; - - // These cases should already be caught by validateMethodOverride. - !(isReactClassMethod && (specPolicy === 'DEFINE_MANY_MERGED' || specPolicy === 'DEFINE_MANY')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: Unexpected spec policy %s for key %s when mixing in component specs.', specPolicy, name) : _prodInvariant('77', specPolicy, name) : void 0; - - // For methods which are defined more than once, call the existing - // methods before calling the new property, merging if appropriate. - if (specPolicy === 'DEFINE_MANY_MERGED') { - proto[name] = createMergedResultFunction(proto[name], property); - } else if (specPolicy === 'DEFINE_MANY') { - proto[name] = createChainedFunction(proto[name], property); - } - } else { - proto[name] = property; - if (process.env.NODE_ENV !== 'production') { - // Add verbose displayName to the function, which helps when looking - // at profiling tools. - if (typeof property === 'function' && spec.displayName) { - proto[name].displayName = spec.displayName + '_' + name; - } - } - } - } - } - } -} - -function mixStaticSpecIntoComponent(Constructor, statics) { - if (!statics) { - return; - } - for (var name in statics) { - var property = statics[name]; - if (!statics.hasOwnProperty(name)) { - continue; - } - - var isReserved = name in RESERVED_SPEC_KEYS; - !!isReserved ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You are attempting to define a reserved property, `%s`, that shouldn\'t be on the "statics" key. Define it as an instance property instead; it will still be accessible on the constructor.', name) : _prodInvariant('78', name) : void 0; - - var isInherited = name in Constructor; - !!isInherited ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You are attempting to define `%s` on your component more than once. This conflict may be due to a mixin.', name) : _prodInvariant('79', name) : void 0; - Constructor[name] = property; - } -} - -/** - * Merge two objects, but throw if both contain the same key. - * - * @param {object} one The first object, which is mutated. - * @param {object} two The second object - * @return {object} one after it has been mutated to contain everything in two. - */ -function mergeIntoWithNoDuplicateKeys(one, two) { - !(one && two && typeof one === 'object' && typeof two === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.') : _prodInvariant('80') : void 0; - - for (var key in two) { - if (two.hasOwnProperty(key)) { - !(one[key] === undefined) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mergeIntoWithNoDuplicateKeys(): Tried to merge two objects with the same key: `%s`. This conflict may be due to a mixin; in particular, this may be caused by two getInitialState() or getDefaultProps() methods returning objects with clashing keys.', key) : _prodInvariant('81', key) : void 0; - one[key] = two[key]; - } - } - return one; -} - -/** - * Creates a function that invokes two functions and merges their return values. - * - * @param {function} one Function to invoke first. - * @param {function} two Function to invoke second. - * @return {function} Function that invokes the two argument functions. - * @private - */ -function createMergedResultFunction(one, two) { - return function mergedResult() { - var a = one.apply(this, arguments); - var b = two.apply(this, arguments); - if (a == null) { - return b; - } else if (b == null) { - return a; - } - var c = {}; - mergeIntoWithNoDuplicateKeys(c, a); - mergeIntoWithNoDuplicateKeys(c, b); - return c; - }; -} - -/** - * Creates a function that invokes two functions and ignores their return vales. - * - * @param {function} one Function to invoke first. - * @param {function} two Function to invoke second. - * @return {function} Function that invokes the two argument functions. - * @private - */ -function createChainedFunction(one, two) { - return function chainedFunction() { - one.apply(this, arguments); - two.apply(this, arguments); - }; -} - -/** - * Binds a method to the component. - * - * @param {object} component Component whose method is going to be bound. - * @param {function} method Method to be bound. - * @return {function} The bound method. - */ -function bindAutoBindMethod(component, method) { - var boundMethod = method.bind(component); - if (process.env.NODE_ENV !== 'production') { - boundMethod.__reactBoundContext = component; - boundMethod.__reactBoundMethod = method; - boundMethod.__reactBoundArguments = null; - var componentName = component.constructor.displayName; - var _bind = boundMethod.bind; - boundMethod.bind = function (newThis) { - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - // User is trying to bind() an autobound method; we effectively will - // ignore the value of "this" that the user is trying to use, so - // let's warn. - if (newThis !== component && newThis !== null) { - process.env.NODE_ENV !== 'production' ? warning(false, 'bind(): React component methods may only be bound to the ' + 'component instance. See %s', componentName) : void 0; - } else if (!args.length) { - process.env.NODE_ENV !== 'production' ? warning(false, 'bind(): You are binding a component method to the component. ' + 'React does this for you automatically in a high-performance ' + 'way, so you can safely remove this call. See %s', componentName) : void 0; - return boundMethod; - } - var reboundMethod = _bind.apply(boundMethod, arguments); - reboundMethod.__reactBoundContext = component; - reboundMethod.__reactBoundMethod = method; - reboundMethod.__reactBoundArguments = args; - return reboundMethod; - }; - } - return boundMethod; -} - -/** - * Binds all auto-bound methods in a component. - * - * @param {object} component Component whose method is going to be bound. - */ -function bindAutoBindMethods(component) { - var pairs = component.__reactAutoBindPairs; - for (var i = 0; i < pairs.length; i += 2) { - var autoBindKey = pairs[i]; - var method = pairs[i + 1]; - component[autoBindKey] = bindAutoBindMethod(component, method); - } -} - -/** - * Add more to the ReactClass base class. These are all legacy features and - * therefore not already part of the modern ReactComponent. - */ -var ReactClassMixin = { - - /** - * TODO: This will be deprecated because state should always keep a consistent - * type signature and the only use case for this, is to avoid that. - */ - replaceState: function (newState, callback) { - this.updater.enqueueReplaceState(this, newState); - if (callback) { - this.updater.enqueueCallback(this, callback, 'replaceState'); - } - }, - - /** - * Checks whether or not this composite component is mounted. - * @return {boolean} True if mounted, false otherwise. - * @protected - * @final - */ - isMounted: function () { - return this.updater.isMounted(this); - } -}; - -var ReactClassComponent = function () {}; -_assign(ReactClassComponent.prototype, ReactComponent.prototype, ReactClassMixin); - -/** - * Module for creating composite components. - * - * @class ReactClass - */ -var ReactClass = { - - /** - * Creates a composite component class given a class specification. - * See https://facebook.github.io/react/docs/top-level-api.html#react.createclass - * - * @param {object} spec Class specification (which must define `render`). - * @return {function} Component constructor function. - * @public - */ - createClass: function (spec) { - // To keep our warnings more understandable, we'll use a little hack here to - // ensure that Constructor.name !== 'Constructor'. This makes sure we don't - // unnecessarily identify a class without displayName as 'Constructor'. - var Constructor = identity(function (props, context, updater) { - // This constructor gets overridden by mocks. The argument is used - // by mocks to assert on what gets mounted. - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(this instanceof Constructor, 'Something is calling a React component directly. Use a factory or ' + 'JSX instead. See: https://fb.me/react-legacyfactory') : void 0; - } - - // Wire up auto-binding - if (this.__reactAutoBindPairs.length) { - bindAutoBindMethods(this); - } - - this.props = props; - this.context = context; - this.refs = emptyObject; - this.updater = updater || ReactNoopUpdateQueue; - - this.state = null; - - // ReactClasses doesn't have constructors. Instead, they use the - // getInitialState and componentWillMount methods for initialization. - - var initialState = this.getInitialState ? this.getInitialState() : null; - if (process.env.NODE_ENV !== 'production') { - // We allow auto-mocks to proceed as if they're returning null. - if (initialState === undefined && this.getInitialState._isMockFunction) { - // This is probably bad practice. Consider warning here and - // deprecating this convenience. - initialState = null; - } - } - !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getInitialState(): must return an object or null', Constructor.displayName || 'ReactCompositeComponent') : _prodInvariant('82', Constructor.displayName || 'ReactCompositeComponent') : void 0; - - this.state = initialState; - }); - Constructor.prototype = new ReactClassComponent(); - Constructor.prototype.constructor = Constructor; - Constructor.prototype.__reactAutoBindPairs = []; - - injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor)); - - mixSpecIntoComponent(Constructor, spec); - - // Initialize the defaultProps property after all mixins have been merged. - if (Constructor.getDefaultProps) { - Constructor.defaultProps = Constructor.getDefaultProps(); - } - - if (process.env.NODE_ENV !== 'production') { - // This is a tag to indicate that the use of these method names is ok, - // since it's used with createClass. If it's not, then it's likely a - // mistake so we'll warn you to use the static property, property - // initializer or constructor respectively. - if (Constructor.getDefaultProps) { - Constructor.getDefaultProps.isReactClassApproved = {}; - } - if (Constructor.prototype.getInitialState) { - Constructor.prototype.getInitialState.isReactClassApproved = {}; - } - } - - !Constructor.prototype.render ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createClass(...): Class specification must implement a `render` method.') : _prodInvariant('83') : void 0; - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(!Constructor.prototype.componentShouldUpdate, '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', spec.displayName || 'A component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(!Constructor.prototype.componentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', spec.displayName || 'A component') : void 0; - } - - // Reduce time spent doing lookups by setting these on the prototype. - for (var methodName in ReactClassInterface) { - if (!Constructor.prototype[methodName]) { - Constructor.prototype[methodName] = null; - } - } - - return Constructor; - }, - - injection: { - injectMixin: function (mixin) { - injectedMixins.push(mixin); - } - } - -}; - -module.exports = ReactClass; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 328 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactElement = __webpack_require__(22); - -/** - * Create a factory that creates HTML tag elements. - * - * @private - */ -var createDOMFactory = ReactElement.createFactory; -if (process.env.NODE_ENV !== 'production') { - var ReactElementValidator = __webpack_require__(104); - createDOMFactory = ReactElementValidator.createFactory; -} - -/** - * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. - * This is also accessible via `React.DOM`. - * - * @public - */ -var ReactDOMFactories = { - a: createDOMFactory('a'), - abbr: createDOMFactory('abbr'), - address: createDOMFactory('address'), - area: createDOMFactory('area'), - article: createDOMFactory('article'), - aside: createDOMFactory('aside'), - audio: createDOMFactory('audio'), - b: createDOMFactory('b'), - base: createDOMFactory('base'), - bdi: createDOMFactory('bdi'), - bdo: createDOMFactory('bdo'), - big: createDOMFactory('big'), - blockquote: createDOMFactory('blockquote'), - body: createDOMFactory('body'), - br: createDOMFactory('br'), - button: createDOMFactory('button'), - canvas: createDOMFactory('canvas'), - caption: createDOMFactory('caption'), - cite: createDOMFactory('cite'), - code: createDOMFactory('code'), - col: createDOMFactory('col'), - colgroup: createDOMFactory('colgroup'), - data: createDOMFactory('data'), - datalist: createDOMFactory('datalist'), - dd: createDOMFactory('dd'), - del: createDOMFactory('del'), - details: createDOMFactory('details'), - dfn: createDOMFactory('dfn'), - dialog: createDOMFactory('dialog'), - div: createDOMFactory('div'), - dl: createDOMFactory('dl'), - dt: createDOMFactory('dt'), - em: createDOMFactory('em'), - embed: createDOMFactory('embed'), - fieldset: createDOMFactory('fieldset'), - figcaption: createDOMFactory('figcaption'), - figure: createDOMFactory('figure'), - footer: createDOMFactory('footer'), - form: createDOMFactory('form'), - h1: createDOMFactory('h1'), - h2: createDOMFactory('h2'), - h3: createDOMFactory('h3'), - h4: createDOMFactory('h4'), - h5: createDOMFactory('h5'), - h6: createDOMFactory('h6'), - head: createDOMFactory('head'), - header: createDOMFactory('header'), - hgroup: createDOMFactory('hgroup'), - hr: createDOMFactory('hr'), - html: createDOMFactory('html'), - i: createDOMFactory('i'), - iframe: createDOMFactory('iframe'), - img: createDOMFactory('img'), - input: createDOMFactory('input'), - ins: createDOMFactory('ins'), - kbd: createDOMFactory('kbd'), - keygen: createDOMFactory('keygen'), - label: createDOMFactory('label'), - legend: createDOMFactory('legend'), - li: createDOMFactory('li'), - link: createDOMFactory('link'), - main: createDOMFactory('main'), - map: createDOMFactory('map'), - mark: createDOMFactory('mark'), - menu: createDOMFactory('menu'), - menuitem: createDOMFactory('menuitem'), - meta: createDOMFactory('meta'), - meter: createDOMFactory('meter'), - nav: createDOMFactory('nav'), - noscript: createDOMFactory('noscript'), - object: createDOMFactory('object'), - ol: createDOMFactory('ol'), - optgroup: createDOMFactory('optgroup'), - option: createDOMFactory('option'), - output: createDOMFactory('output'), - p: createDOMFactory('p'), - param: createDOMFactory('param'), - picture: createDOMFactory('picture'), - pre: createDOMFactory('pre'), - progress: createDOMFactory('progress'), - q: createDOMFactory('q'), - rp: createDOMFactory('rp'), - rt: createDOMFactory('rt'), - ruby: createDOMFactory('ruby'), - s: createDOMFactory('s'), - samp: createDOMFactory('samp'), - script: createDOMFactory('script'), - section: createDOMFactory('section'), - select: createDOMFactory('select'), - small: createDOMFactory('small'), - source: createDOMFactory('source'), - span: createDOMFactory('span'), - strong: createDOMFactory('strong'), - style: createDOMFactory('style'), - sub: createDOMFactory('sub'), - summary: createDOMFactory('summary'), - sup: createDOMFactory('sup'), - table: createDOMFactory('table'), - tbody: createDOMFactory('tbody'), - td: createDOMFactory('td'), - textarea: createDOMFactory('textarea'), - tfoot: createDOMFactory('tfoot'), - th: createDOMFactory('th'), - thead: createDOMFactory('thead'), - time: createDOMFactory('time'), - title: createDOMFactory('title'), - tr: createDOMFactory('tr'), - track: createDOMFactory('track'), - u: createDOMFactory('u'), - ul: createDOMFactory('ul'), - 'var': createDOMFactory('var'), - video: createDOMFactory('video'), - wbr: createDOMFactory('wbr'), - - // SVG - circle: createDOMFactory('circle'), - clipPath: createDOMFactory('clipPath'), - defs: createDOMFactory('defs'), - ellipse: createDOMFactory('ellipse'), - g: createDOMFactory('g'), - image: createDOMFactory('image'), - line: createDOMFactory('line'), - linearGradient: createDOMFactory('linearGradient'), - mask: createDOMFactory('mask'), - path: createDOMFactory('path'), - pattern: createDOMFactory('pattern'), - polygon: createDOMFactory('polygon'), - polyline: createDOMFactory('polyline'), - radialGradient: createDOMFactory('radialGradient'), - rect: createDOMFactory('rect'), - stop: createDOMFactory('stop'), - svg: createDOMFactory('svg'), - text: createDOMFactory('text'), - tspan: createDOMFactory('tspan') -}; - -module.exports = ReactDOMFactories; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 329 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactElement = __webpack_require__(22); -var ReactPropTypeLocationNames = __webpack_require__(65); -var ReactPropTypesSecret = __webpack_require__(105); - -var emptyFunction = __webpack_require__(12); -var getIteratorFn = __webpack_require__(67); -var warning = __webpack_require__(3); - -/** - * Collection of methods that allow declaration and validation of props that are - * supplied to React components. Example usage: - * - * var Props = require('ReactPropTypes'); - * var MyArticle = React.createClass({ - * propTypes: { - * // An optional string prop named "description". - * description: Props.string, - * - * // A required enum prop named "category". - * category: Props.oneOf(['News','Photos']).isRequired, - * - * // A prop named "dialog" that requires an instance of Dialog. - * dialog: Props.instanceOf(Dialog).isRequired - * }, - * render: function() { ... } - * }); - * - * A more formal specification of how these methods are used: - * - * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) - * decl := ReactPropTypes.{type}(.isRequired)? - * - * Each and every declaration produces a function with the same signature. This - * allows the creation of custom validation functions. For example: - * - * var MyLink = React.createClass({ - * propTypes: { - * // An optional string or URI prop named "href". - * href: function(props, propName, componentName) { - * var propValue = props[propName]; - * if (propValue != null && typeof propValue !== 'string' && - * !(propValue instanceof URI)) { - * return new Error( - * 'Expected a string or an URI for ' + propName + ' in ' + - * componentName - * ); - * } - * } - * }, - * render: function() {...} - * }); - * - * @internal - */ - -var ANONYMOUS = '<<anonymous>>'; - -var ReactPropTypes = { - array: createPrimitiveTypeChecker('array'), - bool: createPrimitiveTypeChecker('boolean'), - func: createPrimitiveTypeChecker('function'), - number: createPrimitiveTypeChecker('number'), - object: createPrimitiveTypeChecker('object'), - string: createPrimitiveTypeChecker('string'), - symbol: createPrimitiveTypeChecker('symbol'), - - any: createAnyTypeChecker(), - arrayOf: createArrayOfTypeChecker, - element: createElementTypeChecker(), - instanceOf: createInstanceTypeChecker, - node: createNodeChecker(), - objectOf: createObjectOfTypeChecker, - oneOf: createEnumTypeChecker, - oneOfType: createUnionTypeChecker, - shape: createShapeTypeChecker -}; - -/** - * inlined Object.is polyfill to avoid requiring consumers ship their own - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is - */ -/*eslint-disable no-self-compare*/ -function is(x, y) { - // SameValue algorithm - if (x === y) { - // Steps 1-5, 7-10 - // Steps 6.b-6.e: +0 != -0 - return x !== 0 || 1 / x === 1 / y; - } else { - // Step 6.a: NaN == NaN - return x !== x && y !== y; - } -} -/*eslint-enable no-self-compare*/ - -/** - * We use an Error-like object for backward compatibility as people may call - * PropTypes directly and inspect their output. However we don't use real - * Errors anymore. We don't inspect their stack anyway, and creating them - * is prohibitively expensive if they are created too often, such as what - * happens in oneOfType() for any type before the one that matched. - */ -function PropTypeError(message) { - this.message = message; - this.stack = ''; -} -// Make `instanceof Error` still work for returned errors. -PropTypeError.prototype = Error.prototype; - -function createChainableTypeChecker(validate) { - if (process.env.NODE_ENV !== 'production') { - var manualPropTypeCallCache = {}; - } - function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { - componentName = componentName || ANONYMOUS; - propFullName = propFullName || propName; - if (process.env.NODE_ENV !== 'production') { - if (secret !== ReactPropTypesSecret && typeof console !== 'undefined') { - var cacheKey = componentName + ':' + propName; - if (!manualPropTypeCallCache[cacheKey]) { - process.env.NODE_ENV !== 'production' ? warning(false, 'You are manually calling a React.PropTypes validation ' + 'function for the `%s` prop on `%s`. This is deprecated ' + 'and will not work in production with the next major version. ' + 'You may be seeing this warning due to a third-party PropTypes ' + 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.', propFullName, componentName) : void 0; - manualPropTypeCallCache[cacheKey] = true; - } - } - } - if (props[propName] == null) { - var locationName = ReactPropTypeLocationNames[location]; - if (isRequired) { - if (props[propName] === null) { - return new PropTypeError('The ' + locationName + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); - } - return new PropTypeError('The ' + locationName + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.')); - } - return null; - } else { - return validate(props, propName, componentName, location, propFullName); - } - } - - var chainedCheckType = checkType.bind(null, false); - chainedCheckType.isRequired = checkType.bind(null, true); - - return chainedCheckType; -} - -function createPrimitiveTypeChecker(expectedType) { - function validate(props, propName, componentName, location, propFullName, secret) { - var propValue = props[propName]; - var propType = getPropType(propValue); - if (propType !== expectedType) { - var locationName = ReactPropTypeLocationNames[location]; - // `propValue` being instance of, say, date/regexp, pass the 'object' - // check, but we can offer a more precise error message here rather than - // 'of type `object`'. - var preciseType = getPreciseType(propValue); - - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.')); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createAnyTypeChecker() { - return createChainableTypeChecker(emptyFunction.thatReturns(null)); -} - -function createArrayOfTypeChecker(typeChecker) { - function validate(props, propName, componentName, location, propFullName) { - if (typeof typeChecker !== 'function') { - return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.'); - } - var propValue = props[propName]; - if (!Array.isArray(propValue)) { - var locationName = ReactPropTypeLocationNames[location]; - var propType = getPropType(propValue); - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); - } - for (var i = 0; i < propValue.length; i++) { - var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret); - if (error instanceof Error) { - return error; - } - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createElementTypeChecker() { - function validate(props, propName, componentName, location, propFullName) { - var propValue = props[propName]; - if (!ReactElement.isValidElement(propValue)) { - var locationName = ReactPropTypeLocationNames[location]; - var propType = getPropType(propValue); - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.')); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createInstanceTypeChecker(expectedClass) { - function validate(props, propName, componentName, location, propFullName) { - if (!(props[propName] instanceof expectedClass)) { - var locationName = ReactPropTypeLocationNames[location]; - var expectedClassName = expectedClass.name || ANONYMOUS; - var actualClassName = getClassName(props[propName]); - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createEnumTypeChecker(expectedValues) { - if (!Array.isArray(expectedValues)) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOf, expected an instance of array.') : void 0; - return emptyFunction.thatReturnsNull; - } - - function validate(props, propName, componentName, location, propFullName) { - var propValue = props[propName]; - for (var i = 0; i < expectedValues.length; i++) { - if (is(propValue, expectedValues[i])) { - return null; - } - } - - var locationName = ReactPropTypeLocationNames[location]; - var valuesString = JSON.stringify(expectedValues); - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); - } - return createChainableTypeChecker(validate); -} - -function createObjectOfTypeChecker(typeChecker) { - function validate(props, propName, componentName, location, propFullName) { - if (typeof typeChecker !== 'function') { - return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.'); - } - var propValue = props[propName]; - var propType = getPropType(propValue); - if (propType !== 'object') { - var locationName = ReactPropTypeLocationNames[location]; - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.')); - } - for (var key in propValue) { - if (propValue.hasOwnProperty(key)) { - var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); - if (error instanceof Error) { - return error; - } - } - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createUnionTypeChecker(arrayOfTypeCheckers) { - if (!Array.isArray(arrayOfTypeCheckers)) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOfType, expected an instance of array.') : void 0; - return emptyFunction.thatReturnsNull; - } - - function validate(props, propName, componentName, location, propFullName) { - for (var i = 0; i < arrayOfTypeCheckers.length; i++) { - var checker = arrayOfTypeCheckers[i]; - if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret) == null) { - return null; - } - } - - var locationName = ReactPropTypeLocationNames[location]; - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.')); - } - return createChainableTypeChecker(validate); -} - -function createNodeChecker() { - function validate(props, propName, componentName, location, propFullName) { - if (!isNode(props[propName])) { - var locationName = ReactPropTypeLocationNames[location]; - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createShapeTypeChecker(shapeTypes) { - function validate(props, propName, componentName, location, propFullName) { - var propValue = props[propName]; - var propType = getPropType(propValue); - if (propType !== 'object') { - var locationName = ReactPropTypeLocationNames[location]; - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); - } - for (var key in shapeTypes) { - var checker = shapeTypes[key]; - if (!checker) { - continue; - } - var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); - if (error) { - return error; - } - } - return null; - } - return createChainableTypeChecker(validate); -} - -function isNode(propValue) { - switch (typeof propValue) { - case 'number': - case 'string': - case 'undefined': - return true; - case 'boolean': - return !propValue; - case 'object': - if (Array.isArray(propValue)) { - return propValue.every(isNode); - } - if (propValue === null || ReactElement.isValidElement(propValue)) { - return true; - } - - var iteratorFn = getIteratorFn(propValue); - if (iteratorFn) { - var iterator = iteratorFn.call(propValue); - var step; - if (iteratorFn !== propValue.entries) { - while (!(step = iterator.next()).done) { - if (!isNode(step.value)) { - return false; - } - } - } else { - // Iterator will provide entry [k,v] tuples rather than values. - while (!(step = iterator.next()).done) { - var entry = step.value; - if (entry) { - if (!isNode(entry[1])) { - return false; - } - } - } - } - } else { - return false; - } - - return true; - default: - return false; - } -} - -function isSymbol(propType, propValue) { - // Native Symbol. - if (propType === 'symbol') { - return true; - } - - // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' - if (propValue['@@toStringTag'] === 'Symbol') { - return true; - } - - // Fallback for non-spec compliant Symbols which are polyfilled. - if (typeof Symbol === 'function' && propValue instanceof Symbol) { - return true; - } - - return false; -} - -// Equivalent of `typeof` but with special handling for array and regexp. -function getPropType(propValue) { - var propType = typeof propValue; - if (Array.isArray(propValue)) { - return 'array'; - } - if (propValue instanceof RegExp) { - // Old webkits (at least until Android 4.0) return 'function' rather than - // 'object' for typeof a RegExp. We'll normalize this here so that /bla/ - // passes PropTypes.object. - return 'object'; - } - if (isSymbol(propType, propValue)) { - return 'symbol'; - } - return propType; -} - -// This handles more types than `getPropType`. Only used for error messages. -// See `createPrimitiveTypeChecker`. -function getPreciseType(propValue) { - var propType = getPropType(propValue); - if (propType === 'object') { - if (propValue instanceof Date) { - return 'date'; - } else if (propValue instanceof RegExp) { - return 'regexp'; - } - } - return propType; -} - -// Returns class name of the object, if any. -function getClassName(propValue) { - if (!propValue.constructor || !propValue.constructor.name) { - return ANONYMOUS; - } - return propValue.constructor.name; -} - -module.exports = ReactPropTypes; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 330 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var ReactComponent = __webpack_require__(63); -var ReactNoopUpdateQueue = __webpack_require__(64); - -var emptyObject = __webpack_require__(28); - -/** - * Base class helpers for the updating state of a component. - */ -function ReactPureComponent(props, context, updater) { - // Duplicated from ReactComponent. - this.props = props; - this.context = context; - this.refs = emptyObject; - // We initialize the default updater but the real one gets injected by the - // renderer. - this.updater = updater || ReactNoopUpdateQueue; -} - -function ComponentDummy() {} -ComponentDummy.prototype = ReactComponent.prototype; -ReactPureComponent.prototype = new ComponentDummy(); -ReactPureComponent.prototype.constructor = ReactPureComponent; -// Avoid an extra prototype jump for these methods. -_assign(ReactPureComponent.prototype, ReactComponent.prototype); -ReactPureComponent.prototype.isPureReactComponent = true; - -module.exports = ReactPureComponent; - -/***/ }), -/* 331 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -module.exports = '15.4.2'; - -/***/ }), -/* 332 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(23); - -var ReactPropTypeLocationNames = __webpack_require__(65); -var ReactPropTypesSecret = __webpack_require__(105); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -var ReactComponentTreeHook; - -if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'test') { - // Temporary hack. - // Inline requires don't work well with Jest: - // https://github.com/facebook/react/issues/7240 - // Remove the inline requires when we don't need them anymore: - // https://github.com/facebook/react/pull/7178 - ReactComponentTreeHook = __webpack_require__(9); -} - -var loggedTypeFailures = {}; - -/** - * Assert that the values match with the type specs. - * Error messages are memorized and will only be shown once. - * - * @param {object} typeSpecs Map of name to a ReactPropType - * @param {object} values Runtime values that need to be type-checked - * @param {string} location e.g. "prop", "context", "child context" - * @param {string} componentName Name of the component for error messages. - * @param {?object} element The React element that is being type-checked - * @param {?number} debugID The React component instance that is being type-checked - * @private - */ -function checkReactTypeSpec(typeSpecs, values, location, componentName, element, debugID) { - for (var typeSpecName in typeSpecs) { - if (typeSpecs.hasOwnProperty(typeSpecName)) { - var error; - // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - !(typeof typeSpecs[typeSpecName] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : _prodInvariant('84', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : void 0; - error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); - } catch (ex) { - error = ex; - } - process.env.NODE_ENV !== 'production' ? warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName, typeof error) : void 0; - if (error instanceof Error && !(error.message in loggedTypeFailures)) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error.message] = true; - - var componentStackInfo = ''; - - if (process.env.NODE_ENV !== 'production') { - if (!ReactComponentTreeHook) { - ReactComponentTreeHook = __webpack_require__(9); - } - if (debugID !== null) { - componentStackInfo = ReactComponentTreeHook.getStackAddendumByID(debugID); - } else if (element !== null) { - componentStackInfo = ReactComponentTreeHook.getCurrentStackAddendum(element); - } - } - - process.env.NODE_ENV !== 'production' ? warning(false, 'Failed %s type: %s%s', location, error.message, componentStackInfo) : void 0; - } - } - } -} - -module.exports = checkReactTypeSpec; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 333 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - -var _prodInvariant = __webpack_require__(23); - -var ReactElement = __webpack_require__(22); - -var invariant = __webpack_require__(2); - -/** - * Returns the first child in a collection of children and verifies that there - * is only one child in the collection. - * - * See https://facebook.github.io/react/docs/top-level-api.html#react.children.only - * - * The current implementation of this function assumes that a single child gets - * passed without a wrapper, but the purpose of this helper function is to - * abstract away the particular structure of children. - * - * @param {?object} children Child collection structure. - * @return {ReactElement} The first and only `ReactElement` contained in the - * structure. - */ -function onlyChild(children) { - !ReactElement.isValidElement(children) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'React.Children.only expected to receive a single React element child.') : _prodInvariant('143') : void 0; - return children; -} - -module.exports = onlyChild; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 334 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(23); - -var ReactCurrentOwner = __webpack_require__(15); -var REACT_ELEMENT_TYPE = __webpack_require__(103); - -var getIteratorFn = __webpack_require__(67); -var invariant = __webpack_require__(2); -var KeyEscapeUtils = __webpack_require__(324); -var warning = __webpack_require__(3); - -var SEPARATOR = '.'; -var SUBSEPARATOR = ':'; - -/** - * This is inlined from ReactElement since this file is shared between - * isomorphic and renderers. We could extract this to a - * - */ - -/** - * TODO: Test that a single child and an array with one item have the same key - * pattern. - */ - -var didWarnAboutMaps = false; - -/** - * Generate a key string that identifies a component within a set. - * - * @param {*} component A component that could contain a manual key. - * @param {number} index Index that is used if a manual key is not provided. - * @return {string} - */ -function getComponentKey(component, index) { - // Do some typechecking here since we call this blindly. We want to ensure - // that we don't block potential future ES APIs. - if (component && typeof component === 'object' && component.key != null) { - // Explicit key - return KeyEscapeUtils.escape(component.key); - } - // Implicit key determined by the index in the set - return index.toString(36); -} - -/** - * @param {?*} children Children tree container. - * @param {!string} nameSoFar Name of the key path so far. - * @param {!function} callback Callback to invoke with each child found. - * @param {?*} traverseContext Used to pass information throughout the traversal - * process. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) { - var type = typeof children; - - if (type === 'undefined' || type === 'boolean') { - // All of the above are perceived as null. - children = null; - } - - if (children === null || type === 'string' || type === 'number' || - // The following is inlined from ReactElement. This means we can optimize - // some checks. React Fiber also inlines this logic for similar purposes. - type === 'object' && children.$$typeof === REACT_ELEMENT_TYPE) { - callback(traverseContext, children, - // If it's the only child, treat the name as if it was wrapped in an array - // so that it's consistent if the number of children grows. - nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar); - return 1; - } - - var child; - var nextName; - var subtreeCount = 0; // Count of children found in the current subtree. - var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR; - - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - child = children[i]; - nextName = nextNamePrefix + getComponentKey(child, i); - subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); - } - } else { - var iteratorFn = getIteratorFn(children); - if (iteratorFn) { - var iterator = iteratorFn.call(children); - var step; - if (iteratorFn !== children.entries) { - var ii = 0; - while (!(step = iterator.next()).done) { - child = step.value; - nextName = nextNamePrefix + getComponentKey(child, ii++); - subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); - } - } else { - if (process.env.NODE_ENV !== 'production') { - var mapsAsChildrenAddendum = ''; - if (ReactCurrentOwner.current) { - var mapsAsChildrenOwnerName = ReactCurrentOwner.current.getName(); - if (mapsAsChildrenOwnerName) { - mapsAsChildrenAddendum = ' Check the render method of `' + mapsAsChildrenOwnerName + '`.'; - } - } - process.env.NODE_ENV !== 'production' ? warning(didWarnAboutMaps, 'Using Maps as children is not yet fully supported. It is an ' + 'experimental feature that might be removed. Convert it to a ' + 'sequence / iterable of keyed ReactElements instead.%s', mapsAsChildrenAddendum) : void 0; - didWarnAboutMaps = true; - } - // Iterator will provide entry [k,v] tuples rather than values. - while (!(step = iterator.next()).done) { - var entry = step.value; - if (entry) { - child = entry[1]; - nextName = nextNamePrefix + KeyEscapeUtils.escape(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0); - subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); - } - } - } - } else if (type === 'object') { - var addendum = ''; - if (process.env.NODE_ENV !== 'production') { - addendum = ' If you meant to render a collection of children, use an array ' + 'instead or wrap the object using createFragment(object) from the ' + 'React add-ons.'; - if (children._isReactElement) { - addendum = ' It looks like you\'re using an element created by a different ' + 'version of React. Make sure to use only one copy of React.'; - } - if (ReactCurrentOwner.current) { - var name = ReactCurrentOwner.current.getName(); - if (name) { - addendum += ' Check the render method of `' + name + '`.'; - } - } - } - var childrenString = String(children); - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : _prodInvariant('31', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : void 0; - } - } - - return subtreeCount; -} - -/** - * Traverses children that are typically specified as `props.children`, but - * might also be specified through attributes: - * - * - `traverseAllChildren(this.props.children, ...)` - * - `traverseAllChildren(this.props.leftPanelChildren, ...)` - * - * The `traverseContext` is an optional argument that is passed through the - * entire traversal. It can be used to store accumulations or anything else that - * the callback might find relevant. - * - * @param {?*} children Children tree object. - * @param {!function} callback To invoke upon traversing each child. - * @param {?*} traverseContext Context for traversal. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildren(children, callback, traverseContext) { - if (children == null) { - return 0; - } - - return traverseAllChildrenImpl(children, '', callback, traverseContext); -} - -module.exports = traverseAllChildren; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 335 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -module.exports = function (str) { - return encodeURIComponent(str).replace(/[!'()*]/g, function (c) { - return '%' + c.charCodeAt(0).toString(16).toUpperCase(); - }); -}; - - -/***/ }), -/* 336 */ -/***/ (function(module, exports) { - -module.exports = function(module) { - if(!module.webpackPolyfill) { - module.deprecate = function() {}; - module.paths = []; - // module.parent = undefined by default - if(!module.children) module.children = []; - Object.defineProperty(module, "loaded", { - enumerable: true, - get: function() { - return module.l; - } - }); - Object.defineProperty(module, "id", { - enumerable: true, - get: function() { - return module.i; - } - }); - module.webpackPolyfill = 1; - } - return module; -}; - - -/***/ }), -/* 337 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(106); - - -/***/ }) -/******/ ]); -}); \ No newline at end of file +x.brewer=b={OrRd:["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"],PuBu:["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"],BuPu:["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"],Oranges:["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"],BuGn:["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"],YlOrBr:["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"],YlGn:["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"],Reds:["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"],RdPu:["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"],Greens:["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"],YlGnBu:["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"],Purples:["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"],GnBu:["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"],Greys:["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"],YlOrRd:["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"],PuRd:["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"],Blues:["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"],PuBuGn:["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"],Spectral:["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"],RdYlGn:["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"],RdBu:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"],PiYG:["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"],PRGn:["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"],RdYlBu:["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"],BrBG:["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"],RdGy:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"],PuOr:["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"],Set2:["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"],Accent:["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"],Set1:["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"],Set3:["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"],Dark2:["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"],Paired:["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"],Pastel2:["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"],Pastel1:["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"]},ke={indigo:"#4b0082",gold:"#ffd700",hotpink:"#ff69b4",firebrick:"#b22222",indianred:"#cd5c5c",yellow:"#ffff00",mistyrose:"#ffe4e1",darkolivegreen:"#556b2f",olive:"#808000",darkseagreen:"#8fbc8f",pink:"#ffc0cb",tomato:"#ff6347",lightcoral:"#f08080",orangered:"#ff4500",navajowhite:"#ffdead",lime:"#00ff00",palegreen:"#98fb98",darkslategrey:"#2f4f4f",greenyellow:"#adff2f",burlywood:"#deb887",seashell:"#fff5ee",mediumspringgreen:"#00fa9a",fuchsia:"#ff00ff",papayawhip:"#ffefd5",blanchedalmond:"#ffebcd",chartreuse:"#7fff00",dimgray:"#696969",black:"#000000",peachpuff:"#ffdab9",springgreen:"#00ff7f",aquamarine:"#7fffd4",white:"#ffffff",orange:"#ffa500",lightsalmon:"#ffa07a",darkslategray:"#2f4f4f",brown:"#a52a2a",ivory:"#fffff0",dodgerblue:"#1e90ff",peru:"#cd853f",lawngreen:"#7cfc00",chocolate:"#d2691e",crimson:"#dc143c",forestgreen:"#228b22",darkgrey:"#a9a9a9",lightseagreen:"#20b2aa",cyan:"#00ffff",mintcream:"#f5fffa",silver:"#c0c0c0",antiquewhite:"#faebd7",mediumorchid:"#ba55d3",skyblue:"#87ceeb",gray:"#808080",darkturquoise:"#00ced1",goldenrod:"#daa520",darkgreen:"#006400",floralwhite:"#fffaf0",darkviolet:"#9400d3",darkgray:"#a9a9a9",moccasin:"#ffe4b5",saddlebrown:"#8b4513",grey:"#808080",darkslateblue:"#483d8b",lightskyblue:"#87cefa",lightpink:"#ffb6c1",mediumvioletred:"#c71585",slategrey:"#708090",red:"#ff0000",deeppink:"#ff1493",limegreen:"#32cd32",darkmagenta:"#8b008b",palegoldenrod:"#eee8aa",plum:"#dda0dd",turquoise:"#40e0d0",lightgrey:"#d3d3d3",lightgoldenrodyellow:"#fafad2",darkgoldenrod:"#b8860b",lavender:"#e6e6fa",maroon:"#800000",yellowgreen:"#9acd32",sandybrown:"#f4a460",thistle:"#d8bfd8",violet:"#ee82ee",navy:"#000080",magenta:"#ff00ff",dimgrey:"#696969",tan:"#d2b48c",rosybrown:"#bc8f8f",olivedrab:"#6b8e23",blue:"#0000ff",lightblue:"#add8e6",ghostwhite:"#f8f8ff",honeydew:"#f0fff0",cornflowerblue:"#6495ed",slateblue:"#6a5acd",linen:"#faf0e6",darkblue:"#00008b",powderblue:"#b0e0e6",seagreen:"#2e8b57",darkkhaki:"#bdb76b",snow:"#fffafa",sienna:"#a0522d",mediumblue:"#0000cd",royalblue:"#4169e1",lightcyan:"#e0ffff",green:"#008000",mediumpurple:"#9370db",midnightblue:"#191970",cornsilk:"#fff8dc",paleturquoise:"#afeeee",bisque:"#ffe4c4",slategray:"#708090",darkcyan:"#008b8b",khaki:"#f0e68c",wheat:"#f5deb3",teal:"#008080",darkorchid:"#9932cc",deepskyblue:"#00bfff",salmon:"#fa8072",darkred:"#8b0000",steelblue:"#4682b4",palevioletred:"#db7093",lightslategray:"#778899",aliceblue:"#f0f8ff",lightslategrey:"#778899",lightgreen:"#90ee90",orchid:"#da70d6",gainsboro:"#dcdcdc",mediumseagreen:"#3cb371",lightgray:"#d3d3d3",mediumturquoise:"#48d1cc",lemonchiffon:"#fffacd",cadetblue:"#5f9ea0",lightyellow:"#ffffe0",lavenderblush:"#fff0f5",coral:"#ff7f50",purple:"#800080",aqua:"#00ffff",whitesmoke:"#f5f5f5",mediumslateblue:"#7b68ee",darkorange:"#ff8c00",mediumaquamarine:"#66cdaa",darksalmon:"#e9967a",beige:"#f5f5dc",blueviolet:"#8a2be2",azure:"#f0ffff",lightsteelblue:"#b0c4de",oldlace:"#fdf5e6",rebeccapurple:"#663399"},x.colors=k=ke,U=function(){var e,t,n,r,i,a,s,l,c;return t=Ce(arguments),i=t[0],e=t[1],n=t[2],l=(i+16)/116,s=isNaN(e)?l:l+e/500,c=isNaN(n)?l:l-n/200,l=o.Yn*W(l),s=o.Xn*W(s),c=o.Zn*W(c),a=Pe(3.2404542*s-1.5371385*l-.4985314*c),r=Pe(-.969266*s+1.8760108*l+.041556*c),n=Pe(.0556434*s-.2040259*l+1.0572252*c),a=K(a,0,255),r=K(r,0,255),n=K(n,0,255),[a,r,n,t.length>3?t[3]:1]},Pe=function(e){return we(255*(e<=.00304?12.92*e:1.055*re(e,1/2.4)-.055))},W=function(e){return e>o.t1?e*e*e:o.t2*(e-o.t0)},o={Kn:18,Xn:.95047,Yn:1,Zn:1.08883,t0:.137931034,t1:.206896552,t2:.12841855,t3:.008856452},ue=function(){var e,t,n,r,i,a,o,s;return r=Ce(arguments),n=r[0],t=r[1],e=r[2],i=me(n,t,e),a=i[0],o=i[1],s=i[2],[116*o-16,500*(a-o),200*(o-s)]},ge=function(e){return(e/=255)<=.04045?e/12.92:re((e+.055)/1.055,2.4)},Se=function(e){return e>o.t3?re(e,1/3):e/o.t2+o.t0},me=function(){var e,t,n,r,i,a,s;return r=Ce(arguments),n=r[0],t=r[1],e=r[2],n=ge(n),t=ge(t),e=ge(e),i=Se((.4124564*n+.3575761*t+.1804375*e)/o.Xn),a=Se((.2126729*n+.7151522*t+.072175*e)/o.Yn),s=Se((.0193339*n+.119192*t+.9503041*e)/o.Zn),[i,a,s]},x.lab=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["lab"]),function(){})},f.lab=U,i.prototype.lab=function(){return ue(this._rgb)},v=function(e){var t,n,r,i,a,o,s,l,c,u,h;return e=function(){var t,n,r;for(r=[],n=0,t=e.length;n<t;n++)i=e[n],r.push(x(i));return r}(),2===e.length?(c=function(){var t,n,r;for(r=[],n=0,t=e.length;n<t;n++)i=e[n],r.push(i.lab());return r}(),a=c[0],o=c[1],t=function(e){var t,n;return n=function(){var n,r;for(r=[],t=n=0;n<=2;t=++n)r.push(a[t]+e*(o[t]-a[t]));return r}(),x.lab.apply(x,n)}):3===e.length?(u=function(){var t,n,r;for(r=[],n=0,t=e.length;n<t;n++)i=e[n],r.push(i.lab());return r}(),a=u[0],o=u[1],s=u[2],t=function(e){var t,n;return n=function(){var n,r;for(r=[],t=n=0;n<=2;t=++n)r.push((1-e)*(1-e)*a[t]+2*(1-e)*e*o[t]+e*e*s[t]);return r}(),x.lab.apply(x,n)}):4===e.length?(h=function(){var t,n,r;for(r=[],n=0,t=e.length;n<t;n++)i=e[n],r.push(i.lab());return r}(),a=h[0],o=h[1],s=h[2],l=h[3],t=function(e){var t,n;return n=function(){var n,r;for(r=[],t=n=0;n<=2;t=++n)r.push((1-e)*(1-e)*(1-e)*a[t]+3*(1-e)*(1-e)*e*o[t]+3*(1-e)*e*e*s[t]+e*e*e*l[t]);return r}(),x.lab.apply(x,n)}):5===e.length&&(n=v(e.slice(0,3)),r=v(e.slice(2,5)),t=function(e){return e<.5?n(2*e):r(2*(e-.5))}),t},x.bezier=function(e){var t;return t=v(e),t.scale=function(){return x.scale(t)},t},x.cubehelix=function(e,t,n,r,i){var a,o,s;return null==e&&(e=300),null==t&&(t=-1.5),null==n&&(n=1),null==r&&(r=1),null==i&&(i=[0,1]),o=i[1]-i[0],a=0,s=function(s){var l,c,h,d,f,p,m,g,v;return l=u*((e+120)/360+t*s),m=re(i[0]+o*s,r),p=0!==a?n[0]+s*a:n,c=p*m*(1-m)/2,d=S(l),v=be(l),g=m+c*(-.14861*d+1.78277*v),f=m+c*(-.29227*d-.90649*v),h=m+c*(1.97294*d),x(E([255*g,255*f,255*h]))},s.start=function(t){return null==t?e:(e=t,s)},s.rotations=function(e){return null==e?t:(t=e,s)},s.gamma=function(e){return null==e?r:(r=e,s)},s.hue=function(e){return null==e?n:(n=e,"array"===Ee(n)?(a=n[1]-n[0],0===a&&(n=n[1])):a=0,s)},s.lightness=function(e){return null==e?i:(i=e,"array"===Ee(i)?(o=i[1]-i[0],0===o&&(i=i[1])):o=0,s)},s.scale=function(){return x.scale(s)},s.hue(n),s},x.random=function(){var e,t,n,r;for(t="0123456789abcdef",e="#",n=r=0;r<6;n=++r)e+=t.charAt(I(16*Math.random()));return new i(e)},x.average=function(e){var t,n,r,a,o,s,l,c,u;for(c=a=n=t=0,o=e.length,l=0,s=e.length;l<s;l++)r=e[l],u=x(r).rgba(),c+=u[0],a+=u[1],n+=u[2],t+=u[3];return new i(c/o,a/o,n/o,t/o)},f.rgb=function(){var e,t,n,r;t=Ce(arguments),n=[];for(e in t)r=t[e],n.push(r);return n},x.rgb=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["rgb"]),function(){})},i.prototype.rgb=function(){return this._rgb.slice(0,3)},i.prototype.rgba=function(){return this._rgb},h.push({p:15,test:function(e){var t;return t=Ce(arguments),"array"===Ee(t)&&3===t.length?"rgb":4===t.length&&"number"===Ee(t[3])&&t[3]>=0&&t[3]<=1?"rgb":void 0}}),L=function(e){var t,n,r,i,a,o;if(e.match(/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/))return 4!==e.length&&7!==e.length||(e=e.substr(1)),3===e.length&&(e=e.split(""),e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),o=parseInt(e,16),i=o>>16,r=o>>8&255,n=255&o,[i,r,n,1];if(e.match(/^#?([A-Fa-f0-9]{8})$/))return 9===e.length&&(e=e.substr(1)),o=parseInt(e,16),i=o>>24&255,r=o>>16&255,n=o>>8&255,t=we((255&o)/255*100)/100,[i,r,n,t];if(null!=f.css&&(a=f.css(e)))return a;throw"unknown color: "+e},oe=function(e,t){var n,r,i,a,o,s,l;return null==t&&(t="rgb"),o=e[0],i=e[1],r=e[2],n=e[3],l=o<<16|i<<8|r,s="000000"+l.toString(16),s=s.substr(s.length-6),a="0"+we(255*n).toString(16),a=a.substr(a.length-2),"#"+function(){switch(t.toLowerCase()){case"rgba":return s+a;case"argb":return a+s;default:return s}}()},f.hex=function(e){return L(e)},x.hex=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["hex"]),function(){})},i.prototype.hex=function(e){return null==e&&(e="rgb"),oe(this._rgb,e)},h.push({p:10,test:function(e){if(1===arguments.length&&"string"===Ee(e))return"hex"}}),B=function(){var e,t,n,r,i,a,o,s,l,c,u,h,d,f;if(e=Ce(arguments),i=e[0],u=e[1],o=e[2],0===u)l=r=t=255*o;else{for(f=[0,0,0],n=[0,0,0],d=o<.5?o*(1+u):o+u-o*u,h=2*o-d,i/=360,f[0]=i+1/3,f[1]=i,f[2]=i-1/3,a=s=0;s<=2;a=++s)f[a]<0&&(f[a]+=1),f[a]>1&&(f[a]-=1),6*f[a]<1?n[a]=h+6*(d-h)*f[a]:2*f[a]<1?n[a]=d:3*f[a]<2?n[a]=h+(d-h)*(2/3-f[a])*6:n[a]=h;c=[we(255*n[0]),we(255*n[1]),we(255*n[2])],l=c[0],r=c[1],t=c[2]}return e.length>3?[l,r,t,e[3]]:[l,r,t]},le=function(e,t,n){var r,i,a,o,s;return void 0!==e&&e.length>=3&&(o=e,e=o[0],t=o[1],n=o[2]),e/=255,t/=255,n/=255,a=Math.min(e,t,n),$=Math.max(e,t,n),i=($+a)/2,$===a?(s=0,r=Number.NaN):s=i<.5?($-a)/($+a):($-a)/(2-$-a),e===$?r=(t-n)/($-a):t===$?r=2+(n-e)/($-a):n===$&&(r=4+(e-t)/($-a)),r*=60,r<0&&(r+=360),[r,s,i]},x.hsl=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["hsl"]),function(){})},f.hsl=B,i.prototype.hsl=function(){return le(this._rgb)},z=function(){var e,t,n,r,i,a,o,s,l,c,u,h,d,f,p,m,g,v;if(e=Ce(arguments),i=e[0],m=e[1],v=e[2],v*=255,0===m)l=r=t=v;else switch(360===i&&(i=0),i>360&&(i-=360),i<0&&(i+=360),i/=60,a=I(i),n=i-a,o=v*(1-m),s=v*(1-m*n),g=v*(1-m*(1-n)),a){case 0:c=[v,g,o],l=c[0],r=c[1],t=c[2];break;case 1:u=[s,v,o],l=u[0],r=u[1],t=u[2];break;case 2:h=[o,v,g],l=h[0],r=h[1],t=h[2];break;case 3:d=[o,s,v],l=d[0],r=d[1],t=d[2];break;case 4:f=[g,o,v],l=f[0],r=f[1],t=f[2];break;case 5:p=[v,o,s],l=p[0],r=p[1],t=p[2]}return l=we(l),r=we(r),t=we(t),[l,r,t,e.length>3?e[3]:1]},ce=function(){var e,t,n,r,i,a,o,s,l;return o=Ce(arguments),a=o[0],n=o[1],e=o[2],i=Math.min(a,n,e),$=Math.max(a,n,e),t=$-i,l=$/255,0===$?(r=Number.NaN,s=0):(s=t/$,a===$&&(r=(n-e)/t),n===$&&(r=2+(e-a)/t),e===$&&(r=4+(a-n)/t),r*=60,r<0&&(r+=360)),[r,s,l]},x.hsv=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["hsv"]),function(){})},f.hsv=z,i.prototype.hsv=function(){return ce(this._rgb)},te=function(e){var t,n,r;return"number"===Ee(e)&&e>=0&&e<=16777215?(r=e>>16,n=e>>8&255,t=255&e,[r,n,t,1]):(console.warn("unknown num color: "+e),[0,0,0,1])},fe=function(){var e,t,n,r;return r=Ce(arguments),n=r[0],t=r[1],e=r[2],(n<<16)+(t<<8)+e},x.num=function(e){return new i(e,"num")},i.prototype.num=function(e){return null==e&&(e="rgb"),fe(this._rgb,e)},f.num=te,h.push({p:10,test:function(e){if(1===arguments.length&&"number"===Ee(e)&&e>=0&&e<=16777215)return"num"}}),P=function(e){var t,n,r,i,a,o,s,l;if(e=e.toLowerCase(),null!=x.colors&&x.colors[e])return L(x.colors[e]);if(a=e.match(/rgb\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*\)/)){for(s=a.slice(1,4),i=o=0;o<=2;i=++o)s[i]=+s[i];s[3]=1}else if(a=e.match(/rgba\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*,\s*([01]|[01]?\.\d+)\)/))for(s=a.slice(1,5),i=l=0;l<=3;i=++l)s[i]=+s[i];else if(a=e.match(/rgb\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/)){for(s=a.slice(1,4),i=t=0;t<=2;i=++t)s[i]=we(2.55*s[i]);s[3]=1}else if(a=e.match(/rgba\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/)){for(s=a.slice(1,5),i=n=0;n<=2;i=++n)s[i]=we(2.55*s[i]);s[3]=+s[3]}else(a=e.match(/hsl\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/))?(r=a.slice(1,4),r[1]*=.01,r[2]*=.01,s=B(r),s[3]=1):(a=e.match(/hsla\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/))&&(r=a.slice(1,4),r[1]*=.01,r[2]*=.01,s=B(r),s[3]=+a[4]);return s},ae=function(e){var t;return t=e[3]<1?"rgba":"rgb","rgb"===t?t+"("+e.slice(0,3).map(we).join(",")+")":"rgba"===t?t+"("+e.slice(0,3).map(we).join(",")+","+e[3]+")":void 0},ve=function(e){return we(100*e)/100},O=function(e,t){var n;return n=t<1?"hsla":"hsl",e[0]=ve(e[0]||0),e[1]=ve(100*e[1])+"%",e[2]=ve(100*e[2])+"%","hsla"===n&&(e[3]=t),n+"("+e.join(",")+")"},f.css=function(e){return P(e)},x.css=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["css"]),function(){})},i.prototype.css=function(e){return null==e&&(e="rgb"),"rgb"===e.slice(0,3)?ae(this._rgb):"hsl"===e.slice(0,3)?O(this.hsl(),this.alpha()):void 0},f.named=function(e){return L(ke[e])},h.push({p:20,test:function(e){if(1===arguments.length&&null!=ke[e])return"named"}}),i.prototype.name=function(e){var t,n;arguments.length&&(ke[e]&&(this._rgb=L(ke[e])),this._rgb[3]=1),t=this.hex();for(n in ke)if(t===ke[n])return n;return t},G=function(){var e,t,n,r;return r=Ce(arguments),n=r[0],e=r[1],t=r[2],t*=a,[n,S(t)*e,be(t)*e]},H=function(){var e,t,n,r,i,a,o,s,l,c,u;return n=Ce(arguments),s=n[0],i=n[1],o=n[2],c=G(s,i,o),e=c[0],t=c[1],r=c[2],u=U(e,t,r),l=u[0],a=u[1],r=u[2],[K(l,0,255),K(a,0,255),K(r,0,255),n.length>3?n[3]:1]},V=function(){var e,t,n,r,i,a;return a=Ce(arguments),i=a[0],e=a[1],t=a[2],n=_e(e*e+t*t),r=(g(t,e)*c+360)%360,0===we(1e4*n)&&(r=Number.NaN),[i,n,r]},he=function(){var e,t,n,r,i,a,o;return a=Ce(arguments),i=a[0],n=a[1],t=a[2],o=ue(i,n,t),r=o[0],e=o[1],t=o[2],V(r,e,t)},x.lch=function(){var e;return e=Ce(arguments),new i(e,"lch")},x.hcl=function(){var e;return e=Ce(arguments),new i(e,"hcl")},f.lch=H,f.hcl=function(){var e,t,n,r;return r=Ce(arguments),t=r[0],e=r[1],n=r[2],H([n,e,t])},i.prototype.lch=function(){return he(this._rgb)},i.prototype.hcl=function(){return he(this._rgb).reverse()},ie=function(e){var t,n,r,i,a,o,s,l,c;return null==e&&(e="rgb"),l=Ce(arguments),s=l[0],i=l[1],t=l[2],s/=255,i/=255,t/=255,a=1-Math.max(s,Math.max(i,t)),r=a<1?1/(1-a):0,n=(1-s-a)*r,o=(1-i-a)*r,c=(1-t-a)*r,[n,o,c,a]},C=function(){var e,t,n,r,i,a,o,s,l;return t=Ce(arguments),r=t[0],o=t[1],l=t[2],a=t[3],e=t.length>4?t[4]:1,1===a?[0,0,0,e]:(s=r>=1?0:we(255*(1-r)*(1-a)),i=o>=1?0:we(255*(1-o)*(1-a)),n=l>=1?0:we(255*(1-l)*(1-a)),[s,i,n,e])},f.cmyk=function(){return C(Ce(arguments))},x.cmyk=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["cmyk"]),function(){})},i.prototype.cmyk=function(){return ie(this._rgb)},f.gl=function(){var e,t,n,r,i;for(r=function(){var e,n;e=Ce(arguments),n=[];for(t in e)i=e[t],n.push(i);return n}.apply(this,arguments),e=n=0;n<=2;e=++n)r[e]*=255;return r},x.gl=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["gl"]),function(){})},i.prototype.gl=function(){var e;return e=this._rgb,[e[0]/255,e[1]/255,e[2]/255,e[3]]},de=function(e,t,n){var r;return r=Ce(arguments),e=r[0],t=r[1],n=r[2],e=Y(e),t=Y(t),n=Y(n),.2126*e+.7152*t+.0722*n},Y=function(e){return e/=255,e<=.03928?e/12.92:re((e+.055)/1.055,2.4)},p=[],R=function(e,t,n,r){var i,a,o,s;for(null==n&&(n=.5),null==r&&(r="rgb"),"object"!==Ee(e)&&(e=x(e)),"object"!==Ee(t)&&(t=x(t)),o=0,a=p.length;o<a;o++)if(i=p[o],r===i[0]){s=i[1](e,t,n,r);break}if(null==s)throw"color mode "+r+" is not supported";return s.alpha(e.alpha()+n*(t.alpha()-e.alpha())),s},x.interpolate=R,i.prototype.interpolate=function(e,t,n){return R(this,e,t,n)},x.mix=R,i.prototype.mix=i.prototype.interpolate,q=function(e,t,n,r){var a,o;return a=e._rgb,o=t._rgb,new i(a[0]+n*(o[0]-a[0]),a[1]+n*(o[1]-a[1]),a[2]+n*(o[2]-a[2]),r)},p.push(["rgb",q]),i.prototype.luminance=function(e,t){var n,r,i,a;return null==t&&(t="rgb"),arguments.length?(0===e?this._rgb=[0,0,0,this._rgb[3]]:1===e?this._rgb=[255,255,255,this._rgb[3]]:(r=1e-7,i=20,a=function(n,o){var s,l;return l=n.interpolate(o,.5,t),s=l.luminance(),Math.abs(e-s)<r||!i--?l:s>e?a(n,l):a(l,o)},n=de(this._rgb),this._rgb=(n>e?a(x("black"),this):a(this,x("white"))).rgba()),this):de(this._rgb)},xe=function(e){var t,n,r,i;return i=e/100,i<66?(r=255,n=-155.25485562709179-.44596950469579133*(n=i-2)+104.49216199393888*Q(n),t=i<20?0:-254.76935184120902+.8274096064007395*(t=i-10)+115.67994401066147*Q(t)):(r=351.97690566805693+.114206453784165*(r=i-55)-40.25366309332127*Q(r),n=325.4494125711974+.07943456536662342*(n=i-50)-28.0852963507957*Q(n),t=255),E([r,n,t])},pe=function(){var e,t,n,r,i,a,o,s,l;for(o=Ce(arguments),a=o[0],n=o[1],e=o[2],i=1e3,r=4e4,t=.4;r-i>t;)l=.5*(r+i),s=xe(l),s[2]/s[0]>=e/a?r=l:i=l;return we(l)},x.temperature=x.kelvin=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["temperature"]),function(){})},f.temperature=f.kelvin=f.K=xe,i.prototype.temperature=function(){return pe(this._rgb)},i.prototype.kelvin=i.prototype.temperature,x.contrast=function(e,t){var n,r,a,o;return"string"!==(a=Ee(e))&&"number"!==a||(e=new i(e)),"string"!==(o=Ee(t))&&"number"!==o||(t=new i(t)),n=e.luminance(),r=t.luminance(),n>r?(n+.05)/(r+.05):(r+.05)/(n+.05)},i.prototype.get=function(e){var t,n,r,i,a,o;return r=this,a=e.split("."),i=a[0],t=a[1],o=r[i](),t?(n=i.indexOf(t),n>-1?o[n]:console.warn("unknown channel "+t+" in mode "+i)):o},i.prototype.set=function(e,t){var n,r,i,a,o,s;if(i=this,o=e.split("."),a=o[0],n=o[1],n)if(s=i[a](),r=a.indexOf(n),r>-1)if("string"===Ee(t))switch(t.charAt(0)){case"+":s[r]+=+t;break;case"-":s[r]+=+t;break;case"*":s[r]*=+t.substr(1);break;case"/":s[r]/=+t.substr(1);break;default:s[r]=+t}else s[r]=t;else console.warn("unknown channel "+n+" in mode "+a);else s=t;return i._rgb=x(s,a).alpha(i.alpha())._rgb,i},i.prototype.darken=function(e){var t,n;return null==e&&(e=1),n=this,t=n.lab(),t[0]-=o.Kn*e,x.lab(t).alpha(n.alpha())},i.prototype.brighten=function(e){return null==e&&(e=1),this.darken(-e)},i.prototype.darker=i.prototype.darken,i.prototype.brighter=i.prototype.brighten,i.prototype.saturate=function(e){var t,n;return null==e&&(e=1),n=this,t=n.lch(),t[1]+=e*o.Kn,t[1]<0&&(t[1]=0),x.lch(t).alpha(n.alpha())},i.prototype.desaturate=function(e){return null==e&&(e=1),this.saturate(-e)},i.prototype.premultiply=function(){var e,t;return t=this.rgb(),e=this.alpha(),x(t[0]*e,t[1]*e,t[2]*e,e)},w=function(e,t,n){if(!w[n])throw"unknown blend mode "+n;return w[n](e,t)},y=function(e){return function(t,n){var r,i;return r=x(n).rgb(),i=x(t).rgb(),x(e(r,i),"rgb")}},N=function(e){return function(t,n){var r,i,a;for(a=[],r=i=0;i<=3;r=++i)a[r]=e(t[r],n[r]);return a}},ee=function(e,t){return e},J=function(e,t){return e*t/255},T=function(e,t){return e>t?t:e},X=function(e,t){return e>t?e:t},ye=function(e,t){return 255*(1-(1-e/255)*(1-t/255))},ne=function(e,t){return t<128?2*e*t/255:255*(1-2*(1-e/255)*(1-t/255))},_=function(e,t){return 255*(1-(1-t/255)/(e/255))},M=function(e,t){return 255===e?255:(e=255*(t/255)/(1-e/255),e>255?255:e)},w.normal=y(N(ee)),w.multiply=y(N(J)),w.screen=y(N(ye)),w.overlay=y(N(ne)),w.darken=y(N(T)),w.lighten=y(N(X)),w.dodge=y(N(M)),w.burn=y(N(_)),x.blend=w,x.analyze=function(e){var t,n,r,i;for(r={min:Number.MAX_VALUE,max:Number.MAX_VALUE*-1,sum:0,values:[],count:0},n=0,t=e.length;n<t;n++)i=e[n],null==i||isNaN(i)||(r.values.push(i),r.sum+=i,i<r.min&&(r.min=i),i>r.max&&(r.max=i),r.count+=1);return r.domain=[r.min,r.max],r.limits=function(e,t){return x.limits(r,e,t)},r},x.scale=function(e,t){var n,r,i,a,o,s,l,c,u,h,d,f,p,m,g,v,w,y,b,_,E;return u="rgb",h=x("#ccc"),m=0,s=!1,o=[0,1],p=[],f=[0,0],n=!1,i=[],d=!1,c=0,l=1,a=!1,r={},_=function(e){var t,n,r,a,o,s,l;if(null==e&&(e=["#fff","#000"]),null!=e&&"string"===Ee(e)&&null!=(null!=(a=x.brewer)?a[e]:void 0)&&(e=x.brewer[e]),"array"===Ee(e)){for(e=e.slice(0),t=r=0,o=e.length-1;0<=o?r<=o:r>=o;t=0<=o?++r:--r)n=e[t],"string"===Ee(n)&&(e[t]=x(n));for(p.length=0,t=l=0,s=e.length-1;0<=s?l<=s:l>=s;t=0<=s?++l:--l)p.push(t/(e.length-1))}return b(),i=e},w=function(e){var t,r;if(null!=n){for(r=n.length-1,t=0;t<r&&e>=n[t];)t++;return t-1}return 0},E=function(e){return e},g=function(e){var t,r,i,a,o;return o=e,n.length>2&&(a=n.length-1,t=w(e),i=n[0]+(n[1]-n[0])*(0+.5*m),r=n[a-1]+(n[a]-n[a-1])*(1-.5*m),o=c+(n[t]+.5*(n[t+1]-n[t])-i)/(r-i)*(l-c)),o},y=function(e,t){var a,o,s,d,m,g,v,y;if(null==t&&(t=!1),isNaN(e))return h;if(t?y=e:n&&n.length>2?(a=w(e),y=a/(n.length-2),y=f[0]+y*(1-f[0]-f[1])):l!==c?(y=(e-c)/(l-c),y=f[0]+y*(1-f[0]-f[1]),y=Math.min(1,Math.max(0,y))):y=1,t||(y=E(y)),d=Math.floor(1e4*y),r[d])o=r[d];else{if("array"===Ee(i))for(s=m=0,v=p.length-1;0<=v?m<=v:m>=v;s=0<=v?++m:--m){if(g=p[s],y<=g){o=i[s];break}if(y>=g&&s===p.length-1){o=i[s];break}if(y>g&&y<p[s+1]){y=(y-g)/(p[s+1]-g),o=x.interpolate(i[s],i[s+1],y,u);break}}else"function"===Ee(i)&&(o=i(y));r[d]=o}return o},b=function(){return r={}},_(e),v=function(e){var t;return t=x(y(e)),d&&t[d]?t[d]():t},v.classes=function(e){var t;return null!=e?("array"===Ee(e)?(n=e,o=[e[0],e[e.length-1]]):(t=x.analyze(o),n=0===e?[t.min,t.max]:x.limits(t,"e",e)),v):n},v.domain=function(e){var t,n,r,a,s,u,h;if(!arguments.length)return o;if(c=e[0],l=e[e.length-1],p=[],r=i.length,e.length===r&&c!==l)for(s=0,a=e.length;s<a;s++)n=e[s],p.push((n-c)/(l-c));else for(t=h=0,u=r-1;0<=u?h<=u:h>=u;t=0<=u?++h:--h)p.push(t/(r-1));return o=[c,l],v},v.mode=function(e){return arguments.length?(u=e,b(),v):u},v.range=function(e,t){return _(e,t),v},v.out=function(e){return d=e,v},v.spread=function(e){return arguments.length?(m=e,v):m},v.correctLightness=function(e){return null==e&&(e=!0),a=e,b(),E=a?function(e){var t,n,r,i,a,o,s,l,c;for(t=y(0,!0).lab()[0],n=y(1,!0).lab()[0],s=t>n,r=y(e,!0).lab()[0],a=t+(n-t)*e,i=r-a,l=0,c=1,o=20;Math.abs(i)>.01&&o-- >0;)!function(){return s&&(i*=-1),i<0?(l=e,e+=.5*(c-e)):(c=e,e+=.5*(l-e)),r=y(e,!0).lab()[0],i=r-a}();return e}:function(e){return e},v},v.padding=function(e){return null!=e?("number"===Ee(e)&&(e=[e,e]),f=e,v):f},v.colors=function(){var t,r,i,a,s,l,c,u,h;if(a=0,s="hex",1===arguments.length&&("string"===Ee(arguments[0])?s=arguments[0]:a=arguments[0]),2===arguments.length&&(a=arguments[0],s=arguments[1]),a)return r=o[0],t=o[1]-r,function(){c=[];for(var e=0;0<=a?e<a:e>a;0<=a?e++:e--)c.push(e);return c}.apply(this).map(function(e){return v(r+e/(a-1)*t)[s]()});if(e=[],u=[],n&&n.length>2)for(i=h=1,l=n.length;1<=l?h<l:h>l;i=1<=l?++h:--h)u.push(.5*(n[i-1]+n[i]));else u=o;return u.map(function(e){return v(e)[s]()})},v},null==x.scales&&(x.scales={}),x.scales.cool=function(){return x.scale([x.hsl(180,1,.9),x.hsl(250,.7,.4)])},x.scales.hot=function(){return x.scale(["#000","#f00","#ff0","#fff"],[0,.25,.75,1]).mode("rgb")},x.analyze=function(e,t,n){var r,i,a,o,s,l,c;if(s={min:Number.MAX_VALUE,max:Number.MAX_VALUE*-1,sum:0,values:[],count:0},null==n&&(n=function(){return!0}),r=function(e){null==e||isNaN(e)||(s.values.push(e),s.sum+=e,e<s.min&&(s.min=e),e>s.max&&(s.max=e),s.count+=1)},c=function(e,i){if(n(e,i))return r(null!=t&&"function"===Ee(t)?t(e):null!=t&&"string"===Ee(t)||"number"===Ee(t)?e[t]:e)},"array"===Ee(e))for(o=0,a=e.length;o<a;o++)l=e[o],c(l);else for(i in e)l=e[i],c(l,i);return s.domain=[s.min,s.max],s.limits=function(e,t){return x.limits(s,e,t)},s},x.limits=function(e,t,n){var r,i,a,o,s,l,c,u,h,d,f,p,g,v,w,y,b,_,E,C,k,S,P,T,M,N,L,A,O,B,z,R,D,j,F,q,V,U,W,G,H,X,K,Y,Z,J,ee,te,ne,ie,ae,oe,se,le,ce;if(null==t&&(t="equal"),null==n&&(n=7),"array"===Ee(e)&&(e=x.analyze(e)),M=e.min,$=e.max,ae=e.sum,le=e.values.sort(function(e,t){return e-t}),P=[],"c"===t.substr(0,1)&&(P.push(M),P.push($)),"e"===t.substr(0,1)){for(P.push(M),C=z=1,F=n-1;1<=F?z<=F:z>=F;C=1<=F?++z:--z)P.push(M+C/n*($-M));P.push($)}else if("l"===t.substr(0,1)){if(M<=0)throw"Logarithmic scales are only possible for values > 0";for(N=Math.LOG10E*Q(M),T=Math.LOG10E*Q($),P.push(M),C=ce=1,q=n-1;1<=q?ce<=q:ce>=q;C=1<=q?++ce:--ce)P.push(re(10,N+C/n*(T-N)));P.push($)}else if("q"===t.substr(0,1)){for(P.push(M),C=r=1,X=n-1;1<=X?r<=X:r>=X;C=1<=X?++r:--r)R=le.length*C/n,D=I(R),D===R?P.push(le[D]):(j=R-D,P.push(le[D]*j+le[D+1]*(1-j)));P.push($)}else if("k"===t.substr(0,1)){for(A=le.length,v=new Array(A),_=new Array(n),ie=!0,O=0,y=null,y=[],y.push(M),C=i=1,K=n-1;1<=K?i<=K:i>=K;C=1<=K?++i:--i)y.push(M+C/n*($-M));for(y.push($);ie;){for(k=a=0,Y=n-1;0<=Y?a<=Y:a>=Y;k=0<=Y?++a:--a)_[k]=0;for(C=o=0,Z=A-1;0<=Z?o<=Z:o>=Z;C=0<=Z?++o:--o){for(se=le[C],L=Number.MAX_VALUE,k=s=0,J=n-1;0<=J?s<=J:s>=J;k=0<=J?++s:--s)E=m(y[k]-se),E<L&&(L=E,w=k);_[w]++,v[C]=w}for(B=new Array(n),k=l=0,ee=n-1;0<=ee?l<=ee:l>=ee;k=0<=ee?++l:--l)B[k]=null;for(C=c=0,te=A-1;0<=te?c<=te:c>=te;C=0<=te?++c:--c)b=v[C],null===B[b]?B[b]=le[C]:B[b]+=le[C];for(k=u=0,ne=n-1;0<=ne?u<=ne:u>=ne;k=0<=ne?++u:--u)B[k]*=1/_[k];for(ie=!1,k=h=0,V=n-1;0<=V?h<=V:h>=V;k=0<=V?++h:--h)if(B[k]!==y[C]){ie=!0;break}y=B,O++,O>200&&(ie=!1)}for(S={},k=d=0,U=n-1;0<=U?d<=U:d>=U;k=0<=U?++d:--d)S[k]=[];for(C=f=0,W=A-1;0<=W?f<=W:f>=W;C=0<=W?++f:--f)b=v[C],S[b].push(le[C]);for(oe=[],k=p=0,G=n-1;0<=G?p<=G:p>=G;k=0<=G?++p:--p)oe.push(S[k][0]),oe.push(S[k][S[k].length-1]);for(oe=oe.sort(function(e,t){return e-t}),P.push(oe[0]),C=g=1,H=oe.length-1;g<=H;C=g+=2)isNaN(oe[C])||P.push(oe[C])}return P},A=function(e,t,n){var r,i,a,o;return r=Ce(arguments),e=r[0],t=r[1],n=r[2],e/=360,e<1/3?(i=(1-t)/3,o=(1+t*S(u*e)/S(l-u*e))/3,a=1-(i+o)):e<2/3?(e-=1/3,o=(1-t)/3,a=(1+t*S(u*e)/S(l-u*e))/3,i=1-(o+a)):(e-=2/3,a=(1-t)/3,i=(1+t*S(u*e)/S(l-u*e))/3,o=1-(a+i)),o=K(n*o*3),a=K(n*a*3),i=K(n*i*3),[255*o,255*a,255*i,r.length>3?r[3]:1]},se=function(){var e,t,n,r,i,a,o,s;return o=Ce(arguments),a=o[0],t=o[1],e=o[2],u=2*Math.PI,a/=255,t/=255,e/=255,i=Math.min(a,t,e),r=(a+t+e)/3,s=1-i/r,0===s?n=0:(n=(a-t+(a-e))/2,n/=Math.sqrt((a-t)*(a-t)+(a-e)*(t-e)),n=Math.acos(n),e>t&&(n=u-n),n/=u),[360*n,s,r]},x.hsi=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["hsi"]),function(){})},f.hsi=A,i.prototype.hsi=function(){return se(this._rgb)},D=function(e,t,n,r){var i,a,o,s,l,c,u,h,d,f,p,m,g;return"hsl"===r?(m=e.hsl(),g=t.hsl()):"hsv"===r?(m=e.hsv(),g=t.hsv()):"hsi"===r?(m=e.hsi(),g=t.hsi()):"lch"!==r&&"hcl"!==r||(r="hcl",m=e.hcl(),g=t.hcl()),"h"===r.substr(0,1)&&(o=m[0],f=m[1],c=m[2],s=g[0],p=g[1],u=g[2]),isNaN(o)||isNaN(s)?isNaN(o)?isNaN(s)?a=Number.NaN:(a=s,1!==c&&0!==c||"hsv"===r||(d=p)):(a=o,1!==u&&0!==u||"hsv"===r||(d=f)):(i=s>o&&s-o>180?s-(o+360):s<o&&o-s>180?s+360-o:s-o,a=o+n*i),null==d&&(d=f+n*(p-f)),l=c+n*(u-c),h=x[r](a,d,l)},p=p.concat(function(){var e,t,n,r;for(n=["hsv","hsl","hsi","hcl","lch"],r=[],t=0,e=n.length;t<e;t++)Z=n[t],r.push([Z,D]);return r}()),F=function(e,t,n,r){var i,a;return i=e.num(),a=t.num(),x.num(i+(a-i)*n,"num")},p.push(["num",F]),j=function(e,t,n,r){var a,o,s;return o=e.lab(),s=t.lab(),a=new i(o[0]+n*(s[0]-o[0]),o[1]+n*(s[1]-o[1]),o[2]+n*(s[2]-o[2]),r)},p.push(["lab",j])}).call(this)}).call(t,n(324)(e))},function(e,t,n){function r(e){return null===e||void 0===e}function i(e){return!(!e||"object"!=typeof e||"number"!=typeof e.length)&&("function"==typeof e.copy&&"function"==typeof e.slice&&!(e.length>0&&"number"!=typeof e[0]))}function a(e,t,n){var a,u;if(r(e)||r(t))return!1;if(e.prototype!==t.prototype)return!1;if(l(e))return!!l(t)&&(e=o.call(e),t=o.call(t),c(e,t,n));if(i(e)){if(!i(t))return!1;if(e.length!==t.length)return!1;for(a=0;a<e.length;a++)if(e[a]!==t[a])return!1;return!0}try{var h=s(e),d=s(t)}catch(e){return!1}if(h.length!=d.length)return!1;for(h.sort(),d.sort(),a=h.length-1;a>=0;a--)if(h[a]!=d[a])return!1;for(a=h.length-1;a>=0;a--)if(u=h[a],!c(e[u],t[u],n))return!1;return typeof e==typeof t}var o=Array.prototype.slice,s=n(210),l=n(209),c=e.exports=function(e,t,n){return n||(n={}),e===t||(e instanceof Date&&t instanceof Date?e.getTime()===t.getTime():!e||!t||"object"!=typeof e&&"object"!=typeof t?n.strict?e===t:e==t:a(e,t,n))}},function(e,t){function n(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function r(e){return e&&"object"==typeof e&&"number"==typeof e.length&&Object.prototype.hasOwnProperty.call(e,"callee")&&!Object.prototype.propertyIsEnumerable.call(e,"callee")||!1}var i="[object Arguments]"==function(){return Object.prototype.toString.call(arguments)}();t=e.exports=i?n:r,t.supported=n,t.unsupported=r},function(e,t){function n(e){var t=[];for(var n in e)t.push(n);return t}t=e.exports="function"==typeof Object.keys?Object.keys:n,t.shim=n},function(e,t,n){"use strict";function r(e){return e.replace(i,function(e,t){return t.toUpperCase()})}var i=/-(.)/g;e.exports=r},function(e,t,n){"use strict";function r(e){return i(e.replace(a,"ms-"))}var i=n(211),a=/^-ms-/;e.exports=r},function(e,t,n){ +"use strict";function r(e,t){return!(!e||!t)&&(e===t||!i(e)&&(i(t)?r(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}var i=n(221);e.exports=r},function(e,t,n){"use strict";function r(e){var t=e.length;if(Array.isArray(e)||"object"!=typeof e&&"function"!=typeof e?o(!1):void 0,"number"!=typeof t?o(!1):void 0,0===t||t-1 in e?void 0:o(!1),"function"==typeof e.callee?o(!1):void 0,e.hasOwnProperty)try{return Array.prototype.slice.call(e)}catch(e){}for(var n=Array(t),r=0;r<t;r++)n[r]=e[r];return n}function i(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"length"in e&&!("setInterval"in e)&&"number"!=typeof e.nodeType&&(Array.isArray(e)||"callee"in e||"item"in e)}function a(e){return i(e)?Array.isArray(e)?e.slice():r(e):[e]}var o=n(1);e.exports=a},function(e,t,n){"use strict";function r(e){var t=e.match(u);return t&&t[1].toLowerCase()}function i(e,t){var n=c;c?void 0:l(!1);var i=r(e),a=i&&s(i);if(a){n.innerHTML=a[1]+e+a[2];for(var u=a[0];u--;)n=n.lastChild}else n.innerHTML=e;var h=n.getElementsByTagName("script");h.length&&(t?void 0:l(!1),o(h).forEach(t));for(var d=Array.from(n.childNodes);n.lastChild;)n.removeChild(n.lastChild);return d}var a=n(7),o=n(214),s=n(216),l=n(1),c=a.canUseDOM?document.createElement("div"):null,u=/^\s*<(\w+)/;e.exports=i},function(e,t,n){"use strict";function r(e){return o?void 0:a(!1),d.hasOwnProperty(e)||(e="*"),s.hasOwnProperty(e)||("*"===e?o.innerHTML="<link />":o.innerHTML="<"+e+"></"+e+">",s[e]=!o.firstChild),s[e]?d[e]:null}var i=n(7),a=n(1),o=i.canUseDOM?document.createElement("div"):null,s={},l=[1,'<select multiple="true">',"</select>"],c=[1,"<table>","</table>"],u=[3,"<table><tbody><tr>","</tr></tbody></table>"],h=[1,'<svg xmlns="http://www.w3.org/2000/svg">',"</svg>"],d={"*":[1,"?<div>","</div>"],area:[1,"<map>","</map>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],legend:[1,"<fieldset>","</fieldset>"],param:[1,"<object>","</object>"],tr:[2,"<table><tbody>","</tbody></table>"],optgroup:l,option:l,caption:c,colgroup:c,tbody:c,tfoot:c,thead:c,td:u,th:u},f=["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"];f.forEach(function(e){d[e]=h,s[e]=!0}),e.exports=r},function(e,t,n){"use strict";function r(e){return e===window?{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}:{x:e.scrollLeft,y:e.scrollTop}}e.exports=r},function(e,t,n){"use strict";function r(e){return e.replace(i,"-$1").toLowerCase()}var i=/([A-Z])/g;e.exports=r},function(e,t,n){"use strict";function r(e){return i(e).replace(a,"-ms-")}var i=n(218),a=/^ms-/;e.exports=r},function(e,t,n){"use strict";function r(e){return!(!e||!("function"==typeof Node?e instanceof Node:"object"==typeof e&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName))}e.exports=r},function(e,t,n){"use strict";function r(e){return i(e)&&3==e.nodeType}var i=n(220);e.exports=r},function(e,t,n){"use strict";function r(e){var t={};return function(n){return t.hasOwnProperty(n)||(t[n]=e.call(this,n)),t[n]}}e.exports=r},function(e,t,n){"use strict";function r(e,t,n){function r(){o=!0,n.apply(this,arguments)}function i(){o||(a<e?t.call(this,a++,i,r):r.apply(this,arguments))}var a=0,o=!1;i()}t.__esModule=!0,t.loopAsync=r},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){return l+e}function a(e,t){try{window.sessionStorage.setItem(i(e),JSON.stringify(t))}catch(e){if(e.name===u)return;if(e.name===c&&0===window.sessionStorage.length)return;throw e}}function o(e){var t=void 0;try{t=window.sessionStorage.getItem(i(e))}catch(e){if(e.name===u)return null}if(t)try{return JSON.parse(t)}catch(e){}return null}t.__esModule=!0,t.saveState=a,t.readState=o;var s=n(8),l=(r(s),"@@History/"),c="QuotaExceededError",u="SecurityError"},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){function t(e){return l.canUseDOM?void 0:s.default(!1),n.listen(e)}var n=h.default(a({getUserConfirmation:c.getUserConfirmation},e,{go:c.go}));return a({},n,{listen:t})}t.__esModule=!0;var a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=n(10),s=r(o),l=n(40),c=n(70),u=n(71),h=r(u);t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){return"string"==typeof e&&"/"===e.charAt(0)}function a(){var e=g.getHashPath();return!!i(e)||(g.replaceHashPath("/"+e),!1)}function o(e,t,n){return e+(e.indexOf("?")===-1?"?":"&")+(t+"="+n)}function s(e,t){return e.replace(new RegExp("[?&]?"+t+"=[a-zA-Z0-9]+"),"")}function l(e,t){var n=e.match(new RegExp("\\?.*?\\b"+t+"=(.+?)\\b"));return n&&n[1]}function c(){function e(){var e=g.getHashPath(),t=void 0,n=void 0;P?(t=l(e,P),e=s(e,P),t?n=v.readState(t):(n=null,t=T.createKey(),g.replaceHashPath(o(e,P,t)))):t=n=null;var r=_.default(e);return T.createLocation(u({},r,{state:n}),void 0,t)}function t(t){function n(){a()&&r(e())}var r=t.transitionTo;return a(),g.addEventListener(window,"hashchange",n),function(){g.removeEventListener(window,"hashchange",n)}}function n(e){var t=e.basename,n=e.pathname,r=e.search,i=e.state,a=e.action,s=e.key;if(a!==p.POP){var l=(t||"")+n+r;P?(l=o(l,P,s),v.saveState(s,i)):e.key=e.state=null;var c=g.getHashPath();a===p.PUSH?c!==l&&(window.location.hash=l):c!==l&&g.replaceHashPath(l)}}function r(e){1===++M&&(N=t(T));var n=T.listenBefore(e);return function(){n(),0===--M&&N()}}function i(e){1===++M&&(N=t(T));var n=T.listen(e);return function(){n(),0===--M&&N()}}function c(e){T.push(e)}function h(e){T.replace(e)}function d(e){T.go(e)}function w(e){return"#"+T.createHref(e)}function b(e){1===++M&&(N=t(T)),T.registerTransitionHook(e)}function E(e){T.unregisterTransitionHook(e),0===--M&&N()}function C(e,t){T.pushState(e,t)}function k(e,t){T.replaceState(e,t)}var S=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];m.canUseDOM?void 0:f.default(!1);var P=S.queryKey;(void 0===P||P)&&(P="string"==typeof P?P:x);var T=y.default(u({},S,{getCurrentLocation:e,finishTransition:n,saveState:v.saveState})),M=0,N=void 0;g.supportsGoWithoutReloadUsingHash();return u({},T,{listenBefore:r,listen:i,push:c,replace:h,go:d,createHref:w,registerTransitionHook:b,unregisterTransitionHook:E,pushState:C,replaceState:k})}t.__esModule=!0;var u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},h=n(8),d=(r(h),n(10)),f=r(d),p=n(27),m=n(40),g=n(70),v=n(224),w=n(225),y=r(w),b=n(19),_=r(b),x="_k";t.default=c,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(){var e=arguments.length<=0||void 0===arguments[0]?"/":arguments[0],t=arguments.length<=1||void 0===arguments[1]?o.POP:arguments[1],n=arguments.length<=2||void 0===arguments[2]?null:arguments[2],r=arguments.length<=3||void 0===arguments[3]?null:arguments[3];"string"==typeof e&&(e=l.default(e)),"object"==typeof t&&(e=a({},e,{state:t}),t=n||o.POP,n=r);var i=e.pathname||"/",s=e.search||"",c=e.hash||"",u=e.state||null;return{pathname:i,search:s,hash:c,state:u,action:t,key:n}}t.__esModule=!0;var a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=n(27),s=n(19),l=r(s);t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){return e.filter(function(e){return e.state}).reduce(function(e,t){return e[t.key]=t.state,e},{})}function a(){function e(e,t){v[e]=t}function t(e){return v[e]}function n(){var e=m[g],n=e.key,r=e.basename,i=e.pathname,a=e.search,s=(r||"")+i+(a||""),l=void 0;n?l=t(n):(l=null,n=h.createKey(),e.key=n);var c=p.default(s);return h.createLocation(o({},c,{state:l}),void 0,n)}function r(e){var t=g+e;return t>=0&&t<m.length}function a(e){if(e){if(!r(e))return;g+=e;var t=n();h.transitionTo(o({},t,{action:u.POP}))}}function s(t){switch(t.action){case u.PUSH:g+=1,g<m.length&&m.splice(g),m.push(t),e(t.key,t.state);break;case u.REPLACE:m[g]=t,e(t.key,t.state)}}var l=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];Array.isArray(l)?l={entries:l}:"string"==typeof l&&(l={entries:[l]});var h=d.default(o({},l,{getCurrentLocation:n,finishTransition:s,saveState:e,go:a})),f=l,m=f.entries,g=f.current;"string"==typeof m?m=[m]:Array.isArray(m)||(m=["/"]),m=m.map(function(e){var t=h.createKey();return"string"==typeof e?{pathname:e,key:t}:"object"==typeof e&&e?o({},e,{key:t}):void c.default(!1)}),null==g?g=m.length-1:g>=0&&g<m.length?void 0:c.default(!1);var v=i(m);return h}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s=n(8),l=(r(s),n(10)),c=r(l),u=n(27),h=n(71),d=r(h),f=n(19),p=r(f);t.default=a,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e){return function(){function t(e){return b&&null==e.basename&&(0===e.pathname.indexOf(b)?(e.pathname=e.pathname.substring(b.length),e.basename=b,""===e.pathname&&(e.pathname="/")):e.basename=""),e}function n(e){if(!b)return e;"string"==typeof e&&(e=f.default(e));var t=e.pathname,n="/"===b.slice(-1)?b:b+"/",r="/"===t.charAt(0)?t.slice(1):t,i=n+r;return o({},e,{pathname:i})}function r(e){return x.listenBefore(function(n,r){c.default(e,t(n),r)})}function a(e){return x.listen(function(n){e(t(n))})}function l(e){x.push(n(e))}function u(e){x.replace(n(e))}function d(e){return x.createPath(n(e))}function p(e){return x.createHref(n(e))}function g(){return t(x.createLocation.apply(x,arguments))}function v(e,t){"string"==typeof t&&(t=f.default(t)),l(o({state:e},t))}function w(e,t){"string"==typeof t&&(t=f.default(t)),u(o({state:e},t))}var y=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],b=y.basename,_=i(y,["basename"]),x=e(_);if(null==b&&s.canUseDOM){var E=document.getElementsByTagName("base")[0];E&&(b=h.default(E.href))}return o({},x,{listenBefore:r,listen:a,push:l,replace:u,createPath:d,createHref:p,createLocation:g,pushState:m.default(v,"pushState is deprecated; use push instead"),replaceState:m.default(w,"replaceState is deprecated; use replace instead")})}}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s=n(40),l=n(42),c=r(l),u=n(72),h=r(u),d=n(19),f=r(d),p=n(41),m=r(p);t.default=a,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e){return c.stringify(e).replace(/%20/g,"+")}function o(e){return function(){function t(e){if(null==e.query){var t=e.search;e.query=x(t.substring(1)),e[g]={search:t,searchBase:""}}return e}function n(e,t){var n,r=void 0;if(!t||""===(r=_(t)))return e;"string"==typeof e&&(e=f.default(e));var i=e[g],a=void 0;a=i&&e.search===i.search?i.searchBase:e.search||"";var o=a+(a?"&":"?")+r;return s({},e,(n={search:o},n[g]={search:o,searchBase:a},n))}function r(e){return C.listenBefore(function(n,r){h.default(e,t(n),r)})}function o(e){return C.listen(function(n){e(t(n))})}function l(e){C.push(n(e,e.query))}function c(e){C.replace(n(e,e.query))}function u(e,t){return C.createPath(n(e,t||e.query))}function d(e,t){return C.createHref(n(e,t||e.query))}function p(){return t(C.createLocation.apply(C,arguments))}function w(e,t,n){"string"==typeof t&&(t=f.default(t)),l(s({state:e},t,{query:n}))}function y(e,t,n){"string"==typeof t&&(t=f.default(t)),c(s({state:e},t,{query:n}))}var b=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],_=b.stringifyQuery,x=b.parseQueryString,E=i(b,["stringifyQuery","parseQueryString"]),C=e(E);return"function"!=typeof _&&(_=a),"function"!=typeof x&&(x=v),s({},C,{listenBefore:r,listen:o,push:l,replace:c,createPath:u,createHref:d,createLocation:p,pushState:m.default(w,"pushState is deprecated; use push instead"),replaceState:m.default(y,"replaceState is deprecated; use replace instead")})}}t.__esModule=!0;var s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l=n(8),c=(r(l),n(231)),u=n(42),h=r(u),d=n(19),f=r(d),p=n(41),m=r(p),g="$searchBase",v=c.parse;t.default=o,e.exports=t.default},function(e,t,n){"use strict";var r=n(323);t.extract=function(e){return e.split("?")[1]||""},t.parse=function(e){return"string"!=typeof e?{}:(e=e.trim().replace(/^(\?|#|&)/,""),e?e.split("&").reduce(function(e,t){var n=t.replace(/\+/g," ").split("="),r=n.shift(),i=n.length>0?n.join("="):void 0;return r=decodeURIComponent(r),i=void 0===i?null:decodeURIComponent(i),e.hasOwnProperty(r)?Array.isArray(e[r])?e[r].push(i):e[r]=[e[r],i]:e[r]=i,e},{}):{})},t.stringify=function(e){return e?Object.keys(e).sort().map(function(t){var n=e[t];return void 0===n?"":null===n?t:Array.isArray(n)?n.slice().sort().map(function(e){return r(t)+"="+r(e)}).join("&"):r(t)+"="+r(n)}).filter(function(e){return e.length>0}).join("&"):""}},function(e,t,n){"use strict";e.exports=n(246)},function(e,t,n){"use strict";var r={Properties:{"aria-current":0,"aria-details":0,"aria-disabled":0,"aria-hidden":0,"aria-invalid":0,"aria-keyshortcuts":0,"aria-label":0,"aria-roledescription":0,"aria-autocomplete":0,"aria-checked":0,"aria-expanded":0,"aria-haspopup":0,"aria-level":0,"aria-modal":0,"aria-multiline":0,"aria-multiselectable":0,"aria-orientation":0,"aria-placeholder":0,"aria-pressed":0,"aria-readonly":0,"aria-required":0,"aria-selected":0,"aria-sort":0,"aria-valuemax":0,"aria-valuemin":0,"aria-valuenow":0,"aria-valuetext":0,"aria-atomic":0,"aria-busy":0,"aria-live":0,"aria-relevant":0,"aria-dropeffect":0,"aria-grabbed":0,"aria-activedescendant":0,"aria-colcount":0,"aria-colindex":0,"aria-colspan":0,"aria-controls":0,"aria-describedby":0,"aria-errormessage":0,"aria-flowto":0,"aria-labelledby":0,"aria-owns":0,"aria-posinset":0,"aria-rowcount":0,"aria-rowindex":0,"aria-rowspan":0,"aria-setsize":0},DOMAttributeNames:{},DOMPropertyNames:{}};e.exports=r},function(e,t,n){"use strict";var r=n(6),i=n(68),a={focusDOMComponent:function(){i(r.getNodeFromInstance(this))}};e.exports=a},function(e,t,n){"use strict";function r(){var e=window.opera;return"object"==typeof e&&"function"==typeof e.version&&parseInt(e.version(),10)<=12}function i(e){return(e.ctrlKey||e.altKey||e.metaKey)&&!(e.ctrlKey&&e.altKey)}function a(e){switch(e){case"topCompositionStart":return S.compositionStart;case"topCompositionEnd":return S.compositionEnd;case"topCompositionUpdate":return S.compositionUpdate}}function o(e,t){return"topKeyDown"===e&&t.keyCode===y}function s(e,t){switch(e){case"topKeyUp":return w.indexOf(t.keyCode)!==-1;case"topKeyDown":return t.keyCode!==y;case"topKeyPress":case"topMouseDown":case"topBlur":return!0;default:return!1}}function l(e){var t=e.detail;return"object"==typeof t&&"data"in t?t.data:null}function c(e,t,n,r){var i,c;if(b?i=a(e):T?s(e,n)&&(i=S.compositionEnd):o(e,n)&&(i=S.compositionStart),!i)return null;E&&(T||i!==S.compositionStart?i===S.compositionEnd&&T&&(c=T.getData()):T=m.getPooled(r));var u=g.getPooled(i,t,n,r);if(c)u.data=c;else{var h=l(n);null!==h&&(u.data=h)}return f.accumulateTwoPhaseDispatches(u),u}function u(e,t){switch(e){case"topCompositionEnd":return l(t);case"topKeyPress":var n=t.which;return n!==C?null:(P=!0,k);case"topTextInput":var r=t.data;return r===k&&P?null:r;default:return null}}function h(e,t){if(T){if("topCompositionEnd"===e||!b&&s(e,t)){var n=T.getData();return m.release(T),T=null,n}return null}switch(e){case"topPaste":return null;case"topKeyPress":return t.which&&!i(t)?String.fromCharCode(t.which):null;case"topCompositionEnd":return E?null:t.data;default:return null}}function d(e,t,n,r){var i;if(i=x?u(e,n):h(e,n),!i)return null;var a=v.getPooled(S.beforeInput,t,n,r);return a.data=i,f.accumulateTwoPhaseDispatches(a),a}var f=n(29),p=n(7),m=n(241),g=n(278),v=n(281),w=[9,13,27,32],y=229,b=p.canUseDOM&&"CompositionEvent"in window,_=null;p.canUseDOM&&"documentMode"in document&&(_=document.documentMode);var x=p.canUseDOM&&"TextEvent"in window&&!_&&!r(),E=p.canUseDOM&&(!b||_&&_>8&&_<=11),C=32,k=String.fromCharCode(C),S={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["topCompositionEnd","topKeyPress","topTextInput","topPaste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:["topBlur","topCompositionEnd","topKeyDown","topKeyPress","topKeyUp","topMouseDown"]},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:["topBlur","topCompositionStart","topKeyDown","topKeyPress","topKeyUp","topMouseDown"]},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:["topBlur","topCompositionUpdate","topKeyDown","topKeyPress","topKeyUp","topMouseDown"]}},P=!1,T=null,M={eventTypes:S,extractEvents:function(e,t,n,r){return[c(e,t,n,r),d(e,t,n,r)]}};e.exports=M},function(e,t,n){"use strict";var r=n(74),i=n(7),a=(n(11),n(212),n(287)),o=n(219),s=n(222),l=(n(2),s(function(e){return o(e)})),c=!1,u="cssFloat";if(i.canUseDOM){var h=document.createElement("div").style;try{h.font=""}catch(e){c=!0}void 0===document.documentElement.style.cssFloat&&(u="styleFloat")}var d={createMarkupForStyles:function(e,t){var n="";for(var r in e)if(e.hasOwnProperty(r)){var i=e[r];null!=i&&(n+=l(r)+":",n+=a(r,i,t)+";")}return n||null},setValueForStyles:function(e,t,n){var i=e.style;for(var o in t)if(t.hasOwnProperty(o)){var s=a(o,t[o],n);if("float"!==o&&"cssFloat"!==o||(o=u),s)i[o]=s;else{var l=c&&r.shorthandPropertyExpansions[o];if(l)for(var h in l)i[h]="";else i[o]=""}}}};e.exports=d},function(e,t,n){"use strict";function r(e){var t=e.nodeName&&e.nodeName.toLowerCase();return"select"===t||"input"===t&&"file"===e.type}function i(e){var t=E.getPooled(P.change,M,e,C(e));y.accumulateTwoPhaseDispatches(t),x.batchedUpdates(a,t)}function a(e){w.enqueueEvents(e),w.processEventQueue(!1)}function o(e,t){T=e,M=t,T.attachEvent("onchange",i)}function s(){T&&(T.detachEvent("onchange",i),T=null,M=null)}function l(e,t){if("topChange"===e)return t}function c(e,t,n){"topFocus"===e?(s(),o(t,n)):"topBlur"===e&&s()}function u(e,t){T=e,M=t,N=e.value,I=Object.getOwnPropertyDescriptor(e.constructor.prototype,"value"),Object.defineProperty(T,"value",O),T.attachEvent?T.attachEvent("onpropertychange",d):T.addEventListener("propertychange",d,!1)}function h(){T&&(delete T.value,T.detachEvent?T.detachEvent("onpropertychange",d):T.removeEventListener("propertychange",d,!1),T=null,M=null,N=null,I=null)}function d(e){if("value"===e.propertyName){var t=e.srcElement.value;t!==N&&(N=t,i(e))}}function f(e,t){if("topInput"===e)return t}function p(e,t,n){"topFocus"===e?(h(),u(t,n)):"topBlur"===e&&h()}function m(e,t){if(("topSelectionChange"===e||"topKeyUp"===e||"topKeyDown"===e)&&T&&T.value!==N)return N=T.value,M}function g(e){return e.nodeName&&"input"===e.nodeName.toLowerCase()&&("checkbox"===e.type||"radio"===e.type)}function v(e,t){if("topClick"===e)return t}var w=n(28),y=n(29),b=n(7),_=n(6),x=n(12),E=n(14),C=n(55),k=n(56),S=n(91),P={change:{phasedRegistrationNames:{bubbled:"onChange",captured:"onChangeCapture"},dependencies:["topBlur","topChange","topClick","topFocus","topInput","topKeyDown","topKeyUp","topSelectionChange"]}},T=null,M=null,N=null,I=null,L=!1;b.canUseDOM&&(L=k("change")&&(!document.documentMode||document.documentMode>8));var A=!1;b.canUseDOM&&(A=k("input")&&(!document.documentMode||document.documentMode>11));var O={get:function(){return I.get.call(this)},set:function(e){N=""+e,I.set.call(this,e)}},B={eventTypes:P,extractEvents:function(e,t,n,i){var a,o,s=t?_.getNodeFromInstance(t):window;if(r(s)?L?a=l:o=c:S(s)?A?a=f:(a=m,o=p):g(s)&&(a=v),a){var u=a(e,t);if(u){var h=E.getPooled(P.change,u,n,i);return h.type="change",y.accumulateTwoPhaseDispatches(h),h}}o&&o(e,s,t)}};e.exports=B},function(e,t,n){"use strict";var r=n(3),i=n(20),a=n(7),o=n(215),s=n(9),l=(n(1),{dangerouslyReplaceNodeWithMarkup:function(e,t){if(a.canUseDOM?void 0:r("56"),t?void 0:r("57"),"HTML"===e.nodeName?r("58"):void 0,"string"==typeof t){var n=o(t,s)[0];e.parentNode.replaceChild(n,e)}else i.replaceChildWithTree(e,t)}});e.exports=l},function(e,t,n){"use strict";var r=["ResponderEventPlugin","SimpleEventPlugin","TapEventPlugin","EnterLeaveEventPlugin","ChangeEventPlugin","SelectEventPlugin","BeforeInputEventPlugin"];e.exports=r},function(e,t,n){"use strict";var r=n(29),i=n(6),a=n(34),o={mouseEnter:{registrationName:"onMouseEnter",dependencies:["topMouseOut","topMouseOver"]},mouseLeave:{registrationName:"onMouseLeave",dependencies:["topMouseOut","topMouseOver"]}},s={eventTypes:o,extractEvents:function(e,t,n,s){if("topMouseOver"===e&&(n.relatedTarget||n.fromElement))return null;if("topMouseOut"!==e&&"topMouseOver"!==e)return null;var l;if(s.window===s)l=s;else{var c=s.ownerDocument;l=c?c.defaultView||c.parentWindow:window}var u,h;if("topMouseOut"===e){u=t;var d=n.relatedTarget||n.toElement;h=d?i.getClosestInstanceFromNode(d):null}else u=null,h=t;if(u===h)return null;var f=null==u?l:i.getNodeFromInstance(u),p=null==h?l:i.getNodeFromInstance(h),m=a.getPooled(o.mouseLeave,u,n,s);m.type="mouseleave",m.target=f,m.relatedTarget=p;var g=a.getPooled(o.mouseEnter,h,n,s);return g.type="mouseenter",g.target=p,g.relatedTarget=f,r.accumulateEnterLeaveDispatches(m,g,u,h),[m,g]}};e.exports=s},function(e,t,n){"use strict";function r(e){this._root=e,this._startText=this.getText(),this._fallbackText=null}var i=n(5),a=n(17),o=n(89);i(r.prototype,{destructor:function(){this._root=null,this._startText=null,this._fallbackText=null},getText:function(){return"value"in this._root?this._root.value:this._root[o()]},getData:function(){if(this._fallbackText)return this._fallbackText;var e,t,n=this._startText,r=n.length,i=this.getText(),a=i.length;for(e=0;e<r&&n[e]===i[e];e++);var o=r-e;for(t=1;t<=o&&n[r-t]===i[a-t];t++);var s=t>1?1-t:void 0;return this._fallbackText=i.slice(e,s),this._fallbackText}}),a.addPoolingTo(r),e.exports=r},function(e,t,n){"use strict";var r=n(21),i=r.injection.MUST_USE_PROPERTY,a=r.injection.HAS_BOOLEAN_VALUE,o=r.injection.HAS_NUMERIC_VALUE,s=r.injection.HAS_POSITIVE_NUMERIC_VALUE,l=r.injection.HAS_OVERLOADED_BOOLEAN_VALUE,c={isCustomAttribute:RegExp.prototype.test.bind(new RegExp("^(data|aria)-["+r.ATTRIBUTE_NAME_CHAR+"]*$")),Properties:{accept:0,acceptCharset:0,accessKey:0,action:0,allowFullScreen:a,allowTransparency:0,alt:0,as:0,async:a,autoComplete:0,autoPlay:a,capture:a,cellPadding:0,cellSpacing:0,charSet:0,challenge:0,checked:i|a,cite:0,classID:0,className:0,cols:s,colSpan:0,content:0,contentEditable:0,contextMenu:0,controls:a,coords:0,crossOrigin:0,data:0,dateTime:0,default:a,defer:a,dir:0,disabled:a,download:l,draggable:0,encType:0,form:0,formAction:0,formEncType:0,formMethod:0,formNoValidate:a,formTarget:0,frameBorder:0,headers:0,height:0,hidden:a,high:0,href:0,hrefLang:0,htmlFor:0,httpEquiv:0,icon:0,id:0,inputMode:0,integrity:0,is:0,keyParams:0,keyType:0,kind:0,label:0,lang:0,list:0,loop:a,low:0,manifest:0,marginHeight:0,marginWidth:0,max:0,maxLength:0,media:0,mediaGroup:0,method:0,min:0,minLength:0,multiple:i|a,muted:i|a,name:0,nonce:0,noValidate:a,open:a,optimum:0,pattern:0,placeholder:0,playsInline:a,poster:0,preload:0,profile:0,radioGroup:0,readOnly:a,referrerPolicy:0,rel:0,required:a,reversed:a,role:0,rows:s,rowSpan:o,sandbox:0,scope:0,scoped:a,scrolling:0,seamless:a,selected:i|a,shape:0,size:s,sizes:0,span:s,spellCheck:0,src:0,srcDoc:0,srcLang:0,srcSet:0,start:o,step:0,style:0,summary:0,tabIndex:0,target:0,title:0,type:0,useMap:0,value:0,width:0,wmode:0,wrap:0,about:0,datatype:0,inlist:0,prefix:0,property:0,resource:0,typeof:0,vocab:0,autoCapitalize:0,autoCorrect:0,autoSave:0,color:0,itemProp:0,itemScope:a,itemType:0,itemID:0,itemRef:0,results:0,security:0,unselectable:0},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{}};e.exports=c},function(e,t,n){"use strict";(function(t){function r(e,t,n,r){var i=void 0===e[n];null!=t&&i&&(e[n]=a(t,!0))}var i=n(22),a=n(90),o=(n(47),n(57)),s=n(93);n(2);"undefined"!=typeof t&&t.env,1;var l={instantiateChildren:function(e,t,n,i){if(null==e)return null;var a={};return s(e,r,a),a},updateChildren:function(e,t,n,r,s,l,c,u,h){if(t||e){var d,f;for(d in t)if(t.hasOwnProperty(d)){f=e&&e[d];var p=f&&f._currentElement,m=t[d];if(null!=f&&o(p,m))i.receiveComponent(f,m,s,u),t[d]=f;else{f&&(r[d]=i.getHostNode(f),i.unmountComponent(f,!1));var g=a(m,!0);t[d]=g;var v=i.mountComponent(g,s,l,c,u,h);n.push(v)}}for(d in e)!e.hasOwnProperty(d)||t&&t.hasOwnProperty(d)||(f=e[d],r[d]=i.getHostNode(f),i.unmountComponent(f,!1))}},unmountChildren:function(e,t){for(var n in e)if(e.hasOwnProperty(n)){var r=e[n];i.unmountComponent(r,t)}}};e.exports=l}).call(t,n(73))},function(e,t,n){"use strict";var r=n(43),i=n(251),a={processChildrenUpdates:i.dangerouslyProcessChildrenUpdates,replaceNodeWithMarkup:r.dangerouslyReplaceNodeWithMarkup};e.exports=a},function(e,t,n){"use strict";function r(e){}function i(e,t){}function a(e){return!(!e.prototype||!e.prototype.isReactComponent)}function o(e){return!(!e.prototype||!e.prototype.isPureReactComponent)}var s=n(3),l=n(5),c=n(23),u=n(49),h=n(15),d=n(50),f=n(30),p=(n(11),n(84)),m=n(22),g=n(26),v=(n(1),n(39)),w=n(57),y=(n(2),{ImpureClass:0,PureClass:1,StatelessFunctional:2});r.prototype.render=function(){var e=f.get(this)._currentElement.type,t=e(this.props,this.context,this.updater);return i(e,t),t};var b=1,_={construct:function(e){this._currentElement=e,this._rootNodeID=0,this._compositeType=null,this._instance=null,this._hostParent=null,this._hostContainerInfo=null,this._updateBatchNumber=null,this._pendingElement=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._renderedNodeType=null,this._renderedComponent=null,this._context=null,this._mountOrder=0,this._topLevelWrapper=null,this._pendingCallbacks=null,this._calledComponentWillUnmount=!1},mountComponent:function(e,t,n,l){this._context=l,this._mountOrder=b++,this._hostParent=t,this._hostContainerInfo=n;var u,h=this._currentElement.props,d=this._processContext(l),p=this._currentElement.type,m=e.getUpdateQueue(),v=a(p),w=this._constructComponent(v,h,d,m);v||null!=w&&null!=w.render?o(p)?this._compositeType=y.PureClass:this._compositeType=y.ImpureClass:(u=w,i(p,u),null===w||w===!1||c.isValidElement(w)?void 0:s("105",p.displayName||p.name||"Component"),w=new r(p),this._compositeType=y.StatelessFunctional);w.props=h,w.context=d,w.refs=g,w.updater=m,this._instance=w,f.set(w,this);var _=w.state;void 0===_&&(w.state=_=null),"object"!=typeof _||Array.isArray(_)?s("106",this.getName()||"ReactCompositeComponent"):void 0,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1;var x;return x=w.unstable_handleError?this.performInitialMountWithErrorHandling(u,t,n,e,l):this.performInitialMount(u,t,n,e,l),w.componentDidMount&&e.getReactMountReady().enqueue(w.componentDidMount,w),x},_constructComponent:function(e,t,n,r){return this._constructComponentWithoutOwner(e,t,n,r)},_constructComponentWithoutOwner:function(e,t,n,r){var i=this._currentElement.type;return e?new i(t,n,r):i(t,n,r)},performInitialMountWithErrorHandling:function(e,t,n,r,i){var a,o=r.checkpoint();try{a=this.performInitialMount(e,t,n,r,i)}catch(s){r.rollback(o),this._instance.unstable_handleError(s),this._pendingStateQueue&&(this._instance.state=this._processPendingState(this._instance.props,this._instance.context)),o=r.checkpoint(),this._renderedComponent.unmountComponent(!0),r.rollback(o),a=this.performInitialMount(e,t,n,r,i)}return a},performInitialMount:function(e,t,n,r,i){var a=this._instance,o=0;a.componentWillMount&&(a.componentWillMount(),this._pendingStateQueue&&(a.state=this._processPendingState(a.props,a.context))),void 0===e&&(e=this._renderValidatedComponent());var s=p.getType(e);this._renderedNodeType=s;var l=this._instantiateReactComponent(e,s!==p.EMPTY);this._renderedComponent=l;var c=m.mountComponent(l,r,t,n,this._processChildContext(i),o);return c},getHostNode:function(){return m.getHostNode(this._renderedComponent)},unmountComponent:function(e){if(this._renderedComponent){var t=this._instance;if(t.componentWillUnmount&&!t._calledComponentWillUnmount)if(t._calledComponentWillUnmount=!0,e){var n=this.getName()+".componentWillUnmount()";d.invokeGuardedCallback(n,t.componentWillUnmount.bind(t))}else t.componentWillUnmount();this._renderedComponent&&(m.unmountComponent(this._renderedComponent,e),this._renderedNodeType=null,this._renderedComponent=null,this._instance=null),this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._pendingCallbacks=null,this._pendingElement=null,this._context=null,this._rootNodeID=0,this._topLevelWrapper=null,f.remove(t)}},_maskContext:function(e){var t=this._currentElement.type,n=t.contextTypes;if(!n)return g;var r={};for(var i in n)r[i]=e[i];return r},_processContext:function(e){var t=this._maskContext(e);return t},_processChildContext:function(e){var t,n=this._currentElement.type,r=this._instance;if(r.getChildContext&&(t=r.getChildContext()),t){"object"!=typeof n.childContextTypes?s("107",this.getName()||"ReactCompositeComponent"):void 0;for(var i in t)i in n.childContextTypes?void 0:s("108",this.getName()||"ReactCompositeComponent",i);return l({},e,t)}return e},_checkContextTypes:function(e,t,n){},receiveComponent:function(e,t,n){var r=this._currentElement,i=this._context;this._pendingElement=null,this.updateComponent(t,r,e,i,n)},performUpdateIfNecessary:function(e){null!=this._pendingElement?m.receiveComponent(this,this._pendingElement,e,this._context):null!==this._pendingStateQueue||this._pendingForceUpdate?this.updateComponent(e,this._currentElement,this._currentElement,this._context,this._context):this._updateBatchNumber=null},updateComponent:function(e,t,n,r,i){var a=this._instance;null==a?s("136",this.getName()||"ReactCompositeComponent"):void 0;var o,l=!1;this._context===i?o=a.context:(o=this._processContext(i),l=!0);var c=t.props,u=n.props;t!==n&&(l=!0),l&&a.componentWillReceiveProps&&a.componentWillReceiveProps(u,o);var h=this._processPendingState(u,o),d=!0;this._pendingForceUpdate||(a.shouldComponentUpdate?d=a.shouldComponentUpdate(u,h,o):this._compositeType===y.PureClass&&(d=!v(c,u)||!v(a.state,h))),this._updateBatchNumber=null,d?(this._pendingForceUpdate=!1,this._performComponentUpdate(n,u,h,o,e,i)):(this._currentElement=n,this._context=i,a.props=u,a.state=h,a.context=o)},_processPendingState:function(e,t){var n=this._instance,r=this._pendingStateQueue,i=this._pendingReplaceState;if(this._pendingReplaceState=!1,this._pendingStateQueue=null,!r)return n.state;if(i&&1===r.length)return r[0];for(var a=l({},i?r[0]:n.state),o=i?1:0;o<r.length;o++){var s=r[o];l(a,"function"==typeof s?s.call(n,a,e,t):s)}return a},_performComponentUpdate:function(e,t,n,r,i,a){var o,s,l,c=this._instance,u=Boolean(c.componentDidUpdate);u&&(o=c.props,s=c.state,l=c.context),c.componentWillUpdate&&c.componentWillUpdate(t,n,r),this._currentElement=e,this._context=a,c.props=t,c.state=n,c.context=r,this._updateRenderedComponent(i,a),u&&i.getReactMountReady().enqueue(c.componentDidUpdate.bind(c,o,s,l),c); +},_updateRenderedComponent:function(e,t){var n=this._renderedComponent,r=n._currentElement,i=this._renderValidatedComponent(),a=0;if(w(r,i))m.receiveComponent(n,i,e,this._processChildContext(t));else{var o=m.getHostNode(n);m.unmountComponent(n,!1);var s=p.getType(i);this._renderedNodeType=s;var l=this._instantiateReactComponent(i,s!==p.EMPTY);this._renderedComponent=l;var c=m.mountComponent(l,e,this._hostParent,this._hostContainerInfo,this._processChildContext(t),a);this._replaceNodeWithMarkup(o,c,n)}},_replaceNodeWithMarkup:function(e,t,n){u.replaceNodeWithMarkup(e,t,n)},_renderValidatedComponentWithoutOwnerOrContext:function(){var e,t=this._instance;return e=t.render()},_renderValidatedComponent:function(){var e;if(this._compositeType!==y.StatelessFunctional){h.current=this;try{e=this._renderValidatedComponentWithoutOwnerOrContext()}finally{h.current=null}}else e=this._renderValidatedComponentWithoutOwnerOrContext();return null===e||e===!1||c.isValidElement(e)?void 0:s("109",this.getName()||"ReactCompositeComponent"),e},attachRef:function(e,t){var n=this.getPublicInstance();null==n?s("110"):void 0;var r=t.getPublicInstance(),i=n.refs===g?n.refs={}:n.refs;i[e]=r},detachRef:function(e){var t=this.getPublicInstance().refs;delete t[e]},getName:function(){var e=this._currentElement.type,t=this._instance&&this._instance.constructor;return e.displayName||t&&t.displayName||e.name||t&&t.name||null},getPublicInstance:function(){var e=this._instance;return this._compositeType===y.StatelessFunctional?null:e},_instantiateReactComponent:null};e.exports=_},function(e,t,n){"use strict";var r=n(6),i=n(259),a=n(83),o=n(22),s=n(12),l=n(272),c=n(288),u=n(88),h=n(296);n(2);i.inject();var d={findDOMNode:c,render:a.render,unmountComponentAtNode:a.unmountComponentAtNode,version:l,unstable_batchedUpdates:s.batchedUpdates,unstable_renderSubtreeIntoContainer:h};"undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject&&__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ComponentTree:{getClosestInstanceFromNode:r.getClosestInstanceFromNode,getNodeFromInstance:function(e){return e._renderedComponent&&(e=u(e)),e?r.getNodeFromInstance(e):null}},Mount:a,Reconciler:o});e.exports=d},function(e,t,n){"use strict";function r(e){if(e){var t=e._currentElement._owner||null;if(t){var n=t.getName();if(n)return" This DOM node was rendered by `"+n+"`."}}return""}function i(e,t){t&&(K[e._tag]&&(null!=t.children||null!=t.dangerouslySetInnerHTML?m("137",e._tag,e._currentElement._owner?" Check the render method of "+e._currentElement._owner.getName()+".":""):void 0),null!=t.dangerouslySetInnerHTML&&(null!=t.children?m("60"):void 0,"object"==typeof t.dangerouslySetInnerHTML&&V in t.dangerouslySetInnerHTML?void 0:m("61")),null!=t.style&&"object"!=typeof t.style?m("62",r(e)):void 0)}function a(e,t,n,r){if(!(r instanceof A)){var i=e._hostContainerInfo,a=i._node&&i._node.nodeType===W,s=a?i._node:i._ownerDocument;D(t,s),r.getReactMountReady().enqueue(o,{inst:e,registrationName:t,listener:n})}}function o(){var e=this;E.putListener(e.inst,e.registrationName,e.listener)}function s(){var e=this;T.postMountWrapper(e)}function l(){var e=this;I.postMountWrapper(e)}function c(){var e=this;M.postMountWrapper(e)}function u(){var e=this;e._rootNodeID?void 0:m("63");var t=R(e);switch(t?void 0:m("64"),e._tag){case"iframe":case"object":e._wrapperState.listeners=[k.trapBubbledEvent("topLoad","load",t)];break;case"video":case"audio":e._wrapperState.listeners=[];for(var n in G)G.hasOwnProperty(n)&&e._wrapperState.listeners.push(k.trapBubbledEvent(n,G[n],t));break;case"source":e._wrapperState.listeners=[k.trapBubbledEvent("topError","error",t)];break;case"img":e._wrapperState.listeners=[k.trapBubbledEvent("topError","error",t),k.trapBubbledEvent("topLoad","load",t)];break;case"form":e._wrapperState.listeners=[k.trapBubbledEvent("topReset","reset",t),k.trapBubbledEvent("topSubmit","submit",t)];break;case"input":case"select":case"textarea":e._wrapperState.listeners=[k.trapBubbledEvent("topInvalid","invalid",t)]}}function h(){N.postUpdateWrapper(this)}function d(e){Z.call(Y,e)||(Q.test(e)?void 0:m("65",e),Y[e]=!0)}function f(e,t){return e.indexOf("-")>=0||null!=t.is}function p(e){var t=e.type;d(t),this._currentElement=e,this._tag=t.toLowerCase(),this._namespaceURI=null,this._renderedChildren=null,this._previousStyle=null,this._previousStyleCopy=null,this._hostNode=null,this._hostParent=null,this._rootNodeID=0,this._domID=0,this._hostContainerInfo=null,this._wrapperState=null,this._topLevelWrapper=null,this._flags=0}var m=n(3),g=n(5),v=n(234),w=n(236),y=n(20),b=n(44),_=n(21),x=n(76),E=n(28),C=n(45),k=n(33),S=n(77),P=n(6),T=n(252),M=n(253),N=n(78),I=n(256),L=(n(11),n(265)),A=n(270),O=(n(9),n(36)),B=(n(1),n(56),n(39),n(58),n(2),S),z=E.deleteListener,R=P.getNodeFromInstance,D=k.listenTo,j=C.registrationNameModules,F={string:!0,number:!0},q="style",V="__html",U={children:null,dangerouslySetInnerHTML:null,suppressContentEditableWarning:null},W=11,G={topAbort:"abort",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topSeeked:"seeked",topSeeking:"seeking",topStalled:"stalled",topSuspend:"suspend",topTimeUpdate:"timeupdate",topVolumeChange:"volumechange",topWaiting:"waiting"},H={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},X={listing:!0,pre:!0,textarea:!0},K=g({menuitem:!0},H),Q=/^[a-zA-Z][a-zA-Z:_\.\-\d]*$/,Y={},Z={}.hasOwnProperty,$=1;p.displayName="ReactDOMComponent",p.Mixin={mountComponent:function(e,t,n,r){this._rootNodeID=$++,this._domID=n._idCounter++,this._hostParent=t,this._hostContainerInfo=n;var a=this._currentElement.props;switch(this._tag){case"audio":case"form":case"iframe":case"img":case"link":case"object":case"source":case"video":this._wrapperState={listeners:null},e.getReactMountReady().enqueue(u,this);break;case"input":T.mountWrapper(this,a,t),a=T.getHostProps(this,a),e.getReactMountReady().enqueue(u,this);break;case"option":M.mountWrapper(this,a,t),a=M.getHostProps(this,a);break;case"select":N.mountWrapper(this,a,t),a=N.getHostProps(this,a),e.getReactMountReady().enqueue(u,this);break;case"textarea":I.mountWrapper(this,a,t),a=I.getHostProps(this,a),e.getReactMountReady().enqueue(u,this)}i(this,a);var o,h;null!=t?(o=t._namespaceURI,h=t._tag):n._tag&&(o=n._namespaceURI,h=n._tag),(null==o||o===b.svg&&"foreignobject"===h)&&(o=b.html),o===b.html&&("svg"===this._tag?o=b.svg:"math"===this._tag&&(o=b.mathml)),this._namespaceURI=o;var d;if(e.useCreateElement){var f,p=n._ownerDocument;if(o===b.html)if("script"===this._tag){var m=p.createElement("div"),g=this._currentElement.type;m.innerHTML="<"+g+"></"+g+">",f=m.removeChild(m.firstChild)}else f=a.is?p.createElement(this._currentElement.type,a.is):p.createElement(this._currentElement.type);else f=p.createElementNS(o,this._currentElement.type);P.precacheNode(this,f),this._flags|=B.hasCachedChildNodes,this._hostParent||x.setAttributeForRoot(f),this._updateDOMProperties(null,a,e);var w=y(f);this._createInitialChildren(e,a,r,w),d=w}else{var _=this._createOpenTagMarkupAndPutListeners(e,a),E=this._createContentMarkup(e,a,r);d=!E&&H[this._tag]?_+"/>":_+">"+E+"</"+this._currentElement.type+">"}switch(this._tag){case"input":e.getReactMountReady().enqueue(s,this),a.autoFocus&&e.getReactMountReady().enqueue(v.focusDOMComponent,this);break;case"textarea":e.getReactMountReady().enqueue(l,this),a.autoFocus&&e.getReactMountReady().enqueue(v.focusDOMComponent,this);break;case"select":a.autoFocus&&e.getReactMountReady().enqueue(v.focusDOMComponent,this);break;case"button":a.autoFocus&&e.getReactMountReady().enqueue(v.focusDOMComponent,this);break;case"option":e.getReactMountReady().enqueue(c,this)}return d},_createOpenTagMarkupAndPutListeners:function(e,t){var n="<"+this._currentElement.type;for(var r in t)if(t.hasOwnProperty(r)){var i=t[r];if(null!=i)if(j.hasOwnProperty(r))i&&a(this,r,i,e);else{r===q&&(i&&(i=this._previousStyleCopy=g({},t.style)),i=w.createMarkupForStyles(i,this));var o=null;null!=this._tag&&f(this._tag,t)?U.hasOwnProperty(r)||(o=x.createMarkupForCustomAttribute(r,i)):o=x.createMarkupForProperty(r,i),o&&(n+=" "+o)}}return e.renderToStaticMarkup?n:(this._hostParent||(n+=" "+x.createMarkupForRoot()),n+=" "+x.createMarkupForID(this._domID))},_createContentMarkup:function(e,t,n){var r="",i=t.dangerouslySetInnerHTML;if(null!=i)null!=i.__html&&(r=i.__html);else{var a=F[typeof t.children]?t.children:null,o=null!=a?null:t.children;if(null!=a)r=O(a);else if(null!=o){var s=this.mountChildren(o,e,n);r=s.join("")}}return X[this._tag]&&"\n"===r.charAt(0)?"\n"+r:r},_createInitialChildren:function(e,t,n,r){var i=t.dangerouslySetInnerHTML;if(null!=i)null!=i.__html&&y.queueHTML(r,i.__html);else{var a=F[typeof t.children]?t.children:null,o=null!=a?null:t.children;if(null!=a)""!==a&&y.queueText(r,a);else if(null!=o)for(var s=this.mountChildren(o,e,n),l=0;l<s.length;l++)y.queueChild(r,s[l])}},receiveComponent:function(e,t,n){var r=this._currentElement;this._currentElement=e,this.updateComponent(t,r,e,n)},updateComponent:function(e,t,n,r){var a=t.props,o=this._currentElement.props;switch(this._tag){case"input":a=T.getHostProps(this,a),o=T.getHostProps(this,o);break;case"option":a=M.getHostProps(this,a),o=M.getHostProps(this,o);break;case"select":a=N.getHostProps(this,a),o=N.getHostProps(this,o);break;case"textarea":a=I.getHostProps(this,a),o=I.getHostProps(this,o)}switch(i(this,o),this._updateDOMProperties(a,o,e),this._updateDOMChildren(a,o,e,r),this._tag){case"input":T.updateWrapper(this);break;case"textarea":I.updateWrapper(this);break;case"select":e.getReactMountReady().enqueue(h,this)}},_updateDOMProperties:function(e,t,n){var r,i,o;for(r in e)if(!t.hasOwnProperty(r)&&e.hasOwnProperty(r)&&null!=e[r])if(r===q){var s=this._previousStyleCopy;for(i in s)s.hasOwnProperty(i)&&(o=o||{},o[i]="");this._previousStyleCopy=null}else j.hasOwnProperty(r)?e[r]&&z(this,r):f(this._tag,e)?U.hasOwnProperty(r)||x.deleteValueForAttribute(R(this),r):(_.properties[r]||_.isCustomAttribute(r))&&x.deleteValueForProperty(R(this),r);for(r in t){var l=t[r],c=r===q?this._previousStyleCopy:null!=e?e[r]:void 0;if(t.hasOwnProperty(r)&&l!==c&&(null!=l||null!=c))if(r===q)if(l?l=this._previousStyleCopy=g({},l):this._previousStyleCopy=null,c){for(i in c)!c.hasOwnProperty(i)||l&&l.hasOwnProperty(i)||(o=o||{},o[i]="");for(i in l)l.hasOwnProperty(i)&&c[i]!==l[i]&&(o=o||{},o[i]=l[i])}else o=l;else if(j.hasOwnProperty(r))l?a(this,r,l,n):c&&z(this,r);else if(f(this._tag,t))U.hasOwnProperty(r)||x.setValueForAttribute(R(this),r,l);else if(_.properties[r]||_.isCustomAttribute(r)){var u=R(this);null!=l?x.setValueForProperty(u,r,l):x.deleteValueForProperty(u,r)}}o&&w.setValueForStyles(R(this),o,this)},_updateDOMChildren:function(e,t,n,r){var i=F[typeof e.children]?e.children:null,a=F[typeof t.children]?t.children:null,o=e.dangerouslySetInnerHTML&&e.dangerouslySetInnerHTML.__html,s=t.dangerouslySetInnerHTML&&t.dangerouslySetInnerHTML.__html,l=null!=i?null:e.children,c=null!=a?null:t.children,u=null!=i||null!=o,h=null!=a||null!=s;null!=l&&null==c?this.updateChildren(null,n,r):u&&!h&&this.updateTextContent(""),null!=a?i!==a&&this.updateTextContent(""+a):null!=s?o!==s&&this.updateMarkup(""+s):null!=c&&this.updateChildren(c,n,r)},getHostNode:function(){return R(this)},unmountComponent:function(e){switch(this._tag){case"audio":case"form":case"iframe":case"img":case"link":case"object":case"source":case"video":var t=this._wrapperState.listeners;if(t)for(var n=0;n<t.length;n++)t[n].remove();break;case"html":case"head":case"body":m("66",this._tag)}this.unmountChildren(e),P.uncacheNode(this),E.deleteAllListeners(this),this._rootNodeID=0,this._domID=0,this._wrapperState=null},getPublicInstance:function(){return R(this)}},g(p.prototype,p.Mixin,L.Mixin),e.exports=p},function(e,t,n){"use strict";function r(e,t){var n={_topLevelWrapper:e,_idCounter:1,_ownerDocument:t?t.nodeType===i?t:t.ownerDocument:null,_node:t,_tag:t?t.nodeName.toLowerCase():null,_namespaceURI:t?t.namespaceURI:null};return n}var i=(n(58),9);e.exports=r},function(e,t,n){"use strict";var r=n(5),i=n(20),a=n(6),o=function(e){this._currentElement=null,this._hostNode=null,this._hostParent=null,this._hostContainerInfo=null,this._domID=0};r(o.prototype,{mountComponent:function(e,t,n,r){var o=n._idCounter++;this._domID=o,this._hostParent=t,this._hostContainerInfo=n;var s=" react-empty: "+this._domID+" ";if(e.useCreateElement){var l=n._ownerDocument,c=l.createComment(s);return a.precacheNode(this,c),i(c)}return e.renderToStaticMarkup?"":"<!--"+s+"-->"},receiveComponent:function(){},getHostNode:function(){return a.getNodeFromInstance(this)},unmountComponent:function(){a.uncacheNode(this)}}),e.exports=o},function(e,t,n){"use strict";var r={useCreateElement:!0,useFiber:!1};e.exports=r},function(e,t,n){"use strict";var r=n(43),i=n(6),a={dangerouslyProcessChildrenUpdates:function(e,t){var n=i.getNodeFromInstance(e);r.processUpdates(n,t)}};e.exports=a},function(e,t,n){"use strict";function r(){this._rootNodeID&&h.updateWrapper(this)}function i(e){var t=this._currentElement.props,n=l.executeOnChange(t,e);u.asap(r,this);var i=t.name;if("radio"===t.type&&null!=i){for(var o=c.getNodeFromInstance(this),s=o;s.parentNode;)s=s.parentNode;for(var h=s.querySelectorAll("input[name="+JSON.stringify(""+i)+'][type="radio"]'),d=0;d<h.length;d++){var f=h[d];if(f!==o&&f.form===o.form){var p=c.getInstanceFromNode(f);p?void 0:a("90"),u.asap(r,p)}}}return n}var a=n(3),o=n(5),s=n(76),l=n(48),c=n(6),u=n(12),h=(n(1),n(2),{getHostProps:function(e,t){var n=l.getValue(t),r=l.getChecked(t),i=o({type:void 0,step:void 0,min:void 0,max:void 0},t,{defaultChecked:void 0,defaultValue:void 0,value:null!=n?n:e._wrapperState.initialValue,checked:null!=r?r:e._wrapperState.initialChecked,onChange:e._wrapperState.onChange});return i},mountWrapper:function(e,t){var n=t.defaultValue;e._wrapperState={initialChecked:null!=t.checked?t.checked:t.defaultChecked,initialValue:null!=t.value?t.value:n,listeners:null,onChange:i.bind(e)}},updateWrapper:function(e){var t=e._currentElement.props,n=t.checked;null!=n&&s.setValueForProperty(c.getNodeFromInstance(e),"checked",n||!1);var r=c.getNodeFromInstance(e),i=l.getValue(t);if(null!=i){var a=""+i;a!==r.value&&(r.value=a)}else null==t.value&&null!=t.defaultValue&&r.defaultValue!==""+t.defaultValue&&(r.defaultValue=""+t.defaultValue),null==t.checked&&null!=t.defaultChecked&&(r.defaultChecked=!!t.defaultChecked)},postMountWrapper:function(e){var t=e._currentElement.props,n=c.getNodeFromInstance(e);switch(t.type){case"submit":case"reset":break;case"color":case"date":case"datetime":case"datetime-local":case"month":case"time":case"week":n.value="",n.value=n.defaultValue;break;default:n.value=n.value}var r=n.name;""!==r&&(n.name=""),n.defaultChecked=!n.defaultChecked,n.defaultChecked=!n.defaultChecked,""!==r&&(n.name=r)}});e.exports=h},function(e,t,n){"use strict";function r(e){var t="";return a.Children.forEach(e,function(e){null!=e&&("string"==typeof e||"number"==typeof e?t+=e:l||(l=!0))}),t}var i=n(5),a=n(23),o=n(6),s=n(78),l=(n(2),!1),c={mountWrapper:function(e,t,n){var i=null;if(null!=n){var a=n;"optgroup"===a._tag&&(a=a._hostParent),null!=a&&"select"===a._tag&&(i=s.getSelectValueContext(a))}var o=null;if(null!=i){var l;if(l=null!=t.value?t.value+"":r(t.children),o=!1,Array.isArray(i)){for(var c=0;c<i.length;c++)if(""+i[c]===l){o=!0;break}}else o=""+i===l}e._wrapperState={selected:o}},postMountWrapper:function(e){var t=e._currentElement.props;if(null!=t.value){var n=o.getNodeFromInstance(e);n.setAttribute("value",t.value)}},getHostProps:function(e,t){var n=i({selected:void 0,children:void 0},t);null!=e._wrapperState.selected&&(n.selected=e._wrapperState.selected);var a=r(t.children);return a&&(n.children=a),n}};e.exports=c},function(e,t,n){"use strict";function r(e,t,n,r){return e===n&&t===r}function i(e){var t=document.selection,n=t.createRange(),r=n.text.length,i=n.duplicate();i.moveToElementText(e),i.setEndPoint("EndToStart",n);var a=i.text.length,o=a+r;return{start:a,end:o}}function a(e){var t=window.getSelection&&window.getSelection();if(!t||0===t.rangeCount)return null;var n=t.anchorNode,i=t.anchorOffset,a=t.focusNode,o=t.focusOffset,s=t.getRangeAt(0);try{s.startContainer.nodeType,s.endContainer.nodeType}catch(e){return null}var l=r(t.anchorNode,t.anchorOffset,t.focusNode,t.focusOffset),c=l?0:s.toString().length,u=s.cloneRange();u.selectNodeContents(e),u.setEnd(s.startContainer,s.startOffset);var h=r(u.startContainer,u.startOffset,u.endContainer,u.endOffset),d=h?0:u.toString().length,f=d+c,p=document.createRange();p.setStart(n,i),p.setEnd(a,o);var m=p.collapsed;return{start:m?f:d,end:m?d:f}}function o(e,t){var n,r,i=document.selection.createRange().duplicate();void 0===t.end?(n=t.start,r=n):t.start>t.end?(n=t.end,r=t.start):(n=t.start,r=t.end),i.moveToElementText(e),i.moveStart("character",n),i.setEndPoint("EndToStart",i),i.moveEnd("character",r-n),i.select()}function s(e,t){if(window.getSelection){var n=window.getSelection(),r=e[u()].length,i=Math.min(t.start,r),a=void 0===t.end?i:Math.min(t.end,r);if(!n.extend&&i>a){var o=a;a=i,i=o}var s=c(e,i),l=c(e,a);if(s&&l){var h=document.createRange();h.setStart(s.node,s.offset),n.removeAllRanges(),i>a?(n.addRange(h),n.extend(l.node,l.offset)):(h.setEnd(l.node,l.offset),n.addRange(h))}}}var l=n(7),c=n(293),u=n(89),h=l.canUseDOM&&"selection"in document&&!("getSelection"in window),d={getOffsets:h?i:a,setOffsets:h?o:s};e.exports=d},function(e,t,n){"use strict";var r=n(3),i=n(5),a=n(43),o=n(20),s=n(6),l=n(36),c=(n(1),n(58),function(e){this._currentElement=e,this._stringText=""+e,this._hostNode=null,this._hostParent=null,this._domID=0,this._mountIndex=0,this._closingComment=null,this._commentNodes=null});i(c.prototype,{mountComponent:function(e,t,n,r){var i=n._idCounter++,a=" react-text: "+i+" ",c=" /react-text ";if(this._domID=i,this._hostParent=t,e.useCreateElement){var u=n._ownerDocument,h=u.createComment(a),d=u.createComment(c),f=o(u.createDocumentFragment());return o.queueChild(f,o(h)),this._stringText&&o.queueChild(f,o(u.createTextNode(this._stringText))),o.queueChild(f,o(d)),s.precacheNode(this,h),this._closingComment=d,f}var p=l(this._stringText);return e.renderToStaticMarkup?p:"<!--"+a+"-->"+p+"<!--"+c+"-->"},receiveComponent:function(e,t){if(e!==this._currentElement){this._currentElement=e;var n=""+e;if(n!==this._stringText){this._stringText=n;var r=this.getHostNode();a.replaceDelimitedText(r[0],r[1],n)}}},getHostNode:function(){var e=this._commentNodes;if(e)return e;if(!this._closingComment)for(var t=s.getNodeFromInstance(this),n=t.nextSibling;;){if(null==n?r("67",this._domID):void 0,8===n.nodeType&&" /react-text "===n.nodeValue){this._closingComment=n;break}n=n.nextSibling}return e=[this._hostNode,this._closingComment],this._commentNodes=e,e},unmountComponent:function(){this._closingComment=null,this._commentNodes=null,s.uncacheNode(this)}}),e.exports=c},function(e,t,n){"use strict";function r(){this._rootNodeID&&u.updateWrapper(this)}function i(e){var t=this._currentElement.props,n=s.executeOnChange(t,e);return c.asap(r,this),n}var a=n(3),o=n(5),s=n(48),l=n(6),c=n(12),u=(n(1),n(2),{getHostProps:function(e,t){null!=t.dangerouslySetInnerHTML?a("91"):void 0;var n=o({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue,onChange:e._wrapperState.onChange});return n},mountWrapper:function(e,t){var n=s.getValue(t),r=n;if(null==n){var o=t.defaultValue,l=t.children;null!=l&&(null!=o?a("92"):void 0,Array.isArray(l)&&(l.length<=1?void 0:a("93"),l=l[0]),o=""+l),null==o&&(o=""),r=o}e._wrapperState={initialValue:""+r,listeners:null,onChange:i.bind(e)}},updateWrapper:function(e){var t=e._currentElement.props,n=l.getNodeFromInstance(e),r=s.getValue(t);if(null!=r){var i=""+r;i!==n.value&&(n.value=i),null==t.defaultValue&&(n.defaultValue=i)}null!=t.defaultValue&&(n.defaultValue=t.defaultValue)},postMountWrapper:function(e){var t=l.getNodeFromInstance(e),n=t.textContent;n===e._wrapperState.initialValue&&(t.value=n)}});e.exports=u},function(e,t,n){"use strict";function r(e,t){"_hostNode"in e?void 0:l("33"),"_hostNode"in t?void 0:l("33");for(var n=0,r=e;r;r=r._hostParent)n++;for(var i=0,a=t;a;a=a._hostParent)i++;for(;n-i>0;)e=e._hostParent,n--;for(;i-n>0;)t=t._hostParent,i--;for(var o=n;o--;){if(e===t)return e;e=e._hostParent,t=t._hostParent}return null}function i(e,t){"_hostNode"in e?void 0:l("35"),"_hostNode"in t?void 0:l("35");for(;t;){if(t===e)return!0;t=t._hostParent}return!1}function a(e){return"_hostNode"in e?void 0:l("36"),e._hostParent}function o(e,t,n){for(var r=[];e;)r.push(e),e=e._hostParent;var i;for(i=r.length;i-- >0;)t(r[i],"captured",n);for(i=0;i<r.length;i++)t(r[i],"bubbled",n)}function s(e,t,n,i,a){for(var o=e&&t?r(e,t):null,s=[];e&&e!==o;)s.push(e),e=e._hostParent;for(var l=[];t&&t!==o;)l.push(t),t=t._hostParent;var c;for(c=0;c<s.length;c++)n(s[c],"bubbled",i);for(c=l.length;c-- >0;)n(l[c],"captured",a)}var l=n(3);n(1);e.exports={isAncestor:i,getLowestCommonAncestor:r,getParentInstance:a,traverseTwoPhase:o,traverseEnterLeave:s}},function(e,t,n){"use strict";function r(){this.reinitializeTransaction()}var i=n(5),a=n(12),o=n(35),s=n(9),l={initialize:s,close:function(){d.isBatchingUpdates=!1}},c={initialize:s,close:a.flushBatchedUpdates.bind(a)},u=[c,l];i(r.prototype,o,{getTransactionWrappers:function(){return u}});var h=new r,d={isBatchingUpdates:!1,batchedUpdates:function(e,t,n,r,i,a){var o=d.isBatchingUpdates;return d.isBatchingUpdates=!0,o?e(t,n,r,i,a):h.perform(e,null,t,n,r,i,a)}};e.exports=d},function(e,t,n){"use strict";function r(){E||(E=!0,w.EventEmitter.injectReactEventListener(v),w.EventPluginHub.injectEventPluginOrder(s),w.EventPluginUtils.injectComponentTree(d),w.EventPluginUtils.injectTreeTraversal(p),w.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:x,EnterLeaveEventPlugin:l,ChangeEventPlugin:o,SelectEventPlugin:_,BeforeInputEventPlugin:a}),w.HostComponent.injectGenericComponentClass(h),w.HostComponent.injectTextComponentClass(m),w.DOMProperty.injectDOMPropertyConfig(i),w.DOMProperty.injectDOMPropertyConfig(c),w.DOMProperty.injectDOMPropertyConfig(b),w.EmptyComponent.injectEmptyComponentFactory(function(e){return new f(e)}),w.Updates.injectReconcileTransaction(y),w.Updates.injectBatchingStrategy(g),w.Component.injectEnvironment(u))}var i=n(233),a=n(235),o=n(237),s=n(239),l=n(240),c=n(242),u=n(244),h=n(247),d=n(6),f=n(249),p=n(257),m=n(255),g=n(258),v=n(262),w=n(263),y=n(268),b=n(273),_=n(274),x=n(275),E=!1;e.exports={inject:r}},function(e,t,n){"use strict";var r="function"==typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103;e.exports=r},function(e,t,n){"use strict";function r(e){i.enqueueEvents(e),i.processEventQueue(!1)}var i=n(28),a={handleTopLevel:function(e,t,n,a){var o=i.extractEvents(e,t,n,a);r(o)}};e.exports=a},function(e,t,n){"use strict";function r(e){for(;e._hostParent;)e=e._hostParent;var t=h.getNodeFromInstance(e),n=t.parentNode;return h.getClosestInstanceFromNode(n)}function i(e,t){this.topLevelType=e,this.nativeEvent=t,this.ancestors=[]}function a(e){var t=f(e.nativeEvent),n=h.getClosestInstanceFromNode(t),i=n;do e.ancestors.push(i),i=i&&r(i);while(i);for(var a=0;a<e.ancestors.length;a++)n=e.ancestors[a],m._handleTopLevel(e.topLevelType,n,e.nativeEvent,f(e.nativeEvent))}function o(e){var t=p(window);e(t)}var s=n(5),l=n(67),c=n(7),u=n(17),h=n(6),d=n(12),f=n(55),p=n(217);s(i.prototype,{destructor:function(){this.topLevelType=null,this.nativeEvent=null,this.ancestors.length=0}}),u.addPoolingTo(i,u.twoArgumentPooler);var m={_enabled:!0,_handleTopLevel:null,WINDOW_HANDLE:c.canUseDOM?window:null,setHandleTopLevel:function(e){m._handleTopLevel=e},setEnabled:function(e){m._enabled=!!e},isEnabled:function(){return m._enabled},trapBubbledEvent:function(e,t,n){return n?l.listen(n,t,m.dispatchEvent.bind(null,e)):null},trapCapturedEvent:function(e,t,n){return n?l.capture(n,t,m.dispatchEvent.bind(null,e)):null},monitorScrollValue:function(e){var t=o.bind(null,e);l.listen(window,"scroll",t)},dispatchEvent:function(e,t){if(m._enabled){var n=i.getPooled(e,t);try{d.batchedUpdates(a,n)}finally{i.release(n)}}}};e.exports=m},function(e,t,n){"use strict";var r=n(21),i=n(28),a=n(46),o=n(49),s=n(79),l=n(33),c=n(81),u=n(12),h={Component:o.injection,DOMProperty:r.injection,EmptyComponent:s.injection,EventPluginHub:i.injection,EventPluginUtils:a.injection,EventEmitter:l.injection,HostComponent:c.injection,Updates:u.injection};e.exports=h},function(e,t,n){"use strict";var r=n(286),i=/\/?>/,a=/^<\!\-\-/,o={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(e){var t=r(e);return a.test(e)?e:e.replace(i," "+o.CHECKSUM_ATTR_NAME+'="'+t+'"$&')},canReuseMarkup:function(e,t){var n=t.getAttribute(o.CHECKSUM_ATTR_NAME);n=n&&parseInt(n,10);var i=r(e);return i===n}};e.exports=o},function(e,t,n){"use strict";function r(e,t,n){return{type:"INSERT_MARKUP",content:e,fromIndex:null,fromNode:null,toIndex:n,afterNode:t}}function i(e,t,n){return{type:"MOVE_EXISTING",content:null,fromIndex:e._mountIndex,fromNode:d.getHostNode(e),toIndex:n,afterNode:t}}function a(e,t){return{type:"REMOVE_NODE",content:null,fromIndex:e._mountIndex,fromNode:t,toIndex:null,afterNode:null}}function o(e){return{type:"SET_MARKUP",content:e,fromIndex:null,fromNode:null,toIndex:null,afterNode:null}}function s(e){return{type:"TEXT_CONTENT",content:e,fromIndex:null,fromNode:null,toIndex:null,afterNode:null}}function l(e,t){return t&&(e=e||[],e.push(t)),e}function c(e,t){h.processChildrenUpdates(e,t)}var u=n(3),h=n(49),d=(n(30),n(11),n(15),n(22)),f=n(243),p=(n(9),n(289)),m=(n(1),{Mixin:{_reconcilerInstantiateChildren:function(e,t,n){return f.instantiateChildren(e,t,n)},_reconcilerUpdateChildren:function(e,t,n,r,i,a){var o,s=0;return o=p(t,s),f.updateChildren(e,o,n,r,i,this,this._hostContainerInfo,a,s),o},mountChildren:function(e,t,n){var r=this._reconcilerInstantiateChildren(e,t,n);this._renderedChildren=r;var i=[],a=0;for(var o in r)if(r.hasOwnProperty(o)){var s=r[o],l=0,c=d.mountComponent(s,t,this,this._hostContainerInfo,n,l);s._mountIndex=a++,i.push(c)}return i},updateTextContent:function(e){var t=this._renderedChildren;f.unmountChildren(t,!1);for(var n in t)t.hasOwnProperty(n)&&u("118");var r=[s(e)];c(this,r)},updateMarkup:function(e){var t=this._renderedChildren;f.unmountChildren(t,!1);for(var n in t)t.hasOwnProperty(n)&&u("118");var r=[o(e)];c(this,r)},updateChildren:function(e,t,n){this._updateChildren(e,t,n)},_updateChildren:function(e,t,n){var r=this._renderedChildren,i={},a=[],o=this._reconcilerUpdateChildren(r,e,a,i,t,n);if(o||r){var s,u=null,h=0,f=0,p=0,m=null;for(s in o)if(o.hasOwnProperty(s)){var g=r&&r[s],v=o[s];g===v?(u=l(u,this.moveChild(g,m,h,f)),f=Math.max(g._mountIndex,f),g._mountIndex=h):(g&&(f=Math.max(g._mountIndex,f)),u=l(u,this._mountChildAtIndex(v,a[p],m,h,t,n)),p++),h++,m=d.getHostNode(v)}for(s in i)i.hasOwnProperty(s)&&(u=l(u,this._unmountChild(r[s],i[s])));u&&c(this,u),this._renderedChildren=o}},unmountChildren:function(e){var t=this._renderedChildren;f.unmountChildren(t,e),this._renderedChildren=null},moveChild:function(e,t,n,r){if(e._mountIndex<r)return i(e,t,n)},createChild:function(e,t,n){return r(n,t,e._mountIndex)},removeChild:function(e,t){return a(e,t)},_mountChildAtIndex:function(e,t,n,r,i,a){return e._mountIndex=r,this.createChild(e,n,t)},_unmountChild:function(e,t){var n=this.removeChild(e,t);return e._mountIndex=null,n}}});e.exports=m},function(e,t,n){"use strict";function r(e){return!(!e||"function"!=typeof e.attachRef||"function"!=typeof e.detachRef)}var i=n(3),a=(n(1),{addComponentAsRefTo:function(e,t,n){r(n)?void 0:i("119"),n.attachRef(t,e)},removeComponentAsRefFrom:function(e,t,n){r(n)?void 0:i("120");var a=n.getPublicInstance();a&&a.refs[t]===e.getPublicInstance()&&n.detachRef(t)}});e.exports=a},function(e,t,n){"use strict";var r="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";e.exports=r},function(e,t,n){"use strict";function r(e){this.reinitializeTransaction(),this.renderToStaticMarkup=!1,this.reactMountReady=a.getPooled(null),this.useCreateElement=e}var i=n(5),a=n(75),o=n(17),s=n(33),l=n(82),c=(n(11),n(35)),u=n(51),h={initialize:l.getSelectionInformation,close:l.restoreSelection},d={initialize:function(){var e=s.isEnabled();return s.setEnabled(!1),e},close:function(e){s.setEnabled(e)}},f={initialize:function(){this.reactMountReady.reset()},close:function(){this.reactMountReady.notifyAll()}},p=[h,d,f],m={getTransactionWrappers:function(){return p},getReactMountReady:function(){return this.reactMountReady},getUpdateQueue:function(){return u},checkpoint:function(){return this.reactMountReady.checkpoint()},rollback:function(e){this.reactMountReady.rollback(e)},destructor:function(){a.release(this.reactMountReady),this.reactMountReady=null}};i(r.prototype,c,m),o.addPoolingTo(r),e.exports=r},function(e,t,n){"use strict";function r(e,t,n){"function"==typeof e?e(t.getPublicInstance()):a.addComponentAsRefTo(t,e,n)}function i(e,t,n){"function"==typeof e?e(null):a.removeComponentAsRefFrom(t,e,n)}var a=n(266),o={};o.attachRefs=function(e,t){if(null!==t&&"object"==typeof t){var n=t.ref;null!=n&&r(n,e,t._owner)}},o.shouldUpdateRefs=function(e,t){var n=null,r=null;null!==e&&"object"==typeof e&&(n=e.ref,r=e._owner);var i=null,a=null;return null!==t&&"object"==typeof t&&(i=t.ref,a=t._owner),n!==i||"string"==typeof i&&a!==r},o.detachRefs=function(e,t){if(null!==t&&"object"==typeof t){var n=t.ref;null!=n&&i(n,e,t._owner)}},e.exports=o},function(e,t,n){"use strict";function r(e){this.reinitializeTransaction(),this.renderToStaticMarkup=e,this.useCreateElement=!1,this.updateQueue=new s(this)}var i=n(5),a=n(17),o=n(35),s=(n(11),n(271)),l=[],c={enqueue:function(){}},u={getTransactionWrappers:function(){return l},getReactMountReady:function(){return c},getUpdateQueue:function(){return this.updateQueue},destructor:function(){},checkpoint:function(){},rollback:function(){}};i(r.prototype,o,u),a.addPoolingTo(r),e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){}var a=n(51),o=(n(2),function(){function e(t){r(this,e),this.transaction=t}return e.prototype.isMounted=function(e){return!1},e.prototype.enqueueCallback=function(e,t,n){this.transaction.isInTransaction()&&a.enqueueCallback(e,t,n)},e.prototype.enqueueForceUpdate=function(e){this.transaction.isInTransaction()?a.enqueueForceUpdate(e):i(e,"forceUpdate")},e.prototype.enqueueReplaceState=function(e,t){this.transaction.isInTransaction()?a.enqueueReplaceState(e,t):i(e,"replaceState")},e.prototype.enqueueSetState=function(e,t){this.transaction.isInTransaction()?a.enqueueSetState(e,t):i(e,"setState")},e}());e.exports=o},function(e,t,n){"use strict";e.exports="15.4.2"},function(e,t,n){"use strict";var r={xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace"},i={accentHeight:"accent-height",accumulate:0,additive:0,alignmentBaseline:"alignment-baseline",allowReorder:"allowReorder",alphabetic:0,amplitude:0,arabicForm:"arabic-form",ascent:0,attributeName:"attributeName",attributeType:"attributeType",autoReverse:"autoReverse",azimuth:0,baseFrequency:"baseFrequency",baseProfile:"baseProfile",baselineShift:"baseline-shift",bbox:0,begin:0,bias:0,by:0,calcMode:"calcMode",capHeight:"cap-height",clip:0,clipPath:"clip-path",clipRule:"clip-rule",clipPathUnits:"clipPathUnits",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorProfile:"color-profile",colorRendering:"color-rendering",contentScriptType:"contentScriptType",contentStyleType:"contentStyleType",cursor:0,cx:0,cy:0,d:0,decelerate:0,descent:0,diffuseConstant:"diffuseConstant", +direction:0,display:0,divisor:0,dominantBaseline:"dominant-baseline",dur:0,dx:0,dy:0,edgeMode:"edgeMode",elevation:0,enableBackground:"enable-background",end:0,exponent:0,externalResourcesRequired:"externalResourcesRequired",fill:0,fillOpacity:"fill-opacity",fillRule:"fill-rule",filter:0,filterRes:"filterRes",filterUnits:"filterUnits",floodColor:"flood-color",floodOpacity:"flood-opacity",focusable:0,fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",format:0,from:0,fx:0,fy:0,g1:0,g2:0,glyphName:"glyph-name",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",glyphRef:"glyphRef",gradientTransform:"gradientTransform",gradientUnits:"gradientUnits",hanging:0,horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",ideographic:0,imageRendering:"image-rendering",in:0,in2:0,intercept:0,k:0,k1:0,k2:0,k3:0,k4:0,kernelMatrix:"kernelMatrix",kernelUnitLength:"kernelUnitLength",kerning:0,keyPoints:"keyPoints",keySplines:"keySplines",keyTimes:"keyTimes",lengthAdjust:"lengthAdjust",letterSpacing:"letter-spacing",lightingColor:"lighting-color",limitingConeAngle:"limitingConeAngle",local:0,markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",markerHeight:"markerHeight",markerUnits:"markerUnits",markerWidth:"markerWidth",mask:0,maskContentUnits:"maskContentUnits",maskUnits:"maskUnits",mathematical:0,mode:0,numOctaves:"numOctaves",offset:0,opacity:0,operator:0,order:0,orient:0,orientation:0,origin:0,overflow:0,overlinePosition:"overline-position",overlineThickness:"overline-thickness",paintOrder:"paint-order",panose1:"panose-1",pathLength:"pathLength",patternContentUnits:"patternContentUnits",patternTransform:"patternTransform",patternUnits:"patternUnits",pointerEvents:"pointer-events",points:0,pointsAtX:"pointsAtX",pointsAtY:"pointsAtY",pointsAtZ:"pointsAtZ",preserveAlpha:"preserveAlpha",preserveAspectRatio:"preserveAspectRatio",primitiveUnits:"primitiveUnits",r:0,radius:0,refX:"refX",refY:"refY",renderingIntent:"rendering-intent",repeatCount:"repeatCount",repeatDur:"repeatDur",requiredExtensions:"requiredExtensions",requiredFeatures:"requiredFeatures",restart:0,result:0,rotate:0,rx:0,ry:0,scale:0,seed:0,shapeRendering:"shape-rendering",slope:0,spacing:0,specularConstant:"specularConstant",specularExponent:"specularExponent",speed:0,spreadMethod:"spreadMethod",startOffset:"startOffset",stdDeviation:"stdDeviation",stemh:0,stemv:0,stitchTiles:"stitchTiles",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",string:0,stroke:0,strokeDasharray:"stroke-dasharray",strokeDashoffset:"stroke-dashoffset",strokeLinecap:"stroke-linecap",strokeLinejoin:"stroke-linejoin",strokeMiterlimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",surfaceScale:"surfaceScale",systemLanguage:"systemLanguage",tableValues:"tableValues",targetX:"targetX",targetY:"targetY",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",textLength:"textLength",to:0,transform:0,u1:0,u2:0,underlinePosition:"underline-position",underlineThickness:"underline-thickness",unicode:0,unicodeBidi:"unicode-bidi",unicodeRange:"unicode-range",unitsPerEm:"units-per-em",vAlphabetic:"v-alphabetic",vHanging:"v-hanging",vIdeographic:"v-ideographic",vMathematical:"v-mathematical",values:0,vectorEffect:"vector-effect",version:0,vertAdvY:"vert-adv-y",vertOriginX:"vert-origin-x",vertOriginY:"vert-origin-y",viewBox:"viewBox",viewTarget:"viewTarget",visibility:0,widths:0,wordSpacing:"word-spacing",writingMode:"writing-mode",x:0,xHeight:"x-height",x1:0,x2:0,xChannelSelector:"xChannelSelector",xlinkActuate:"xlink:actuate",xlinkArcrole:"xlink:arcrole",xlinkHref:"xlink:href",xlinkRole:"xlink:role",xlinkShow:"xlink:show",xlinkTitle:"xlink:title",xlinkType:"xlink:type",xmlBase:"xml:base",xmlns:0,xmlnsXlink:"xmlns:xlink",xmlLang:"xml:lang",xmlSpace:"xml:space",y:0,y1:0,y2:0,yChannelSelector:"yChannelSelector",z:0,zoomAndPan:"zoomAndPan"},a={Properties:{},DOMAttributeNamespaces:{xlinkActuate:r.xlink,xlinkArcrole:r.xlink,xlinkHref:r.xlink,xlinkRole:r.xlink,xlinkShow:r.xlink,xlinkTitle:r.xlink,xlinkType:r.xlink,xmlBase:r.xml,xmlLang:r.xml,xmlSpace:r.xml},DOMAttributeNames:{}};Object.keys(i).forEach(function(e){a.Properties[e]=0,i[e]&&(a.DOMAttributeNames[e]=i[e])}),e.exports=a},function(e,t,n){"use strict";function r(e){if("selectionStart"in e&&l.hasSelectionCapabilities(e))return{start:e.selectionStart,end:e.selectionEnd};if(window.getSelection){var t=window.getSelection();return{anchorNode:t.anchorNode,anchorOffset:t.anchorOffset,focusNode:t.focusNode,focusOffset:t.focusOffset}}if(document.selection){var n=document.selection.createRange();return{parentElement:n.parentElement(),text:n.text,top:n.boundingTop,left:n.boundingLeft}}}function i(e,t){if(w||null==m||m!==u())return null;var n=r(m);if(!v||!d(v,n)){v=n;var i=c.getPooled(p.select,g,e,t);return i.type="select",i.target=m,a.accumulateTwoPhaseDispatches(i),i}return null}var a=n(29),o=n(7),s=n(6),l=n(82),c=n(14),u=n(69),h=n(91),d=n(39),f=o.canUseDOM&&"documentMode"in document&&document.documentMode<=11,p={select:{phasedRegistrationNames:{bubbled:"onSelect",captured:"onSelectCapture"},dependencies:["topBlur","topContextMenu","topFocus","topKeyDown","topKeyUp","topMouseDown","topMouseUp","topSelectionChange"]}},m=null,g=null,v=null,w=!1,y=!1,b={eventTypes:p,extractEvents:function(e,t,n,r){if(!y)return null;var a=t?s.getNodeFromInstance(t):window;switch(e){case"topFocus":(h(a)||"true"===a.contentEditable)&&(m=a,g=t,v=null);break;case"topBlur":m=null,g=null,v=null;break;case"topMouseDown":w=!0;break;case"topContextMenu":case"topMouseUp":return w=!1,i(n,r);case"topSelectionChange":if(f)break;case"topKeyDown":case"topKeyUp":return i(n,r)}return null},didPutListener:function(e,t,n){"onSelect"===t&&(y=!0)}};e.exports=b},function(e,t,n){"use strict";function r(e){return"."+e._rootNodeID}function i(e){return"button"===e||"input"===e||"select"===e||"textarea"===e}var a=n(3),o=n(67),s=n(29),l=n(6),c=n(276),u=n(277),h=n(14),d=n(280),f=n(282),p=n(34),m=n(279),g=n(283),v=n(284),w=n(31),y=n(285),b=n(9),_=n(53),x=(n(1),{}),E={};["abort","animationEnd","animationIteration","animationStart","blur","canPlay","canPlayThrough","click","contextMenu","copy","cut","doubleClick","drag","dragEnd","dragEnter","dragExit","dragLeave","dragOver","dragStart","drop","durationChange","emptied","encrypted","ended","error","focus","input","invalid","keyDown","keyPress","keyUp","load","loadedData","loadedMetadata","loadStart","mouseDown","mouseMove","mouseOut","mouseOver","mouseUp","paste","pause","play","playing","progress","rateChange","reset","scroll","seeked","seeking","stalled","submit","suspend","timeUpdate","touchCancel","touchEnd","touchMove","touchStart","transitionEnd","volumeChange","waiting","wheel"].forEach(function(e){var t=e[0].toUpperCase()+e.slice(1),n="on"+t,r="top"+t,i={phasedRegistrationNames:{bubbled:n,captured:n+"Capture"},dependencies:[r]};x[e]=i,E[r]=i});var C={},k={eventTypes:x,extractEvents:function(e,t,n,r){var i=E[e];if(!i)return null;var o;switch(e){case"topAbort":case"topCanPlay":case"topCanPlayThrough":case"topDurationChange":case"topEmptied":case"topEncrypted":case"topEnded":case"topError":case"topInput":case"topInvalid":case"topLoad":case"topLoadedData":case"topLoadedMetadata":case"topLoadStart":case"topPause":case"topPlay":case"topPlaying":case"topProgress":case"topRateChange":case"topReset":case"topSeeked":case"topSeeking":case"topStalled":case"topSubmit":case"topSuspend":case"topTimeUpdate":case"topVolumeChange":case"topWaiting":o=h;break;case"topKeyPress":if(0===_(n))return null;case"topKeyDown":case"topKeyUp":o=f;break;case"topBlur":case"topFocus":o=d;break;case"topClick":if(2===n.button)return null;case"topDoubleClick":case"topMouseDown":case"topMouseMove":case"topMouseUp":case"topMouseOut":case"topMouseOver":case"topContextMenu":o=p;break;case"topDrag":case"topDragEnd":case"topDragEnter":case"topDragExit":case"topDragLeave":case"topDragOver":case"topDragStart":case"topDrop":o=m;break;case"topTouchCancel":case"topTouchEnd":case"topTouchMove":case"topTouchStart":o=g;break;case"topAnimationEnd":case"topAnimationIteration":case"topAnimationStart":o=c;break;case"topTransitionEnd":o=v;break;case"topScroll":o=w;break;case"topWheel":o=y;break;case"topCopy":case"topCut":case"topPaste":o=u}o?void 0:a("86",e);var l=o.getPooled(i,t,n,r);return s.accumulateTwoPhaseDispatches(l),l},didPutListener:function(e,t,n){if("onClick"===t&&!i(e._tag)){var a=r(e),s=l.getNodeFromInstance(e);C[a]||(C[a]=o.listen(s,"click",b))}},willDeleteListener:function(e,t){if("onClick"===t&&!i(e._tag)){var n=r(e);C[n].remove(),delete C[n]}}};e.exports=k},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(14),a={animationName:null,elapsedTime:null,pseudoElement:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(14),a={clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(14),a={data:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(34),a={dataTransfer:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(31),a={relatedTarget:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(14),a={data:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(31),a=n(53),o=n(290),s=n(54),l={key:o,location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:s,charCode:function(e){return"keypress"===e.type?a(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?a(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}};i.augmentClass(r,l),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(31),a=n(54),o={touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:a};i.augmentClass(r,o),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(14),a={propertyName:null,elapsedTime:null,pseudoElement:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(34),a={deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:null,deltaMode:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e){for(var t=1,n=0,r=0,a=e.length,o=a&-4;r<o;){for(var s=Math.min(r+4096,o);r<s;r+=4)n+=(t+=e.charCodeAt(r))+(t+=e.charCodeAt(r+1))+(t+=e.charCodeAt(r+2))+(t+=e.charCodeAt(r+3));t%=i,n%=i}for(;r<a;r++)n+=t+=e.charCodeAt(r);return t%=i,n%=i,t|n<<16}var i=65521;e.exports=r},function(e,t,n){"use strict";function r(e,t,n){var r=null==t||"boolean"==typeof t||""===t;if(r)return"";var i=isNaN(t);if(i||0===t||a.hasOwnProperty(e)&&a[e])return""+t;if("string"==typeof t){t=t.trim()}return t+"px"}var i=n(74),a=(n(2),i.isUnitlessNumber);e.exports=r},function(e,t,n){"use strict";function r(e){if(null==e)return null;if(1===e.nodeType)return e;var t=o.get(e);return t?(t=s(t),t?a.getNodeFromInstance(t):null):void("function"==typeof e.render?i("44"):i("45",Object.keys(e)))}var i=n(3),a=(n(15),n(6)),o=n(30),s=n(88);n(1),n(2);e.exports=r},function(e,t,n){"use strict";(function(t){function r(e,t,n,r){if(e&&"object"==typeof e){var i=e,a=void 0===i[n];a&&null!=t&&(i[n]=t)}}function i(e,t){if(null==e)return e;var n={};return a(e,r,n),n}var a=(n(47),n(93));n(2);"undefined"!=typeof t&&t.env,1,e.exports=i}).call(t,n(73))},function(e,t,n){"use strict";function r(e){if(e.key){var t=a[e.key]||e.key;if("Unidentified"!==t)return t}if("keypress"===e.type){var n=i(e);return 13===n?"Enter":String.fromCharCode(n)}return"keydown"===e.type||"keyup"===e.type?o[e.keyCode]||"Unidentified":""}var i=n(53),a={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},o={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"};e.exports=r},function(e,t,n){"use strict";function r(e){var t=e&&(i&&e[i]||e[a]);if("function"==typeof t)return t}var i="function"==typeof Symbol&&Symbol.iterator,a="@@iterator";e.exports=r},function(e,t,n){"use strict";function r(){return i++}var i=1;e.exports=r},function(e,t,n){"use strict";function r(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function i(e){for(;e;){if(e.nextSibling)return e.nextSibling;e=e.parentNode}}function a(e,t){for(var n=r(e),a=0,o=0;n;){if(3===n.nodeType){if(o=a+n.textContent.length,a<=t&&o>=t)return{node:n,offset:t-a};a=o}n=r(i(n))}}e.exports=a},function(e,t,n){"use strict";function r(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n["ms"+e]="MS"+t,n["O"+e]="o"+t.toLowerCase(),n}function i(e){if(s[e])return s[e];if(!o[e])return e;var t=o[e];for(var n in t)if(t.hasOwnProperty(n)&&n in l)return s[e]=t[n];return""}var a=n(7),o={animationend:r("Animation","AnimationEnd"),animationiteration:r("Animation","AnimationIteration"),animationstart:r("Animation","AnimationStart"),transitionend:r("Transition","TransitionEnd")},s={},l={};a.canUseDOM&&(l=document.createElement("div").style,"AnimationEvent"in window||(delete o.animationend.animation,delete o.animationiteration.animation,delete o.animationstart.animation),"TransitionEvent"in window||delete o.transitionend.transition),e.exports=i},function(e,t,n){"use strict";function r(e){return'"'+i(e)+'"'}var i=n(36);e.exports=r},function(e,t,n){"use strict";var r=n(83);e.exports=r.renderSubtreeIntoContainer},function(e,t,n){"use strict";t.__esModule=!0;var r=n(18),i={contextTypes:{history:r.history},componentWillMount:function(){this.history=this.context.history}};t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s=n(4),l=r(s),c=n(94),u=r(c),h=function(e){function t(){i(this,t),e.apply(this,arguments)}return a(t,e),t.prototype.render=function(){return l.default.createElement(u.default,o({},this.props,{onlyActiveOnIndex:!0}))},t}(s.Component);t.default=h,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var o=n(8),s=(r(o),n(10)),l=r(s),c=n(4),u=r(c),h=n(95),d=r(h),f=n(18),p=u.default.PropTypes,m=p.string,g=p.object,v=function(e){function t(){i(this,t),e.apply(this,arguments)}return a(t,e),t.prototype.render=function(){l.default(!1)},t}(c.Component);v.propTypes={to:m.isRequired,query:g,state:g,onEnter:f.falsy,children:f.falsy},v.createRouteFromReactElement=function(e,t){t&&(t.indexRoute=d.default.createRouteFromReactElement(e))},t.default=v,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var o=n(8),s=(r(o),n(10)),l=r(s),c=n(4),u=r(c),h=n(16),d=n(18),f=u.default.PropTypes.func,p=function(e){function t(){i(this,t),e.apply(this,arguments)}return a(t,e),t.prototype.render=function(){l.default(!1)},t}(c.Component);p.propTypes={path:d.falsy,component:d.component,components:d.components,getComponent:f,getComponents:f},p.createRouteFromReactElement=function(e,t){t&&(t.indexRoute=h.createRouteFromReactElement(e))},t.default=p,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(4),a=r(i),o=n(10),s=r(o),l=a.default.PropTypes.object,c={contextTypes:{history:l.isRequired,route:l},propTypes:{route:l},componentDidMount:function(){this.routerWillLeave?void 0:s.default(!1);var e=this.props.route||this.context.route;e?void 0:s.default(!1),this._unlistenBeforeLeavingRoute=this.context.history.listenBeforeLeavingRoute(e,this.routerWillLeave)},componentWillUnmount:function(){this._unlistenBeforeLeavingRoute&&this._unlistenBeforeLeavingRoute()}};t.default=c,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var o=n(10),s=r(o),l=n(4),c=r(l),u=n(16),h=n(18),d=c.default.PropTypes,f=d.string,p=d.func,m=function(e){function t(){i(this,t),e.apply(this,arguments)}return a(t,e),t.prototype.render=function(){s.default(!1)},t}(l.Component);m.createRouteFromReactElement=u.createRouteFromReactElement,m.propTypes={path:f,component:h.component,components:h.components,getComponent:p,getComponents:p},t.default=m,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(4),a=r(i),o=a.default.PropTypes.object,s={propTypes:{route:o.isRequired},childContextTypes:{route:o.isRequired},getChildContext:function(){return{route:this.props.route}}};t.default=s,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l=n(8),c=(r(l),n(4)),u=r(c),h=n(226),d=r(h),f=n(16),p=n(96),m=r(p),g=n(60),v=r(g),w=n(18),y=u.default.PropTypes,b=y.func,_=y.object,x=function(e){function t(n,r){a(this,t),e.call(this,n,r),this.state={location:null,routes:null,params:null,components:null}}return o(t,e),t.prototype.handleError=function(e){if(!this.props.onError)throw e;this.props.onError.call(this,e)},t.prototype.componentWillMount=function(){var e=this,t=this.props,n=t.history,r=t.children,i=t.routes,a=t.parseQueryString,o=t.stringifyQuery,s=n?function(){return n}:d.default;this.history=v.default(s)({routes:f.createRoutes(i||r),parseQueryString:a,stringifyQuery:o}),this._unlisten=this.history.listen(function(t,n){t?e.handleError(t):e.setState(n,e.props.onUpdate)})},t.prototype.componentWillReceiveProps=function(e){},t.prototype.componentWillUnmount=function(){this._unlisten&&this._unlisten()},t.prototype.render=function(){var e=this.state,n=e.location,r=e.routes,a=e.params,o=e.components,l=this.props,c=l.RoutingContext,h=l.createElement,d=i(l,["RoutingContext","createElement"]);return null==n?null:(Object.keys(t.propTypes).forEach(function(e){return delete d[e]}),u.default.createElement(c,s({},d,{history:this.history,createElement:h,location:n,routes:r,params:a,components:o})))},t}(c.Component);x.propTypes={history:_,children:w.routes,routes:w.routes,RoutingContext:b.isRequired,createElement:b,onError:b,onUpdate:b,parseQueryString:b,stringifyQuery:b},x.defaultProps={RoutingContext:m.default},t.default=x,e.exports=t.default},function(e,t,n){"use strict";function r(e,t){return function(n,r,i){e.apply(t,arguments),e.length<3&&i()}}function i(e){return e.reduce(function(e,t){return t.onEnter&&e.push(r(t.onEnter,t)),e},[])}function a(e,t,n){function r(e,t,n){o={pathname:t,query:n,state:e}}var a=i(e);if(!a.length)return void n();var o=void 0;s.loopAsync(a.length,function(e,n,i){a[e](t,r,function(e){e||o?i(e,o):n()})},n)}function o(e){for(var t=0,n=e.length;t<n;++t)e[t].onLeave&&e[t].onLeave.call(e[t])}t.__esModule=!0,t.runEnterHooks=a,t.runLeaveHooks=o;var s=n(59)},function(e,t,n){"use strict";function r(e,t,n){if(!e.path)return!1;var r=a.getParamNames(e.path);return r.some(function(e){return t.params[e]!==n.params[e]})}function i(e,t){var n=e&&e.routes,i=t.routes,a=void 0,o=void 0;return n?(a=n.filter(function(n){return i.indexOf(n)===-1||r(n,e,t)}),a.reverse(),o=i.filter(function(e){return n.indexOf(e)===-1||a.indexOf(e)!==-1})):(a=[],o=i),{leaveRoutes:a,enterRoutes:o}}t.__esModule=!0;var a=n(32);t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e,t,n){t.component||t.components?n(null,t.component||t.components):t.getComponent?t.getComponent(e,n):t.getComponents?t.getComponents(e,n):n()}function i(e,t){a.mapAsync(e.routes,function(t,n,i){r(e.location,t,i)},t)}t.__esModule=!0;var a=n(59);t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e,t){var n={};if(!e.path)return n;var r=i.getParamNames(e.path);for(var a in t)t.hasOwnProperty(a)&&r.indexOf(a)!==-1&&(n[a]=t[a]);return n}t.__esModule=!0;var i=n(32);t.default=r,e.exports=t.default},function(e,t,n){"use strict";function r(e,t){if(e==t)return!0;if(null==e||null==t)return!1;if(Array.isArray(e))return Array.isArray(t)&&e.length===t.length&&e.every(function(e,n){return r(e,t[n])});if("object"==typeof e){for(var n in e)if(e.hasOwnProperty(n))if(void 0===e[n]){if(void 0!==t[n])return!1}else{if(!t.hasOwnProperty(n))return!1;if(!r(e[n],t[n]))return!1}return!0}return String(e)===String(t)}function i(e,t,n){return e.every(function(e,r){return String(t[r])===String(n[e])})}function a(e,t,n){for(var r=e,a=[],o=[],s=0,l=t.length;s<l;++s){var u=t[s],h=u.path||"";if("/"===h.charAt(0)&&(r=e,a=[],o=[]),null!==r){var d=c.matchPattern(h,r);r=d.remainingPathname,a=[].concat(a,d.paramNames),o=[].concat(o,d.paramValues)}if(""===r&&u.path&&i(a,o,n))return s}return null}function o(e,t,n,r){var i=a(e,t,n);return null!==i&&(!r||t.slice(i+1).every(function(e){return!e.path}))}function s(e,t){return null==t?null==e:null==e||r(e,t)}function l(e,t,n,r,i,a){return null!=r&&(!!o(e,i,a,n)&&s(t,r.query))}t.__esModule=!0;var c=n(32);t.default=l,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n=e.routes,r=e.location,i=e.parseQueryString,o=e.stringifyQuery,l=e.basename;r?void 0:s.default(!1);var c=m({routes:d.createRoutes(n),parseQueryString:i,stringifyQuery:o,basename:l});"string"==typeof r&&(r=c.createLocation(r)),c.match(r,function(e,n,r){t(e,n,r&&a({},r,{history:c}))})}t.__esModule=!0;var a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=n(10),s=r(o),l=n(228),c=r(l),u=n(229),h=r(u),d=n(16),f=n(60),p=r(f),m=p.default(h.default(c.default));t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t,n){e.childRoutes?n(null,e.childRoutes):e.getChildRoutes?e.getChildRoutes(t,function(e,t){n(e,!e&&f.createRoutes(t))}):n()}function a(e,t,n){e.indexRoute?n(null,e.indexRoute):e.getIndexRoute?e.getIndexRoute(t,function(e,t){n(e,!e&&f.createRoutes(t)[0])}):e.childRoutes?!function(){var r=e.childRoutes.filter(function(e){return!e.hasOwnProperty("path")});h.loopAsync(r.length,function(e,n,i){a(r[e],t,function(t,a){if(t||a){var o=[r[e]].concat(Array.isArray(a)?a:[a]);i(t,o)}else n()})},function(e,t){n(null,t)})}():n()}function o(e,t,n){return t.reduce(function(e,t,r){var i=n&&n[r];return Array.isArray(e[t])?e[t].push(i):t in e?e[t]=[e[t],i]:e[t]=i,e},e)}function s(e,t){return o({},e,t)}function l(e,t,n,r,o,l){var u=e.path||"";if("/"===u.charAt(0)&&(n=t.pathname,r=[],o=[]),null!==n){var h=d.matchPattern(u,n);if(n=h.remainingPathname,r=[].concat(r,h.paramNames),o=[].concat(o,h.paramValues),""===n&&e.path){var f=function(){var n={routes:[e],params:s(r,o)};return a(e,t,function(e,t){if(e)l(e);else{if(Array.isArray(t)){var r;(r=n.routes).push.apply(r,t)}else t&&n.routes.push(t);l(null,n)}}),{v:void 0}}();if("object"==typeof f)return f.v}}null!=n||e.childRoutes?i(e,t,function(i,a){i?l(i):a?c(a,t,function(t,n){t?l(t):n?(n.routes.unshift(e),l(null,n)):l()},n,r,o):l()}):l()}function c(e,t,n){var r=arguments.length<=3||void 0===arguments[3]?t.pathname:arguments[3],i=arguments.length<=4||void 0===arguments[4]?[]:arguments[4],a=arguments.length<=5||void 0===arguments[5]?[]:arguments[5];return function(){h.loopAsync(e.length,function(n,o,s){l(e[n],t,r,i,a,function(e,t){e||t?s(e,t):o()})},n)}()}t.__esModule=!0;var u=n(8),h=(r(u),n(59)),d=n(32),f=n(16);t.default=c,e.exports=t.default},function(e,t,n){"use strict";function r(e){var t=/[=:]/g,n={"=":"=0",":":"=2"},r=(""+e).replace(t,function(e){return n[e]});return"$"+r}function i(e){var t=/(=0|=2)/g,n={"=0":"=","=2":":"},r="."===e[0]&&"$"===e[1]?e.substring(2):e.substring(1);return(""+r).replace(t,function(e){return n[e]})}var a={escape:r,unescape:i};e.exports=a},function(e,t,n){"use strict";var r=n(25),i=(n(1),function(e){var t=this;if(t.instancePool.length){var n=t.instancePool.pop();return t.call(n,e),n}return new t(e)}),a=function(e,t){var n=this;if(n.instancePool.length){var r=n.instancePool.pop();return n.call(r,e,t),r}return new n(e,t)},o=function(e,t,n){var r=this;if(r.instancePool.length){var i=r.instancePool.pop();return r.call(i,e,t,n),i}return new r(e,t,n)},s=function(e,t,n,r){var i=this;if(i.instancePool.length){var a=i.instancePool.pop();return i.call(a,e,t,n,r),a}return new i(e,t,n,r)},l=function(e){var t=this;e instanceof t?void 0:r("25"),e.destructor(),t.instancePool.length<t.poolSize&&t.instancePool.push(e)},c=10,u=i,h=function(e,t){var n=e;return n.instancePool=[],n.getPooled=t||u,n.poolSize||(n.poolSize=c),n.release=l,n},d={addPoolingTo:h,oneArgumentPooler:i,twoArgumentPooler:a,threeArgumentPooler:o,fourArgumentPooler:s};e.exports=d},function(e,t,n){"use strict";function r(e){return(""+e).replace(b,"$&/")}function i(e,t){this.func=e,this.context=t,this.count=0}function a(e,t,n){var r=e.func,i=e.context;r.call(i,t,e.count++)}function o(e,t,n){if(null==e)return e;var r=i.getPooled(t,n);v(e,a,r),i.release(r)}function s(e,t,n,r){this.result=e,this.keyPrefix=t,this.func=n,this.context=r,this.count=0}function l(e,t,n){var i=e.result,a=e.keyPrefix,o=e.func,s=e.context,l=o.call(s,t,e.count++);Array.isArray(l)?c(l,i,n,g.thatReturnsArgument):null!=l&&(m.isValidElement(l)&&(l=m.cloneAndReplaceKey(l,a+(!l.key||t&&t.key===l.key?"":r(l.key)+"/")+n)),i.push(l))}function c(e,t,n,i,a){var o="";null!=n&&(o=r(n)+"/");var c=s.getPooled(t,o,i,a);v(e,l,c),s.release(c)}function u(e,t,n){if(null==e)return e;var r=[];return c(e,r,null,t,n),r}function h(e,t,n){return null}function d(e,t){return v(e,h,null)}function f(e){var t=[];return c(e,t,null,g.thatReturnsArgument),t}var p=n(313),m=n(24),g=n(9),v=n(322),w=p.twoArgumentPooler,y=p.fourArgumentPooler,b=/\/+/g;i.prototype.destructor=function(){this.func=null,this.context=null,this.count=0},p.addPoolingTo(i,w),s.prototype.destructor=function(){this.result=null,this.keyPrefix=null,this.func=null,this.context=null,this.count=0},p.addPoolingTo(s,y);var _={forEach:o,map:u,mapIntoWithKeyPrefixInternal:c,count:d,toArray:f};e.exports=_},function(e,t,n){"use strict";function r(e){return e}function i(e,t){var n=b.hasOwnProperty(t)?b[t]:null;x.hasOwnProperty(t)&&("OVERRIDE_BASE"!==n?d("73",t):void 0),e&&("DEFINE_MANY"!==n&&"DEFINE_MANY_MERGED"!==n?d("74",t):void 0)}function a(e,t){if(t){"function"==typeof t?d("75"):void 0,m.isValidElement(t)?d("76"):void 0;var n=e.prototype,r=n.__reactAutoBindPairs;t.hasOwnProperty(w)&&_.mixins(e,t.mixins);for(var a in t)if(t.hasOwnProperty(a)&&a!==w){var o=t[a],s=n.hasOwnProperty(a);if(i(s,a),_.hasOwnProperty(a))_[a](e,o);else{var u=b.hasOwnProperty(a),h="function"==typeof o,f=h&&!u&&!s&&t.autobind!==!1;if(f)r.push(a,o),n[a]=o;else if(s){var p=b[a];!u||"DEFINE_MANY_MERGED"!==p&&"DEFINE_MANY"!==p?d("77",p,a):void 0,"DEFINE_MANY_MERGED"===p?n[a]=l(n[a],o):"DEFINE_MANY"===p&&(n[a]=c(n[a],o))}else n[a]=o}}}else;}function o(e,t){if(t)for(var n in t){var r=t[n];if(t.hasOwnProperty(n)){var i=n in _;i?d("78",n):void 0;var a=n in e;a?d("79",n):void 0,e[n]=r}}}function s(e,t){e&&t&&"object"==typeof e&&"object"==typeof t?void 0:d("80");for(var n in t)t.hasOwnProperty(n)&&(void 0!==e[n]?d("81",n):void 0,e[n]=t[n]);return e}function l(e,t){return function(){var n=e.apply(this,arguments),r=t.apply(this,arguments);if(null==n)return r;if(null==r)return n;var i={};return s(i,n),s(i,r),i}}function c(e,t){return function(){e.apply(this,arguments),t.apply(this,arguments)}}function u(e,t){var n=t.bind(e);return n}function h(e){for(var t=e.__reactAutoBindPairs,n=0;n<t.length;n+=2){var r=t[n],i=t[n+1];e[r]=u(e,i)}}var d=n(25),f=n(5),p=n(61),m=n(24),g=(n(100),n(62)),v=n(26),w=(n(1),n(2),"mixins"),y=[],b={mixins:"DEFINE_MANY",statics:"DEFINE_MANY",propTypes:"DEFINE_MANY",contextTypes:"DEFINE_MANY",childContextTypes:"DEFINE_MANY",getDefaultProps:"DEFINE_MANY_MERGED",getInitialState:"DEFINE_MANY_MERGED",getChildContext:"DEFINE_MANY_MERGED",render:"DEFINE_ONCE",componentWillMount:"DEFINE_MANY",componentDidMount:"DEFINE_MANY",componentWillReceiveProps:"DEFINE_MANY",shouldComponentUpdate:"DEFINE_ONCE",componentWillUpdate:"DEFINE_MANY",componentDidUpdate:"DEFINE_MANY",componentWillUnmount:"DEFINE_MANY",updateComponent:"OVERRIDE_BASE"},_={displayName:function(e,t){e.displayName=t},mixins:function(e,t){if(t)for(var n=0;n<t.length;n++)a(e,t[n])},childContextTypes:function(e,t){e.childContextTypes=f({},e.childContextTypes,t); +},contextTypes:function(e,t){e.contextTypes=f({},e.contextTypes,t)},getDefaultProps:function(e,t){e.getDefaultProps?e.getDefaultProps=l(e.getDefaultProps,t):e.getDefaultProps=t},propTypes:function(e,t){e.propTypes=f({},e.propTypes,t)},statics:function(e,t){o(e,t)},autobind:function(){}},x={replaceState:function(e,t){this.updater.enqueueReplaceState(this,e),t&&this.updater.enqueueCallback(this,t,"replaceState")},isMounted:function(){return this.updater.isMounted(this)}},E=function(){};f(E.prototype,p.prototype,x);var C={createClass:function(e){var t=r(function(e,n,r){this.__reactAutoBindPairs.length&&h(this),this.props=e,this.context=n,this.refs=v,this.updater=r||g,this.state=null;var i=this.getInitialState?this.getInitialState():null;"object"!=typeof i||Array.isArray(i)?d("82",t.displayName||"ReactCompositeComponent"):void 0,this.state=i});t.prototype=new E,t.prototype.constructor=t,t.prototype.__reactAutoBindPairs=[],y.forEach(a.bind(null,t)),a(t,e),t.getDefaultProps&&(t.defaultProps=t.getDefaultProps()),t.prototype.render?void 0:d("83");for(var n in b)t.prototype[n]||(t.prototype[n]=null);return t},injection:{injectMixin:function(e){y.push(e)}}};e.exports=C},function(e,t,n){"use strict";var r=n(24),i=r.createFactory,a={a:i("a"),abbr:i("abbr"),address:i("address"),area:i("area"),article:i("article"),aside:i("aside"),audio:i("audio"),b:i("b"),base:i("base"),bdi:i("bdi"),bdo:i("bdo"),big:i("big"),blockquote:i("blockquote"),body:i("body"),br:i("br"),button:i("button"),canvas:i("canvas"),caption:i("caption"),cite:i("cite"),code:i("code"),col:i("col"),colgroup:i("colgroup"),data:i("data"),datalist:i("datalist"),dd:i("dd"),del:i("del"),details:i("details"),dfn:i("dfn"),dialog:i("dialog"),div:i("div"),dl:i("dl"),dt:i("dt"),em:i("em"),embed:i("embed"),fieldset:i("fieldset"),figcaption:i("figcaption"),figure:i("figure"),footer:i("footer"),form:i("form"),h1:i("h1"),h2:i("h2"),h3:i("h3"),h4:i("h4"),h5:i("h5"),h6:i("h6"),head:i("head"),header:i("header"),hgroup:i("hgroup"),hr:i("hr"),html:i("html"),i:i("i"),iframe:i("iframe"),img:i("img"),input:i("input"),ins:i("ins"),kbd:i("kbd"),keygen:i("keygen"),label:i("label"),legend:i("legend"),li:i("li"),link:i("link"),main:i("main"),map:i("map"),mark:i("mark"),menu:i("menu"),menuitem:i("menuitem"),meta:i("meta"),meter:i("meter"),nav:i("nav"),noscript:i("noscript"),object:i("object"),ol:i("ol"),optgroup:i("optgroup"),option:i("option"),output:i("output"),p:i("p"),param:i("param"),picture:i("picture"),pre:i("pre"),progress:i("progress"),q:i("q"),rp:i("rp"),rt:i("rt"),ruby:i("ruby"),s:i("s"),samp:i("samp"),script:i("script"),section:i("section"),select:i("select"),small:i("small"),source:i("source"),span:i("span"),strong:i("strong"),style:i("style"),sub:i("sub"),summary:i("summary"),sup:i("sup"),table:i("table"),tbody:i("tbody"),td:i("td"),textarea:i("textarea"),tfoot:i("tfoot"),th:i("th"),thead:i("thead"),time:i("time"),title:i("title"),tr:i("tr"),track:i("track"),u:i("u"),ul:i("ul"),var:i("var"),video:i("video"),wbr:i("wbr"),circle:i("circle"),clipPath:i("clipPath"),defs:i("defs"),ellipse:i("ellipse"),g:i("g"),image:i("image"),line:i("line"),linearGradient:i("linearGradient"),mask:i("mask"),path:i("path"),pattern:i("pattern"),polygon:i("polygon"),polyline:i("polyline"),radialGradient:i("radialGradient"),rect:i("rect"),stop:i("stop"),svg:i("svg"),text:i("text"),tspan:i("tspan")};e.exports=a},function(e,t,n){"use strict";function r(e,t){return e===t?0!==e||1/e===1/t:e!==e&&t!==t}function i(e){this.message=e,this.stack=""}function a(e){function t(t,n,r,a,o,s,l){a=a||S,s=s||r;if(null==n[r]){var c=x[o];return t?new i(null===n[r]?"The "+c+" `"+s+"` is marked as required "+("in `"+a+"`, but its value is `null`."):"The "+c+" `"+s+"` is marked as required in "+("`"+a+"`, but its value is `undefined`.")):null}return e(n,r,a,o,s)}var n=t.bind(null,!1);return n.isRequired=t.bind(null,!0),n}function o(e){function t(t,n,r,a,o,s){var l=t[n],c=w(l);if(c!==e){var u=x[a],h=y(l);return new i("Invalid "+u+" `"+o+"` of type "+("`"+h+"` supplied to `"+r+"`, expected ")+("`"+e+"`."))}return null}return a(t)}function s(){return a(C.thatReturns(null))}function l(e){function t(t,n,r,a,o){if("function"!=typeof e)return new i("Property `"+o+"` of component `"+r+"` has invalid PropType notation inside arrayOf.");var s=t[n];if(!Array.isArray(s)){var l=x[a],c=w(s);return new i("Invalid "+l+" `"+o+"` of type "+("`"+c+"` supplied to `"+r+"`, expected an array."))}for(var u=0;u<s.length;u++){var h=e(s,u,r,a,o+"["+u+"]",E);if(h instanceof Error)return h}return null}return a(t)}function c(){function e(e,t,n,r,a){var o=e[t];if(!_.isValidElement(o)){var s=x[r],l=w(o);return new i("Invalid "+s+" `"+a+"` of type "+("`"+l+"` supplied to `"+n+"`, expected a single ReactElement."))}return null}return a(e)}function u(e){function t(t,n,r,a,o){if(!(t[n]instanceof e)){var s=x[a],l=e.name||S,c=b(t[n]);return new i("Invalid "+s+" `"+o+"` of type "+("`"+c+"` supplied to `"+r+"`, expected ")+("instance of `"+l+"`."))}return null}return a(t)}function h(e){function t(t,n,a,o,s){for(var l=t[n],c=0;c<e.length;c++)if(r(l,e[c]))return null;var u=x[o],h=JSON.stringify(e);return new i("Invalid "+u+" `"+s+"` of value `"+l+"` "+("supplied to `"+a+"`, expected one of "+h+"."))}return Array.isArray(e)?a(t):C.thatReturnsNull}function d(e){function t(t,n,r,a,o){if("function"!=typeof e)return new i("Property `"+o+"` of component `"+r+"` has invalid PropType notation inside objectOf.");var s=t[n],l=w(s);if("object"!==l){var c=x[a];return new i("Invalid "+c+" `"+o+"` of type "+("`"+l+"` supplied to `"+r+"`, expected an object."))}for(var u in s)if(s.hasOwnProperty(u)){var h=e(s,u,r,a,o+"."+u,E);if(h instanceof Error)return h}return null}return a(t)}function f(e){function t(t,n,r,a,o){for(var s=0;s<e.length;s++){var l=e[s];if(null==l(t,n,r,a,o,E))return null}var c=x[a];return new i("Invalid "+c+" `"+o+"` supplied to "+("`"+r+"`."))}return Array.isArray(e)?a(t):C.thatReturnsNull}function p(){function e(e,t,n,r,a){if(!g(e[t])){var o=x[r];return new i("Invalid "+o+" `"+a+"` supplied to "+("`"+n+"`, expected a ReactNode."))}return null}return a(e)}function m(e){function t(t,n,r,a,o){var s=t[n],l=w(s);if("object"!==l){var c=x[a];return new i("Invalid "+c+" `"+o+"` of type `"+l+"` "+("supplied to `"+r+"`, expected `object`."))}for(var u in e){var h=e[u];if(h){var d=h(s,u,r,a,o+"."+u,E);if(d)return d}}return null}return a(t)}function g(e){switch(typeof e){case"number":case"string":case"undefined":return!0;case"boolean":return!e;case"object":if(Array.isArray(e))return e.every(g);if(null===e||_.isValidElement(e))return!0;var t=k(e);if(!t)return!1;var n,r=t.call(e);if(t!==e.entries){for(;!(n=r.next()).done;)if(!g(n.value))return!1}else for(;!(n=r.next()).done;){var i=n.value;if(i&&!g(i[1]))return!1}return!0;default:return!1}}function v(e,t){return"symbol"===e||("Symbol"===t["@@toStringTag"]||"function"==typeof Symbol&&t instanceof Symbol)}function w(e){var t=typeof e;return Array.isArray(e)?"array":e instanceof RegExp?"object":v(t,e)?"symbol":t}function y(e){var t=w(e);if("object"===t){if(e instanceof Date)return"date";if(e instanceof RegExp)return"regexp"}return t}function b(e){return e.constructor&&e.constructor.name?e.constructor.name:S}var _=n(24),x=n(100),E=n(318),C=n(9),k=n(102),S=(n(2),"<<anonymous>>"),P={array:o("array"),bool:o("boolean"),func:o("function"),number:o("number"),object:o("object"),string:o("string"),symbol:o("symbol"),any:s(),arrayOf:l,element:c(),instanceOf:u,node:p(),objectOf:d,oneOf:h,oneOfType:f,shape:m};i.prototype=Error.prototype,e.exports=P},function(e,t,n){"use strict";var r="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";e.exports=r},function(e,t,n){"use strict";function r(e,t,n){this.props=e,this.context=t,this.refs=l,this.updater=n||s}function i(){}var a=n(5),o=n(61),s=n(62),l=n(26);i.prototype=o.prototype,r.prototype=new i,r.prototype.constructor=r,a(r.prototype,o.prototype),r.prototype.isPureReactComponent=!0,e.exports=r},function(e,t,n){"use strict";e.exports="15.4.2"},function(e,t,n){"use strict";function r(e){return a.isValidElement(e)?void 0:i("143"),e}var i=n(25),a=n(24);n(1);e.exports=r},function(e,t,n){"use strict";function r(e,t){return e&&"object"==typeof e&&null!=e.key?c.escape(e.key):t.toString(36)}function i(e,t,n,a){var d=typeof e;if("undefined"!==d&&"boolean"!==d||(e=null),null===e||"string"===d||"number"===d||"object"===d&&e.$$typeof===s)return n(a,e,""===t?u+r(e,0):t),1;var f,p,m=0,g=""===t?u:t+h;if(Array.isArray(e))for(var v=0;v<e.length;v++)f=e[v],p=g+r(f,v),m+=i(f,p,n,a);else{var w=l(e);if(w){var y,b=w.call(e);if(w!==e.entries)for(var _=0;!(y=b.next()).done;)f=y.value,p=g+r(f,_++),m+=i(f,p,n,a);else for(;!(y=b.next()).done;){var x=y.value;x&&(f=x[1],p=g+c.escape(x[0])+h+r(f,0),m+=i(f,p,n,a))}}else if("object"===d){var E="",C=String(e);o("31","[object Object]"===C?"object with keys {"+Object.keys(e).join(", ")+"}":C,E)}}return m}function a(e,t,n){return null==e?0:i(e,"",t,n)}var o=n(25),s=(n(15),n(99)),l=n(102),c=(n(1),n(312)),u=(n(2),"."),h=":";e.exports=a},function(e,t,n){"use strict";e.exports=function(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})}},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}},function(e,t,n){e.exports=n(103)}])}); \ No newline at end of file diff --git a/en-GB/article.js b/en-GB/article.js index 710b40fc..0fad81db 100644 --- a/en-GB/article.js +++ b/en-GB/article.js @@ -1,6791 +1,5 @@ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else if(typeof exports === 'object') - exports["BezierArticle"] = factory(); - else - root["BezierArticle"] = factory(); -})(this, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; - -/******/ // 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] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; - -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - -/******/ // Flag the module as loaded -/******/ module.l = true; - -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } - - -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; - -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; - -/******/ // identity function for calling harmony imports with the correct context -/******/ __webpack_require__.i = function(value) { return value; }; - -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; - -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; - -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; - -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; - -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 337); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports) { - -// shim for using process in browser -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; - -process.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; }; - - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); -var Locale = __webpack_require__(68); -var locale = new Locale(); - -module.exports = function generateBase(page, handler) { - - // the basic class just has a title and basic content. - var componentClass = { - getDefaultProps: function getDefaultProps() { - return { - title: locale.getTitle(page) - }; - }, - - render: function render() { - return locale.getContent(page, this); - } - }; - - // if the content requires code bindings, ensure those exist: - if (handler) { - Object.keys(handler).forEach(function (key) { - componentClass[key] = handler[key]; - }); - } - - // then build the actual React class - return React.createClass(componentClass); -}; - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ - -var validateFormat = function validateFormat(format) {}; - -if (process.env.NODE_ENV !== 'production') { - validateFormat = function validateFormat(format) { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - }; -} - -function invariant(condition, format, a, b, c, d, e, f) { - validateFormat(format); - - if (!condition) { - var error; - if (format === undefined) { - error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error(format.replace(/%s/g, function () { - return args[argIndex++]; - })); - error.name = 'Invariant Violation'; - } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -} - -module.exports = invariant; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var emptyFunction = __webpack_require__(12); - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = emptyFunction; - -if (process.env.NODE_ENV !== 'production') { - (function () { - var printWarning = function printWarning(format) { - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - var argIndex = 0; - var message = 'Warning: ' + format.replace(/%s/g, function () { - return args[argIndex++]; - }); - if (typeof console !== 'undefined') { - console.error(message); - } - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch (x) {} - }; - - warning = function warning(condition, format) { - if (format === undefined) { - throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); - } - - if (format.indexOf('Failed Composite propType: ') === 0) { - return; // Ignore CompositeComponent proptype check. - } - - if (!condition) { - for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { - args[_key2 - 2] = arguments[_key2]; - } - - printWarning.apply(undefined, [format].concat(args)); - } - }; - })(); -} - -module.exports = warning; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - -/** - * WARNING: DO NOT manually require this module. - * This is a replacement for `invariant(...)` used by the error code system - * and will _only_ be required by the corresponding babel pass. - * It always throws. - */ - -function reactProdInvariant(code) { - var argCount = arguments.length - 1; - - var message = 'Minified React error #' + code + '; visit ' + 'http://facebook.github.io/react/docs/error-decoder.html?invariant=' + code; - - for (var argIdx = 0; argIdx < argCount; argIdx++) { - message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]); - } - - message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.'; - - var error = new Error(message); - error.name = 'Invariant Violation'; - error.framesToPop = 1; // we don't care about reactProdInvariant's own frame - - throw error; -} - -module.exports = reactProdInvariant; - -/***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = __webpack_require__(27); - - -/***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -/* eslint-disable no-unused-vars */ -var hasOwnProperty = Object.prototype.hasOwnProperty; -var propIsEnumerable = Object.prototype.propertyIsEnumerable; - -function toObject(val) { - if (val === null || val === undefined) { - throw new TypeError('Object.assign cannot be called with null or undefined'); - } - - return Object(val); -} - -function shouldUseNative() { - try { - if (!Object.assign) { - return false; - } - - // Detect buggy property enumeration order in older V8 versions. - - // https://bugs.chromium.org/p/v8/issues/detail?id=4118 - var test1 = new String('abc'); // eslint-disable-line - test1[5] = 'de'; - if (Object.getOwnPropertyNames(test1)[0] === '5') { - return false; - } - - // https://bugs.chromium.org/p/v8/issues/detail?id=3056 - var test2 = {}; - for (var i = 0; i < 10; i++) { - test2['_' + String.fromCharCode(i)] = i; - } - var order2 = Object.getOwnPropertyNames(test2).map(function (n) { - return test2[n]; - }); - if (order2.join('') !== '0123456789') { - return false; - } - - // https://bugs.chromium.org/p/v8/issues/detail?id=3056 - var test3 = {}; - 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { - test3[letter] = letter; - }); - if (Object.keys(Object.assign({}, test3)).join('') !== - 'abcdefghijklmnopqrst') { - return false; - } - - return true; - } catch (e) { - // We don't expect any of the above to throw, but better to be safe. - return false; - } -} - -module.exports = shouldUseNative() ? Object.assign : function (target, source) { - var from; - var to = toObject(target); - var symbols; - - for (var s = 1; s < arguments.length; s++) { - from = Object(arguments[s]); - - for (var key in from) { - if (hasOwnProperty.call(from, key)) { - to[key] = from[key]; - } - } - - if (Object.getOwnPropertySymbols) { - symbols = Object.getOwnPropertySymbols(from); - for (var i = 0; i < symbols.length; i++) { - if (propIsEnumerable.call(from, symbols[i])) { - to[symbols[i]] = from[symbols[i]]; - } - } - } - } - - return to; -}; - - -/***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var DOMProperty = __webpack_require__(18); -var ReactDOMComponentFlags = __webpack_require__(81); - -var invariant = __webpack_require__(2); - -var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; -var Flags = ReactDOMComponentFlags; - -var internalInstanceKey = '__reactInternalInstance$' + Math.random().toString(36).slice(2); - -/** - * Check if a given node should be cached. - */ -function shouldPrecacheNode(node, nodeID) { - return node.nodeType === 1 && node.getAttribute(ATTR_NAME) === String(nodeID) || node.nodeType === 8 && node.nodeValue === ' react-text: ' + nodeID + ' ' || node.nodeType === 8 && node.nodeValue === ' react-empty: ' + nodeID + ' '; -} - -/** - * Drill down (through composites and empty components) until we get a host or - * host text component. - * - * This is pretty polymorphic but unavoidable with the current structure we have - * for `_renderedChildren`. - */ -function getRenderedHostOrTextFromComponent(component) { - var rendered; - while (rendered = component._renderedComponent) { - component = rendered; - } - return component; -} - -/** - * Populate `_hostNode` on the rendered host/text component with the given - * DOM node. The passed `inst` can be a composite. - */ -function precacheNode(inst, node) { - var hostInst = getRenderedHostOrTextFromComponent(inst); - hostInst._hostNode = node; - node[internalInstanceKey] = hostInst; -} - -function uncacheNode(inst) { - var node = inst._hostNode; - if (node) { - delete node[internalInstanceKey]; - inst._hostNode = null; - } -} - -/** - * Populate `_hostNode` on each child of `inst`, assuming that the children - * match up with the DOM (element) children of `node`. - * - * We cache entire levels at once to avoid an n^2 problem where we access the - * children of a node sequentially and have to walk from the start to our target - * node every time. - * - * Since we update `_renderedChildren` and the actual DOM at (slightly) - * different times, we could race here and see a newer `_renderedChildren` than - * the DOM nodes we see. To avoid this, ReactMultiChild calls - * `prepareToManageChildren` before we change `_renderedChildren`, at which - * time the container's child nodes are always cached (until it unmounts). - */ -function precacheChildNodes(inst, node) { - if (inst._flags & Flags.hasCachedChildNodes) { - return; - } - var children = inst._renderedChildren; - var childNode = node.firstChild; - outer: for (var name in children) { - if (!children.hasOwnProperty(name)) { - continue; - } - var childInst = children[name]; - var childID = getRenderedHostOrTextFromComponent(childInst)._domID; - if (childID === 0) { - // We're currently unmounting this child in ReactMultiChild; skip it. - continue; - } - // We assume the child nodes are in the same order as the child instances. - for (; childNode !== null; childNode = childNode.nextSibling) { - if (shouldPrecacheNode(childNode, childID)) { - precacheNode(childInst, childNode); - continue outer; - } - } - // We reached the end of the DOM children without finding an ID match. - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Unable to find element with ID %s.', childID) : _prodInvariant('32', childID) : void 0; - } - inst._flags |= Flags.hasCachedChildNodes; -} - -/** - * Given a DOM node, return the closest ReactDOMComponent or - * ReactDOMTextComponent instance ancestor. - */ -function getClosestInstanceFromNode(node) { - if (node[internalInstanceKey]) { - return node[internalInstanceKey]; - } - - // Walk up the tree until we find an ancestor whose instance we have cached. - var parents = []; - while (!node[internalInstanceKey]) { - parents.push(node); - if (node.parentNode) { - node = node.parentNode; - } else { - // Top of the tree. This node must not be part of a React tree (or is - // unmounted, potentially). - return null; - } - } - - var closest; - var inst; - for (; node && (inst = node[internalInstanceKey]); node = parents.pop()) { - closest = inst; - if (parents.length) { - precacheChildNodes(inst, node); - } - } - - return closest; -} - -/** - * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent - * instance, or null if the node was not rendered by this React. - */ -function getInstanceFromNode(node) { - var inst = getClosestInstanceFromNode(node); - if (inst != null && inst._hostNode === node) { - return inst; - } else { - return null; - } -} - -/** - * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding - * DOM node. - */ -function getNodeFromInstance(inst) { - // Without this first invariant, passing a non-DOM-component triggers the next - // invariant for a missing parent, which is super confusing. - !(inst._hostNode !== undefined) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0; - - if (inst._hostNode) { - return inst._hostNode; - } - - // Walk up the tree until we find an ancestor whose DOM node we have cached. - var parents = []; - while (!inst._hostNode) { - parents.push(inst); - !inst._hostParent ? process.env.NODE_ENV !== 'production' ? invariant(false, 'React DOM tree root should always have a node reference.') : _prodInvariant('34') : void 0; - inst = inst._hostParent; - } - - // Now parents contains each ancestor that does *not* have a cached native - // node, and `inst` is the deepest ancestor that does. - for (; parents.length; inst = parents.pop()) { - precacheChildNodes(inst, inst._hostNode); - } - - return inst._hostNode; -} - -var ReactDOMComponentTree = { - getClosestInstanceFromNode: getClosestInstanceFromNode, - getInstanceFromNode: getInstanceFromNode, - getNodeFromInstance: getNodeFromInstance, - precacheChildNodes: precacheChildNodes, - precacheNode: precacheNode, - uncacheNode: uncacheNode -}; - -module.exports = ReactDOMComponentTree; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); - -/** - * Simple, lightweight module assisting with the detection and context of - * Worker. Helps avoid circular dependencies and allows code to reason about - * whether or not they are in a Worker, even if they never include the main - * `ReactWorker` dependency. - */ -var ExecutionEnvironment = { - - canUseDOM: canUseDOM, - - canUseWorkers: typeof Worker !== 'undefined', - - canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent), - - canUseViewport: canUseDOM && !!window.screen, - - isInWorker: !canUseDOM // For now, this is true - might change in the future. - -}; - -module.exports = ExecutionEnvironment; - -/***/ }), -/* 9 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(23); - -var ReactCurrentOwner = __webpack_require__(15); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -function isNative(fn) { - // Based on isNative() from Lodash - var funcToString = Function.prototype.toString; - var hasOwnProperty = Object.prototype.hasOwnProperty; - var reIsNative = RegExp('^' + funcToString - // Take an example native function source for comparison - .call(hasOwnProperty) - // Strip regex characters so we can use it for regex - .replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') - // Remove hasOwnProperty from the template to make it generic - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'); - try { - var source = funcToString.call(fn); - return reIsNative.test(source); - } catch (err) { - return false; - } -} - -var canUseCollections = -// Array.from -typeof Array.from === 'function' && -// Map -typeof Map === 'function' && isNative(Map) && -// Map.prototype.keys -Map.prototype != null && typeof Map.prototype.keys === 'function' && isNative(Map.prototype.keys) && -// Set -typeof Set === 'function' && isNative(Set) && -// Set.prototype.keys -Set.prototype != null && typeof Set.prototype.keys === 'function' && isNative(Set.prototype.keys); - -var setItem; -var getItem; -var removeItem; -var getItemIDs; -var addRoot; -var removeRoot; -var getRootIDs; - -if (canUseCollections) { - var itemMap = new Map(); - var rootIDSet = new Set(); - - setItem = function (id, item) { - itemMap.set(id, item); - }; - getItem = function (id) { - return itemMap.get(id); - }; - removeItem = function (id) { - itemMap['delete'](id); - }; - getItemIDs = function () { - return Array.from(itemMap.keys()); - }; - - addRoot = function (id) { - rootIDSet.add(id); - }; - removeRoot = function (id) { - rootIDSet['delete'](id); - }; - getRootIDs = function () { - return Array.from(rootIDSet.keys()); - }; -} else { - var itemByKey = {}; - var rootByKey = {}; - - // Use non-numeric keys to prevent V8 performance issues: - // https://github.com/facebook/react/pull/7232 - var getKeyFromID = function (id) { - return '.' + id; - }; - var getIDFromKey = function (key) { - return parseInt(key.substr(1), 10); - }; - - setItem = function (id, item) { - var key = getKeyFromID(id); - itemByKey[key] = item; - }; - getItem = function (id) { - var key = getKeyFromID(id); - return itemByKey[key]; - }; - removeItem = function (id) { - var key = getKeyFromID(id); - delete itemByKey[key]; - }; - getItemIDs = function () { - return Object.keys(itemByKey).map(getIDFromKey); - }; - - addRoot = function (id) { - var key = getKeyFromID(id); - rootByKey[key] = true; - }; - removeRoot = function (id) { - var key = getKeyFromID(id); - delete rootByKey[key]; - }; - getRootIDs = function () { - return Object.keys(rootByKey).map(getIDFromKey); - }; -} - -var unmountedIDs = []; - -function purgeDeep(id) { - var item = getItem(id); - if (item) { - var childIDs = item.childIDs; - - removeItem(id); - childIDs.forEach(purgeDeep); - } -} - -function describeComponentFrame(name, source, ownerName) { - return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : ''); -} - -function getDisplayName(element) { - if (element == null) { - return '#empty'; - } else if (typeof element === 'string' || typeof element === 'number') { - return '#text'; - } else if (typeof element.type === 'string') { - return element.type; - } else { - return element.type.displayName || element.type.name || 'Unknown'; - } -} - -function describeID(id) { - var name = ReactComponentTreeHook.getDisplayName(id); - var element = ReactComponentTreeHook.getElement(id); - var ownerID = ReactComponentTreeHook.getOwnerID(id); - var ownerName; - if (ownerID) { - ownerName = ReactComponentTreeHook.getDisplayName(ownerID); - } - process.env.NODE_ENV !== 'production' ? warning(element, 'ReactComponentTreeHook: Missing React element for debugID %s when ' + 'building stack', id) : void 0; - return describeComponentFrame(name, element && element._source, ownerName); -} - -var ReactComponentTreeHook = { - onSetChildren: function (id, nextChildIDs) { - var item = getItem(id); - !item ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Item must have been set') : _prodInvariant('144') : void 0; - item.childIDs = nextChildIDs; - - for (var i = 0; i < nextChildIDs.length; i++) { - var nextChildID = nextChildIDs[i]; - var nextChild = getItem(nextChildID); - !nextChild ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected hook events to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('140') : void 0; - !(nextChild.childIDs != null || typeof nextChild.element !== 'object' || nextChild.element == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onSetChildren() to fire for a container child before its parent includes it in onSetChildren().') : _prodInvariant('141') : void 0; - !nextChild.isMounted ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onMountComponent() to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('71') : void 0; - if (nextChild.parentID == null) { - nextChild.parentID = id; - // TODO: This shouldn't be necessary but mounting a new root during in - // componentWillMount currently causes not-yet-mounted components to - // be purged from our tree data so their parent id is missing. - } - !(nextChild.parentID === id) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onBeforeMountComponent() parent and onSetChildren() to be consistent (%s has parents %s and %s).', nextChildID, nextChild.parentID, id) : _prodInvariant('142', nextChildID, nextChild.parentID, id) : void 0; - } - }, - onBeforeMountComponent: function (id, element, parentID) { - var item = { - element: element, - parentID: parentID, - text: null, - childIDs: [], - isMounted: false, - updateCount: 0 - }; - setItem(id, item); - }, - onBeforeUpdateComponent: function (id, element) { - var item = getItem(id); - if (!item || !item.isMounted) { - // We may end up here as a result of setState() in componentWillUnmount(). - // In this case, ignore the element. - return; - } - item.element = element; - }, - onMountComponent: function (id) { - var item = getItem(id); - !item ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Item must have been set') : _prodInvariant('144') : void 0; - item.isMounted = true; - var isRoot = item.parentID === 0; - if (isRoot) { - addRoot(id); - } - }, - onUpdateComponent: function (id) { - var item = getItem(id); - if (!item || !item.isMounted) { - // We may end up here as a result of setState() in componentWillUnmount(). - // In this case, ignore the element. - return; - } - item.updateCount++; - }, - onUnmountComponent: function (id) { - var item = getItem(id); - if (item) { - // We need to check if it exists. - // `item` might not exist if it is inside an error boundary, and a sibling - // error boundary child threw while mounting. Then this instance never - // got a chance to mount, but it still gets an unmounting event during - // the error boundary cleanup. - item.isMounted = false; - var isRoot = item.parentID === 0; - if (isRoot) { - removeRoot(id); - } - } - unmountedIDs.push(id); - }, - purgeUnmountedComponents: function () { - if (ReactComponentTreeHook._preventPurging) { - // Should only be used for testing. - return; - } - - for (var i = 0; i < unmountedIDs.length; i++) { - var id = unmountedIDs[i]; - purgeDeep(id); - } - unmountedIDs.length = 0; - }, - isMounted: function (id) { - var item = getItem(id); - return item ? item.isMounted : false; - }, - getCurrentStackAddendum: function (topElement) { - var info = ''; - if (topElement) { - var name = getDisplayName(topElement); - var owner = topElement._owner; - info += describeComponentFrame(name, topElement._source, owner && owner.getName()); - } - - var currentOwner = ReactCurrentOwner.current; - var id = currentOwner && currentOwner._debugID; - - info += ReactComponentTreeHook.getStackAddendumByID(id); - return info; - }, - getStackAddendumByID: function (id) { - var info = ''; - while (id) { - info += describeID(id); - id = ReactComponentTreeHook.getParentID(id); - } - return info; - }, - getChildIDs: function (id) { - var item = getItem(id); - return item ? item.childIDs : []; - }, - getDisplayName: function (id) { - var element = ReactComponentTreeHook.getElement(id); - if (!element) { - return null; - } - return getDisplayName(element); - }, - getElement: function (id) { - var item = getItem(id); - return item ? item.element : null; - }, - getOwnerID: function (id) { - var element = ReactComponentTreeHook.getElement(id); - if (!element || !element._owner) { - return null; - } - return element._owner._debugID; - }, - getParentID: function (id) { - var item = getItem(id); - return item ? item.parentID : null; - }, - getSource: function (id) { - var item = getItem(id); - var element = item ? item.element : null; - var source = element != null ? element._source : null; - return source; - }, - getText: function (id) { - var element = ReactComponentTreeHook.getElement(id); - if (typeof element === 'string') { - return element; - } else if (typeof element === 'number') { - return '' + element; - } else { - return null; - } - }, - getUpdateCount: function (id) { - var item = getItem(id); - return item ? item.updateCount : 0; - }, - - - getRootIDs: getRootIDs, - getRegisteredIDs: getItemIDs -}; - -module.exports = ReactComponentTreeHook; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 10 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -// Trust the developer to only use ReactInstrumentation with a __DEV__ check - -var debugTool = null; - -if (process.env.NODE_ENV !== 'production') { - var ReactDebugTool = __webpack_require__(266); - debugTool = ReactDebugTool; -} - -module.exports = { debugTool: debugTool }; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - - - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = function() {}; - -if (process.env.NODE_ENV !== 'production') { - warning = function(condition, format, args) { - var len = arguments.length; - args = new Array(len > 2 ? len - 2 : 0); - for (var key = 2; key < len; key++) { - args[key - 2] = arguments[key]; - } - if (format === undefined) { - throw new Error( - '`warning(condition, format, ...args)` requires a warning ' + - 'message argument' - ); - } - - if (format.length < 10 || (/^[s\W]*$/).test(format)) { - throw new Error( - 'The warning format should be able to uniquely identify this ' + - 'warning. Please, use a more descriptive format than: ' + format - ); - } - - if (!condition) { - var argIndex = 0; - var message = 'Warning: ' + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - if (typeof console !== 'undefined') { - console.error(message); - } - try { - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch(x) {} - } - }; -} - -module.exports = warning; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - -function makeEmptyFunction(arg) { - return function () { - return arg; - }; -} - -/** - * This function accepts and discards inputs; it has no side effects. This is - * primarily useful idiomatically for overridable function endpoints which - * always need to be callable, since JS lacks a null-call idiom ala Cocoa. - */ -var emptyFunction = function emptyFunction() {}; - -emptyFunction.thatReturns = makeEmptyFunction; -emptyFunction.thatReturnsFalse = makeEmptyFunction(false); -emptyFunction.thatReturnsTrue = makeEmptyFunction(true); -emptyFunction.thatReturnsNull = makeEmptyFunction(null); -emptyFunction.thatReturnsThis = function () { - return this; -}; -emptyFunction.thatReturnsArgument = function (arg) { - return arg; -}; - -module.exports = emptyFunction; - -/***/ }), -/* 13 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - - - -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ - -var invariant = function(condition, format, a, b, c, d, e, f) { - if (process.env.NODE_ENV !== 'production') { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - } - - if (!condition) { - var error; - if (format === undefined) { - error = new Error( - 'Minified exception occurred; use the non-minified dev environment ' + - 'for the full error message and additional helpful warnings.' - ); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error( - format.replace(/%s/g, function() { return args[argIndex++]; }) - ); - error.name = 'Invariant Violation'; - } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -}; - -module.exports = invariant; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var CallbackQueue = __webpack_require__(79); -var PooledClass = __webpack_require__(20); -var ReactFeatureFlags = __webpack_require__(84); -var ReactReconciler = __webpack_require__(26); -var Transaction = __webpack_require__(38); - -var invariant = __webpack_require__(2); - -var dirtyComponents = []; -var updateBatchNumber = 0; -var asapCallbackQueue = CallbackQueue.getPooled(); -var asapEnqueued = false; - -var batchingStrategy = null; - -function ensureInjected() { - !(ReactUpdates.ReactReconcileTransaction && batchingStrategy) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must inject a reconcile transaction class and batching strategy') : _prodInvariant('123') : void 0; -} - -var NESTED_UPDATES = { - initialize: function () { - this.dirtyComponentsLength = dirtyComponents.length; - }, - close: function () { - if (this.dirtyComponentsLength !== dirtyComponents.length) { - // Additional updates were enqueued by componentDidUpdate handlers or - // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run - // these new updates so that if A's componentDidUpdate calls setState on - // B, B will update before the callback A's updater provided when calling - // setState. - dirtyComponents.splice(0, this.dirtyComponentsLength); - flushBatchedUpdates(); - } else { - dirtyComponents.length = 0; - } - } -}; - -var UPDATE_QUEUEING = { - initialize: function () { - this.callbackQueue.reset(); - }, - close: function () { - this.callbackQueue.notifyAll(); - } -}; - -var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING]; - -function ReactUpdatesFlushTransaction() { - this.reinitializeTransaction(); - this.dirtyComponentsLength = null; - this.callbackQueue = CallbackQueue.getPooled(); - this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled( - /* useCreateElement */true); -} - -_assign(ReactUpdatesFlushTransaction.prototype, Transaction, { - getTransactionWrappers: function () { - return TRANSACTION_WRAPPERS; - }, - - destructor: function () { - this.dirtyComponentsLength = null; - CallbackQueue.release(this.callbackQueue); - this.callbackQueue = null; - ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction); - this.reconcileTransaction = null; - }, - - perform: function (method, scope, a) { - // Essentially calls `this.reconcileTransaction.perform(method, scope, a)` - // with this transaction's wrappers around it. - return Transaction.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a); - } -}); - -PooledClass.addPoolingTo(ReactUpdatesFlushTransaction); - -function batchedUpdates(callback, a, b, c, d, e) { - ensureInjected(); - return batchingStrategy.batchedUpdates(callback, a, b, c, d, e); -} - -/** - * Array comparator for ReactComponents by mount ordering. - * - * @param {ReactComponent} c1 first component you're comparing - * @param {ReactComponent} c2 second component you're comparing - * @return {number} Return value usable by Array.prototype.sort(). - */ -function mountOrderComparator(c1, c2) { - return c1._mountOrder - c2._mountOrder; -} - -function runBatchedUpdates(transaction) { - var len = transaction.dirtyComponentsLength; - !(len === dirtyComponents.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected flush transaction\'s stored dirty-components length (%s) to match dirty-components array length (%s).', len, dirtyComponents.length) : _prodInvariant('124', len, dirtyComponents.length) : void 0; - - // Since reconciling a component higher in the owner hierarchy usually (not - // always -- see shouldComponentUpdate()) will reconcile children, reconcile - // them before their children by sorting the array. - dirtyComponents.sort(mountOrderComparator); - - // Any updates enqueued while reconciling must be performed after this entire - // batch. Otherwise, if dirtyComponents is [A, B] where A has children B and - // C, B could update twice in a single batch if C's render enqueues an update - // to B (since B would have already updated, we should skip it, and the only - // way we can know to do so is by checking the batch counter). - updateBatchNumber++; - - for (var i = 0; i < len; i++) { - // If a component is unmounted before pending changes apply, it will still - // be here, but we assume that it has cleared its _pendingCallbacks and - // that performUpdateIfNecessary is a noop. - var component = dirtyComponents[i]; - - // If performUpdateIfNecessary happens to enqueue any new updates, we - // shouldn't execute the callbacks until the next render happens, so - // stash the callbacks first - var callbacks = component._pendingCallbacks; - component._pendingCallbacks = null; - - var markerName; - if (ReactFeatureFlags.logTopLevelRenders) { - var namedComponent = component; - // Duck type TopLevelWrapper. This is probably always true. - if (component._currentElement.type.isReactTopLevelWrapper) { - namedComponent = component._renderedComponent; - } - markerName = 'React update: ' + namedComponent.getName(); - console.time(markerName); - } - - ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction, updateBatchNumber); - - if (markerName) { - console.timeEnd(markerName); - } - - if (callbacks) { - for (var j = 0; j < callbacks.length; j++) { - transaction.callbackQueue.enqueue(callbacks[j], component.getPublicInstance()); - } - } - } -} - -var flushBatchedUpdates = function () { - // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents - // array and perform any updates enqueued by mount-ready handlers (i.e., - // componentDidUpdate) but we need to check here too in order to catch - // updates enqueued by setState callbacks and asap calls. - while (dirtyComponents.length || asapEnqueued) { - if (dirtyComponents.length) { - var transaction = ReactUpdatesFlushTransaction.getPooled(); - transaction.perform(runBatchedUpdates, null, transaction); - ReactUpdatesFlushTransaction.release(transaction); - } - - if (asapEnqueued) { - asapEnqueued = false; - var queue = asapCallbackQueue; - asapCallbackQueue = CallbackQueue.getPooled(); - queue.notifyAll(); - CallbackQueue.release(queue); - } - } -}; - -/** - * Mark a component as needing a rerender, adding an optional callback to a - * list of functions which will be executed once the rerender occurs. - */ -function enqueueUpdate(component) { - ensureInjected(); - - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. (This is called by each top-level update - // function, like setState, forceUpdate, etc.; creation and - // destruction of top-level components is guarded in ReactMount.) - - if (!batchingStrategy.isBatchingUpdates) { - batchingStrategy.batchedUpdates(enqueueUpdate, component); - return; - } - - dirtyComponents.push(component); - if (component._updateBatchNumber == null) { - component._updateBatchNumber = updateBatchNumber + 1; - } -} - -/** - * Enqueue a callback to be run at the end of the current batching cycle. Throws - * if no updates are currently being performed. - */ -function asap(callback, context) { - !batchingStrategy.isBatchingUpdates ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context whereupdates are not being batched.') : _prodInvariant('125') : void 0; - asapCallbackQueue.enqueue(callback, context); - asapEnqueued = true; -} - -var ReactUpdatesInjection = { - injectReconcileTransaction: function (ReconcileTransaction) { - !ReconcileTransaction ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a reconcile transaction class') : _prodInvariant('126') : void 0; - ReactUpdates.ReactReconcileTransaction = ReconcileTransaction; - }, - - injectBatchingStrategy: function (_batchingStrategy) { - !_batchingStrategy ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batching strategy') : _prodInvariant('127') : void 0; - !(typeof _batchingStrategy.batchedUpdates === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batchedUpdates() function') : _prodInvariant('128') : void 0; - !(typeof _batchingStrategy.isBatchingUpdates === 'boolean') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : _prodInvariant('129') : void 0; - batchingStrategy = _batchingStrategy; - } -}; - -var ReactUpdates = { - /** - * React references `ReactReconcileTransaction` using this property in order - * to allow dependency injection. - * - * @internal - */ - ReactReconcileTransaction: null, - - batchedUpdates: batchedUpdates, - enqueueUpdate: enqueueUpdate, - flushBatchedUpdates: flushBatchedUpdates, - injection: ReactUpdatesInjection, - asap: asap -}; - -module.exports = ReactUpdates; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 15 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/** - * Keeps track of the current owner. - * - * The current owner is the component who should own any components that are - * currently being constructed. - */ -var ReactCurrentOwner = { - - /** - * @internal - * @type {ReactComponent} - */ - current: null - -}; - -module.exports = ReactCurrentOwner; - -/***/ }), -/* 16 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -var React = __webpack_require__(5); -var noop = __webpack_require__(107); - -module.exports = function (Component) { - var options = Component.keyHandlingOptions, - propName = options.propName || "", - values = options.values || {}, - controller = options.controller || noop, - getDefaultProps = Component.getDefaultProps, - ref = "wrappedComponent"; - - return React.createClass({ - values: values, - - getDefaultProps: getDefaultProps, - - onKeyDown: function onKeyDown(event, api) { - var v = this.values[event.keyCode]; - if (v) { - event.preventDefault(); - if (typeof v === "function") { - v(api); - } else { - api[propName] += v; - controller(api); - } - } - }, - - getComponent: function getComponent() { - var wrappedComponent = this.refs[ref]; - if (wrappedComponent.getComponent) { - return wrappedComponent.getComponent(); - } - return wrappedComponent; - }, - - render: function render() { - return React.createElement(Component, _extends({}, this.props, { onKeyDown: this.onKeyDown, ref: ref })); - } - }); -}; - -/***/ }), -/* 17 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var PooledClass = __webpack_require__(20); - -var emptyFunction = __webpack_require__(12); -var warning = __webpack_require__(3); - -var didWarnForAddedNewProperty = false; -var isProxySupported = typeof Proxy === 'function'; - -var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances']; - -/** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var EventInterface = { - type: null, - target: null, - // currentTarget is set when dispatching; no use in copying it here - currentTarget: emptyFunction.thatReturnsNull, - eventPhase: null, - bubbles: null, - cancelable: null, - timeStamp: function (event) { - return event.timeStamp || Date.now(); - }, - defaultPrevented: null, - isTrusted: null -}; - -/** - * Synthetic events are dispatched by event plugins, typically in response to a - * top-level event delegation handler. - * - * These systems should generally use pooling to reduce the frequency of garbage - * collection. The system should check `isPersistent` to determine whether the - * event should be released into the pool after being dispatched. Users that - * need a persisted event should invoke `persist`. - * - * Synthetic events (and subclasses) implement the DOM Level 3 Events API by - * normalizing browser quirks. Subclasses do not necessarily have to implement a - * DOM interface; custom application-specific events can also subclass this. - * - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {*} targetInst Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @param {DOMEventTarget} nativeEventTarget Target node. - */ -function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) { - if (process.env.NODE_ENV !== 'production') { - // these have a getter/setter for warnings - delete this.nativeEvent; - delete this.preventDefault; - delete this.stopPropagation; - } - - this.dispatchConfig = dispatchConfig; - this._targetInst = targetInst; - this.nativeEvent = nativeEvent; - - var Interface = this.constructor.Interface; - for (var propName in Interface) { - if (!Interface.hasOwnProperty(propName)) { - continue; - } - if (process.env.NODE_ENV !== 'production') { - delete this[propName]; // this has a getter/setter for warnings - } - var normalize = Interface[propName]; - if (normalize) { - this[propName] = normalize(nativeEvent); - } else { - if (propName === 'target') { - this.target = nativeEventTarget; - } else { - this[propName] = nativeEvent[propName]; - } - } - } - - var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false; - if (defaultPrevented) { - this.isDefaultPrevented = emptyFunction.thatReturnsTrue; - } else { - this.isDefaultPrevented = emptyFunction.thatReturnsFalse; - } - this.isPropagationStopped = emptyFunction.thatReturnsFalse; - return this; -} - -_assign(SyntheticEvent.prototype, { - - preventDefault: function () { - this.defaultPrevented = true; - var event = this.nativeEvent; - if (!event) { - return; - } - - if (event.preventDefault) { - event.preventDefault(); - } else if (typeof event.returnValue !== 'unknown') { - // eslint-disable-line valid-typeof - event.returnValue = false; - } - this.isDefaultPrevented = emptyFunction.thatReturnsTrue; - }, - - stopPropagation: function () { - var event = this.nativeEvent; - if (!event) { - return; - } - - if (event.stopPropagation) { - event.stopPropagation(); - } else if (typeof event.cancelBubble !== 'unknown') { - // eslint-disable-line valid-typeof - // The ChangeEventPlugin registers a "propertychange" event for - // IE. This event does not support bubbling or cancelling, and - // any references to cancelBubble throw "Member not found". A - // typeof check of "unknown" circumvents this issue (and is also - // IE specific). - event.cancelBubble = true; - } - - this.isPropagationStopped = emptyFunction.thatReturnsTrue; - }, - - /** - * We release all dispatched `SyntheticEvent`s after each event loop, adding - * them back into the pool. This allows a way to hold onto a reference that - * won't be added back into the pool. - */ - persist: function () { - this.isPersistent = emptyFunction.thatReturnsTrue; - }, - - /** - * Checks if this event should be released back into the pool. - * - * @return {boolean} True if this should not be released, false otherwise. - */ - isPersistent: emptyFunction.thatReturnsFalse, - - /** - * `PooledClass` looks for `destructor` on each instance it releases. - */ - destructor: function () { - var Interface = this.constructor.Interface; - for (var propName in Interface) { - if (process.env.NODE_ENV !== 'production') { - Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName])); - } else { - this[propName] = null; - } - } - for (var i = 0; i < shouldBeReleasedProperties.length; i++) { - this[shouldBeReleasedProperties[i]] = null; - } - if (process.env.NODE_ENV !== 'production') { - Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null)); - Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction)); - Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction)); - } - } - -}); - -SyntheticEvent.Interface = EventInterface; - -if (process.env.NODE_ENV !== 'production') { - if (isProxySupported) { - /*eslint-disable no-func-assign */ - SyntheticEvent = new Proxy(SyntheticEvent, { - construct: function (target, args) { - return this.apply(target, Object.create(target.prototype), args); - }, - apply: function (constructor, that, args) { - return new Proxy(constructor.apply(that, args), { - set: function (target, prop, value) { - if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) { - process.env.NODE_ENV !== 'production' ? warning(didWarnForAddedNewProperty || target.isPersistent(), 'This synthetic event is reused for performance reasons. If you\'re ' + 'seeing this, you\'re adding a new property in the synthetic event object. ' + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.') : void 0; - didWarnForAddedNewProperty = true; - } - target[prop] = value; - return true; - } - }); - } - }); - /*eslint-enable no-func-assign */ - } -} -/** - * Helper to reduce boilerplate when creating subclasses. - * - * @param {function} Class - * @param {?object} Interface - */ -SyntheticEvent.augmentClass = function (Class, Interface) { - var Super = this; - - var E = function () {}; - E.prototype = Super.prototype; - var prototype = new E(); - - _assign(prototype, Class.prototype); - Class.prototype = prototype; - Class.prototype.constructor = Class; - - Class.Interface = _assign({}, Super.Interface, Interface); - Class.augmentClass = Super.augmentClass; - - PooledClass.addPoolingTo(Class, PooledClass.fourArgumentPooler); -}; - -PooledClass.addPoolingTo(SyntheticEvent, PooledClass.fourArgumentPooler); - -module.exports = SyntheticEvent; - -/** - * Helper to nullify syntheticEvent instance properties when destructing - * - * @param {object} SyntheticEvent - * @param {String} propName - * @return {object} defineProperty object - */ -function getPooledWarningPropertyDefinition(propName, getVal) { - var isFunction = typeof getVal === 'function'; - return { - configurable: true, - set: set, - get: get - }; - - function set(val) { - var action = isFunction ? 'setting the method' : 'setting the property'; - warn(action, 'This is effectively a no-op'); - return val; - } - - function get() { - var action = isFunction ? 'accessing the method' : 'accessing the property'; - var result = isFunction ? 'This is a no-op function' : 'This is set to null'; - warn(action, result); - return getVal; - } - - function warn(action, result) { - var warningCondition = false; - process.env.NODE_ENV !== 'production' ? warning(warningCondition, 'This synthetic event is reused for performance reasons. If you\'re seeing this, ' + 'you\'re %s `%s` on a released/nullified synthetic event. %s. ' + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0; - } -} -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -function checkMask(value, bitmask) { - return (value & bitmask) === bitmask; -} - -var DOMPropertyInjection = { - /** - * Mapping from normalized, camelcased property names to a configuration that - * specifies how the associated DOM property should be accessed or rendered. - */ - MUST_USE_PROPERTY: 0x1, - HAS_BOOLEAN_VALUE: 0x4, - HAS_NUMERIC_VALUE: 0x8, - HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8, - HAS_OVERLOADED_BOOLEAN_VALUE: 0x20, - - /** - * Inject some specialized knowledge about the DOM. This takes a config object - * with the following properties: - * - * isCustomAttribute: function that given an attribute name will return true - * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* - * attributes where it's impossible to enumerate all of the possible - * attribute names, - * - * Properties: object mapping DOM property name to one of the - * DOMPropertyInjection constants or null. If your attribute isn't in here, - * it won't get written to the DOM. - * - * DOMAttributeNames: object mapping React attribute name to the DOM - * attribute name. Attribute names not specified use the **lowercase** - * normalized name. - * - * DOMAttributeNamespaces: object mapping React attribute name to the DOM - * attribute namespace URL. (Attribute names not specified use no namespace.) - * - * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. - * Property names not specified use the normalized name. - * - * DOMMutationMethods: Properties that require special mutation methods. If - * `value` is undefined, the mutation method should unset the property. - * - * @param {object} domPropertyConfig the config as described above. - */ - injectDOMPropertyConfig: function (domPropertyConfig) { - var Injection = DOMPropertyInjection; - var Properties = domPropertyConfig.Properties || {}; - var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {}; - var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; - var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; - var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; - - if (domPropertyConfig.isCustomAttribute) { - DOMProperty._isCustomAttributeFunctions.push(domPropertyConfig.isCustomAttribute); - } - - for (var propName in Properties) { - !!DOMProperty.properties.hasOwnProperty(propName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property \'%s\' which has already been injected. You may be accidentally injecting the same DOM property config twice, or you may be injecting two configs that have conflicting property names.', propName) : _prodInvariant('48', propName) : void 0; - - var lowerCased = propName.toLowerCase(); - var propConfig = Properties[propName]; - - var propertyInfo = { - attributeName: lowerCased, - attributeNamespace: null, - propertyName: propName, - mutationMethod: null, - - mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY), - hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE), - hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE), - hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE), - hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE) - }; - !(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or numeric value, but not a combination: %s', propName) : _prodInvariant('50', propName) : void 0; - - if (process.env.NODE_ENV !== 'production') { - DOMProperty.getPossibleStandardName[lowerCased] = propName; - } - - if (DOMAttributeNames.hasOwnProperty(propName)) { - var attributeName = DOMAttributeNames[propName]; - propertyInfo.attributeName = attributeName; - if (process.env.NODE_ENV !== 'production') { - DOMProperty.getPossibleStandardName[attributeName] = propName; - } - } - - if (DOMAttributeNamespaces.hasOwnProperty(propName)) { - propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName]; - } - - if (DOMPropertyNames.hasOwnProperty(propName)) { - propertyInfo.propertyName = DOMPropertyNames[propName]; - } - - if (DOMMutationMethods.hasOwnProperty(propName)) { - propertyInfo.mutationMethod = DOMMutationMethods[propName]; - } - - DOMProperty.properties[propName] = propertyInfo; - } - } -}; - -/* eslint-disable max-len */ -var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD'; -/* eslint-enable max-len */ - -/** - * DOMProperty exports lookup objects that can be used like functions: - * - * > DOMProperty.isValid['id'] - * true - * > DOMProperty.isValid['foobar'] - * undefined - * - * Although this may be confusing, it performs better in general. - * - * @see http://jsperf.com/key-exists - * @see http://jsperf.com/key-missing - */ -var DOMProperty = { - - ID_ATTRIBUTE_NAME: 'data-reactid', - ROOT_ATTRIBUTE_NAME: 'data-reactroot', - - ATTRIBUTE_NAME_START_CHAR: ATTRIBUTE_NAME_START_CHAR, - ATTRIBUTE_NAME_CHAR: ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040', - - /** - * Map from property "standard name" to an object with info about how to set - * the property in the DOM. Each object contains: - * - * attributeName: - * Used when rendering markup or with `*Attribute()`. - * attributeNamespace - * propertyName: - * Used on DOM node instances. (This includes properties that mutate due to - * external factors.) - * mutationMethod: - * If non-null, used instead of the property or `setAttribute()` after - * initial render. - * mustUseProperty: - * Whether the property must be accessed and mutated as an object property. - * hasBooleanValue: - * Whether the property should be removed when set to a falsey value. - * hasNumericValue: - * Whether the property must be numeric or parse as a numeric and should be - * removed when set to a falsey value. - * hasPositiveNumericValue: - * Whether the property must be positive numeric or parse as a positive - * numeric and should be removed when set to a falsey value. - * hasOverloadedBooleanValue: - * Whether the property can be used as a flag as well as with a value. - * Removed when strictly equal to false; present without a value when - * strictly equal to true; present with a value otherwise. - */ - properties: {}, - - /** - * Mapping from lowercase property names to the properly cased version, used - * to warn in the case of missing properties. Available only in __DEV__. - * - * autofocus is predefined, because adding it to the property whitelist - * causes unintended side effects. - * - * @type {Object} - */ - getPossibleStandardName: process.env.NODE_ENV !== 'production' ? { autofocus: 'autoFocus' } : null, - - /** - * All of the isCustomAttribute() functions that have been injected. - */ - _isCustomAttributeFunctions: [], - - /** - * Checks whether a property name is a custom attribute. - * @method - */ - isCustomAttribute: function (attributeName) { - for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { - var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; - if (isCustomAttributeFn(attributeName)) { - return true; - } - } - return false; - }, - - injection: DOMPropertyInjection -}; - -module.exports = DOMProperty; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 19 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -exports.isReactChildren = isReactChildren; -exports.createRouteFromReactElement = createRouteFromReactElement; -exports.createRoutesFromReactChildren = createRoutesFromReactChildren; -exports.createRoutes = createRoutes; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -function isValidChild(object) { - return object == null || _react2['default'].isValidElement(object); -} - -function isReactChildren(object) { - return isValidChild(object) || Array.isArray(object) && object.every(isValidChild); -} - -function checkPropTypes(componentName, propTypes, props) { - componentName = componentName || 'UnknownComponent'; - - for (var propName in propTypes) { - if (propTypes.hasOwnProperty(propName)) { - var error = propTypes[propName](props, propName, componentName); - - /* istanbul ignore if: error logging */ - if (error instanceof Error) process.env.NODE_ENV !== 'production' ? _warning2['default'](false, error.message) : undefined; - } - } -} - -function createRoute(defaultProps, props) { - return _extends({}, defaultProps, props); -} - -function createRouteFromReactElement(element) { - var type = element.type; - var route = createRoute(type.defaultProps, element.props); - - if (type.propTypes) checkPropTypes(type.displayName || type.name, type.propTypes, route); - - if (route.children) { - var childRoutes = createRoutesFromReactChildren(route.children, route); - - if (childRoutes.length) route.childRoutes = childRoutes; - - delete route.children; - } - - return route; -} - -/** - * Creates and returns a routes object from the given ReactChildren. JSX - * provides a convenient way to visualize how routes in the hierarchy are - * nested. - * - * import { Route, createRoutesFromReactChildren } from 'react-router' - * - * const routes = createRoutesFromReactChildren( - * <Route component={App}> - * <Route path="home" component={Dashboard}/> - * <Route path="news" component={NewsFeed}/> - * </Route> - * ) - * - * Note: This method is automatically used when you provide <Route> children - * to a <Router> component. - */ - -function createRoutesFromReactChildren(children, parentRoute) { - var routes = []; - - _react2['default'].Children.forEach(children, function (element) { - if (_react2['default'].isValidElement(element)) { - // Component classes may have a static create* method. - if (element.type.createRouteFromReactElement) { - var route = element.type.createRouteFromReactElement(element, parentRoute); - - if (route) routes.push(route); - } else { - routes.push(createRouteFromReactElement(element)); - } - } - }); - - return routes; -} - -/** - * Creates and returns an array of routes from the given object which - * may be a JSX route, a plain object route, or an array of either. - */ - -function createRoutes(routes) { - if (isReactChildren(routes)) { - routes = createRoutesFromReactChildren(routes); - } else if (routes && !Array.isArray(routes)) { - routes = [routes]; - } - - return routes; -} -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -/** - * Static poolers. Several custom versions for each potential number of - * arguments. A completely generic pooler is easy to implement, but would - * require accessing the `arguments` object. In each of these, `this` refers to - * the Class itself, not an instance. If any others are needed, simply add them - * here, or in their own files. - */ -var oneArgumentPooler = function (copyFieldsFrom) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, copyFieldsFrom); - return instance; - } else { - return new Klass(copyFieldsFrom); - } -}; - -var twoArgumentPooler = function (a1, a2) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2); - return instance; - } else { - return new Klass(a1, a2); - } -}; - -var threeArgumentPooler = function (a1, a2, a3) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3); - return instance; - } else { - return new Klass(a1, a2, a3); - } -}; - -var fourArgumentPooler = function (a1, a2, a3, a4) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3, a4); - return instance; - } else { - return new Klass(a1, a2, a3, a4); - } -}; - -var standardReleaser = function (instance) { - var Klass = this; - !(instance instanceof Klass) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : _prodInvariant('25') : void 0; - instance.destructor(); - if (Klass.instancePool.length < Klass.poolSize) { - Klass.instancePool.push(instance); - } -}; - -var DEFAULT_POOL_SIZE = 10; -var DEFAULT_POOLER = oneArgumentPooler; - -/** - * Augments `CopyConstructor` to be a poolable class, augmenting only the class - * itself (statically) not adding any prototypical fields. Any CopyConstructor - * you give this may have a `poolSize` property, and will look for a - * prototypical `destructor` on instances. - * - * @param {Function} CopyConstructor Constructor that can be used to reset. - * @param {Function} pooler Customizable pooler. - */ -var addPoolingTo = function (CopyConstructor, pooler) { - // Casting as any so that flow ignores the actual implementation and trusts - // it to match the type we declared - var NewKlass = CopyConstructor; - NewKlass.instancePool = []; - NewKlass.getPooled = pooler || DEFAULT_POOLER; - if (!NewKlass.poolSize) { - NewKlass.poolSize = DEFAULT_POOL_SIZE; - } - NewKlass.release = standardReleaser; - return NewKlass; -}; - -var PooledClass = { - addPoolingTo: addPoolingTo, - oneArgumentPooler: oneArgumentPooler, - twoArgumentPooler: twoArgumentPooler, - threeArgumentPooler: threeArgumentPooler, - fourArgumentPooler: fourArgumentPooler -}; - -module.exports = PooledClass; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 21 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.falsy = falsy; - -var _react = __webpack_require__(5); - -var func = _react.PropTypes.func; -var object = _react.PropTypes.object; -var arrayOf = _react.PropTypes.arrayOf; -var oneOfType = _react.PropTypes.oneOfType; -var element = _react.PropTypes.element; -var shape = _react.PropTypes.shape; -var string = _react.PropTypes.string; - -function falsy(props, propName, componentName) { - if (props[propName]) return new Error('<' + componentName + '> should not have a "' + propName + '" prop'); -} - -var history = shape({ - listen: func.isRequired, - pushState: func.isRequired, - replaceState: func.isRequired, - go: func.isRequired -}); - -exports.history = history; -var location = shape({ - pathname: string.isRequired, - search: string.isRequired, - state: object, - action: string.isRequired, - key: string -}); - -exports.location = location; -var component = oneOfType([func, string]); -exports.component = component; -var components = oneOfType([component, object]); -exports.components = components; -var route = oneOfType([object, element]); -exports.route = route; -var routes = oneOfType([route, arrayOf(route)]); - -exports.routes = routes; -exports['default'] = { - falsy: falsy, - history: history, - location: location, - component: component, - components: components, - route: route -}; - -/***/ }), -/* 22 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var ReactCurrentOwner = __webpack_require__(15); - -var warning = __webpack_require__(3); -var canDefineProperty = __webpack_require__(66); -var hasOwnProperty = Object.prototype.hasOwnProperty; - -var REACT_ELEMENT_TYPE = __webpack_require__(103); - -var RESERVED_PROPS = { - key: true, - ref: true, - __self: true, - __source: true -}; - -var specialPropKeyWarningShown, specialPropRefWarningShown; - -function hasValidRef(config) { - if (process.env.NODE_ENV !== 'production') { - if (hasOwnProperty.call(config, 'ref')) { - var getter = Object.getOwnPropertyDescriptor(config, 'ref').get; - if (getter && getter.isReactWarning) { - return false; - } - } - } - return config.ref !== undefined; -} - -function hasValidKey(config) { - if (process.env.NODE_ENV !== 'production') { - if (hasOwnProperty.call(config, 'key')) { - var getter = Object.getOwnPropertyDescriptor(config, 'key').get; - if (getter && getter.isReactWarning) { - return false; - } - } - } - return config.key !== undefined; -} - -function defineKeyPropWarningGetter(props, displayName) { - var warnAboutAccessingKey = function () { - if (!specialPropKeyWarningShown) { - specialPropKeyWarningShown = true; - process.env.NODE_ENV !== 'production' ? warning(false, '%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName) : void 0; - } - }; - warnAboutAccessingKey.isReactWarning = true; - Object.defineProperty(props, 'key', { - get: warnAboutAccessingKey, - configurable: true - }); -} - -function defineRefPropWarningGetter(props, displayName) { - var warnAboutAccessingRef = function () { - if (!specialPropRefWarningShown) { - specialPropRefWarningShown = true; - process.env.NODE_ENV !== 'production' ? warning(false, '%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName) : void 0; - } - }; - warnAboutAccessingRef.isReactWarning = true; - Object.defineProperty(props, 'ref', { - get: warnAboutAccessingRef, - configurable: true - }); -} - -/** - * Factory method to create a new React element. This no longer adheres to - * the class pattern, so do not use new to call it. Also, no instanceof check - * will work. Instead test $$typeof field against Symbol.for('react.element') to check - * if something is a React Element. - * - * @param {*} type - * @param {*} key - * @param {string|object} ref - * @param {*} self A *temporary* helper to detect places where `this` is - * different from the `owner` when React.createElement is called, so that we - * can warn. We want to get rid of owner and replace string `ref`s with arrow - * functions, and as long as `this` and owner are the same, there will be no - * change in behavior. - * @param {*} source An annotation object (added by a transpiler or otherwise) - * indicating filename, line number, and/or other information. - * @param {*} owner - * @param {*} props - * @internal - */ -var ReactElement = function (type, key, ref, self, source, owner, props) { - var element = { - // This tag allow us to uniquely identify this as a React Element - $$typeof: REACT_ELEMENT_TYPE, - - // Built-in properties that belong on the element - type: type, - key: key, - ref: ref, - props: props, - - // Record the component responsible for creating this element. - _owner: owner - }; - - if (process.env.NODE_ENV !== 'production') { - // The validation flag is currently mutative. We put it on - // an external backing store so that we can freeze the whole object. - // This can be replaced with a WeakMap once they are implemented in - // commonly used development environments. - element._store = {}; - - // To make comparing ReactElements easier for testing purposes, we make - // the validation flag non-enumerable (where possible, which should - // include every environment we run tests in), so the test framework - // ignores it. - if (canDefineProperty) { - Object.defineProperty(element._store, 'validated', { - configurable: false, - enumerable: false, - writable: true, - value: false - }); - // self and source are DEV only properties. - Object.defineProperty(element, '_self', { - configurable: false, - enumerable: false, - writable: false, - value: self - }); - // Two elements created in two different places should be considered - // equal for testing purposes and therefore we hide it from enumeration. - Object.defineProperty(element, '_source', { - configurable: false, - enumerable: false, - writable: false, - value: source - }); - } else { - element._store.validated = false; - element._self = self; - element._source = source; - } - if (Object.freeze) { - Object.freeze(element.props); - Object.freeze(element); - } - } - - return element; -}; - -/** - * Create and return a new ReactElement of the given type. - * See https://facebook.github.io/react/docs/top-level-api.html#react.createelement - */ -ReactElement.createElement = function (type, config, children) { - var propName; - - // Reserved names are extracted - var props = {}; - - var key = null; - var ref = null; - var self = null; - var source = null; - - if (config != null) { - if (hasValidRef(config)) { - ref = config.ref; - } - if (hasValidKey(config)) { - key = '' + config.key; - } - - self = config.__self === undefined ? null : config.__self; - source = config.__source === undefined ? null : config.__source; - // Remaining properties are added to a new props object - for (propName in config) { - if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { - props[propName] = config[propName]; - } - } - } - - // Children can be more than one argument, and those are transferred onto - // the newly allocated props object. - var childrenLength = arguments.length - 2; - if (childrenLength === 1) { - props.children = children; - } else if (childrenLength > 1) { - var childArray = Array(childrenLength); - for (var i = 0; i < childrenLength; i++) { - childArray[i] = arguments[i + 2]; - } - if (process.env.NODE_ENV !== 'production') { - if (Object.freeze) { - Object.freeze(childArray); - } - } - props.children = childArray; - } - - // Resolve default props - if (type && type.defaultProps) { - var defaultProps = type.defaultProps; - for (propName in defaultProps) { - if (props[propName] === undefined) { - props[propName] = defaultProps[propName]; - } - } - } - if (process.env.NODE_ENV !== 'production') { - if (key || ref) { - if (typeof props.$$typeof === 'undefined' || props.$$typeof !== REACT_ELEMENT_TYPE) { - var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type; - if (key) { - defineKeyPropWarningGetter(props, displayName); - } - if (ref) { - defineRefPropWarningGetter(props, displayName); - } - } - } - } - return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props); -}; - -/** - * Return a function that produces ReactElements of a given type. - * See https://facebook.github.io/react/docs/top-level-api.html#react.createfactory - */ -ReactElement.createFactory = function (type) { - var factory = ReactElement.createElement.bind(null, type); - // Expose the type on the factory and the prototype so that it can be - // easily accessed on elements. E.g. `<Foo />.type === Foo`. - // This should not be named `constructor` since this may not be the function - // that created the element, and it may not even be a constructor. - // Legacy hook TODO: Warn if this is accessed - factory.type = type; - return factory; -}; - -ReactElement.cloneAndReplaceKey = function (oldElement, newKey) { - var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props); - - return newElement; -}; - -/** - * Clone and return a new ReactElement using element as the starting point. - * See https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement - */ -ReactElement.cloneElement = function (element, config, children) { - var propName; - - // Original props are copied - var props = _assign({}, element.props); - - // Reserved names are extracted - var key = element.key; - var ref = element.ref; - // Self is preserved since the owner is preserved. - var self = element._self; - // Source is preserved since cloneElement is unlikely to be targeted by a - // transpiler, and the original source is probably a better indicator of the - // true owner. - var source = element._source; - - // Owner will be preserved, unless ref is overridden - var owner = element._owner; - - if (config != null) { - if (hasValidRef(config)) { - // Silently steal the ref from the parent. - ref = config.ref; - owner = ReactCurrentOwner.current; - } - if (hasValidKey(config)) { - key = '' + config.key; - } - - // Remaining properties override existing props - var defaultProps; - if (element.type && element.type.defaultProps) { - defaultProps = element.type.defaultProps; - } - for (propName in config) { - if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { - if (config[propName] === undefined && defaultProps !== undefined) { - // Resolve default props - props[propName] = defaultProps[propName]; - } else { - props[propName] = config[propName]; - } - } - } - } - - // Children can be more than one argument, and those are transferred onto - // the newly allocated props object. - var childrenLength = arguments.length - 2; - if (childrenLength === 1) { - props.children = children; - } else if (childrenLength > 1) { - var childArray = Array(childrenLength); - for (var i = 0; i < childrenLength; i++) { - childArray[i] = arguments[i + 2]; - } - props.children = childArray; - } - - return ReactElement(element.type, key, ref, self, source, owner, props); -}; - -/** - * Verifies the object is a ReactElement. - * See https://facebook.github.io/react/docs/top-level-api.html#react.isvalidelement - * @param {?object} object - * @return {boolean} True if `object` is a valid component. - * @final - */ -ReactElement.isValidElement = function (object) { - return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; -}; - -module.exports = ReactElement; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 23 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - -/** - * WARNING: DO NOT manually require this module. - * This is a replacement for `invariant(...)` used by the error code system - * and will _only_ be required by the corresponding babel pass. - * It always throws. - */ - -function reactProdInvariant(code) { - var argCount = arguments.length - 1; - - var message = 'Minified React error #' + code + '; visit ' + 'http://facebook.github.io/react/docs/error-decoder.html?invariant=' + code; - - for (var argIdx = 0; argIdx < argCount; argIdx++) { - message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]); - } - - message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.'; - - var error = new Error(message); - error.name = 'Invariant Violation'; - error.framesToPop = 1; // we don't care about reactProdInvariant's own frame - - throw error; -} - -module.exports = reactProdInvariant; - -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _extractPath = __webpack_require__(77); - -var _extractPath2 = _interopRequireDefault(_extractPath); - -function parsePath(path) { - var pathname = _extractPath2['default'](path); - var search = ''; - var hash = ''; - - process.env.NODE_ENV !== 'production' ? _warning2['default'](path === pathname, 'A path must be pathname + search + hash only, not a fully qualified URL like "%s"', path) : undefined; - - var hashIndex = pathname.indexOf('#'); - if (hashIndex !== -1) { - hash = pathname.substring(hashIndex); - pathname = pathname.substring(0, hashIndex); - } - - var searchIndex = pathname.indexOf('?'); - if (searchIndex !== -1) { - search = pathname.substring(searchIndex); - pathname = pathname.substring(0, searchIndex); - } - - if (pathname === '') pathname = '/'; - - return { - pathname: pathname, - search: search, - hash: hash - }; -} - -exports['default'] = parsePath; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 25 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMNamespaces = __webpack_require__(47); -var setInnerHTML = __webpack_require__(40); - -var createMicrosoftUnsafeLocalFunction = __webpack_require__(54); -var setTextContent = __webpack_require__(97); - -var ELEMENT_NODE_TYPE = 1; -var DOCUMENT_FRAGMENT_NODE_TYPE = 11; - -/** - * In IE (8-11) and Edge, appending nodes with no children is dramatically - * faster than appending a full subtree, so we essentially queue up the - * .appendChild calls here and apply them so each node is added to its parent - * before any children are added. - * - * In other browsers, doing so is slower or neutral compared to the other order - * (in Firefox, twice as slow) so we only do this inversion in IE. - * - * See https://github.com/spicyj/innerhtml-vs-createelement-vs-clonenode. - */ -var enableLazy = typeof document !== 'undefined' && typeof document.documentMode === 'number' || typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string' && /\bEdge\/\d/.test(navigator.userAgent); - -function insertTreeChildren(tree) { - if (!enableLazy) { - return; - } - var node = tree.node; - var children = tree.children; - if (children.length) { - for (var i = 0; i < children.length; i++) { - insertTreeBefore(node, children[i], null); - } - } else if (tree.html != null) { - setInnerHTML(node, tree.html); - } else if (tree.text != null) { - setTextContent(node, tree.text); - } -} - -var insertTreeBefore = createMicrosoftUnsafeLocalFunction(function (parentNode, tree, referenceNode) { - // DocumentFragments aren't actually part of the DOM after insertion so - // appending children won't update the DOM. We need to ensure the fragment - // is properly populated first, breaking out of our lazy approach for just - // this level. Also, some <object> plugins (like Flash Player) will read - // <param> nodes immediately upon insertion into the DOM, so <object> - // must also be populated prior to insertion into the DOM. - if (tree.node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE || tree.node.nodeType === ELEMENT_NODE_TYPE && tree.node.nodeName.toLowerCase() === 'object' && (tree.node.namespaceURI == null || tree.node.namespaceURI === DOMNamespaces.html)) { - insertTreeChildren(tree); - parentNode.insertBefore(tree.node, referenceNode); - } else { - parentNode.insertBefore(tree.node, referenceNode); - insertTreeChildren(tree); - } -}); - -function replaceChildWithTree(oldNode, newTree) { - oldNode.parentNode.replaceChild(newTree.node, oldNode); - insertTreeChildren(newTree); -} - -function queueChild(parentTree, childTree) { - if (enableLazy) { - parentTree.children.push(childTree); - } else { - parentTree.node.appendChild(childTree.node); - } -} - -function queueHTML(tree, html) { - if (enableLazy) { - tree.html = html; - } else { - setInnerHTML(tree.node, html); - } -} - -function queueText(tree, text) { - if (enableLazy) { - tree.text = text; - } else { - setTextContent(tree.node, text); - } -} - -function toString() { - return this.node.nodeName; -} - -function DOMLazyTree(node) { - return { - node: node, - children: [], - html: null, - text: null, - toString: toString - }; -} - -DOMLazyTree.insertTreeBefore = insertTreeBefore; -DOMLazyTree.replaceChildWithTree = replaceChildWithTree; -DOMLazyTree.queueChild = queueChild; -DOMLazyTree.queueHTML = queueHTML; -DOMLazyTree.queueText = queueText; - -module.exports = DOMLazyTree; - -/***/ }), -/* 26 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactRef = __webpack_require__(280); -var ReactInstrumentation = __webpack_require__(10); - -var warning = __webpack_require__(3); - -/** - * Helper to call ReactRef.attachRefs with this composite component, split out - * to avoid allocations in the transaction mount-ready queue. - */ -function attachRefs() { - ReactRef.attachRefs(this, this._currentElement); -} - -var ReactReconciler = { - - /** - * Initializes the component, renders markup, and registers event listeners. - * - * @param {ReactComponent} internalInstance - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {?object} the containing host component instance - * @param {?object} info about the host container - * @return {?string} Rendered markup to be inserted into the DOM. - * @final - * @internal - */ - mountComponent: function (internalInstance, transaction, hostParent, hostContainerInfo, context, parentDebugID // 0 in production and for roots - ) { - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onBeforeMountComponent(internalInstance._debugID, internalInstance._currentElement, parentDebugID); - } - } - var markup = internalInstance.mountComponent(transaction, hostParent, hostContainerInfo, context, parentDebugID); - if (internalInstance._currentElement && internalInstance._currentElement.ref != null) { - transaction.getReactMountReady().enqueue(attachRefs, internalInstance); - } - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onMountComponent(internalInstance._debugID); - } - } - return markup; - }, - - /** - * Returns a value that can be passed to - * ReactComponentEnvironment.replaceNodeWithMarkup. - */ - getHostNode: function (internalInstance) { - return internalInstance.getHostNode(); - }, - - /** - * Releases any resources allocated by `mountComponent`. - * - * @final - * @internal - */ - unmountComponent: function (internalInstance, safely) { - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onBeforeUnmountComponent(internalInstance._debugID); - } - } - ReactRef.detachRefs(internalInstance, internalInstance._currentElement); - internalInstance.unmountComponent(safely); - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onUnmountComponent(internalInstance._debugID); - } - } - }, - - /** - * Update a component using a new element. - * - * @param {ReactComponent} internalInstance - * @param {ReactElement} nextElement - * @param {ReactReconcileTransaction} transaction - * @param {object} context - * @internal - */ - receiveComponent: function (internalInstance, nextElement, transaction, context) { - var prevElement = internalInstance._currentElement; - - if (nextElement === prevElement && context === internalInstance._context) { - // Since elements are immutable after the owner is rendered, - // we can do a cheap identity compare here to determine if this is a - // superfluous reconcile. It's possible for state to be mutable but such - // change should trigger an update of the owner which would recreate - // the element. We explicitly check for the existence of an owner since - // it's possible for an element created outside a composite to be - // deeply mutated and reused. - - // TODO: Bailing out early is just a perf optimization right? - // TODO: Removing the return statement should affect correctness? - return; - } - - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, nextElement); - } - } - - var refsChanged = ReactRef.shouldUpdateRefs(prevElement, nextElement); - - if (refsChanged) { - ReactRef.detachRefs(internalInstance, prevElement); - } - - internalInstance.receiveComponent(nextElement, transaction, context); - - if (refsChanged && internalInstance._currentElement && internalInstance._currentElement.ref != null) { - transaction.getReactMountReady().enqueue(attachRefs, internalInstance); - } - - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID); - } - } - }, - - /** - * Flush any dirty changes in a component. - * - * @param {ReactComponent} internalInstance - * @param {ReactReconcileTransaction} transaction - * @internal - */ - performUpdateIfNecessary: function (internalInstance, transaction, updateBatchNumber) { - if (internalInstance._updateBatchNumber !== updateBatchNumber) { - // The component's enqueued batch number should always be the current - // batch or the following one. - process.env.NODE_ENV !== 'production' ? warning(internalInstance._updateBatchNumber == null || internalInstance._updateBatchNumber === updateBatchNumber + 1, 'performUpdateIfNecessary: Unexpected batch number (current %s, ' + 'pending %s)', updateBatchNumber, internalInstance._updateBatchNumber) : void 0; - return; - } - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, internalInstance._currentElement); - } - } - internalInstance.performUpdateIfNecessary(transaction); - if (process.env.NODE_ENV !== 'production') { - if (internalInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID); - } - } - } - -}; - -module.exports = ReactReconciler; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 27 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var ReactChildren = __webpack_require__(326); -var ReactComponent = __webpack_require__(63); -var ReactPureComponent = __webpack_require__(330); -var ReactClass = __webpack_require__(327); -var ReactDOMFactories = __webpack_require__(328); -var ReactElement = __webpack_require__(22); -var ReactPropTypes = __webpack_require__(329); -var ReactVersion = __webpack_require__(331); - -var onlyChild = __webpack_require__(333); -var warning = __webpack_require__(3); - -var createElement = ReactElement.createElement; -var createFactory = ReactElement.createFactory; -var cloneElement = ReactElement.cloneElement; - -if (process.env.NODE_ENV !== 'production') { - var ReactElementValidator = __webpack_require__(104); - createElement = ReactElementValidator.createElement; - createFactory = ReactElementValidator.createFactory; - cloneElement = ReactElementValidator.cloneElement; -} - -var __spread = _assign; - -if (process.env.NODE_ENV !== 'production') { - var warned = false; - __spread = function () { - process.env.NODE_ENV !== 'production' ? warning(warned, 'React.__spread is deprecated and should not be used. Use ' + 'Object.assign directly or another helper function with similar ' + 'semantics. You may be seeing this warning due to your compiler. ' + 'See https://fb.me/react-spread-deprecation for more details.') : void 0; - warned = true; - return _assign.apply(null, arguments); - }; -} - -var React = { - - // Modern - - Children: { - map: ReactChildren.map, - forEach: ReactChildren.forEach, - count: ReactChildren.count, - toArray: ReactChildren.toArray, - only: onlyChild - }, - - Component: ReactComponent, - PureComponent: ReactPureComponent, - - createElement: createElement, - cloneElement: cloneElement, - isValidElement: ReactElement.isValidElement, - - // Classic - - PropTypes: ReactPropTypes, - createClass: ReactClass.createClass, - createFactory: createFactory, - createMixin: function (mixin) { - // Currently a noop. Will be used to validate and trace mixins. - return mixin; - }, - - // This looks DOM specific but these are actually isomorphic helpers - // since they are just generating DOM strings. - DOM: ReactDOMFactories, - - version: ReactVersion, - - // Deprecated hook for JSX spread, don't use this for anything. - __spread: __spread -}; - -module.exports = React; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var emptyObject = {}; - -if (process.env.NODE_ENV !== 'production') { - Object.freeze(emptyObject); -} - -module.exports = emptyObject; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 29 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Indicates that navigation was caused by a call to history.push. - */ - - -exports.__esModule = true; -var PUSH = 'PUSH'; - -exports.PUSH = PUSH; -/** - * Indicates that navigation was caused by a call to history.replace. - */ -var REPLACE = 'REPLACE'; - -exports.REPLACE = REPLACE; -/** - * Indicates that navigation was caused by some other action such - * as using a browser's back/forward buttons and/or manually manipulating - * the URL in a browser's location bar. This is the default. - * - * See https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate - * for more information. - */ -var POP = 'POP'; - -exports.POP = POP; -exports['default'] = { - PUSH: PUSH, - REPLACE: REPLACE, - POP: POP -}; - -/***/ }), -/* 30 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var EventPluginRegistry = __webpack_require__(35); -var EventPluginUtils = __webpack_require__(48); -var ReactErrorUtils = __webpack_require__(52); - -var accumulateInto = __webpack_require__(91); -var forEachAccumulated = __webpack_require__(92); -var invariant = __webpack_require__(2); - -/** - * Internal store for event listeners - */ -var listenerBank = {}; - -/** - * Internal queue of events that have accumulated their dispatches and are - * waiting to have their dispatches executed. - */ -var eventQueue = null; - -/** - * Dispatches an event and releases it back into the pool, unless persistent. - * - * @param {?object} event Synthetic event to be dispatched. - * @param {boolean} simulated If the event is simulated (changes exn behavior) - * @private - */ -var executeDispatchesAndRelease = function (event, simulated) { - if (event) { - EventPluginUtils.executeDispatchesInOrder(event, simulated); - - if (!event.isPersistent()) { - event.constructor.release(event); - } - } -}; -var executeDispatchesAndReleaseSimulated = function (e) { - return executeDispatchesAndRelease(e, true); -}; -var executeDispatchesAndReleaseTopLevel = function (e) { - return executeDispatchesAndRelease(e, false); -}; - -var getDictionaryKey = function (inst) { - // Prevents V8 performance issue: - // https://github.com/facebook/react/pull/7232 - return '.' + inst._rootNodeID; -}; - -function isInteractive(tag) { - return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; -} - -function shouldPreventMouseEvent(name, type, props) { - switch (name) { - case 'onClick': - case 'onClickCapture': - case 'onDoubleClick': - case 'onDoubleClickCapture': - case 'onMouseDown': - case 'onMouseDownCapture': - case 'onMouseMove': - case 'onMouseMoveCapture': - case 'onMouseUp': - case 'onMouseUpCapture': - return !!(props.disabled && isInteractive(type)); - default: - return false; - } -} - -/** - * This is a unified interface for event plugins to be installed and configured. - * - * Event plugins can implement the following properties: - * - * `extractEvents` {function(string, DOMEventTarget, string, object): *} - * Required. When a top-level event is fired, this method is expected to - * extract synthetic events that will in turn be queued and dispatched. - * - * `eventTypes` {object} - * Optional, plugins that fire events must publish a mapping of registration - * names that are used to register listeners. Values of this mapping must - * be objects that contain `registrationName` or `phasedRegistrationNames`. - * - * `executeDispatch` {function(object, function, string)} - * Optional, allows plugins to override how an event gets dispatched. By - * default, the listener is simply invoked. - * - * Each plugin that is injected into `EventsPluginHub` is immediately operable. - * - * @public - */ -var EventPluginHub = { - - /** - * Methods for injecting dependencies. - */ - injection: { - - /** - * @param {array} InjectedEventPluginOrder - * @public - */ - injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder, - - /** - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - */ - injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName - - }, - - /** - * Stores `listener` at `listenerBank[registrationName][key]`. Is idempotent. - * - * @param {object} inst The instance, which is the source of events. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {function} listener The callback to store. - */ - putListener: function (inst, registrationName, listener) { - !(typeof listener === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener) : _prodInvariant('94', registrationName, typeof listener) : void 0; - - var key = getDictionaryKey(inst); - var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {}); - bankForRegistrationName[key] = listener; - - var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; - if (PluginModule && PluginModule.didPutListener) { - PluginModule.didPutListener(inst, registrationName, listener); - } - }, - - /** - * @param {object} inst The instance, which is the source of events. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @return {?function} The stored callback. - */ - getListener: function (inst, registrationName) { - // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not - // live here; needs to be moved to a better place soon - var bankForRegistrationName = listenerBank[registrationName]; - if (shouldPreventMouseEvent(registrationName, inst._currentElement.type, inst._currentElement.props)) { - return null; - } - var key = getDictionaryKey(inst); - return bankForRegistrationName && bankForRegistrationName[key]; - }, - - /** - * Deletes a listener from the registration bank. - * - * @param {object} inst The instance, which is the source of events. - * @param {string} registrationName Name of listener (e.g. `onClick`). - */ - deleteListener: function (inst, registrationName) { - var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; - if (PluginModule && PluginModule.willDeleteListener) { - PluginModule.willDeleteListener(inst, registrationName); - } - - var bankForRegistrationName = listenerBank[registrationName]; - // TODO: This should never be null -- when is it? - if (bankForRegistrationName) { - var key = getDictionaryKey(inst); - delete bankForRegistrationName[key]; - } - }, - - /** - * Deletes all listeners for the DOM element with the supplied ID. - * - * @param {object} inst The instance, which is the source of events. - */ - deleteAllListeners: function (inst) { - var key = getDictionaryKey(inst); - for (var registrationName in listenerBank) { - if (!listenerBank.hasOwnProperty(registrationName)) { - continue; - } - - if (!listenerBank[registrationName][key]) { - continue; - } - - var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; - if (PluginModule && PluginModule.willDeleteListener) { - PluginModule.willDeleteListener(inst, registrationName); - } - - delete listenerBank[registrationName][key]; - } - }, - - /** - * Allows registered plugins an opportunity to extract events from top-level - * native browser events. - * - * @return {*} An accumulation of synthetic events. - * @internal - */ - extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var events; - var plugins = EventPluginRegistry.plugins; - for (var i = 0; i < plugins.length; i++) { - // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; - if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); - if (extractedEvents) { - events = accumulateInto(events, extractedEvents); - } - } - } - return events; - }, - - /** - * Enqueues a synthetic event that should be dispatched when - * `processEventQueue` is invoked. - * - * @param {*} events An accumulation of synthetic events. - * @internal - */ - enqueueEvents: function (events) { - if (events) { - eventQueue = accumulateInto(eventQueue, events); - } - }, - - /** - * Dispatches all synthetic events on the event queue. - * - * @internal - */ - processEventQueue: function (simulated) { - // Set `eventQueue` to null before processing it so that we can tell if more - // events get enqueued while processing. - var processingEventQueue = eventQueue; - eventQueue = null; - if (simulated) { - forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated); - } else { - forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); - } - !!eventQueue ? process.env.NODE_ENV !== 'production' ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : _prodInvariant('95') : void 0; - // This would be a good time to rethrow if any of the event handlers threw. - ReactErrorUtils.rethrowCaughtError(); - }, - - /** - * These are needed for tests only. Do not use! - */ - __purge: function () { - listenerBank = {}; - }, - - __getListenerBank: function () { - return listenerBank; - } - -}; - -module.exports = EventPluginHub; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 31 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var EventPluginHub = __webpack_require__(30); -var EventPluginUtils = __webpack_require__(48); - -var accumulateInto = __webpack_require__(91); -var forEachAccumulated = __webpack_require__(92); -var warning = __webpack_require__(3); - -var getListener = EventPluginHub.getListener; - -/** - * Some event types have a notion of different registration names for different - * "phases" of propagation. This finds listeners by a given phase. - */ -function listenerAtPhase(inst, event, propagationPhase) { - var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase]; - return getListener(inst, registrationName); -} - -/** - * Tags a `SyntheticEvent` with dispatched listeners. Creating this function - * here, allows us to not have to bind or create functions for each event. - * Mutating the event's members allows us to not have to create a wrapping - * "dispatch" object that pairs the event with the listener. - */ -function accumulateDirectionalDispatches(inst, phase, event) { - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(inst, 'Dispatching inst must not be null') : void 0; - } - var listener = listenerAtPhase(inst, event, phase); - if (listener) { - event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); - } -} - -/** - * Collect dispatches (must be entirely collected before dispatching - see unit - * tests). Lazily allocate the array to conserve memory. We must loop through - * each event and perform the traversal for each one. We cannot perform a - * single traversal for the entire collection of events because each event may - * have a different target. - */ -function accumulateTwoPhaseDispatchesSingle(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - EventPluginUtils.traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); - } -} - -/** - * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. - */ -function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - var targetInst = event._targetInst; - var parentInst = targetInst ? EventPluginUtils.getParentInstance(targetInst) : null; - EventPluginUtils.traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); - } -} - -/** - * Accumulates without regard to direction, does not look for phased - * registration names. Same as `accumulateDirectDispatchesSingle` but without - * requiring that the `dispatchMarker` be the same as the dispatched ID. - */ -function accumulateDispatches(inst, ignoredDirection, event) { - if (event && event.dispatchConfig.registrationName) { - var registrationName = event.dispatchConfig.registrationName; - var listener = getListener(inst, registrationName); - if (listener) { - event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); - } - } -} - -/** - * Accumulates dispatches on an `SyntheticEvent`, but only for the - * `dispatchMarker`. - * @param {SyntheticEvent} event - */ -function accumulateDirectDispatchesSingle(event) { - if (event && event.dispatchConfig.registrationName) { - accumulateDispatches(event._targetInst, null, event); - } -} - -function accumulateTwoPhaseDispatches(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); -} - -function accumulateTwoPhaseDispatchesSkipTarget(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); -} - -function accumulateEnterLeaveDispatches(leave, enter, from, to) { - EventPluginUtils.traverseEnterLeave(from, to, accumulateDispatches, leave, enter); -} - -function accumulateDirectDispatches(events) { - forEachAccumulated(events, accumulateDirectDispatchesSingle); -} - -/** - * A small set of propagation patterns, each of which will accept a small amount - * of information, and generate a set of "dispatch ready event objects" - which - * are sets of events that have already been annotated with a set of dispatched - * listener functions/ids. The API is designed this way to discourage these - * propagation strategies from actually executing the dispatches, since we - * always want to collect the entire set of dispatches before executing event a - * single one. - * - * @constructor EventPropagators - */ -var EventPropagators = { - accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches, - accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget, - accumulateDirectDispatches: accumulateDirectDispatches, - accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches -}; - -module.exports = EventPropagators; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 32 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * `ReactInstanceMap` maintains a mapping from a public facing stateful - * instance (key) and the internal representation (value). This allows public - * methods to accept the user facing instance as an argument and map them back - * to internal methods. - */ - -// TODO: Replace this with ES6: var ReactInstanceMap = new Map(); - -var ReactInstanceMap = { - - /** - * This API should be called `delete` but we'd have to make sure to always - * transform these to strings for IE support. When this transform is fully - * supported we can rename it. - */ - remove: function (key) { - key._reactInternalInstance = undefined; - }, - - get: function (key) { - return key._reactInternalInstance; - }, - - has: function (key) { - return key._reactInternalInstance !== undefined; - }, - - set: function (key, value) { - key._reactInternalInstance = value; - } - -}; - -module.exports = ReactInstanceMap; - -/***/ }), -/* 33 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticEvent = __webpack_require__(17); - -var getEventTarget = __webpack_require__(57); - -/** - * @interface UIEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var UIEventInterface = { - view: function (event) { - if (event.view) { - return event.view; - } - - var target = getEventTarget(event); - if (target.window === target) { - // target is a window object - return target; - } - - var doc = target.ownerDocument; - // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. - if (doc) { - return doc.defaultView || doc.parentWindow; - } else { - return window; - } - }, - detail: function (event) { - return event.detail || 0; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticEvent} - */ -function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface); - -module.exports = SyntheticUIEvent; - -/***/ }), -/* 34 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; -exports.compilePattern = compilePattern; -exports.matchPattern = matchPattern; -exports.getParamNames = getParamNames; -exports.getParams = getParams; -exports.formatPattern = formatPattern; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); -} - -function escapeSource(string) { - return escapeRegExp(string).replace(/\/+/g, '/+'); -} - -function _compilePattern(pattern) { - var regexpSource = ''; - var paramNames = []; - var tokens = []; - - var match = undefined, - lastIndex = 0, - matcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|\*\*|\*|\(|\)/g; - while (match = matcher.exec(pattern)) { - if (match.index !== lastIndex) { - tokens.push(pattern.slice(lastIndex, match.index)); - regexpSource += escapeSource(pattern.slice(lastIndex, match.index)); - } - - if (match[1]) { - regexpSource += '([^/?#]+)'; - paramNames.push(match[1]); - } else if (match[0] === '**') { - regexpSource += '([\\s\\S]*)'; - paramNames.push('splat'); - } else if (match[0] === '*') { - regexpSource += '([\\s\\S]*?)'; - paramNames.push('splat'); - } else if (match[0] === '(') { - regexpSource += '(?:'; - } else if (match[0] === ')') { - regexpSource += ')?'; - } - - tokens.push(match[0]); - - lastIndex = matcher.lastIndex; - } - - if (lastIndex !== pattern.length) { - tokens.push(pattern.slice(lastIndex, pattern.length)); - regexpSource += escapeSource(pattern.slice(lastIndex, pattern.length)); - } - - return { - pattern: pattern, - regexpSource: regexpSource, - paramNames: paramNames, - tokens: tokens - }; -} - -var CompiledPatternsCache = {}; - -function compilePattern(pattern) { - if (!(pattern in CompiledPatternsCache)) CompiledPatternsCache[pattern] = _compilePattern(pattern); - - return CompiledPatternsCache[pattern]; -} - -/** - * Attempts to match a pattern on the given pathname. Patterns may use - * the following special characters: - * - * - :paramName Matches a URL segment up to the next /, ?, or #. The - * captured string is considered a "param" - * - () Wraps a segment of the URL that is optional - * - * Consumes (non-greedy) all characters up to the next - * character in the pattern, or to the end of the URL if - * there is none - * - ** Consumes (greedy) all characters up to the next character - * in the pattern, or to the end of the URL if there is none - * - * The return value is an object with the following properties: - * - * - remainingPathname - * - paramNames - * - paramValues - */ - -function matchPattern(pattern, pathname) { - // Make leading slashes consistent between pattern and pathname. - if (pattern.charAt(0) !== '/') { - pattern = '/' + pattern; - } - if (pathname.charAt(0) !== '/') { - pathname = '/' + pathname; - } - - var _compilePattern2 = compilePattern(pattern); - - var regexpSource = _compilePattern2.regexpSource; - var paramNames = _compilePattern2.paramNames; - var tokens = _compilePattern2.tokens; - - regexpSource += '/*'; // Capture path separators - - // Special-case patterns like '*' for catch-all routes. - var captureRemaining = tokens[tokens.length - 1] !== '*'; - - if (captureRemaining) { - // This will match newlines in the remaining path. - regexpSource += '([\\s\\S]*?)'; - } - - var match = pathname.match(new RegExp('^' + regexpSource + '$', 'i')); - - var remainingPathname = undefined, - paramValues = undefined; - if (match != null) { - if (captureRemaining) { - remainingPathname = match.pop(); - var matchedPath = match[0].substr(0, match[0].length - remainingPathname.length); - - // If we didn't match the entire pathname, then make sure that the match - // we did get ends at a path separator (potentially the one we added - // above at the beginning of the path, if the actual match was empty). - if (remainingPathname && matchedPath.charAt(matchedPath.length - 1) !== '/') { - return { - remainingPathname: null, - paramNames: paramNames, - paramValues: null - }; - } - } else { - // If this matched at all, then the match was the entire pathname. - remainingPathname = ''; - } - - paramValues = match.slice(1).map(function (v) { - return v != null ? decodeURIComponent(v) : v; - }); - } else { - remainingPathname = paramValues = null; - } - - return { - remainingPathname: remainingPathname, - paramNames: paramNames, - paramValues: paramValues - }; -} - -function getParamNames(pattern) { - return compilePattern(pattern).paramNames; -} - -function getParams(pattern, pathname) { - var _matchPattern = matchPattern(pattern, pathname); - - var paramNames = _matchPattern.paramNames; - var paramValues = _matchPattern.paramValues; - - if (paramValues != null) { - return paramNames.reduce(function (memo, paramName, index) { - memo[paramName] = paramValues[index]; - return memo; - }, {}); - } - - return null; -} - -/** - * Returns a version of the given pattern with params interpolated. Throws - * if there is a dynamic segment of the pattern for which there is no param. - */ - -function formatPattern(pattern, params) { - params = params || {}; - - var _compilePattern3 = compilePattern(pattern); - - var tokens = _compilePattern3.tokens; - - var parenCount = 0, - pathname = '', - splatIndex = 0; - - var token = undefined, - paramName = undefined, - paramValue = undefined; - for (var i = 0, len = tokens.length; i < len; ++i) { - token = tokens[i]; - - if (token === '*' || token === '**') { - paramValue = Array.isArray(params.splat) ? params.splat[splatIndex++] : params.splat; - - !(paramValue != null || parenCount > 0) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Missing splat #%s for path "%s"', splatIndex, pattern) : _invariant2['default'](false) : undefined; - - if (paramValue != null) pathname += encodeURI(paramValue); - } else if (token === '(') { - parenCount += 1; - } else if (token === ')') { - parenCount -= 1; - } else if (token.charAt(0) === ':') { - paramName = token.substring(1); - paramValue = params[paramName]; - - !(paramValue != null || parenCount > 0) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Missing "%s" parameter for path "%s"', paramName, pattern) : _invariant2['default'](false) : undefined; - - if (paramValue != null) pathname += encodeURIComponent(paramValue); - } else { - pathname += token; - } - } - - return pathname.replace(/\/+/g, '/'); -} -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 35 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -/** - * Injectable ordering of event plugins. - */ -var eventPluginOrder = null; - -/** - * Injectable mapping from names to event plugin modules. - */ -var namesToPlugins = {}; - -/** - * Recomputes the plugin list using the injected plugins and plugin ordering. - * - * @private - */ -function recomputePluginOrdering() { - if (!eventPluginOrder) { - // Wait until an `eventPluginOrder` is injected. - return; - } - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName]; - var pluginIndex = eventPluginOrder.indexOf(pluginName); - !(pluginIndex > -1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : _prodInvariant('96', pluginName) : void 0; - if (EventPluginRegistry.plugins[pluginIndex]) { - continue; - } - !pluginModule.extractEvents ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : _prodInvariant('97', pluginName) : void 0; - EventPluginRegistry.plugins[pluginIndex] = pluginModule; - var publishedEvents = pluginModule.eventTypes; - for (var eventName in publishedEvents) { - !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : _prodInvariant('98', eventName, pluginName) : void 0; - } - } -} - -/** - * Publishes an event so that it can be dispatched by the supplied plugin. - * - * @param {object} dispatchConfig Dispatch configuration for the event. - * @param {object} PluginModule Plugin publishing the event. - * @return {boolean} True if the event was successfully published. - * @private - */ -function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { - !!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : _prodInvariant('99', eventName) : void 0; - EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; - - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (var phaseName in phasedRegistrationNames) { - if (phasedRegistrationNames.hasOwnProperty(phaseName)) { - var phasedRegistrationName = phasedRegistrationNames[phaseName]; - publishRegistrationName(phasedRegistrationName, pluginModule, eventName); - } - } - return true; - } else if (dispatchConfig.registrationName) { - publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName); - return true; - } - return false; -} - -/** - * Publishes a registration name that is used to identify dispatched events and - * can be used with `EventPluginHub.putListener` to register listeners. - * - * @param {string} registrationName Registration name to add. - * @param {object} PluginModule Plugin publishing the event. - * @private - */ -function publishRegistrationName(registrationName, pluginModule, eventName) { - !!EventPluginRegistry.registrationNameModules[registrationName] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : _prodInvariant('100', registrationName) : void 0; - EventPluginRegistry.registrationNameModules[registrationName] = pluginModule; - EventPluginRegistry.registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies; - - if (process.env.NODE_ENV !== 'production') { - var lowerCasedName = registrationName.toLowerCase(); - EventPluginRegistry.possibleRegistrationNames[lowerCasedName] = registrationName; - - if (registrationName === 'onDoubleClick') { - EventPluginRegistry.possibleRegistrationNames.ondblclick = registrationName; - } - } -} - -/** - * Registers plugins so that they can extract and dispatch events. - * - * @see {EventPluginHub} - */ -var EventPluginRegistry = { - - /** - * Ordered list of injected plugins. - */ - plugins: [], - - /** - * Mapping from event name to dispatch config - */ - eventNameDispatchConfigs: {}, - - /** - * Mapping from registration name to plugin module - */ - registrationNameModules: {}, - - /** - * Mapping from registration name to event name - */ - registrationNameDependencies: {}, - - /** - * Mapping from lowercase registration names to the properly cased version, - * used to warn in the case of missing event handlers. Available - * only in __DEV__. - * @type {Object} - */ - possibleRegistrationNames: process.env.NODE_ENV !== 'production' ? {} : null, - // Trust the developer to only use possibleRegistrationNames in __DEV__ - - /** - * Injects an ordering of plugins (by plugin name). This allows the ordering - * to be decoupled from injection of the actual plugins so that ordering is - * always deterministic regardless of packaging, on-the-fly injection, etc. - * - * @param {array} InjectedEventPluginOrder - * @internal - * @see {EventPluginHub.injection.injectEventPluginOrder} - */ - injectEventPluginOrder: function (injectedEventPluginOrder) { - !!eventPluginOrder ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : _prodInvariant('101') : void 0; - // Clone the ordering so it cannot be dynamically mutated. - eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); - recomputePluginOrdering(); - }, - - /** - * Injects plugins to be used by `EventPluginHub`. The plugin names must be - * in the ordering injected by `injectEventPluginOrder`. - * - * Plugins can be injected as part of page initialization or on-the-fly. - * - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - * @internal - * @see {EventPluginHub.injection.injectEventPluginsByName} - */ - injectEventPluginsByName: function (injectedNamesToPlugins) { - var isOrderingDirty = false; - for (var pluginName in injectedNamesToPlugins) { - if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { - continue; - } - var pluginModule = injectedNamesToPlugins[pluginName]; - if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) { - !!namesToPlugins[pluginName] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : _prodInvariant('102', pluginName) : void 0; - namesToPlugins[pluginName] = pluginModule; - isOrderingDirty = true; - } - } - if (isOrderingDirty) { - recomputePluginOrdering(); - } - }, - - /** - * Looks up the plugin for the supplied event. - * - * @param {object} event A synthetic event. - * @return {?object} The plugin that created the supplied event. - * @internal - */ - getPluginModuleForEvent: function (event) { - var dispatchConfig = event.dispatchConfig; - if (dispatchConfig.registrationName) { - return EventPluginRegistry.registrationNameModules[dispatchConfig.registrationName] || null; - } - if (dispatchConfig.phasedRegistrationNames !== undefined) { - // pulling phasedRegistrationNames out of dispatchConfig helps Flow see - // that it is not undefined. - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - - for (var phase in phasedRegistrationNames) { - if (!phasedRegistrationNames.hasOwnProperty(phase)) { - continue; - } - var pluginModule = EventPluginRegistry.registrationNameModules[phasedRegistrationNames[phase]]; - if (pluginModule) { - return pluginModule; - } - } - } - return null; - }, - - /** - * Exposed for unit testing. - * @private - */ - _resetEventPlugins: function () { - eventPluginOrder = null; - for (var pluginName in namesToPlugins) { - if (namesToPlugins.hasOwnProperty(pluginName)) { - delete namesToPlugins[pluginName]; - } - } - EventPluginRegistry.plugins.length = 0; - - var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs; - for (var eventName in eventNameDispatchConfigs) { - if (eventNameDispatchConfigs.hasOwnProperty(eventName)) { - delete eventNameDispatchConfigs[eventName]; - } - } - - var registrationNameModules = EventPluginRegistry.registrationNameModules; - for (var registrationName in registrationNameModules) { - if (registrationNameModules.hasOwnProperty(registrationName)) { - delete registrationNameModules[registrationName]; - } - } - - if (process.env.NODE_ENV !== 'production') { - var possibleRegistrationNames = EventPluginRegistry.possibleRegistrationNames; - for (var lowerCasedName in possibleRegistrationNames) { - if (possibleRegistrationNames.hasOwnProperty(lowerCasedName)) { - delete possibleRegistrationNames[lowerCasedName]; - } - } - } - } - -}; - -module.exports = EventPluginRegistry; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 36 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var EventPluginRegistry = __webpack_require__(35); -var ReactEventEmitterMixin = __webpack_require__(270); -var ViewportMetrics = __webpack_require__(90); - -var getVendorPrefixedEventName = __webpack_require__(306); -var isEventSupported = __webpack_require__(58); - -/** - * Summary of `ReactBrowserEventEmitter` event handling: - * - * - Top-level delegation is used to trap most native browser events. This - * may only occur in the main thread and is the responsibility of - * ReactEventListener, which is injected and can therefore support pluggable - * event sources. This is the only work that occurs in the main thread. - * - * - We normalize and de-duplicate events to account for browser quirks. This - * may be done in the worker thread. - * - * - Forward these native events (with the associated top-level type used to - * trap it) to `EventPluginHub`, which in turn will ask plugins if they want - * to extract any synthetic events. - * - * - The `EventPluginHub` will then process each event by annotating them with - * "dispatches", a sequence of listeners and IDs that care about that event. - * - * - The `EventPluginHub` then dispatches the events. - * - * Overview of React and the event system: - * - * +------------+ . - * | DOM | . - * +------------+ . - * | . - * v . - * +------------+ . - * | ReactEvent | . - * | Listener | . - * +------------+ . +-----------+ - * | . +--------+|SimpleEvent| - * | . | |Plugin | - * +-----|------+ . v +-----------+ - * | | | . +--------------+ +------------+ - * | +-----------.--->|EventPluginHub| | Event | - * | | . | | +-----------+ | Propagators| - * | ReactEvent | . | | |TapEvent | |------------| - * | Emitter | . | |<---+|Plugin | |other plugin| - * | | . | | +-----------+ | utilities | - * | +-----------.--->| | +------------+ - * | | | . +--------------+ - * +-----|------+ . ^ +-----------+ - * | . | |Enter/Leave| - * + . +-------+|Plugin | - * +-------------+ . +-----------+ - * | application | . - * |-------------| . - * | | . - * | | . - * +-------------+ . - * . - * React Core . General Purpose Event Plugin System - */ - -var hasEventPageXY; -var alreadyListeningTo = {}; -var isMonitoringScrollValue = false; -var reactTopListenersCounter = 0; - -// For events like 'submit' which don't consistently bubble (which we trap at a -// lower node than `document`), binding at `document` would cause duplicate -// events so we don't include them here -var topEventMapping = { - topAbort: 'abort', - topAnimationEnd: getVendorPrefixedEventName('animationend') || 'animationend', - topAnimationIteration: getVendorPrefixedEventName('animationiteration') || 'animationiteration', - topAnimationStart: getVendorPrefixedEventName('animationstart') || 'animationstart', - topBlur: 'blur', - topCanPlay: 'canplay', - topCanPlayThrough: 'canplaythrough', - topChange: 'change', - topClick: 'click', - topCompositionEnd: 'compositionend', - topCompositionStart: 'compositionstart', - topCompositionUpdate: 'compositionupdate', - topContextMenu: 'contextmenu', - topCopy: 'copy', - topCut: 'cut', - topDoubleClick: 'dblclick', - topDrag: 'drag', - topDragEnd: 'dragend', - topDragEnter: 'dragenter', - topDragExit: 'dragexit', - topDragLeave: 'dragleave', - topDragOver: 'dragover', - topDragStart: 'dragstart', - topDrop: 'drop', - topDurationChange: 'durationchange', - topEmptied: 'emptied', - topEncrypted: 'encrypted', - topEnded: 'ended', - topError: 'error', - topFocus: 'focus', - topInput: 'input', - topKeyDown: 'keydown', - topKeyPress: 'keypress', - topKeyUp: 'keyup', - topLoadedData: 'loadeddata', - topLoadedMetadata: 'loadedmetadata', - topLoadStart: 'loadstart', - topMouseDown: 'mousedown', - topMouseMove: 'mousemove', - topMouseOut: 'mouseout', - topMouseOver: 'mouseover', - topMouseUp: 'mouseup', - topPaste: 'paste', - topPause: 'pause', - topPlay: 'play', - topPlaying: 'playing', - topProgress: 'progress', - topRateChange: 'ratechange', - topScroll: 'scroll', - topSeeked: 'seeked', - topSeeking: 'seeking', - topSelectionChange: 'selectionchange', - topStalled: 'stalled', - topSuspend: 'suspend', - topTextInput: 'textInput', - topTimeUpdate: 'timeupdate', - topTouchCancel: 'touchcancel', - topTouchEnd: 'touchend', - topTouchMove: 'touchmove', - topTouchStart: 'touchstart', - topTransitionEnd: getVendorPrefixedEventName('transitionend') || 'transitionend', - topVolumeChange: 'volumechange', - topWaiting: 'waiting', - topWheel: 'wheel' -}; - -/** - * To ensure no conflicts with other potential React instances on the page - */ -var topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2); - -function getListeningForDocument(mountAt) { - // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` - // directly. - if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { - mountAt[topListenersIDKey] = reactTopListenersCounter++; - alreadyListeningTo[mountAt[topListenersIDKey]] = {}; - } - return alreadyListeningTo[mountAt[topListenersIDKey]]; -} - -/** - * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For - * example: - * - * EventPluginHub.putListener('myID', 'onClick', myFunction); - * - * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'. - * - * @internal - */ -var ReactBrowserEventEmitter = _assign({}, ReactEventEmitterMixin, { - - /** - * Injectable event backend - */ - ReactEventListener: null, - - injection: { - /** - * @param {object} ReactEventListener - */ - injectReactEventListener: function (ReactEventListener) { - ReactEventListener.setHandleTopLevel(ReactBrowserEventEmitter.handleTopLevel); - ReactBrowserEventEmitter.ReactEventListener = ReactEventListener; - } - }, - - /** - * Sets whether or not any created callbacks should be enabled. - * - * @param {boolean} enabled True if callbacks should be enabled. - */ - setEnabled: function (enabled) { - if (ReactBrowserEventEmitter.ReactEventListener) { - ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled); - } - }, - - /** - * @return {boolean} True if callbacks are enabled. - */ - isEnabled: function () { - return !!(ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled()); - }, - - /** - * We listen for bubbled touch events on the document object. - * - * Firefox v8.01 (and possibly others) exhibited strange behavior when - * mounting `onmousemove` events at some node that was not the document - * element. The symptoms were that if your mouse is not moving over something - * contained within that mount point (for example on the background) the - * top-level listeners for `onmousemove` won't be called. However, if you - * register the `mousemove` on the document object, then it will of course - * catch all `mousemove`s. This along with iOS quirks, justifies restricting - * top-level listeners to the document object only, at least for these - * movement types of events and possibly all events. - * - * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html - * - * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but - * they bubble to document. - * - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {object} contentDocumentHandle Document which owns the container - */ - listenTo: function (registrationName, contentDocumentHandle) { - var mountAt = contentDocumentHandle; - var isListening = getListeningForDocument(mountAt); - var dependencies = EventPluginRegistry.registrationNameDependencies[registrationName]; - - for (var i = 0; i < dependencies.length; i++) { - var dependency = dependencies[i]; - if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { - if (dependency === 'topWheel') { - if (isEventSupported('wheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'wheel', mountAt); - } else if (isEventSupported('mousewheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'mousewheel', mountAt); - } else { - // Firefox needs to capture a different mouse scroll event. - // @see http://www.quirksmode.org/dom/events/tests/scroll.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'DOMMouseScroll', mountAt); - } - } else if (dependency === 'topScroll') { - - if (isEventSupported('scroll', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topScroll', 'scroll', mountAt); - } else { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topScroll', 'scroll', ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE); - } - } else if (dependency === 'topFocus' || dependency === 'topBlur') { - - if (isEventSupported('focus', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topFocus', 'focus', mountAt); - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topBlur', 'blur', mountAt); - } else if (isEventSupported('focusin')) { - // IE has `focusin` and `focusout` events which bubble. - // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topFocus', 'focusin', mountAt); - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topBlur', 'focusout', mountAt); - } - - // to make sure blur and focus event listeners are only attached once - isListening.topBlur = true; - isListening.topFocus = true; - } else if (topEventMapping.hasOwnProperty(dependency)) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(dependency, topEventMapping[dependency], mountAt); - } - - isListening[dependency] = true; - } - } - }, - - trapBubbledEvent: function (topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelType, handlerBaseName, handle); - }, - - trapCapturedEvent: function (topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelType, handlerBaseName, handle); - }, - - /** - * Protect against document.createEvent() returning null - * Some popup blocker extensions appear to do this: - * https://github.com/facebook/react/issues/6887 - */ - supportsEventPageXY: function () { - if (!document.createEvent) { - return false; - } - var ev = document.createEvent('MouseEvent'); - return ev != null && 'pageX' in ev; - }, - - /** - * Listens to window scroll and resize events. We cache scroll values so that - * application code can access them without triggering reflows. - * - * ViewportMetrics is only used by SyntheticMouse/TouchEvent and only when - * pageX/pageY isn't supported (legacy browsers). - * - * NOTE: Scroll events do not bubble. - * - * @see http://www.quirksmode.org/dom/events/scroll.html - */ - ensureScrollValueMonitoring: function () { - if (hasEventPageXY === undefined) { - hasEventPageXY = ReactBrowserEventEmitter.supportsEventPageXY(); - } - if (!hasEventPageXY && !isMonitoringScrollValue) { - var refresh = ViewportMetrics.refreshScrollValues; - ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh); - isMonitoringScrollValue = true; - } - } - -}); - -module.exports = ReactBrowserEventEmitter; - -/***/ }), -/* 37 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticUIEvent = __webpack_require__(33); -var ViewportMetrics = __webpack_require__(90); - -var getEventModifierState = __webpack_require__(56); - -/** - * @interface MouseEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var MouseEventInterface = { - screenX: null, - screenY: null, - clientX: null, - clientY: null, - ctrlKey: null, - shiftKey: null, - altKey: null, - metaKey: null, - getModifierState: getEventModifierState, - button: function (event) { - // Webkit, Firefox, IE9+ - // which: 1 2 3 - // button: 0 1 2 (standard) - var button = event.button; - if ('which' in event) { - return button; - } - // IE<9 - // which: undefined - // button: 0 0 0 - // button: 1 4 2 (onmouseup) - return button === 2 ? 2 : button === 4 ? 1 : 0; - }, - buttons: null, - relatedTarget: function (event) { - return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement); - }, - // "Proprietary" Interface. - pageX: function (event) { - return 'pageX' in event ? event.pageX : event.clientX + ViewportMetrics.currentScrollLeft; - }, - pageY: function (event) { - return 'pageY' in event ? event.pageY : event.clientY + ViewportMetrics.currentScrollTop; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface); - -module.exports = SyntheticMouseEvent; - -/***/ }), -/* 38 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -var OBSERVED_ERROR = {}; - -/** - * `Transaction` creates a black box that is able to wrap any method such that - * certain invariants are maintained before and after the method is invoked - * (Even if an exception is thrown while invoking the wrapped method). Whoever - * instantiates a transaction can provide enforcers of the invariants at - * creation time. The `Transaction` class itself will supply one additional - * automatic invariant for you - the invariant that any transaction instance - * should not be run while it is already being run. You would typically create a - * single instance of a `Transaction` for reuse multiple times, that potentially - * is used to wrap several different methods. Wrappers are extremely simple - - * they only require implementing two methods. - * - * <pre> - * wrappers (injected at creation time) - * + + - * | | - * +-----------------|--------|--------------+ - * | v | | - * | +---------------+ | | - * | +--| wrapper1 |---|----+ | - * | | +---------------+ v | | - * | | +-------------+ | | - * | | +----| wrapper2 |--------+ | - * | | | +-------------+ | | | - * | | | | | | - * | v v v v | wrapper - * | +---+ +---+ +---------+ +---+ +---+ | invariants - * perform(anyMethod) | | | | | | | | | | | | maintained - * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|--------> - * | | | | | | | | | | | | - * | | | | | | | | | | | | - * | | | | | | | | | | | | - * | +---+ +---+ +---------+ +---+ +---+ | - * | initialize close | - * +-----------------------------------------+ - * </pre> - * - * Use cases: - * - Preserving the input selection ranges before/after reconciliation. - * Restoring selection even in the event of an unexpected error. - * - Deactivating events while rearranging the DOM, preventing blurs/focuses, - * while guaranteeing that afterwards, the event system is reactivated. - * - Flushing a queue of collected DOM mutations to the main UI thread after a - * reconciliation takes place in a worker thread. - * - Invoking any collected `componentDidUpdate` callbacks after rendering new - * content. - * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue - * to preserve the `scrollTop` (an automatic scroll aware DOM). - * - (Future use case): Layout calculations before and after DOM updates. - * - * Transactional plugin API: - * - A module that has an `initialize` method that returns any precomputation. - * - and a `close` method that accepts the precomputation. `close` is invoked - * when the wrapped process is completed, or has failed. - * - * @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules - * that implement `initialize` and `close`. - * @return {Transaction} Single transaction for reuse in thread. - * - * @class Transaction - */ -var TransactionImpl = { - /** - * Sets up this instance so that it is prepared for collecting metrics. Does - * so such that this setup method may be used on an instance that is already - * initialized, in a way that does not consume additional memory upon reuse. - * That can be useful if you decide to make your subclass of this mixin a - * "PooledClass". - */ - reinitializeTransaction: function () { - this.transactionWrappers = this.getTransactionWrappers(); - if (this.wrapperInitData) { - this.wrapperInitData.length = 0; - } else { - this.wrapperInitData = []; - } - this._isInTransaction = false; - }, - - _isInTransaction: false, - - /** - * @abstract - * @return {Array<TransactionWrapper>} Array of transaction wrappers. - */ - getTransactionWrappers: null, - - isInTransaction: function () { - return !!this._isInTransaction; - }, - - /** - * Executes the function within a safety window. Use this for the top level - * methods that result in large amounts of computation/mutations that would - * need to be safety checked. The optional arguments helps prevent the need - * to bind in many cases. - * - * @param {function} method Member of scope to call. - * @param {Object} scope Scope to invoke from. - * @param {Object?=} a Argument to pass to the method. - * @param {Object?=} b Argument to pass to the method. - * @param {Object?=} c Argument to pass to the method. - * @param {Object?=} d Argument to pass to the method. - * @param {Object?=} e Argument to pass to the method. - * @param {Object?=} f Argument to pass to the method. - * - * @return {*} Return value from `method`. - */ - perform: function (method, scope, a, b, c, d, e, f) { - !!this.isInTransaction() ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Transaction.perform(...): Cannot initialize a transaction when there is already an outstanding transaction.') : _prodInvariant('27') : void 0; - var errorThrown; - var ret; - try { - this._isInTransaction = true; - // Catching errors makes debugging more difficult, so we start with - // errorThrown set to true before setting it to false after calling - // close -- if it's still set to true in the finally block, it means - // one of these calls threw. - errorThrown = true; - this.initializeAll(0); - ret = method.call(scope, a, b, c, d, e, f); - errorThrown = false; - } finally { - try { - if (errorThrown) { - // If `method` throws, prefer to show that stack trace over any thrown - // by invoking `closeAll`. - try { - this.closeAll(0); - } catch (err) {} - } else { - // Since `method` didn't throw, we don't want to silence the exception - // here. - this.closeAll(0); - } - } finally { - this._isInTransaction = false; - } - } - return ret; - }, - - initializeAll: function (startIndex) { - var transactionWrappers = this.transactionWrappers; - for (var i = startIndex; i < transactionWrappers.length; i++) { - var wrapper = transactionWrappers[i]; - try { - // Catching errors makes debugging more difficult, so we start with the - // OBSERVED_ERROR state before overwriting it with the real return value - // of initialize -- if it's still set to OBSERVED_ERROR in the finally - // block, it means wrapper.initialize threw. - this.wrapperInitData[i] = OBSERVED_ERROR; - this.wrapperInitData[i] = wrapper.initialize ? wrapper.initialize.call(this) : null; - } finally { - if (this.wrapperInitData[i] === OBSERVED_ERROR) { - // The initializer for wrapper i threw an error; initialize the - // remaining wrappers but silence any exceptions from them to ensure - // that the first error is the one to bubble up. - try { - this.initializeAll(i + 1); - } catch (err) {} - } - } - } - }, - - /** - * Invokes each of `this.transactionWrappers.close[i]` functions, passing into - * them the respective return values of `this.transactionWrappers.init[i]` - * (`close`rs that correspond to initializers that failed will not be - * invoked). - */ - closeAll: function (startIndex) { - !this.isInTransaction() ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Transaction.closeAll(): Cannot close transaction when none are open.') : _prodInvariant('28') : void 0; - var transactionWrappers = this.transactionWrappers; - for (var i = startIndex; i < transactionWrappers.length; i++) { - var wrapper = transactionWrappers[i]; - var initData = this.wrapperInitData[i]; - var errorThrown; - try { - // Catching errors makes debugging more difficult, so we start with - // errorThrown set to true before setting it to false after calling - // close -- if it's still set to true in the finally block, it means - // wrapper.close threw. - errorThrown = true; - if (initData !== OBSERVED_ERROR && wrapper.close) { - wrapper.close.call(this, initData); - } - errorThrown = false; - } finally { - if (errorThrown) { - // The closer for wrapper i threw an error; close the remaining - // wrappers but silence any exceptions from them to ensure that the - // first error is the one to bubble up. - try { - this.closeAll(i + 1); - } catch (e) {} - } - } - } - this.wrapperInitData.length = 0; - } -}; - -module.exports = TransactionImpl; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 39 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * Based on the escape-html library, which is used under the MIT License below: - * - * Copyright (c) 2012-2013 TJ Holowaychuk - * Copyright (c) 2015 Andreas Lubbe - * Copyright (c) 2015 Tiancheng "Timothy" Gu - * - * 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. - * - */ - - - -// code copied and modified from escape-html -/** - * Module variables. - * @private - */ - -var matchHtmlRegExp = /["'&<>]/; - -/** - * Escape special characters in the given string of html. - * - * @param {string} string The string to escape for inserting into HTML - * @return {string} - * @public - */ - -function escapeHtml(string) { - var str = '' + string; - var match = matchHtmlRegExp.exec(str); - - if (!match) { - return str; - } - - var escape; - var html = ''; - var index = 0; - var lastIndex = 0; - - for (index = match.index; index < str.length; index++) { - switch (str.charCodeAt(index)) { - case 34: - // " - escape = '"'; - break; - case 38: - // & - escape = '&'; - break; - case 39: - // ' - escape = '''; // modified from escape-html; used to be ''' - break; - case 60: - // < - escape = '<'; - break; - case 62: - // > - escape = '>'; - break; - default: - continue; - } - - if (lastIndex !== index) { - html += str.substring(lastIndex, index); - } - - lastIndex = index + 1; - html += escape; - } - - return lastIndex !== index ? html + str.substring(lastIndex, index) : html; -} -// end code copied and modified from escape-html - - -/** - * Escapes text to prevent scripting attacks. - * - * @param {*} text Text value to escape. - * @return {string} An escaped string. - */ -function escapeTextContentForBrowser(text) { - if (typeof text === 'boolean' || typeof text === 'number') { - // this shortcircuit helps perf for types that we know will never have - // special characters, especially given that this function is used often - // for numeric dom ids. - return '' + text; - } - return escapeHtml(text); -} - -module.exports = escapeTextContentForBrowser; - -/***/ }), -/* 40 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ExecutionEnvironment = __webpack_require__(8); -var DOMNamespaces = __webpack_require__(47); - -var WHITESPACE_TEST = /^[ \r\n\t\f]/; -var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/; - -var createMicrosoftUnsafeLocalFunction = __webpack_require__(54); - -// SVG temp container for IE lacking innerHTML -var reusableSVGContainer; - -/** - * Set the innerHTML property of a node, ensuring that whitespace is preserved - * even in IE8. - * - * @param {DOMElement} node - * @param {string} html - * @internal - */ -var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) { - // IE does not have innerHTML for SVG nodes, so instead we inject the - // new markup in a temp node and then move the child nodes across into - // the target node - if (node.namespaceURI === DOMNamespaces.svg && !('innerHTML' in node)) { - reusableSVGContainer = reusableSVGContainer || document.createElement('div'); - reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>'; - var svgNode = reusableSVGContainer.firstChild; - while (svgNode.firstChild) { - node.appendChild(svgNode.firstChild); - } - } else { - node.innerHTML = html; - } -}); - -if (ExecutionEnvironment.canUseDOM) { - // IE8: When updating a just created node with innerHTML only leading - // whitespace is removed. When updating an existing node with innerHTML - // whitespace in root TextNodes is also collapsed. - // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html - - // Feature detection; only IE8 is known to behave improperly like this. - var testElement = document.createElement('div'); - testElement.innerHTML = ' '; - if (testElement.innerHTML === '') { - setInnerHTML = function (node, html) { - // Magic theory: IE8 supposedly differentiates between added and updated - // nodes when processing innerHTML, innerHTML on updated nodes suffers - // from worse whitespace behavior. Re-adding a node like this triggers - // the initial and more favorable whitespace behavior. - // TODO: What to do on a detached node? - if (node.parentNode) { - node.parentNode.replaceChild(node, node); - } - - // We also implement a workaround for non-visible tags disappearing into - // thin air on IE8, this only happens if there is no visible text - // in-front of the non-visible tags. Piggyback on the whitespace fix - // and simply check if any non-visible tags appear in the source. - if (WHITESPACE_TEST.test(html) || html[0] === '<' && NONVISIBLE_TEST.test(html)) { - // Recover leading whitespace by temporarily prepending any character. - // \uFEFF has the potential advantage of being zero-width/invisible. - // UglifyJS drops U+FEFF chars when parsing, so use String.fromCharCode - // in hopes that this is preserved even if "\uFEFF" is transformed to - // the actual Unicode character (by Babel, for example). - // https://github.com/mishoo/UglifyJS2/blob/v2.4.20/lib/parse.js#L216 - node.innerHTML = String.fromCharCode(0xFEFF) + html; - - // deleteData leaves an empty `TextNode` which offsets the index of all - // children. Definitely want to avoid this. - var textNode = node.firstChild; - if (textNode.data.length === 1) { - node.removeChild(textNode); - } else { - textNode.deleteData(0, 1); - } - } else { - node.innerHTML = html; - } - }; - } - testElement = null; -} - -module.exports = setInnerHTML; - -/***/ }), -/* 41 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * This is an ordered list of all sections used in the Bezier primer. - * - * The ordering you see here reflects the ordering in which sections - * are present on the Primer page: do not change them unless there is - * a REALLY good reason to =) - * - */ -module.exports = { - preface: __webpack_require__(192), - - // the basic topic(s) introduction(s) - introduction: __webpack_require__(179), - whatis: __webpack_require__(206), - explanation: __webpack_require__(165), - control: __webpack_require__(158), - extended: __webpack_require__(167), - - // basic operations - matrix: __webpack_require__(180), - decasteljau: __webpack_require__(162), - flattening: __webpack_require__(171), - splitting: __webpack_require__(200), - matrixsplit: __webpack_require__(181), - reordering: __webpack_require__(196), - - // information that can be obtained through analysis - derivatives: __webpack_require__(163), - pointvectors: __webpack_require__(189), - components: __webpack_require__(156), - extremities: __webpack_require__(169), - boundingbox: __webpack_require__(135), - aligning: __webpack_require__(127), - tightbounds: __webpack_require__(202), - inflections: __webpack_require__(175), - canonical: __webpack_require__(145), - - // accurate arc length is hard, yo - arclength: __webpack_require__(131), - arclengthapprox: __webpack_require__(133), - tracing: __webpack_require__(204), - - // curve intersections - intersections: __webpack_require__(177), - curveintersection: __webpack_require__(160), - - // curve manipulation - abc: __webpack_require__(125), - moulding: __webpack_require__(183), - pointcurves: __webpack_require__(187), - - // A quick foray into Catmull-Rom splines - catmullconv: __webpack_require__(146), - catmullmoulding: __webpack_require__(148), - - // "things made of more than on curve" - polybezier: __webpack_require__(191), - shapes: __webpack_require__(198), - - // curve offsetting - projections: __webpack_require__(194), - offsetting: __webpack_require__(185), - graduatedoffset: __webpack_require__(173), - - // circle and arc approximation - circles: __webpack_require__(150), - circles_cubic: __webpack_require__(152), - arcapproximation: __webpack_require__(129), - - // A quick foray in to B-Spline land - bsplines: __webpack_require__(139), - - // comments come last for obvious reasons - comments: __webpack_require__(154) -}; - -/***/ }), -/* 42 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - * - */ - -/*eslint-disable no-self-compare */ - - - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -/** - * inlined Object.is polyfill to avoid requiring consumers ship their own - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is - */ -function is(x, y) { - // SameValue algorithm - if (x === y) { - // Steps 1-5, 7-10 - // Steps 6.b-6.e: +0 != -0 - // Added the nonzero y check to make Flow happy, but it is redundant - return x !== 0 || y !== 0 || 1 / x === 1 / y; - } else { - // Step 6.a: NaN == NaN - return x !== x && y !== y; - } -} - -/** - * Performs equality by iterating through keys on an object and returning false - * when any key has values which are not strictly equal between the arguments. - * Returns true when the values of all keys are strictly equal. - */ -function shallowEqual(objA, objB) { - if (is(objA, objB)) { - return true; - } - - if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { - return false; - } - - var keysA = Object.keys(objA); - var keysB = Object.keys(objB); - - if (keysA.length !== keysB.length) { - return false; - } - - // Test for A's keys different from B. - for (var i = 0; i < keysA.length; i++) { - if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { - return false; - } - } - - return true; -} - -module.exports = shallowEqual; - -/***/ }), -/* 43 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); -exports.canUseDOM = canUseDOM; - -/***/ }), -/* 44 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -//import warning from 'warning' - - - -exports.__esModule = true; -function deprecate(fn) { - return fn; - //return function () { - // warning(false, '[history] ' + message) - // return fn.apply(this, arguments) - //} -} - -exports["default"] = deprecate; -module.exports = exports["default"]; - -/***/ }), -/* 45 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -function runTransitionHook(hook, location, callback) { - var result = hook(location, callback); - - if (hook.length < 2) { - // Assume the hook runs synchronously and automatically - // call the callback with the return value. - callback(result); - } else { - process.env.NODE_ENV !== 'production' ? _warning2['default'](result === undefined, 'You should not "return" in a transition hook with a callback argument; call the callback instead') : undefined; - } -} - -exports['default'] = runTransitionHook; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 46 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMLazyTree = __webpack_require__(25); -var Danger = __webpack_require__(243); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactInstrumentation = __webpack_require__(10); - -var createMicrosoftUnsafeLocalFunction = __webpack_require__(54); -var setInnerHTML = __webpack_require__(40); -var setTextContent = __webpack_require__(97); - -function getNodeAfter(parentNode, node) { - // Special case for text components, which return [open, close] comments - // from getHostNode. - if (Array.isArray(node)) { - node = node[1]; - } - return node ? node.nextSibling : parentNode.firstChild; -} - -/** - * Inserts `childNode` as a child of `parentNode` at the `index`. - * - * @param {DOMElement} parentNode Parent node in which to insert. - * @param {DOMElement} childNode Child node to insert. - * @param {number} index Index at which to insert the child. - * @internal - */ -var insertChildAt = createMicrosoftUnsafeLocalFunction(function (parentNode, childNode, referenceNode) { - // We rely exclusively on `insertBefore(node, null)` instead of also using - // `appendChild(node)`. (Using `undefined` is not allowed by all browsers so - // we are careful to use `null`.) - parentNode.insertBefore(childNode, referenceNode); -}); - -function insertLazyTreeChildAt(parentNode, childTree, referenceNode) { - DOMLazyTree.insertTreeBefore(parentNode, childTree, referenceNode); -} - -function moveChild(parentNode, childNode, referenceNode) { - if (Array.isArray(childNode)) { - moveDelimitedText(parentNode, childNode[0], childNode[1], referenceNode); - } else { - insertChildAt(parentNode, childNode, referenceNode); - } -} - -function removeChild(parentNode, childNode) { - if (Array.isArray(childNode)) { - var closingComment = childNode[1]; - childNode = childNode[0]; - removeDelimitedText(parentNode, childNode, closingComment); - parentNode.removeChild(closingComment); - } - parentNode.removeChild(childNode); -} - -function moveDelimitedText(parentNode, openingComment, closingComment, referenceNode) { - var node = openingComment; - while (true) { - var nextNode = node.nextSibling; - insertChildAt(parentNode, node, referenceNode); - if (node === closingComment) { - break; - } - node = nextNode; - } -} - -function removeDelimitedText(parentNode, startNode, closingComment) { - while (true) { - var node = startNode.nextSibling; - if (node === closingComment) { - // The closing comment is removed by ReactMultiChild. - break; - } else { - parentNode.removeChild(node); - } - } -} - -function replaceDelimitedText(openingComment, closingComment, stringText) { - var parentNode = openingComment.parentNode; - var nodeAfterComment = openingComment.nextSibling; - if (nodeAfterComment === closingComment) { - // There are no text nodes between the opening and closing comments; insert - // a new one if stringText isn't empty. - if (stringText) { - insertChildAt(parentNode, document.createTextNode(stringText), nodeAfterComment); - } - } else { - if (stringText) { - // Set the text content of the first node after the opening comment, and - // remove all following nodes up until the closing comment. - setTextContent(nodeAfterComment, stringText); - removeDelimitedText(parentNode, nodeAfterComment, closingComment); - } else { - removeDelimitedText(parentNode, openingComment, closingComment); - } - } - - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: ReactDOMComponentTree.getInstanceFromNode(openingComment)._debugID, - type: 'replace text', - payload: stringText - }); - } -} - -var dangerouslyReplaceNodeWithMarkup = Danger.dangerouslyReplaceNodeWithMarkup; -if (process.env.NODE_ENV !== 'production') { - dangerouslyReplaceNodeWithMarkup = function (oldChild, markup, prevInstance) { - Danger.dangerouslyReplaceNodeWithMarkup(oldChild, markup); - if (prevInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: prevInstance._debugID, - type: 'replace with', - payload: markup.toString() - }); - } else { - var nextInstance = ReactDOMComponentTree.getInstanceFromNode(markup.node); - if (nextInstance._debugID !== 0) { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: nextInstance._debugID, - type: 'mount', - payload: markup.toString() - }); - } - } - }; -} - -/** - * Operations for updating with DOM children. - */ -var DOMChildrenOperations = { - - dangerouslyReplaceNodeWithMarkup: dangerouslyReplaceNodeWithMarkup, - - replaceDelimitedText: replaceDelimitedText, - - /** - * Updates a component's children by processing a series of updates. The - * update configurations are each expected to have a `parentNode` property. - * - * @param {array<object>} updates List of update configurations. - * @internal - */ - processUpdates: function (parentNode, updates) { - if (process.env.NODE_ENV !== 'production') { - var parentNodeDebugID = ReactDOMComponentTree.getInstanceFromNode(parentNode)._debugID; - } - - for (var k = 0; k < updates.length; k++) { - var update = updates[k]; - switch (update.type) { - case 'INSERT_MARKUP': - insertLazyTreeChildAt(parentNode, update.content, getNodeAfter(parentNode, update.afterNode)); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: parentNodeDebugID, - type: 'insert child', - payload: { toIndex: update.toIndex, content: update.content.toString() } - }); - } - break; - case 'MOVE_EXISTING': - moveChild(parentNode, update.fromNode, getNodeAfter(parentNode, update.afterNode)); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: parentNodeDebugID, - type: 'move child', - payload: { fromIndex: update.fromIndex, toIndex: update.toIndex } - }); - } - break; - case 'SET_MARKUP': - setInnerHTML(parentNode, update.content); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: parentNodeDebugID, - type: 'replace children', - payload: update.content.toString() - }); - } - break; - case 'TEXT_CONTENT': - setTextContent(parentNode, update.content); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: parentNodeDebugID, - type: 'replace text', - payload: update.content.toString() - }); - } - break; - case 'REMOVE_NODE': - removeChild(parentNode, update.fromNode); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: parentNodeDebugID, - type: 'remove child', - payload: { fromIndex: update.fromIndex } - }); - } - break; - } - } - } - -}; - -module.exports = DOMChildrenOperations; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 47 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMNamespaces = { - html: 'http://www.w3.org/1999/xhtml', - mathml: 'http://www.w3.org/1998/Math/MathML', - svg: 'http://www.w3.org/2000/svg' -}; - -module.exports = DOMNamespaces; - -/***/ }), -/* 48 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var ReactErrorUtils = __webpack_require__(52); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -/** - * Injected dependencies: - */ - -/** - * - `ComponentTree`: [required] Module that can convert between React instances - * and actual node references. - */ -var ComponentTree; -var TreeTraversal; -var injection = { - injectComponentTree: function (Injected) { - ComponentTree = Injected; - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(Injected && Injected.getNodeFromInstance && Injected.getInstanceFromNode, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0; - } - }, - injectTreeTraversal: function (Injected) { - TreeTraversal = Injected; - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(Injected && Injected.isAncestor && Injected.getLowestCommonAncestor, 'EventPluginUtils.injection.injectTreeTraversal(...): Injected ' + 'module is missing isAncestor or getLowestCommonAncestor.') : void 0; - } - } -}; - -function isEndish(topLevelType) { - return topLevelType === 'topMouseUp' || topLevelType === 'topTouchEnd' || topLevelType === 'topTouchCancel'; -} - -function isMoveish(topLevelType) { - return topLevelType === 'topMouseMove' || topLevelType === 'topTouchMove'; -} -function isStartish(topLevelType) { - return topLevelType === 'topMouseDown' || topLevelType === 'topTouchStart'; -} - -var validateEventDispatches; -if (process.env.NODE_ENV !== 'production') { - validateEventDispatches = function (event) { - var dispatchListeners = event._dispatchListeners; - var dispatchInstances = event._dispatchInstances; - - var listenersIsArr = Array.isArray(dispatchListeners); - var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; - - var instancesIsArr = Array.isArray(dispatchInstances); - var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0; - - process.env.NODE_ENV !== 'production' ? warning(instancesIsArr === listenersIsArr && instancesLen === listenersLen, 'EventPluginUtils: Invalid `event`.') : void 0; - }; -} - -/** - * Dispatch the event to the listener. - * @param {SyntheticEvent} event SyntheticEvent to handle - * @param {boolean} simulated If the event is simulated (changes exn behavior) - * @param {function} listener Application-level callback - * @param {*} inst Internal component instance - */ -function executeDispatch(event, simulated, listener, inst) { - var type = event.type || 'unknown-event'; - event.currentTarget = EventPluginUtils.getNodeFromInstance(inst); - if (simulated) { - ReactErrorUtils.invokeGuardedCallbackWithCatch(type, listener, event); - } else { - ReactErrorUtils.invokeGuardedCallback(type, listener, event); - } - event.currentTarget = null; -} - -/** - * Standard/simple iteration through an event's collected dispatches. - */ -function executeDispatchesInOrder(event, simulated) { - var dispatchListeners = event._dispatchListeners; - var dispatchInstances = event._dispatchInstances; - if (process.env.NODE_ENV !== 'production') { - validateEventDispatches(event); - } - if (Array.isArray(dispatchListeners)) { - for (var i = 0; i < dispatchListeners.length; i++) { - if (event.isPropagationStopped()) { - break; - } - // Listeners and Instances are two parallel arrays that are always in sync. - executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]); - } - } else if (dispatchListeners) { - executeDispatch(event, simulated, dispatchListeners, dispatchInstances); - } - event._dispatchListeners = null; - event._dispatchInstances = null; -} - -/** - * Standard/simple iteration through an event's collected dispatches, but stops - * at the first dispatch execution returning true, and returns that id. - * - * @return {?string} id of the first dispatch execution who's listener returns - * true, or null if no listener returned true. - */ -function executeDispatchesInOrderStopAtTrueImpl(event) { - var dispatchListeners = event._dispatchListeners; - var dispatchInstances = event._dispatchInstances; - if (process.env.NODE_ENV !== 'production') { - validateEventDispatches(event); - } - if (Array.isArray(dispatchListeners)) { - for (var i = 0; i < dispatchListeners.length; i++) { - if (event.isPropagationStopped()) { - break; - } - // Listeners and Instances are two parallel arrays that are always in sync. - if (dispatchListeners[i](event, dispatchInstances[i])) { - return dispatchInstances[i]; - } - } - } else if (dispatchListeners) { - if (dispatchListeners(event, dispatchInstances)) { - return dispatchInstances; - } - } - return null; -} - -/** - * @see executeDispatchesInOrderStopAtTrueImpl - */ -function executeDispatchesInOrderStopAtTrue(event) { - var ret = executeDispatchesInOrderStopAtTrueImpl(event); - event._dispatchInstances = null; - event._dispatchListeners = null; - return ret; -} - -/** - * Execution of a "direct" dispatch - there must be at most one dispatch - * accumulated on the event or it is considered an error. It doesn't really make - * sense for an event with multiple dispatches (bubbled) to keep track of the - * return values at each dispatch execution, but it does tend to make sense when - * dealing with "direct" dispatches. - * - * @return {*} The return value of executing the single dispatch. - */ -function executeDirectDispatch(event) { - if (process.env.NODE_ENV !== 'production') { - validateEventDispatches(event); - } - var dispatchListener = event._dispatchListeners; - var dispatchInstance = event._dispatchInstances; - !!Array.isArray(dispatchListener) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : _prodInvariant('103') : void 0; - event.currentTarget = dispatchListener ? EventPluginUtils.getNodeFromInstance(dispatchInstance) : null; - var res = dispatchListener ? dispatchListener(event) : null; - event.currentTarget = null; - event._dispatchListeners = null; - event._dispatchInstances = null; - return res; -} - -/** - * @param {SyntheticEvent} event - * @return {boolean} True iff number of dispatches accumulated is greater than 0. - */ -function hasDispatches(event) { - return !!event._dispatchListeners; -} - -/** - * General utilities that are useful in creating custom Event Plugins. - */ -var EventPluginUtils = { - isEndish: isEndish, - isMoveish: isMoveish, - isStartish: isStartish, - - executeDirectDispatch: executeDirectDispatch, - executeDispatchesInOrder: executeDispatchesInOrder, - executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, - hasDispatches: hasDispatches, - - getInstanceFromNode: function (node) { - return ComponentTree.getInstanceFromNode(node); - }, - getNodeFromInstance: function (node) { - return ComponentTree.getNodeFromInstance(node); - }, - isAncestor: function (a, b) { - return TreeTraversal.isAncestor(a, b); - }, - getLowestCommonAncestor: function (a, b) { - return TreeTraversal.getLowestCommonAncestor(a, b); - }, - getParentInstance: function (inst) { - return TreeTraversal.getParentInstance(inst); - }, - traverseTwoPhase: function (target, fn, arg) { - return TreeTraversal.traverseTwoPhase(target, fn, arg); - }, - traverseEnterLeave: function (from, to, fn, argFrom, argTo) { - return TreeTraversal.traverseEnterLeave(from, to, fn, argFrom, argTo); - }, - - injection: injection -}; - -module.exports = EventPluginUtils; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 49 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/** - * Escape and wrap key so it is safe to use as a reactid - * - * @param {string} key to be escaped. - * @return {string} the escaped key. - */ - -function escape(key) { - var escapeRegex = /[=:]/g; - var escaperLookup = { - '=': '=0', - ':': '=2' - }; - var escapedString = ('' + key).replace(escapeRegex, function (match) { - return escaperLookup[match]; - }); - - return '$' + escapedString; -} - -/** - * Unescape and unwrap key for human-readable display - * - * @param {string} key to unescape. - * @return {string} the unescaped key. - */ -function unescape(key) { - var unescapeRegex = /(=0|=2)/g; - var unescaperLookup = { - '=0': '=', - '=2': ':' - }; - var keySubstring = key[0] === '.' && key[1] === '$' ? key.substring(2) : key.substring(1); - - return ('' + keySubstring).replace(unescapeRegex, function (match) { - return unescaperLookup[match]; - }); -} - -var KeyEscapeUtils = { - escape: escape, - unescape: unescape -}; - -module.exports = KeyEscapeUtils; - -/***/ }), -/* 50 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var React = __webpack_require__(27); -var ReactPropTypesSecret = __webpack_require__(89); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -var hasReadOnlyValue = { - 'button': true, - 'checkbox': true, - 'image': true, - 'hidden': true, - 'radio': true, - 'reset': true, - 'submit': true -}; - -function _assertSingleLink(inputProps) { - !(inputProps.checkedLink == null || inputProps.valueLink == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a valueLink. If you want to use checkedLink, you probably don\'t want to use valueLink and vice versa.') : _prodInvariant('87') : void 0; -} -function _assertValueLink(inputProps) { - _assertSingleLink(inputProps); - !(inputProps.value == null && inputProps.onChange == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a valueLink and a value or onChange event. If you want to use value or onChange, you probably don\'t want to use valueLink.') : _prodInvariant('88') : void 0; -} - -function _assertCheckedLink(inputProps) { - _assertSingleLink(inputProps); - !(inputProps.checked == null && inputProps.onChange == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a checked property or onChange event. If you want to use checked or onChange, you probably don\'t want to use checkedLink') : _prodInvariant('89') : void 0; -} - -var propTypes = { - value: function (props, propName, componentName) { - if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) { - return null; - } - return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); - }, - checked: function (props, propName, componentName) { - if (!props[propName] || props.onChange || props.readOnly || props.disabled) { - return null; - } - return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); - }, - onChange: React.PropTypes.func -}; - -var loggedTypeFailures = {}; -function getDeclarationErrorAddendum(owner) { - if (owner) { - var name = owner.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -/** - * Provide a linked `value` attribute for controlled forms. You should not use - * this outside of the ReactDOM controlled form components. - */ -var LinkedValueUtils = { - checkPropTypes: function (tagName, props, owner) { - for (var propName in propTypes) { - if (propTypes.hasOwnProperty(propName)) { - var error = propTypes[propName](props, propName, tagName, 'prop', null, ReactPropTypesSecret); - } - if (error instanceof Error && !(error.message in loggedTypeFailures)) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error.message] = true; - - var addendum = getDeclarationErrorAddendum(owner); - process.env.NODE_ENV !== 'production' ? warning(false, 'Failed form propType: %s%s', error.message, addendum) : void 0; - } - } - }, - - /** - * @param {object} inputProps Props for form component - * @return {*} current value of the input either from value prop or link. - */ - getValue: function (inputProps) { - if (inputProps.valueLink) { - _assertValueLink(inputProps); - return inputProps.valueLink.value; - } - return inputProps.value; - }, - - /** - * @param {object} inputProps Props for form component - * @return {*} current checked status of the input either from checked prop - * or link. - */ - getChecked: function (inputProps) { - if (inputProps.checkedLink) { - _assertCheckedLink(inputProps); - return inputProps.checkedLink.value; - } - return inputProps.checked; - }, - - /** - * @param {object} inputProps Props for form component - * @param {SyntheticEvent} event change event to handle - */ - executeOnChange: function (inputProps, event) { - if (inputProps.valueLink) { - _assertValueLink(inputProps); - return inputProps.valueLink.requestChange(event.target.value); - } else if (inputProps.checkedLink) { - _assertCheckedLink(inputProps); - return inputProps.checkedLink.requestChange(event.target.checked); - } else if (inputProps.onChange) { - return inputProps.onChange.call(undefined, event); - } - } -}; - -module.exports = LinkedValueUtils; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 51 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -var injected = false; - -var ReactComponentEnvironment = { - - /** - * Optionally injectable hook for swapping out mount images in the middle of - * the tree. - */ - replaceNodeWithMarkup: null, - - /** - * Optionally injectable hook for processing a queue of child updates. Will - * later move into MultiChildComponents. - */ - processChildrenUpdates: null, - - injection: { - injectEnvironment: function (environment) { - !!injected ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactCompositeComponent: injectEnvironment() can only be called once.') : _prodInvariant('104') : void 0; - ReactComponentEnvironment.replaceNodeWithMarkup = environment.replaceNodeWithMarkup; - ReactComponentEnvironment.processChildrenUpdates = environment.processChildrenUpdates; - injected = true; - } - } - -}; - -module.exports = ReactComponentEnvironment; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 52 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var caughtError = null; - -/** - * Call a function while guarding against errors that happens within it. - * - * @param {String} name of the guard to use for logging or debugging - * @param {Function} func The function to invoke - * @param {*} a First argument - * @param {*} b Second argument - */ -function invokeGuardedCallback(name, func, a) { - try { - func(a); - } catch (x) { - if (caughtError === null) { - caughtError = x; - } - } -} - -var ReactErrorUtils = { - invokeGuardedCallback: invokeGuardedCallback, - - /** - * Invoked by ReactTestUtils.Simulate so that any errors thrown by the event - * handler are sure to be rethrown by rethrowCaughtError. - */ - invokeGuardedCallbackWithCatch: invokeGuardedCallback, - - /** - * During execution of guarded functions we will capture the first error which - * we will rethrow to be handled by the top level error handler. - */ - rethrowCaughtError: function () { - if (caughtError) { - var error = caughtError; - caughtError = null; - throw error; - } - } -}; - -if (process.env.NODE_ENV !== 'production') { - /** - * To help development we can get better devtools integration by simulating a - * real browser event. - */ - if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') { - var fakeNode = document.createElement('react'); - ReactErrorUtils.invokeGuardedCallback = function (name, func, a) { - var boundFunc = func.bind(null, a); - var evtType = 'react-' + name; - fakeNode.addEventListener(evtType, boundFunc, false); - var evt = document.createEvent('Event'); - // $FlowFixMe https://github.com/facebook/flow/issues/2336 - evt.initEvent(evtType, false, false); - fakeNode.dispatchEvent(evt); - fakeNode.removeEventListener(evtType, boundFunc, false); - }; - } -} - -module.exports = ReactErrorUtils; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 53 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var ReactCurrentOwner = __webpack_require__(15); -var ReactInstanceMap = __webpack_require__(32); -var ReactInstrumentation = __webpack_require__(10); -var ReactUpdates = __webpack_require__(14); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -function enqueueUpdate(internalInstance) { - ReactUpdates.enqueueUpdate(internalInstance); -} - -function formatUnexpectedArgument(arg) { - var type = typeof arg; - if (type !== 'object') { - return type; - } - var displayName = arg.constructor && arg.constructor.name || type; - var keys = Object.keys(arg); - if (keys.length > 0 && keys.length < 20) { - return displayName + ' (keys: ' + keys.join(', ') + ')'; - } - return displayName; -} - -function getInternalInstanceReadyForUpdate(publicInstance, callerName) { - var internalInstance = ReactInstanceMap.get(publicInstance); - if (!internalInstance) { - if (process.env.NODE_ENV !== 'production') { - var ctor = publicInstance.constructor; - // Only warn when we have a callerName. Otherwise we should be silent. - // We're probably calling from enqueueCallback. We don't want to warn - // there because we already warned for the corresponding lifecycle method. - process.env.NODE_ENV !== 'production' ? warning(!callerName, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, ctor && (ctor.displayName || ctor.name) || 'ReactClass') : void 0; - } - return null; - } - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, '%s(...): Cannot update during an existing state transition (such as ' + 'within `render` or another component\'s constructor). Render methods ' + 'should be a pure function of props and state; constructor ' + 'side-effects are an anti-pattern, but can be moved to ' + '`componentWillMount`.', callerName) : void 0; - } - - return internalInstance; -} - -/** - * ReactUpdateQueue allows for state updates to be scheduled into a later - * reconciliation step. - */ -var ReactUpdateQueue = { - - /** - * Checks whether or not this composite component is mounted. - * @param {ReactClass} publicInstance The instance we want to test. - * @return {boolean} True if mounted, false otherwise. - * @protected - * @final - */ - isMounted: function (publicInstance) { - if (process.env.NODE_ENV !== 'production') { - var owner = ReactCurrentOwner.current; - if (owner !== null) { - process.env.NODE_ENV !== 'production' ? warning(owner._warnedAboutRefsInRender, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : void 0; - owner._warnedAboutRefsInRender = true; - } - } - var internalInstance = ReactInstanceMap.get(publicInstance); - if (internalInstance) { - // During componentWillMount and render this will still be null but after - // that will always render to something. At least for now. So we can use - // this hack. - return !!internalInstance._renderedComponent; - } else { - return false; - } - }, - - /** - * Enqueue a callback that will be executed after all the pending updates - * have processed. - * - * @param {ReactClass} publicInstance The instance to use as `this` context. - * @param {?function} callback Called after state is updated. - * @param {string} callerName Name of the calling function in the public API. - * @internal - */ - enqueueCallback: function (publicInstance, callback, callerName) { - ReactUpdateQueue.validateCallback(callback, callerName); - var internalInstance = getInternalInstanceReadyForUpdate(publicInstance); - - // Previously we would throw an error if we didn't have an internal - // instance. Since we want to make it a no-op instead, we mirror the same - // behavior we have in other enqueue* methods. - // We also need to ignore callbacks in componentWillMount. See - // enqueueUpdates. - if (!internalInstance) { - return null; - } - - if (internalInstance._pendingCallbacks) { - internalInstance._pendingCallbacks.push(callback); - } else { - internalInstance._pendingCallbacks = [callback]; - } - // TODO: The callback here is ignored when setState is called from - // componentWillMount. Either fix it or disallow doing so completely in - // favor of getInitialState. Alternatively, we can disallow - // componentWillMount during server-side rendering. - enqueueUpdate(internalInstance); - }, - - enqueueCallbackInternal: function (internalInstance, callback) { - if (internalInstance._pendingCallbacks) { - internalInstance._pendingCallbacks.push(callback); - } else { - internalInstance._pendingCallbacks = [callback]; - } - enqueueUpdate(internalInstance); - }, - - /** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldComponentUpdate`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @internal - */ - enqueueForceUpdate: function (publicInstance) { - var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'forceUpdate'); - - if (!internalInstance) { - return; - } - - internalInstance._pendingForceUpdate = true; - - enqueueUpdate(internalInstance); - }, - - /** - * Replaces all of the state. Always use this or `setState` to mutate state. - * You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} completeState Next state. - * @internal - */ - enqueueReplaceState: function (publicInstance, completeState) { - var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'replaceState'); - - if (!internalInstance) { - return; - } - - internalInstance._pendingStateQueue = [completeState]; - internalInstance._pendingReplaceState = true; - - enqueueUpdate(internalInstance); - }, - - /** - * Sets a subset of the state. This only exists because _pendingState is - * internal. This provides a merging strategy that is not available to deep - * properties which is confusing. TODO: Expose pendingState or don't use it - * during the merge. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} partialState Next partial state to be merged with state. - * @internal - */ - enqueueSetState: function (publicInstance, partialState) { - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onSetState(); - process.env.NODE_ENV !== 'production' ? warning(partialState != null, 'setState(...): You passed an undefined or null state object; ' + 'instead, use forceUpdate().') : void 0; - } - - var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState'); - - if (!internalInstance) { - return; - } - - var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []); - queue.push(partialState); - - enqueueUpdate(internalInstance); - }, - - enqueueElementInternal: function (internalInstance, nextElement, nextContext) { - internalInstance._pendingElement = nextElement; - // TODO: introduce _pendingContext instead of setting it directly. - internalInstance._context = nextContext; - enqueueUpdate(internalInstance); - }, - - validateCallback: function (callback, callerName) { - !(!callback || typeof callback === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s(...): Expected the last optional `callback` argument to be a function. Instead received: %s.', callerName, formatUnexpectedArgument(callback)) : _prodInvariant('122', callerName, formatUnexpectedArgument(callback)) : void 0; - } - -}; - -module.exports = ReactUpdateQueue; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 54 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -/* globals MSApp */ - - - -/** - * Create a function which has 'unsafe' privileges (required by windows8 apps) - */ - -var createMicrosoftUnsafeLocalFunction = function (func) { - if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { - return function (arg0, arg1, arg2, arg3) { - MSApp.execUnsafeLocalFunction(function () { - return func(arg0, arg1, arg2, arg3); - }); - }; - } else { - return func; - } -}; - -module.exports = createMicrosoftUnsafeLocalFunction; - -/***/ }), -/* 55 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * `charCode` represents the actual "character code" and is safe to use with - * `String.fromCharCode`. As such, only keys that correspond to printable - * characters produce a valid `charCode`, the only exception to this is Enter. - * The Tab-key is considered non-printable and does not have a `charCode`, - * presumably because it does not produce a tab-character in browsers. - * - * @param {object} nativeEvent Native browser event. - * @return {number} Normalized `charCode` property. - */ - -function getEventCharCode(nativeEvent) { - var charCode; - var keyCode = nativeEvent.keyCode; - - if ('charCode' in nativeEvent) { - charCode = nativeEvent.charCode; - - // FF does not set `charCode` for the Enter-key, check against `keyCode`. - if (charCode === 0 && keyCode === 13) { - charCode = 13; - } - } else { - // IE8 does not implement `charCode`, but `keyCode` has the correct value. - charCode = keyCode; - } - - // Some non-printable keys are reported in `charCode`/`keyCode`, discard them. - // Must not discard the (non-)printable Enter-key. - if (charCode >= 32 || charCode === 13) { - return charCode; - } - - return 0; -} - -module.exports = getEventCharCode; - -/***/ }), -/* 56 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * Translation from modifier key to the associated property in the event. - * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers - */ - -var modifierKeyToProp = { - 'Alt': 'altKey', - 'Control': 'ctrlKey', - 'Meta': 'metaKey', - 'Shift': 'shiftKey' -}; - -// IE8 does not implement getModifierState so we simply map it to the only -// modifier keys exposed by the event itself, does not support Lock-keys. -// Currently, all major browsers except Chrome seems to support Lock-keys. -function modifierStateGetter(keyArg) { - var syntheticEvent = this; - var nativeEvent = syntheticEvent.nativeEvent; - if (nativeEvent.getModifierState) { - return nativeEvent.getModifierState(keyArg); - } - var keyProp = modifierKeyToProp[keyArg]; - return keyProp ? !!nativeEvent[keyProp] : false; -} - -function getEventModifierState(nativeEvent) { - return modifierStateGetter; -} - -module.exports = getEventModifierState; - -/***/ }), -/* 57 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * Gets the target node from a native browser event by accounting for - * inconsistencies in browser DOM APIs. - * - * @param {object} nativeEvent Native browser event. - * @return {DOMEventTarget} Target node. - */ - -function getEventTarget(nativeEvent) { - var target = nativeEvent.target || nativeEvent.srcElement || window; - - // Normalize SVG <use> element events #4963 - if (target.correspondingUseElement) { - target = target.correspondingUseElement; - } - - // Safari may fire events on text nodes (Node.TEXT_NODE is 3). - // @see http://www.quirksmode.org/js/events_properties.html - return target.nodeType === 3 ? target.parentNode : target; -} - -module.exports = getEventTarget; - -/***/ }), -/* 58 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ExecutionEnvironment = __webpack_require__(8); - -var useHasFeature; -if (ExecutionEnvironment.canUseDOM) { - useHasFeature = document.implementation && document.implementation.hasFeature && - // always returns true in newer browsers as per the standard. - // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature - document.implementation.hasFeature('', '') !== true; -} - -/** +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.BezierArticle=t():e.BezierArticle=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=325)}([function(e,t,n){"use strict";var r=n(4),i=n(63),a=new i;e.exports=function(e,t){var n={getDefaultProps:function(){return{title:a.getTitle(e)}},render:function(){return a.getContent(e,this)}};return t&&Object.keys(t).forEach(function(e){n[e]=t[e]}),r.createClass(n)}},function(e,t,n){"use strict";function r(e,t,n,r,a,o,s,l){if(i(t),!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,a,o,s,l],h=0;c=new Error(t.replace(/%s/g,function(){return u[h++]})),c.name="Invariant Violation"}throw c.framesToPop=1,c}}var i=function(e){};e.exports=r},function(e,t,n){"use strict";var r=n(9),i=r;e.exports=i},function(e,t,n){"use strict";function r(e){for(var t=arguments.length-1,n="Minified React error #"+e+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant="+e,r=0;r<t;r++)n+="&args[]="+encodeURIComponent(arguments[r+1]);n+=" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.";var i=new Error(n);throw i.name="Invariant Violation",i.framesToPop=1,i}e.exports=r},function(e,t,n){"use strict";e.exports=n(23)},function(e,t,n){"use strict";function r(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}function i(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;var r=Object.getOwnPropertyNames(t).map(function(e){return t[e]});if("0123456789"!==r.join(""))return!1;var i={};return"abcdefghijklmnopqrst".split("").forEach(function(e){i[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},i)).join("")}catch(e){return!1}}var a=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable;e.exports=i()?Object.assign:function(e,t){for(var n,i,s=r(e),l=1;l<arguments.length;l++){n=Object(arguments[l]);for(var c in n)a.call(n,c)&&(s[c]=n[c]);if(Object.getOwnPropertySymbols){i=Object.getOwnPropertySymbols(n);for(var u=0;u<i.length;u++)o.call(n,i[u])&&(s[i[u]]=n[i[u]])}}return s}},function(e,t,n){"use strict";function r(e,t){return 1===e.nodeType&&e.getAttribute(p)===String(t)||8===e.nodeType&&e.nodeValue===" react-text: "+t+" "||8===e.nodeType&&e.nodeValue===" react-empty: "+t+" "}function i(e){for(var t;t=e._renderedComponent;)e=t;return e}function a(e,t){var n=i(e);n._hostNode=t,t[g]=n}function o(e){var t=e._hostNode;t&&(delete t[g],e._hostNode=null)}function s(e,t){if(!(e._flags&m.hasCachedChildNodes)){var n=e._renderedChildren,o=t.firstChild;e:for(var s in n)if(n.hasOwnProperty(s)){var l=n[s],c=i(l)._domID;if(0!==c){for(;null!==o;o=o.nextSibling)if(r(o,c)){a(l,o);continue e}h("32",c)}}e._flags|=m.hasCachedChildNodes}}function l(e){if(e[g])return e[g];for(var t=[];!e[g];){if(t.push(e),!e.parentNode)return null;e=e.parentNode}for(var n,r;e&&(r=e[g]);e=t.pop())n=r,t.length&&s(r,e);return n}function c(e){var t=l(e);return null!=t&&t._hostNode===e?t:null}function u(e){if(void 0===e._hostNode?h("33"):void 0,e._hostNode)return e._hostNode;for(var t=[];!e._hostNode;)t.push(e),e._hostParent?void 0:h("34"),e=e._hostParent;for(;t.length;e=t.pop())s(e,e._hostNode);return e._hostNode}var h=n(3),d=n(21),f=n(77),p=(n(1),d.ID_ATTRIBUTE_NAME),m=f,g="__reactInternalInstance$"+Math.random().toString(36).slice(2),v={getClosestInstanceFromNode:l,getInstanceFromNode:c,getNodeFromInstance:u,precacheChildNodes:s,precacheNode:a,uncacheNode:o};e.exports=v},function(e,t,n){"use strict";var r=!("undefined"==typeof window||!window.document||!window.document.createElement),i={canUseDOM:r,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:r&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:r&&!!window.screen,isInWorker:!r};e.exports=i},function(e,t,n){"use strict";var r=function(){};e.exports=r},function(e,t,n){"use strict";function r(e){return function(){return e}}var i=function(){};i.thatReturns=r,i.thatReturnsFalse=r(!1),i.thatReturnsTrue=r(!0),i.thatReturnsNull=r(null),i.thatReturnsThis=function(){return this},i.thatReturnsArgument=function(e){return e},e.exports=i},function(e,t,n){"use strict";var r=function(e,t,n,r,i,a,o,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,i,a,o,s],u=0;l=new Error(t.replace(/%s/g,function(){return c[u++]})),l.name="Invariant Violation"}throw l.framesToPop=1,l}};e.exports=r},function(e,t,n){"use strict";var r=null;e.exports={debugTool:r}},function(e,t,n){"use strict";function r(){P.ReactReconcileTransaction&&_?void 0:u("123")}function i(){this.reinitializeTransaction(),this.dirtyComponentsLength=null,this.callbackQueue=d.getPooled(),this.reconcileTransaction=P.ReactReconcileTransaction.getPooled(!0)}function a(e,t,n,i,a,o){return r(),_.batchedUpdates(e,t,n,i,a,o)}function o(e,t){return e._mountOrder-t._mountOrder}function s(e){var t=e.dirtyComponentsLength;t!==v.length?u("124",t,v.length):void 0,v.sort(o),w++;for(var n=0;n<t;n++){var r=v[n],i=r._pendingCallbacks;r._pendingCallbacks=null;var a;if(p.logTopLevelRenders){var s=r;r._currentElement.type.isReactTopLevelWrapper&&(s=r._renderedComponent),a="React update: "+s.getName(),console.time(a)}if(m.performUpdateIfNecessary(r,e.reconcileTransaction,w),a&&console.timeEnd(a),i)for(var l=0;l<i.length;l++)e.callbackQueue.enqueue(i[l],r.getPublicInstance())}}function l(e){return r(),_.isBatchingUpdates?(v.push(e),void(null==e._updateBatchNumber&&(e._updateBatchNumber=w+1))):void _.batchedUpdates(l,e)}function c(e,t){_.isBatchingUpdates?void 0:u("125"),y.enqueue(e,t),b=!0}var u=n(3),h=n(5),d=n(75),f=n(17),p=n(80),m=n(22),g=n(35),v=(n(1),[]),w=0,y=d.getPooled(),b=!1,_=null,x={initialize:function(){this.dirtyComponentsLength=v.length},close:function(){this.dirtyComponentsLength!==v.length?(v.splice(0,this.dirtyComponentsLength),k()):v.length=0}},E={initialize:function(){this.callbackQueue.reset()},close:function(){this.callbackQueue.notifyAll()}},C=[x,E];h(i.prototype,g,{getTransactionWrappers:function(){return C},destructor:function(){this.dirtyComponentsLength=null,d.release(this.callbackQueue),this.callbackQueue=null,P.ReactReconcileTransaction.release(this.reconcileTransaction),this.reconcileTransaction=null},perform:function(e,t,n){return g.perform.call(this,this.reconcileTransaction.perform,this.reconcileTransaction,e,t,n)}}),f.addPoolingTo(i);var k=function(){for(;v.length||b;){if(v.length){var e=i.getPooled();e.perform(s,null,e),i.release(e)}if(b){b=!1;var t=y;y=d.getPooled(),t.notifyAll(),d.release(t)}}},S={injectReconcileTransaction:function(e){e?void 0:u("126"),P.ReactReconcileTransaction=e},injectBatchingStrategy:function(e){e?void 0:u("127"),"function"!=typeof e.batchedUpdates?u("128"):void 0,"boolean"!=typeof e.isBatchingUpdates?u("129"):void 0,_=e}},P={ReactReconcileTransaction:null,batchedUpdates:a,enqueueUpdate:l,flushBatchedUpdates:k,injection:S,asap:c};e.exports=P},function(e,t,n){"use strict";var r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i=n(4),a=n(104);e.exports=function(e){var t=e.keyHandlingOptions,n=t.propName||"",o=t.values||{},s=t.controller||a,l=e.getDefaultProps,c="wrappedComponent";return i.createClass({values:o,getDefaultProps:l,onKeyDown:function(e,t){var r=this.values[e.keyCode];r&&(e.preventDefault(),"function"==typeof r?r(t):(t[n]+=r,s(t)))},getComponent:function(){var e=this.refs[c];return e.getComponent?e.getComponent():e},render:function(){return i.createElement(e,r({},this.props,{onKeyDown:this.onKeyDown,ref:c}))}})}},function(e,t,n){"use strict";function r(e,t,n,r){this.dispatchConfig=e,this._targetInst=t,this.nativeEvent=n;var i=this.constructor.Interface;for(var a in i)if(i.hasOwnProperty(a)){var s=i[a];s?this[a]=s(n):"target"===a?this.target=r:this[a]=n[a]}var l=null!=n.defaultPrevented?n.defaultPrevented:n.returnValue===!1;return l?this.isDefaultPrevented=o.thatReturnsTrue:this.isDefaultPrevented=o.thatReturnsFalse,this.isPropagationStopped=o.thatReturnsFalse,this}var i=n(5),a=n(17),o=n(9),s=(n(2),"function"==typeof Proxy,["dispatchConfig","_targetInst","nativeEvent","isDefaultPrevented","isPropagationStopped","_dispatchListeners","_dispatchInstances"]),l={type:null,target:null,currentTarget:o.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null};i(r.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=o.thatReturnsTrue)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=o.thatReturnsTrue)},persist:function(){this.isPersistent=o.thatReturnsTrue},isPersistent:o.thatReturnsFalse,destructor:function(){var e=this.constructor.Interface;for(var t in e)this[t]=null;for(var n=0;n<s.length;n++)this[s[n]]=null}}),r.Interface=l,r.augmentClass=function(e,t){var n=this,r=function(){};r.prototype=n.prototype;var o=new r;i(o,e.prototype),e.prototype=o,e.prototype.constructor=e,e.Interface=i({},n.Interface,t),e.augmentClass=n.augmentClass,a.addPoolingTo(e,a.fourArgumentPooler)},a.addPoolingTo(r,a.fourArgumentPooler),e.exports=r},function(e,t,n){"use strict";var r={current:null};e.exports=r},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){return null==e||f.default.isValidElement(e)}function a(e){return i(e)||Array.isArray(e)&&e.every(i)}function o(e,t,n){e=e||"UnknownComponent";for(var r in t)if(t.hasOwnProperty(r)){var i=t[r](n,r,e);i instanceof Error}}function s(e,t){return h({},e,t)}function l(e){var t=e.type,n=s(t.defaultProps,e.props);if(t.propTypes&&o(t.displayName||t.name,t.propTypes,n),n.children){var r=c(n.children,n);r.length&&(n.childRoutes=r),delete n.children}return n}function c(e,t){var n=[];return f.default.Children.forEach(e,function(e){if(f.default.isValidElement(e))if(e.type.createRouteFromReactElement){var r=e.type.createRouteFromReactElement(e,t);r&&n.push(r)}else n.push(l(e))}),n}function u(e){return a(e)?e=c(e):e&&!Array.isArray(e)&&(e=[e]),e}t.__esModule=!0;var h=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e};t.isReactChildren=a,t.createRouteFromReactElement=l,t.createRoutesFromReactChildren=c,t.createRoutes=u;var d=n(4),f=r(d),p=n(8);r(p)},function(e,t,n){"use strict";var r=n(3),i=(n(1),function(e){var t=this;if(t.instancePool.length){var n=t.instancePool.pop();return t.call(n,e),n}return new t(e)}),a=function(e,t){var n=this;if(n.instancePool.length){var r=n.instancePool.pop();return n.call(r,e,t),r}return new n(e,t)},o=function(e,t,n){var r=this;if(r.instancePool.length){var i=r.instancePool.pop();return r.call(i,e,t,n),i}return new r(e,t,n)},s=function(e,t,n,r){var i=this;if(i.instancePool.length){var a=i.instancePool.pop();return i.call(a,e,t,n,r),a}return new i(e,t,n,r)},l=function(e){var t=this;e instanceof t?void 0:r("25"),e.destructor(),t.instancePool.length<t.poolSize&&t.instancePool.push(e)},c=10,u=i,h=function(e,t){var n=e;return n.instancePool=[],n.getPooled=t||u,n.poolSize||(n.poolSize=c),n.release=l,n},d={addPoolingTo:h,oneArgumentPooler:i,twoArgumentPooler:a,threeArgumentPooler:o,fourArgumentPooler:s};e.exports=d},function(e,t,n){"use strict";function r(e,t,n){if(e[t])return new Error("<"+n+'> should not have a "'+t+'" prop')}t.__esModule=!0,t.falsy=r;var i=n(4),a=i.PropTypes.func,o=i.PropTypes.object,s=i.PropTypes.arrayOf,l=i.PropTypes.oneOfType,c=i.PropTypes.element,u=i.PropTypes.shape,h=i.PropTypes.string,d=u({listen:a.isRequired,pushState:a.isRequired,replaceState:a.isRequired,go:a.isRequired});t.history=d;var f=u({pathname:h.isRequired,search:h.isRequired,state:o,action:h.isRequired,key:h});t.location=f;var p=l([a,h]);t.component=p;var m=l([p,o]);t.components=m;var g=l([o,c]);t.route=g;var v=l([g,s(g)]);t.routes=v,t.default={falsy:r,history:d,location:f,component:p,components:m,route:g}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){var t=s.default(e),n="",r="",i=t.indexOf("#");i!==-1&&(r=t.substring(i),t=t.substring(0,i));var a=t.indexOf("?");return a!==-1&&(n=t.substring(a),t=t.substring(0,a)),""===t&&(t="/"),{pathname:t,search:n,hash:r}}t.__esModule=!0;var a=n(8),o=(r(a),n(72)),s=r(o);t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e){if(g){var t=e.node,n=e.children;if(n.length)for(var r=0;r<n.length;r++)v(t,n[r],null);else null!=e.html?h(t,e.html):null!=e.text&&f(t,e.text)}}function i(e,t){e.parentNode.replaceChild(t.node,e),r(t)}function a(e,t){g?e.children.push(t):e.node.appendChild(t.node)}function o(e,t){g?e.html=t:h(e.node,t)}function s(e,t){g?e.text=t:f(e.node,t)}function l(){return this.node.nodeName}function c(e){return{node:e,children:[],html:null,text:null,toString:l}}var u=n(44),h=n(37),d=n(52),f=n(92),p=1,m=11,g="undefined"!=typeof document&&"number"==typeof document.documentMode||"undefined"!=typeof navigator&&"string"==typeof navigator.userAgent&&/\bEdge\/\d/.test(navigator.userAgent),v=d(function(e,t,n){t.node.nodeType===m||t.node.nodeType===p&&"object"===t.node.nodeName.toLowerCase()&&(null==t.node.namespaceURI||t.node.namespaceURI===u.html)?(r(t),e.insertBefore(t.node,n)):(e.insertBefore(t.node,n),r(t))});c.insertTreeBefore=v,c.replaceChildWithTree=i,c.queueChild=a,c.queueHTML=o,c.queueText=s,e.exports=c},function(e,t,n){"use strict";function r(e,t){return(e&t)===t}var i=n(3),a=(n(1),{MUST_USE_PROPERTY:1,HAS_BOOLEAN_VALUE:4,HAS_NUMERIC_VALUE:8,HAS_POSITIVE_NUMERIC_VALUE:24,HAS_OVERLOADED_BOOLEAN_VALUE:32,injectDOMPropertyConfig:function(e){var t=a,n=e.Properties||{},o=e.DOMAttributeNamespaces||{},l=e.DOMAttributeNames||{},c=e.DOMPropertyNames||{},u=e.DOMMutationMethods||{};e.isCustomAttribute&&s._isCustomAttributeFunctions.push(e.isCustomAttribute);for(var h in n){s.properties.hasOwnProperty(h)?i("48",h):void 0;var d=h.toLowerCase(),f=n[h],p={attributeName:d,attributeNamespace:null,propertyName:h,mutationMethod:null,mustUseProperty:r(f,t.MUST_USE_PROPERTY),hasBooleanValue:r(f,t.HAS_BOOLEAN_VALUE),hasNumericValue:r(f,t.HAS_NUMERIC_VALUE),hasPositiveNumericValue:r(f,t.HAS_POSITIVE_NUMERIC_VALUE),hasOverloadedBooleanValue:r(f,t.HAS_OVERLOADED_BOOLEAN_VALUE)};if(p.hasBooleanValue+p.hasNumericValue+p.hasOverloadedBooleanValue<=1?void 0:i("50",h),l.hasOwnProperty(h)){var m=l[h];p.attributeName=m}o.hasOwnProperty(h)&&(p.attributeNamespace=o[h]),c.hasOwnProperty(h)&&(p.propertyName=c[h]),u.hasOwnProperty(h)&&(p.mutationMethod=u[h]),s.properties[h]=p}}}),o=":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",s={ID_ATTRIBUTE_NAME:"data-reactid",ROOT_ATTRIBUTE_NAME:"data-reactroot",ATTRIBUTE_NAME_START_CHAR:o,ATTRIBUTE_NAME_CHAR:o+"\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040",properties:{},getPossibleStandardName:null,_isCustomAttributeFunctions:[],isCustomAttribute:function(e){for(var t=0;t<s._isCustomAttributeFunctions.length;t++){var n=s._isCustomAttributeFunctions[t];if(n(e))return!0}return!1},injection:a};e.exports=s},function(e,t,n){"use strict";function r(){i.attachRefs(this,this._currentElement)}var i=n(269),a=(n(11),n(2),{mountComponent:function(e,t,n,i,a,o){var s=e.mountComponent(t,n,i,a,o);return e._currentElement&&null!=e._currentElement.ref&&t.getReactMountReady().enqueue(r,e),s},getHostNode:function(e){return e.getHostNode()},unmountComponent:function(e,t){i.detachRefs(e,e._currentElement),e.unmountComponent(t)},receiveComponent:function(e,t,n,a){var o=e._currentElement;if(t!==o||a!==e._context){var s=i.shouldUpdateRefs(o,t);s&&i.detachRefs(e,o),e.receiveComponent(t,n,a),s&&e._currentElement&&null!=e._currentElement.ref&&n.getReactMountReady().enqueue(r,e)}},performUpdateIfNecessary:function(e,t,n){e._updateBatchNumber===n&&e.performUpdateIfNecessary(t)}});e.exports=a},function(e,t,n){"use strict";var r=n(5),i=n(314),a=n(61),o=n(319),s=n(315),l=n(316),c=n(24),u=n(317),h=n(320),d=n(321),f=(n(2),c.createElement),p=c.createFactory,m=c.cloneElement,g=r,v={Children:{map:i.map,forEach:i.forEach,count:i.count,toArray:i.toArray,only:d},Component:a,PureComponent:o,createElement:f,cloneElement:m,isValidElement:c.isValidElement,PropTypes:u,createClass:s.createClass,createFactory:p,createMixin:function(e){return e},DOM:l,version:h,__spread:g};e.exports=v},function(e,t,n){"use strict";function r(e){return void 0!==e.ref}function i(e){return void 0!==e.key}var a=n(5),o=n(15),s=(n(2),n(101),Object.prototype.hasOwnProperty),l=n(99),c={key:!0,ref:!0,__self:!0,__source:!0},u=function(e,t,n,r,i,a,o){var s={$$typeof:l,type:e,key:t,ref:n,props:o,_owner:a};return s};u.createElement=function(e,t,n){var a,l={},h=null,d=null,f=null,p=null;if(null!=t){r(t)&&(d=t.ref),i(t)&&(h=""+t.key),f=void 0===t.__self?null:t.__self,p=void 0===t.__source?null:t.__source;for(a in t)s.call(t,a)&&!c.hasOwnProperty(a)&&(l[a]=t[a])}var m=arguments.length-2;if(1===m)l.children=n;else if(m>1){for(var g=Array(m),v=0;v<m;v++)g[v]=arguments[v+2];l.children=g}if(e&&e.defaultProps){var w=e.defaultProps;for(a in w)void 0===l[a]&&(l[a]=w[a])}return u(e,h,d,f,p,o.current,l)},u.createFactory=function(e){var t=u.createElement.bind(null,e);return t.type=e,t},u.cloneAndReplaceKey=function(e,t){var n=u(e.type,t,e.ref,e._self,e._source,e._owner,e.props);return n},u.cloneElement=function(e,t,n){var l,h=a({},e.props),d=e.key,f=e.ref,p=e._self,m=e._source,g=e._owner;if(null!=t){r(t)&&(f=t.ref,g=o.current),i(t)&&(d=""+t.key);var v;e.type&&e.type.defaultProps&&(v=e.type.defaultProps);for(l in t)s.call(t,l)&&!c.hasOwnProperty(l)&&(void 0===t[l]&&void 0!==v?h[l]=v[l]:h[l]=t[l])}var w=arguments.length-2;if(1===w)h.children=n;else if(w>1){for(var y=Array(w),b=0;b<w;b++)y[b]=arguments[b+2];h.children=y}return u(e.type,d,f,p,m,g,h)},u.isValidElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===l},e.exports=u},function(e,t,n){"use strict";function r(e){for(var t=arguments.length-1,n="Minified React error #"+e+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant="+e,r=0;r<t;r++)n+="&args[]="+encodeURIComponent(arguments[r+1]);n+=" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.";var i=new Error(n);throw i.name="Invariant Violation",i.framesToPop=1,i}e.exports=r},function(e,t,n){"use strict";var r={};e.exports=r},function(e,t,n){"use strict";t.__esModule=!0;var r="PUSH";t.PUSH=r;var i="REPLACE";t.REPLACE=i;var a="POP";t.POP=a,t.default={PUSH:r,REPLACE:i,POP:a}},function(e,t,n){"use strict";function r(e){return"button"===e||"input"===e||"select"===e||"textarea"===e}function i(e,t,n){switch(e){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":return!(!n.disabled||!r(t));default:return!1}}var a=n(3),o=n(45),s=n(46),l=n(50),c=n(86),u=n(87),h=(n(1),{}),d=null,f=function(e,t){e&&(s.executeDispatchesInOrder(e,t),e.isPersistent()||e.constructor.release(e))},p=function(e){return f(e,!0)},m=function(e){return f(e,!1)},g=function(e){return"."+e._rootNodeID},v={injection:{injectEventPluginOrder:o.injectEventPluginOrder,injectEventPluginsByName:o.injectEventPluginsByName},putListener:function(e,t,n){"function"!=typeof n?a("94",t,typeof n):void 0;var r=g(e),i=h[t]||(h[t]={});i[r]=n;var s=o.registrationNameModules[t];s&&s.didPutListener&&s.didPutListener(e,t,n)},getListener:function(e,t){var n=h[t];if(i(t,e._currentElement.type,e._currentElement.props))return null;var r=g(e);return n&&n[r]},deleteListener:function(e,t){var n=o.registrationNameModules[t];n&&n.willDeleteListener&&n.willDeleteListener(e,t);var r=h[t];if(r){var i=g(e);delete r[i]}},deleteAllListeners:function(e){var t=g(e);for(var n in h)if(h.hasOwnProperty(n)&&h[n][t]){var r=o.registrationNameModules[n];r&&r.willDeleteListener&&r.willDeleteListener(e,n),delete h[n][t]}},extractEvents:function(e,t,n,r){for(var i,a=o.plugins,s=0;s<a.length;s++){var l=a[s];if(l){var u=l.extractEvents(e,t,n,r);u&&(i=c(i,u))}}return i},enqueueEvents:function(e){e&&(d=c(d,e))},processEventQueue:function(e){var t=d;d=null,e?u(t,p):u(t,m),d?a("95"):void 0,l.rethrowCaughtError()},__purge:function(){h={}},__getListenerBank:function(){return h}};e.exports=v},function(e,t,n){"use strict";function r(e,t,n){var r=t.dispatchConfig.phasedRegistrationNames[n];return v(e,r)}function i(e,t,n){var i=r(e,n,t);i&&(n._dispatchListeners=m(n._dispatchListeners,i),n._dispatchInstances=m(n._dispatchInstances,e))}function a(e){e&&e.dispatchConfig.phasedRegistrationNames&&p.traverseTwoPhase(e._targetInst,i,e)}function o(e){if(e&&e.dispatchConfig.phasedRegistrationNames){var t=e._targetInst,n=t?p.getParentInstance(t):null;p.traverseTwoPhase(n,i,e)}}function s(e,t,n){if(n&&n.dispatchConfig.registrationName){var r=n.dispatchConfig.registrationName,i=v(e,r);i&&(n._dispatchListeners=m(n._dispatchListeners,i),n._dispatchInstances=m(n._dispatchInstances,e))}}function l(e){e&&e.dispatchConfig.registrationName&&s(e._targetInst,null,e)}function c(e){g(e,a)}function u(e){g(e,o)}function h(e,t,n,r){p.traverseEnterLeave(n,r,s,e,t)}function d(e){g(e,l)}var f=n(28),p=n(46),m=n(86),g=n(87),v=(n(2),f.getListener),w={accumulateTwoPhaseDispatches:c,accumulateTwoPhaseDispatchesSkipTarget:u,accumulateDirectDispatches:d,accumulateEnterLeaveDispatches:h};e.exports=w},function(e,t,n){"use strict";var r={remove:function(e){e._reactInternalInstance=void 0},get:function(e){return e._reactInternalInstance},has:function(e){return void 0!==e._reactInternalInstance},set:function(e,t){e._reactInternalInstance=t}};e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(14),a=n(55),o={view:function(e){if(e.view)return e.view;var t=a(e);if(t.window===t)return t;var n=t.ownerDocument;return n?n.defaultView||n.parentWindow:window},detail:function(e){return e.detail||0}};i.augmentClass(r,o),e.exports=r},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function a(e){return i(e).replace(/\/+/g,"/+")}function o(e){for(var t="",n=[],r=[],i=void 0,o=0,s=/:([a-zA-Z_$][a-zA-Z0-9_$]*)|\*\*|\*|\(|\)/g;i=s.exec(e);)i.index!==o&&(r.push(e.slice(o,i.index)),t+=a(e.slice(o,i.index))),i[1]?(t+="([^/?#]+)",n.push(i[1])):"**"===i[0]?(t+="([\\s\\S]*)",n.push("splat")):"*"===i[0]?(t+="([\\s\\S]*?)",n.push("splat")):"("===i[0]?t+="(?:":")"===i[0]&&(t+=")?"),r.push(i[0]),o=s.lastIndex;return o!==e.length&&(r.push(e.slice(o,e.length)),t+=a(e.slice(o,e.length))),{pattern:e,regexpSource:t,paramNames:n,tokens:r}}function s(e){return e in p||(p[e]=o(e)),p[e]}function l(e,t){"/"!==e.charAt(0)&&(e="/"+e),"/"!==t.charAt(0)&&(t="/"+t);var n=s(e),r=n.regexpSource,i=n.paramNames,a=n.tokens;r+="/*";var o="*"!==a[a.length-1];o&&(r+="([\\s\\S]*?)");var l=t.match(new RegExp("^"+r+"$","i")),c=void 0,u=void 0;if(null!=l){if(o){c=l.pop();var h=l[0].substr(0,l[0].length-c.length);if(c&&"/"!==h.charAt(h.length-1))return{remainingPathname:null,paramNames:i,paramValues:null}}else c="";u=l.slice(1).map(function(e){return null!=e?decodeURIComponent(e):e})}else c=u=null;return{remainingPathname:c,paramNames:i,paramValues:u}}function c(e){return s(e).paramNames}function u(e,t){var n=l(e,t),r=n.paramNames,i=n.paramValues;return null!=i?r.reduce(function(e,t,n){return e[t]=i[n],e},{}):null}function h(e,t){t=t||{};for(var n=s(e),r=n.tokens,i=0,a="",o=0,l=void 0,c=void 0,u=void 0,h=0,d=r.length;h<d;++h)l=r[h],"*"===l||"**"===l?(u=Array.isArray(t.splat)?t.splat[o++]:t.splat,null!=u||i>0?void 0:f.default(!1),null!=u&&(a+=encodeURI(u))):"("===l?i+=1:")"===l?i-=1:":"===l.charAt(0)?(c=l.substring(1),u=t[c],null!=u||i>0?void 0:f.default(!1),null!=u&&(a+=encodeURIComponent(u))):a+=l;return a.replace(/\/+/g,"/")}t.__esModule=!0,t.compilePattern=s,t.matchPattern=l,t.getParamNames=c,t.getParams=u,t.formatPattern=h;var d=n(10),f=r(d),p={}},function(e,t,n){"use strict";function r(e){return Object.prototype.hasOwnProperty.call(e,m)||(e[m]=f++,h[e[m]]={}),h[e[m]]}var i,a=n(5),o=n(45),s=n(261),l=n(85),c=n(294),u=n(56),h={},d=!1,f=0,p={topAbort:"abort",topAnimationEnd:c("animationend")||"animationend",topAnimationIteration:c("animationiteration")||"animationiteration",topAnimationStart:c("animationstart")||"animationstart",topBlur:"blur",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topChange:"change",topClick:"click",topCompositionEnd:"compositionend",topCompositionStart:"compositionstart",topCompositionUpdate:"compositionupdate",topContextMenu:"contextmenu",topCopy:"copy",topCut:"cut",topDoubleClick:"dblclick",topDrag:"drag",topDragEnd:"dragend",topDragEnter:"dragenter",topDragExit:"dragexit",topDragLeave:"dragleave",topDragOver:"dragover",topDragStart:"dragstart",topDrop:"drop",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topFocus:"focus",topInput:"input",topKeyDown:"keydown",topKeyPress:"keypress",topKeyUp:"keyup",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topMouseDown:"mousedown",topMouseMove:"mousemove",topMouseOut:"mouseout",topMouseOver:"mouseover",topMouseUp:"mouseup",topPaste:"paste",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topScroll:"scroll",topSeeked:"seeked",topSeeking:"seeking",topSelectionChange:"selectionchange",topStalled:"stalled",topSuspend:"suspend",topTextInput:"textInput",topTimeUpdate:"timeupdate",topTouchCancel:"touchcancel",topTouchEnd:"touchend",topTouchMove:"touchmove",topTouchStart:"touchstart",topTransitionEnd:c("transitionend")||"transitionend",topVolumeChange:"volumechange",topWaiting:"waiting",topWheel:"wheel"},m="_reactListenersID"+String(Math.random()).slice(2),g=a({},s,{ReactEventListener:null,injection:{injectReactEventListener:function(e){e.setHandleTopLevel(g.handleTopLevel),g.ReactEventListener=e}},setEnabled:function(e){g.ReactEventListener&&g.ReactEventListener.setEnabled(e)},isEnabled:function(){return!(!g.ReactEventListener||!g.ReactEventListener.isEnabled())},listenTo:function(e,t){for(var n=t,i=r(n),a=o.registrationNameDependencies[e],s=0;s<a.length;s++){var l=a[s];i.hasOwnProperty(l)&&i[l]||("topWheel"===l?u("wheel")?g.ReactEventListener.trapBubbledEvent("topWheel","wheel",n):u("mousewheel")?g.ReactEventListener.trapBubbledEvent("topWheel","mousewheel",n):g.ReactEventListener.trapBubbledEvent("topWheel","DOMMouseScroll",n):"topScroll"===l?u("scroll",!0)?g.ReactEventListener.trapCapturedEvent("topScroll","scroll",n):g.ReactEventListener.trapBubbledEvent("topScroll","scroll",g.ReactEventListener.WINDOW_HANDLE):"topFocus"===l||"topBlur"===l?(u("focus",!0)?(g.ReactEventListener.trapCapturedEvent("topFocus","focus",n),g.ReactEventListener.trapCapturedEvent("topBlur","blur",n)):u("focusin")&&(g.ReactEventListener.trapBubbledEvent("topFocus","focusin",n),g.ReactEventListener.trapBubbledEvent("topBlur","focusout",n)),i.topBlur=!0,i.topFocus=!0):p.hasOwnProperty(l)&&g.ReactEventListener.trapBubbledEvent(l,p[l],n),i[l]=!0)}},trapBubbledEvent:function(e,t,n){return g.ReactEventListener.trapBubbledEvent(e,t,n)},trapCapturedEvent:function(e,t,n){return g.ReactEventListener.trapCapturedEvent(e,t,n)},supportsEventPageXY:function(){if(!document.createEvent)return!1;var e=document.createEvent("MouseEvent");return null!=e&&"pageX"in e},ensureScrollValueMonitoring:function(){if(void 0===i&&(i=g.supportsEventPageXY()),!i&&!d){var e=l.refreshScrollValues;g.ReactEventListener.monitorScrollValue(e),d=!0}}});e.exports=g},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(31),a=n(85),o=n(54),s={screenX:null,screenY:null,clientX:null,clientY:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,getModifierState:o,button:function(e){var t=e.button;return"which"in e?t:2===t?2:4===t?1:0},buttons:null,relatedTarget:function(e){return e.relatedTarget||(e.fromElement===e.srcElement?e.toElement:e.fromElement)},pageX:function(e){return"pageX"in e?e.pageX:e.clientX+a.currentScrollLeft},pageY:function(e){return"pageY"in e?e.pageY:e.clientY+a.currentScrollTop}};i.augmentClass(r,s),e.exports=r},function(e,t,n){"use strict";var r=n(3),i=(n(1),{}),a={reinitializeTransaction:function(){this.transactionWrappers=this.getTransactionWrappers(),this.wrapperInitData?this.wrapperInitData.length=0:this.wrapperInitData=[],this._isInTransaction=!1},_isInTransaction:!1,getTransactionWrappers:null,isInTransaction:function(){return!!this._isInTransaction},perform:function(e,t,n,i,a,o,s,l){this.isInTransaction()?r("27"):void 0;var c,u;try{this._isInTransaction=!0,c=!0,this.initializeAll(0),u=e.call(t,n,i,a,o,s,l),c=!1}finally{try{if(c)try{this.closeAll(0)}catch(e){}else this.closeAll(0)}finally{this._isInTransaction=!1}}return u},initializeAll:function(e){for(var t=this.transactionWrappers,n=e;n<t.length;n++){var r=t[n];try{this.wrapperInitData[n]=i,this.wrapperInitData[n]=r.initialize?r.initialize.call(this):null}finally{if(this.wrapperInitData[n]===i)try{this.initializeAll(n+1)}catch(e){}}}},closeAll:function(e){this.isInTransaction()?void 0:r("28");for(var t=this.transactionWrappers,n=e;n<t.length;n++){var a,o=t[n],s=this.wrapperInitData[n];try{a=!0,s!==i&&o.close&&o.close.call(this,s),a=!1}finally{if(a)try{this.closeAll(n+1)}catch(e){}}}this.wrapperInitData.length=0}};e.exports=a},function(e,t,n){"use strict";function r(e){var t=""+e,n=a.exec(t);if(!n)return t;var r,i="",o=0,s=0;for(o=n.index;o<t.length;o++){switch(t.charCodeAt(o)){case 34:r=""";break;case 38:r="&";break;case 39:r="'";break;case 60:r="<";break;case 62:r=">";break;default:continue}s!==o&&(i+=t.substring(s,o)),s=o+1,i+=r}return s!==o?i+t.substring(s,o):i}function i(e){return"boolean"==typeof e||"number"==typeof e?""+e:r(e)}var a=/["'&<>]/;e.exports=i},function(e,t,n){"use strict";var r,i=n(7),a=n(44),o=/^[ \r\n\t\f]/,s=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,l=n(52),c=l(function(e,t){if(e.namespaceURI!==a.svg||"innerHTML"in e)e.innerHTML=t;else{r=r||document.createElement("div"),r.innerHTML="<svg>"+t+"</svg>";for(var n=r.firstChild;n.firstChild;)e.appendChild(n.firstChild)}});if(i.canUseDOM){var u=document.createElement("div");u.innerHTML=" ",""===u.innerHTML&&(c=function(e,t){if(e.parentNode&&e.parentNode.replaceChild(e,e),o.test(t)||"<"===t[0]&&s.test(t)){e.innerHTML=String.fromCharCode(65279)+t;var n=e.firstChild;1===n.data.length?e.removeChild(n):n.deleteData(0,1)}else e.innerHTML=t}),u=null}e.exports=c},function(e,t,n){"use strict";e.exports={preface:n(189),introduction:n(176),whatis:n(203),explanation:n(162),control:n(155),extended:n(164), +matrix:n(177),decasteljau:n(159),flattening:n(168),splitting:n(197),matrixsplit:n(178),reordering:n(193),derivatives:n(160),pointvectors:n(186),components:n(153),extremities:n(166),boundingbox:n(132),aligning:n(124),tightbounds:n(199),inflections:n(172),canonical:n(142),arclength:n(128),arclengthapprox:n(130),tracing:n(201),intersections:n(174),curveintersection:n(157),abc:n(122),moulding:n(180),pointcurves:n(184),catmullconv:n(143),catmullmoulding:n(145),polybezier:n(188),shapes:n(195),projections:n(191),offsetting:n(182),graduatedoffset:n(170),circles:n(147),circles_cubic:n(149),arcapproximation:n(126),bsplines:n(136),comments:n(151)}},function(e,t,n){"use strict";function r(e,t){return e===t?0!==e||0!==t||1/e===1/t:e!==e&&t!==t}function i(e,t){if(r(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),i=Object.keys(t);if(n.length!==i.length)return!1;for(var o=0;o<n.length;o++)if(!a.call(t,n[o])||!r(e[n[o]],t[n[o]]))return!1;return!0}var a=Object.prototype.hasOwnProperty;e.exports=i},function(e,t,n){"use strict";t.__esModule=!0;var r=!("undefined"==typeof window||!window.document||!window.document.createElement);t.canUseDOM=r},function(e,t,n){"use strict";function r(e){return e}t.__esModule=!0,t.default=r,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t,n){var r=e(t,n);e.length<2&&n(r)}t.__esModule=!0;var a=n(8);r(a);t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e,t){return Array.isArray(t)&&(t=t[1]),t?t.nextSibling:e.firstChild}function i(e,t,n){u.insertTreeBefore(e,t,n)}function a(e,t,n){Array.isArray(t)?s(e,t[0],t[1],n):m(e,t,n)}function o(e,t){if(Array.isArray(t)){var n=t[1];t=t[0],l(e,t,n),e.removeChild(n)}e.removeChild(t)}function s(e,t,n,r){for(var i=t;;){var a=i.nextSibling;if(m(e,i,r),i===n)break;i=a}}function l(e,t,n){for(;;){var r=t.nextSibling;if(r===n)break;e.removeChild(r)}}function c(e,t,n){var r=e.parentNode,i=e.nextSibling;i===t?n&&m(r,document.createTextNode(n),i):n?(p(i,n),l(r,i,t)):l(r,e,t)}var u=n(20),h=n(238),d=(n(6),n(11),n(52)),f=n(37),p=n(92),m=d(function(e,t,n){e.insertBefore(t,n)}),g=h.dangerouslyReplaceNodeWithMarkup,v={dangerouslyReplaceNodeWithMarkup:g,replaceDelimitedText:c,processUpdates:function(e,t){for(var n=0;n<t.length;n++){var s=t[n];switch(s.type){case"INSERT_MARKUP":i(e,s.content,r(e,s.afterNode));break;case"MOVE_EXISTING":a(e,s.fromNode,r(e,s.afterNode));break;case"SET_MARKUP":f(e,s.content);break;case"TEXT_CONTENT":p(e,s.content);break;case"REMOVE_NODE":o(e,s.fromNode)}}}};e.exports=v},function(e,t,n){"use strict";var r={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg"};e.exports=r},function(e,t,n){"use strict";function r(){if(s)for(var e in l){var t=l[e],n=s.indexOf(e);if(n>-1?void 0:o("96",e),!c.plugins[n]){t.extractEvents?void 0:o("97",e),c.plugins[n]=t;var r=t.eventTypes;for(var a in r)i(r[a],t,a)?void 0:o("98",a,e)}}}function i(e,t,n){c.eventNameDispatchConfigs.hasOwnProperty(n)?o("99",n):void 0,c.eventNameDispatchConfigs[n]=e;var r=e.phasedRegistrationNames;if(r){for(var i in r)if(r.hasOwnProperty(i)){var s=r[i];a(s,t,n)}return!0}return!!e.registrationName&&(a(e.registrationName,t,n),!0)}function a(e,t,n){c.registrationNameModules[e]?o("100",e):void 0,c.registrationNameModules[e]=t,c.registrationNameDependencies[e]=t.eventTypes[n].dependencies}var o=n(3),s=(n(1),null),l={},c={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},possibleRegistrationNames:null,injectEventPluginOrder:function(e){s?o("101"):void 0,s=Array.prototype.slice.call(e),r()},injectEventPluginsByName:function(e){var t=!1;for(var n in e)if(e.hasOwnProperty(n)){var i=e[n];l.hasOwnProperty(n)&&l[n]===i||(l[n]?o("102",n):void 0,l[n]=i,t=!0)}t&&r()},getPluginModuleForEvent:function(e){var t=e.dispatchConfig;if(t.registrationName)return c.registrationNameModules[t.registrationName]||null;if(void 0!==t.phasedRegistrationNames){var n=t.phasedRegistrationNames;for(var r in n)if(n.hasOwnProperty(r)){var i=c.registrationNameModules[n[r]];if(i)return i}}return null},_resetEventPlugins:function(){s=null;for(var e in l)l.hasOwnProperty(e)&&delete l[e];c.plugins.length=0;var t=c.eventNameDispatchConfigs;for(var n in t)t.hasOwnProperty(n)&&delete t[n];var r=c.registrationNameModules;for(var i in r)r.hasOwnProperty(i)&&delete r[i]}};e.exports=c},function(e,t,n){"use strict";function r(e){return"topMouseUp"===e||"topTouchEnd"===e||"topTouchCancel"===e}function i(e){return"topMouseMove"===e||"topTouchMove"===e}function a(e){return"topMouseDown"===e||"topTouchStart"===e}function o(e,t,n,r){var i=e.type||"unknown-event";e.currentTarget=v.getNodeFromInstance(r),t?m.invokeGuardedCallbackWithCatch(i,n,e):m.invokeGuardedCallback(i,n,e),e.currentTarget=null}function s(e,t){var n=e._dispatchListeners,r=e._dispatchInstances;if(Array.isArray(n))for(var i=0;i<n.length&&!e.isPropagationStopped();i++)o(e,t,n[i],r[i]);else n&&o(e,t,n,r);e._dispatchListeners=null,e._dispatchInstances=null}function l(e){var t=e._dispatchListeners,n=e._dispatchInstances;if(Array.isArray(t)){for(var r=0;r<t.length&&!e.isPropagationStopped();r++)if(t[r](e,n[r]))return n[r]}else if(t&&t(e,n))return n;return null}function c(e){var t=l(e);return e._dispatchInstances=null,e._dispatchListeners=null,t}function u(e){var t=e._dispatchListeners,n=e._dispatchInstances;Array.isArray(t)?p("103"):void 0,e.currentTarget=t?v.getNodeFromInstance(n):null;var r=t?t(e):null;return e.currentTarget=null,e._dispatchListeners=null,e._dispatchInstances=null,r}function h(e){return!!e._dispatchListeners}var d,f,p=n(3),m=n(50),g=(n(1),n(2),{injectComponentTree:function(e){d=e},injectTreeTraversal:function(e){f=e}}),v={isEndish:r,isMoveish:i,isStartish:a,executeDirectDispatch:u,executeDispatchesInOrder:s,executeDispatchesInOrderStopAtTrue:c,hasDispatches:h,getInstanceFromNode:function(e){return d.getInstanceFromNode(e)},getNodeFromInstance:function(e){return d.getNodeFromInstance(e)},isAncestor:function(e,t){return f.isAncestor(e,t)},getLowestCommonAncestor:function(e,t){return f.getLowestCommonAncestor(e,t)},getParentInstance:function(e){return f.getParentInstance(e)},traverseTwoPhase:function(e,t,n){return f.traverseTwoPhase(e,t,n)},traverseEnterLeave:function(e,t,n,r,i){return f.traverseEnterLeave(e,t,n,r,i)},injection:g};e.exports=v},function(e,t,n){"use strict";function r(e){var t=/[=:]/g,n={"=":"=0",":":"=2"},r=(""+e).replace(t,function(e){return n[e]});return"$"+r}function i(e){var t=/(=0|=2)/g,n={"=0":"=","=2":":"},r="."===e[0]&&"$"===e[1]?e.substring(2):e.substring(1);return(""+r).replace(t,function(e){return n[e]})}var a={escape:r,unescape:i};e.exports=a},function(e,t,n){"use strict";function r(e){null!=e.checkedLink&&null!=e.valueLink?s("87"):void 0}function i(e){r(e),null!=e.value||null!=e.onChange?s("88"):void 0}function a(e){r(e),null!=e.checked||null!=e.onChange?s("89"):void 0}function o(e){if(e){var t=e.getName();if(t)return" Check the render method of `"+t+"`."}return""}var s=n(3),l=n(23),c=n(267),u=(n(1),n(2),{button:!0,checkbox:!0,image:!0,hidden:!0,radio:!0,reset:!0,submit:!0}),h={value:function(e,t,n){return!e[t]||u[e.type]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.")},checked:function(e,t,n){return!e[t]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.")},onChange:l.PropTypes.func},d={},f={checkPropTypes:function(e,t,n){for(var r in h){if(h.hasOwnProperty(r))var i=h[r](t,r,e,"prop",null,c);if(i instanceof Error&&!(i.message in d)){d[i.message]=!0;o(n)}}},getValue:function(e){return e.valueLink?(i(e),e.valueLink.value):e.value},getChecked:function(e){return e.checkedLink?(a(e),e.checkedLink.value):e.checked},executeOnChange:function(e,t){return e.valueLink?(i(e),e.valueLink.requestChange(t.target.value)):e.checkedLink?(a(e),e.checkedLink.requestChange(t.target.checked)):e.onChange?e.onChange.call(void 0,t):void 0}};e.exports=f},function(e,t,n){"use strict";var r=n(3),i=(n(1),!1),a={replaceNodeWithMarkup:null,processChildrenUpdates:null,injection:{injectEnvironment:function(e){i?r("104"):void 0,a.replaceNodeWithMarkup=e.replaceNodeWithMarkup,a.processChildrenUpdates=e.processChildrenUpdates,i=!0}}};e.exports=a},function(e,t,n){"use strict";function r(e,t,n){try{t(n)}catch(e){null===i&&(i=e)}}var i=null,a={invokeGuardedCallback:r,invokeGuardedCallbackWithCatch:r,rethrowCaughtError:function(){if(i){var e=i;throw i=null,e}}};e.exports=a},function(e,t,n){"use strict";function r(e){l.enqueueUpdate(e)}function i(e){var t=typeof e;if("object"!==t)return t;var n=e.constructor&&e.constructor.name||t,r=Object.keys(e);return r.length>0&&r.length<20?n+" (keys: "+r.join(", ")+")":n}function a(e,t){var n=s.get(e);if(!n){return null}return n}var o=n(3),s=(n(15),n(30)),l=(n(11),n(12)),c=(n(1),n(2),{isMounted:function(e){var t=s.get(e);return!!t&&!!t._renderedComponent},enqueueCallback:function(e,t,n){c.validateCallback(t,n);var i=a(e);return i?(i._pendingCallbacks?i._pendingCallbacks.push(t):i._pendingCallbacks=[t],void r(i)):null},enqueueCallbackInternal:function(e,t){e._pendingCallbacks?e._pendingCallbacks.push(t):e._pendingCallbacks=[t],r(e)},enqueueForceUpdate:function(e){var t=a(e,"forceUpdate");t&&(t._pendingForceUpdate=!0,r(t))},enqueueReplaceState:function(e,t){var n=a(e,"replaceState");n&&(n._pendingStateQueue=[t],n._pendingReplaceState=!0,r(n))},enqueueSetState:function(e,t){var n=a(e,"setState");if(n){var i=n._pendingStateQueue||(n._pendingStateQueue=[]);i.push(t),r(n)}},enqueueElementInternal:function(e,t,n){e._pendingElement=t,e._context=n,r(e)},validateCallback:function(e,t){e&&"function"!=typeof e?o("122",t,i(e)):void 0}});e.exports=c},function(e,t,n){"use strict";var r=function(e){return"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(t,n,r,i){MSApp.execUnsafeLocalFunction(function(){return e(t,n,r,i)})}:e};e.exports=r},function(e,t,n){"use strict";function r(e){var t,n=e.keyCode;return"charCode"in e?(t=e.charCode,0===t&&13===n&&(t=13)):t=n,t>=32||13===t?t:0}e.exports=r},function(e,t,n){"use strict";function r(e){var t=this,n=t.nativeEvent;if(n.getModifierState)return n.getModifierState(e);var r=a[e];return!!r&&!!n[r]}function i(e){return r}var a={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};e.exports=i},function(e,t,n){"use strict";function r(e){var t=e.target||e.srcElement||window;return t.correspondingUseElement&&(t=t.correspondingUseElement),3===t.nodeType?t.parentNode:t}e.exports=r},function(e,t,n){"use strict";/** * Checks if an event is supported in the current execution environment. * * NOTE: This will not work correctly for non-generic events such as `change`, @@ -6799,25822 +13,24 @@ if (ExecutionEnvironment.canUseDOM) { * @internal * @license Modernizr 3.0.0pre (Custom Build) | MIT */ -function isEventSupported(eventNameSuffix, capture) { - if (!ExecutionEnvironment.canUseDOM || capture && !('addEventListener' in document)) { - return false; - } - - var eventName = 'on' + eventNameSuffix; - var isSupported = eventName in document; - - if (!isSupported) { - var element = document.createElement('div'); - element.setAttribute(eventName, 'return;'); - isSupported = typeof element[eventName] === 'function'; - } - - if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { - // This is the only way to test support for the `wheel` event in IE9+. - isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); - } - - return isSupported; -} - -module.exports = isEventSupported; - -/***/ }), -/* 59 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * Given a `prevElement` and `nextElement`, determines if the existing - * instance should be updated as opposed to being destroyed or replaced by a new - * instance. Both arguments are elements. This ensures that this logic can - * operate on stateless trees without any backing instance. - * - * @param {?object} prevElement - * @param {?object} nextElement - * @return {boolean} True if the existing instance should be updated. - * @protected - */ - -function shouldUpdateReactComponent(prevElement, nextElement) { - var prevEmpty = prevElement === null || prevElement === false; - var nextEmpty = nextElement === null || nextElement === false; - if (prevEmpty || nextEmpty) { - return prevEmpty === nextEmpty; - } - - var prevType = typeof prevElement; - var nextType = typeof nextElement; - if (prevType === 'string' || prevType === 'number') { - return nextType === 'string' || nextType === 'number'; - } else { - return nextType === 'object' && prevElement.type === nextElement.type && prevElement.key === nextElement.key; - } -} - -module.exports = shouldUpdateReactComponent; - -/***/ }), -/* 60 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var emptyFunction = __webpack_require__(12); -var warning = __webpack_require__(3); - -var validateDOMNesting = emptyFunction; - -if (process.env.NODE_ENV !== 'production') { - // This validation code was written based on the HTML5 parsing spec: - // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope - // - // Note: this does not catch all invalid nesting, nor does it try to (as it's - // not clear what practical benefit doing so provides); instead, we warn only - // for cases where the parser will give a parse tree differing from what React - // intended. For example, <b><div></div></b> is invalid but we don't warn - // because it still parses correctly; we do warn for other cases like nested - // <p> tags where the beginning of the second element implicitly closes the - // first, causing a confusing mess. - - // https://html.spec.whatwg.org/multipage/syntax.html#special - var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp']; - - // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope - var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', - - // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point - // TODO: Distinguish by namespace here -- for <title>, including it here - // errs on the side of fewer warnings - 'foreignObject', 'desc', 'title']; - - // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope - var buttonScopeTags = inScopeTags.concat(['button']); - - // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags - var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt']; - - var emptyAncestorInfo = { - current: null, - - formTag: null, - aTagInScope: null, - buttonTagInScope: null, - nobrTagInScope: null, - pTagInButtonScope: null, - - listItemTagAutoclosing: null, - dlItemTagAutoclosing: null - }; - - var updatedAncestorInfo = function (oldInfo, tag, instance) { - var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo); - var info = { tag: tag, instance: instance }; - - if (inScopeTags.indexOf(tag) !== -1) { - ancestorInfo.aTagInScope = null; - ancestorInfo.buttonTagInScope = null; - ancestorInfo.nobrTagInScope = null; - } - if (buttonScopeTags.indexOf(tag) !== -1) { - ancestorInfo.pTagInButtonScope = null; - } - - // See rules for 'li', 'dd', 'dt' start tags in - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody - if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') { - ancestorInfo.listItemTagAutoclosing = null; - ancestorInfo.dlItemTagAutoclosing = null; - } - - ancestorInfo.current = info; - - if (tag === 'form') { - ancestorInfo.formTag = info; - } - if (tag === 'a') { - ancestorInfo.aTagInScope = info; - } - if (tag === 'button') { - ancestorInfo.buttonTagInScope = info; - } - if (tag === 'nobr') { - ancestorInfo.nobrTagInScope = info; - } - if (tag === 'p') { - ancestorInfo.pTagInButtonScope = info; - } - if (tag === 'li') { - ancestorInfo.listItemTagAutoclosing = info; - } - if (tag === 'dd' || tag === 'dt') { - ancestorInfo.dlItemTagAutoclosing = info; - } - - return ancestorInfo; - }; - - /** - * Returns whether - */ - var isTagValidWithParent = function (tag, parentTag) { - // First, let's check if we're in an unusual parsing mode... - switch (parentTag) { - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect - case 'select': - return tag === 'option' || tag === 'optgroup' || tag === '#text'; - case 'optgroup': - return tag === 'option' || tag === '#text'; - // Strictly speaking, seeing an <option> doesn't mean we're in a <select> - // but - case 'option': - return tag === '#text'; - - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption - // No special behavior since these rules fall back to "in body" mode for - // all except special table nodes which cause bad parsing behavior anyway. - - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr - case 'tr': - return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template'; - - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody - case 'tbody': - case 'thead': - case 'tfoot': - return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template'; - - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup - case 'colgroup': - return tag === 'col' || tag === 'template'; - - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable - case 'table': - return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template'; - - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead - case 'head': - return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template'; - - // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element - case 'html': - return tag === 'head' || tag === 'body'; - case '#document': - return tag === 'html'; - } - - // Probably in the "in body" parsing mode, so we outlaw only tag combos - // where the parsing rules cause implicit opens or closes to be added. - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody - switch (tag) { - case 'h1': - case 'h2': - case 'h3': - case 'h4': - case 'h5': - case 'h6': - return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6'; - - case 'rp': - case 'rt': - return impliedEndTags.indexOf(parentTag) === -1; - - case 'body': - case 'caption': - case 'col': - case 'colgroup': - case 'frame': - case 'head': - case 'html': - case 'tbody': - case 'td': - case 'tfoot': - case 'th': - case 'thead': - case 'tr': - // These tags are only valid with a few parents that have special child - // parsing rules -- if we're down here, then none of those matched and - // so we allow it only if we don't know what the parent is, as all other - // cases are invalid. - return parentTag == null; - } - - return true; - }; - - /** - * Returns whether - */ - var findInvalidAncestorForTag = function (tag, ancestorInfo) { - switch (tag) { - case 'address': - case 'article': - case 'aside': - case 'blockquote': - case 'center': - case 'details': - case 'dialog': - case 'dir': - case 'div': - case 'dl': - case 'fieldset': - case 'figcaption': - case 'figure': - case 'footer': - case 'header': - case 'hgroup': - case 'main': - case 'menu': - case 'nav': - case 'ol': - case 'p': - case 'section': - case 'summary': - case 'ul': - - case 'pre': - case 'listing': - - case 'table': - - case 'hr': - - case 'xmp': - - case 'h1': - case 'h2': - case 'h3': - case 'h4': - case 'h5': - case 'h6': - return ancestorInfo.pTagInButtonScope; - - case 'form': - return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope; - - case 'li': - return ancestorInfo.listItemTagAutoclosing; - - case 'dd': - case 'dt': - return ancestorInfo.dlItemTagAutoclosing; - - case 'button': - return ancestorInfo.buttonTagInScope; - - case 'a': - // Spec says something about storing a list of markers, but it sounds - // equivalent to this check. - return ancestorInfo.aTagInScope; - - case 'nobr': - return ancestorInfo.nobrTagInScope; - } - - return null; - }; - - /** - * Given a ReactCompositeComponent instance, return a list of its recursive - * owners, starting at the root and ending with the instance itself. - */ - var findOwnerStack = function (instance) { - if (!instance) { - return []; - } - - var stack = []; - do { - stack.push(instance); - } while (instance = instance._currentElement._owner); - stack.reverse(); - return stack; - }; - - var didWarn = {}; - - validateDOMNesting = function (childTag, childText, childInstance, ancestorInfo) { - ancestorInfo = ancestorInfo || emptyAncestorInfo; - var parentInfo = ancestorInfo.current; - var parentTag = parentInfo && parentInfo.tag; - - if (childText != null) { - process.env.NODE_ENV !== 'production' ? warning(childTag == null, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0; - childTag = '#text'; - } - - var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo; - var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo); - var problematic = invalidParent || invalidAncestor; - - if (problematic) { - var ancestorTag = problematic.tag; - var ancestorInstance = problematic.instance; - - var childOwner = childInstance && childInstance._currentElement._owner; - var ancestorOwner = ancestorInstance && ancestorInstance._currentElement._owner; - - var childOwners = findOwnerStack(childOwner); - var ancestorOwners = findOwnerStack(ancestorOwner); - - var minStackLen = Math.min(childOwners.length, ancestorOwners.length); - var i; - - var deepestCommon = -1; - for (i = 0; i < minStackLen; i++) { - if (childOwners[i] === ancestorOwners[i]) { - deepestCommon = i; - } else { - break; - } - } - - var UNKNOWN = '(unknown)'; - var childOwnerNames = childOwners.slice(deepestCommon + 1).map(function (inst) { - return inst.getName() || UNKNOWN; - }); - var ancestorOwnerNames = ancestorOwners.slice(deepestCommon + 1).map(function (inst) { - return inst.getName() || UNKNOWN; - }); - var ownerInfo = [].concat( - // If the parent and child instances have a common owner ancestor, start - // with that -- otherwise we just start with the parent's owners. - deepestCommon !== -1 ? childOwners[deepestCommon].getName() || UNKNOWN : [], ancestorOwnerNames, ancestorTag, - // If we're warning about an invalid (non-parent) ancestry, add '...' - invalidAncestor ? ['...'] : [], childOwnerNames, childTag).join(' > '); - - var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + ownerInfo; - if (didWarn[warnKey]) { - return; - } - didWarn[warnKey] = true; - - var tagDisplayName = childTag; - var whitespaceInfo = ''; - if (childTag === '#text') { - if (/\S/.test(childText)) { - tagDisplayName = 'Text nodes'; - } else { - tagDisplayName = 'Whitespace text nodes'; - whitespaceInfo = ' Make sure you don\'t have any extra whitespace between tags on ' + 'each line of your source code.'; - } - } else { - tagDisplayName = '<' + childTag + '>'; - } - - if (invalidParent) { - var info = ''; - if (ancestorTag === 'table' && childTag === 'tr') { - info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.'; - } - process.env.NODE_ENV !== 'production' ? warning(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s ' + 'See %s.%s', tagDisplayName, ancestorTag, whitespaceInfo, ownerInfo, info) : void 0; - } else { - process.env.NODE_ENV !== 'production' ? warning(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>. See %s.', tagDisplayName, ancestorTag, ownerInfo) : void 0; - } - } - }; - - validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo; - - // For testing - validateDOMNesting.isTagValidInContext = function (tag, ancestorInfo) { - ancestorInfo = ancestorInfo || emptyAncestorInfo; - var parentInfo = ancestorInfo.current; - var parentTag = parentInfo && parentInfo.tag; - return isTagValidWithParent(tag, parentTag) && !findInvalidAncestorForTag(tag, ancestorInfo); - }; -} - -module.exports = validateDOMNesting; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 61 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.loopAsync = loopAsync; -exports.mapAsync = mapAsync; - -function loopAsync(turns, work, callback) { - var currentTurn = 0, - isDone = false; - - function done() { - isDone = true; - callback.apply(this, arguments); - } - - function next() { - if (isDone) return; - - if (currentTurn < turns) { - work.call(this, currentTurn++, next, done); - } else { - done.apply(this, arguments); - } - } - - next(); -} - -function mapAsync(array, work, callback) { - var length = array.length; - var values = []; - - if (length === 0) return callback(null, values); - - var isDone = false, - doneCount = 0; - - function done(index, error, value) { - if (isDone) return; - - if (error) { - isDone = true; - callback(error); - } else { - values[index] = value; - - isDone = ++doneCount === length; - - if (isDone) callback(null, values); - } - } - - array.forEach(function (item, index) { - work(item, index, function (error, value) { - done(index, error, value); - }); - }); -} - -/***/ }), -/* 62 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _historyLibActions = __webpack_require__(29); - -var _historyLibUseQueries = __webpack_require__(235); - -var _historyLibUseQueries2 = _interopRequireDefault(_historyLibUseQueries); - -var _computeChangedRoutes2 = __webpack_require__(318); - -var _computeChangedRoutes3 = _interopRequireDefault(_computeChangedRoutes2); - -var _TransitionUtils = __webpack_require__(317); - -var _isActive2 = __webpack_require__(321); - -var _isActive3 = _interopRequireDefault(_isActive2); - -var _getComponents = __webpack_require__(319); - -var _getComponents2 = _interopRequireDefault(_getComponents); - -var _matchRoutes = __webpack_require__(323); - -var _matchRoutes2 = _interopRequireDefault(_matchRoutes); - -function hasAnyProperties(object) { - for (var p in object) { - if (object.hasOwnProperty(p)) return true; - }return false; -} - -/** - * Returns a new createHistory function that may be used to create - * history objects that know about routing. - * - * Enhances history objects with the following methods: - * - * - listen((error, nextState) => {}) - * - listenBeforeLeavingRoute(route, (nextLocation) => {}) - * - match(location, (error, redirectLocation, nextState) => {}) - * - isActive(pathname, query, indexOnly=false) - */ -function useRoutes(createHistory) { - return function () { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - var routes = options.routes; - - var historyOptions = _objectWithoutProperties(options, ['routes']); - - var history = _historyLibUseQueries2['default'](createHistory)(historyOptions); - var state = {}; - - function isActive(pathname, query) { - var indexOnly = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; - - return _isActive3['default'](pathname, query, indexOnly, state.location, state.routes, state.params); - } - - function createLocationFromRedirectInfo(_ref) { - var pathname = _ref.pathname; - var query = _ref.query; - var state = _ref.state; - - return history.createLocation(history.createPath(pathname, query), state, _historyLibActions.REPLACE); - } - - var partialNextState = undefined; - - function match(location, callback) { - if (partialNextState && partialNextState.location === location) { - // Continue from where we left off. - finishMatch(partialNextState, callback); - } else { - _matchRoutes2['default'](routes, location, function (error, nextState) { - if (error) { - callback(error); - } else if (nextState) { - finishMatch(_extends({}, nextState, { location: location }), callback); - } else { - callback(); - } - }); - } - } - - function finishMatch(nextState, callback) { - var _computeChangedRoutes = _computeChangedRoutes3['default'](state, nextState); - - var leaveRoutes = _computeChangedRoutes.leaveRoutes; - var enterRoutes = _computeChangedRoutes.enterRoutes; - - _TransitionUtils.runLeaveHooks(leaveRoutes); - - _TransitionUtils.runEnterHooks(enterRoutes, nextState, function (error, redirectInfo) { - if (error) { - callback(error); - } else if (redirectInfo) { - callback(null, createLocationFromRedirectInfo(redirectInfo)); - } else { - // TODO: Fetch components after state is updated. - _getComponents2['default'](nextState, function (error, components) { - if (error) { - callback(error); - } else { - // TODO: Make match a pure function and have some other API - // for "match and update state". - callback(null, null, state = _extends({}, nextState, { components: components })); - } - }); - } - }); - } - - var RouteGuid = 1; - - function getRouteID(route) { - return route.__id__ || (route.__id__ = RouteGuid++); - } - - var RouteHooks = {}; - - function getRouteHooksForRoutes(routes) { - return routes.reduce(function (hooks, route) { - hooks.push.apply(hooks, RouteHooks[getRouteID(route)]); - return hooks; - }, []); - } - - function transitionHook(location, callback) { - _matchRoutes2['default'](routes, location, function (error, nextState) { - if (nextState == null) { - // TODO: We didn't actually match anything, but hang - // onto error/nextState so we don't have to matchRoutes - // again in the listen callback. - callback(); - return; - } - - // Cache some state here so we don't have to - // matchRoutes() again in the listen callback. - partialNextState = _extends({}, nextState, { location: location }); - - var hooks = getRouteHooksForRoutes(_computeChangedRoutes3['default'](state, partialNextState).leaveRoutes); - - var result = undefined; - for (var i = 0, len = hooks.length; result == null && i < len; ++i) { - // Passing the location arg here indicates to - // the user that this is a transition hook. - result = hooks[i](location); - } - - callback(result); - }); - } - - function beforeUnloadHook() { - // Synchronously check to see if any route hooks want - // to prevent the current window/tab from closing. - if (state.routes) { - var hooks = getRouteHooksForRoutes(state.routes); - - var message = undefined; - for (var i = 0, len = hooks.length; typeof message !== 'string' && i < len; ++i) { - // Passing no args indicates to the user that this is a - // beforeunload hook. We don't know the next location. - message = hooks[i](); - } - - return message; - } - } - - var unlistenBefore = undefined, - unlistenBeforeUnload = undefined; - - /** - * Registers the given hook function to run before leaving the given route. - * - * During a normal transition, the hook function receives the next location - * as its only argument and must return either a) a prompt message to show - * the user, to make sure they want to leave the page or b) false, to prevent - * the transition. - * - * During the beforeunload event (in browsers) the hook receives no arguments. - * In this case it must return a prompt message to prevent the transition. - * - * Returns a function that may be used to unbind the listener. - */ - function listenBeforeLeavingRoute(route, hook) { - // TODO: Warn if they register for a route that isn't currently - // active. They're probably doing something wrong, like re-creating - // route objects on every location change. - var routeID = getRouteID(route); - var hooks = RouteHooks[routeID]; - - if (hooks == null) { - var thereWereNoRouteHooks = !hasAnyProperties(RouteHooks); - - hooks = RouteHooks[routeID] = [hook]; - - if (thereWereNoRouteHooks) { - // setup transition & beforeunload hooks - unlistenBefore = history.listenBefore(transitionHook); - - if (history.listenBeforeUnload) unlistenBeforeUnload = history.listenBeforeUnload(beforeUnloadHook); - } - } else if (hooks.indexOf(hook) === -1) { - hooks.push(hook); - } - - return function () { - var hooks = RouteHooks[routeID]; - - if (hooks != null) { - var newHooks = hooks.filter(function (item) { - return item !== hook; - }); - - if (newHooks.length === 0) { - delete RouteHooks[routeID]; - - if (!hasAnyProperties(RouteHooks)) { - // teardown transition & beforeunload hooks - if (unlistenBefore) { - unlistenBefore(); - unlistenBefore = null; - } - - if (unlistenBeforeUnload) { - unlistenBeforeUnload(); - unlistenBeforeUnload = null; - } - } - } else { - RouteHooks[routeID] = newHooks; - } - } - }; - } - - /** - * This is the API for stateful environments. As the location - * changes, we update state and call the listener. We can also - * gracefully handle errors and redirects. - */ - function listen(listener) { - // TODO: Only use a single history listener. Otherwise we'll - // end up with multiple concurrent calls to match. - return history.listen(function (location) { - if (state.location === location) { - listener(null, state); - } else { - match(location, function (error, redirectLocation, nextState) { - if (error) { - listener(error); - } else if (redirectLocation) { - history.transitionTo(redirectLocation); - } else if (nextState) { - listener(null, nextState); - } else { - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'Location "%s" did not match any routes', location.pathname + location.search + location.hash) : undefined; - } - }); - } - }); - } - - return _extends({}, history, { - isActive: isActive, - match: match, - listenBeforeLeavingRoute: listenBeforeLeavingRoute, - listen: listen - }); - }; -} - -exports['default'] = useRoutes; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 63 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(23); - -var ReactNoopUpdateQueue = __webpack_require__(64); - -var canDefineProperty = __webpack_require__(66); -var emptyObject = __webpack_require__(28); -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -/** - * Base class helpers for the updating state of a component. - */ -function ReactComponent(props, context, updater) { - this.props = props; - this.context = context; - this.refs = emptyObject; - // We initialize the default updater but the real one gets injected by the - // renderer. - this.updater = updater || ReactNoopUpdateQueue; -} - -ReactComponent.prototype.isReactComponent = {}; - -/** - * Sets a subset of the state. Always use this to mutate - * state. You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * There is no guarantee that calls to `setState` will run synchronously, - * as they may eventually be batched together. You can provide an optional - * callback that will be executed when the call to setState is actually - * completed. - * - * When a function is provided to setState, it will be called at some point in - * the future (not synchronously). It will be called with the up to date - * component arguments (state, props, context). These values can be different - * from this.* because your function may be called after receiveProps but before - * shouldComponentUpdate, and this new state, props, and context will not yet be - * assigned to this. - * - * @param {object|function} partialState Next partial state or function to - * produce next partial state to be merged with current state. - * @param {?function} callback Called after state is updated. - * @final - * @protected - */ -ReactComponent.prototype.setState = function (partialState, callback) { - !(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'setState(...): takes an object of state variables to update or a function which returns an object of state variables.') : _prodInvariant('85') : void 0; - this.updater.enqueueSetState(this, partialState); - if (callback) { - this.updater.enqueueCallback(this, callback, 'setState'); - } -}; - -/** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldComponentUpdate`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {?function} callback Called after update is complete. - * @final - * @protected - */ -ReactComponent.prototype.forceUpdate = function (callback) { - this.updater.enqueueForceUpdate(this); - if (callback) { - this.updater.enqueueCallback(this, callback, 'forceUpdate'); - } -}; - -/** - * Deprecated APIs. These APIs used to exist on classic React classes but since - * we would like to deprecate them, we're not going to move them over to this - * modern base class. Instead, we define a getter that warns if it's accessed. - */ -if (process.env.NODE_ENV !== 'production') { - var deprecatedAPIs = { - isMounted: ['isMounted', 'Instead, make sure to clean up subscriptions and pending requests in ' + 'componentWillUnmount to prevent memory leaks.'], - replaceState: ['replaceState', 'Refactor your code to use setState instead (see ' + 'https://github.com/facebook/react/issues/3236).'] - }; - var defineDeprecationWarning = function (methodName, info) { - if (canDefineProperty) { - Object.defineProperty(ReactComponent.prototype, methodName, { - get: function () { - process.env.NODE_ENV !== 'production' ? warning(false, '%s(...) is deprecated in plain JavaScript React classes. %s', info[0], info[1]) : void 0; - return undefined; - } - }); - } - }; - for (var fnName in deprecatedAPIs) { - if (deprecatedAPIs.hasOwnProperty(fnName)) { - defineDeprecationWarning(fnName, deprecatedAPIs[fnName]); - } - } -} - -module.exports = ReactComponent; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 64 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var warning = __webpack_require__(3); - -function warnNoop(publicInstance, callerName) { - if (process.env.NODE_ENV !== 'production') { - var constructor = publicInstance.constructor; - process.env.NODE_ENV !== 'production' ? warning(false, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, constructor && (constructor.displayName || constructor.name) || 'ReactClass') : void 0; - } -} - -/** - * This is the abstract API for an update queue. - */ -var ReactNoopUpdateQueue = { - - /** - * Checks whether or not this composite component is mounted. - * @param {ReactClass} publicInstance The instance we want to test. - * @return {boolean} True if mounted, false otherwise. - * @protected - * @final - */ - isMounted: function (publicInstance) { - return false; - }, - - /** - * Enqueue a callback that will be executed after all the pending updates - * have processed. - * - * @param {ReactClass} publicInstance The instance to use as `this` context. - * @param {?function} callback Called after state is updated. - * @internal - */ - enqueueCallback: function (publicInstance, callback) {}, - - /** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldComponentUpdate`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @internal - */ - enqueueForceUpdate: function (publicInstance) { - warnNoop(publicInstance, 'forceUpdate'); - }, - - /** - * Replaces all of the state. Always use this or `setState` to mutate state. - * You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} completeState Next state. - * @internal - */ - enqueueReplaceState: function (publicInstance, completeState) { - warnNoop(publicInstance, 'replaceState'); - }, - - /** - * Sets a subset of the state. This only exists because _pendingState is - * internal. This provides a merging strategy that is not available to deep - * properties which is confusing. TODO: Expose pendingState or don't use it - * during the merge. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} partialState Next partial state to be merged with state. - * @internal - */ - enqueueSetState: function (publicInstance, partialState) { - warnNoop(publicInstance, 'setState'); - } -}; - -module.exports = ReactNoopUpdateQueue; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 65 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactPropTypeLocationNames = {}; - -if (process.env.NODE_ENV !== 'production') { - ReactPropTypeLocationNames = { - prop: 'prop', - context: 'context', - childContext: 'child context' - }; -} - -module.exports = ReactPropTypeLocationNames; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 66 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var canDefineProperty = false; -if (process.env.NODE_ENV !== 'production') { - try { - // $FlowFixMe https://github.com/facebook/flow/issues/285 - Object.defineProperty({}, 'x', { get: function () {} }); - canDefineProperty = true; - } catch (x) { - // IE will fail on defineProperty - } -} - -module.exports = canDefineProperty; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 67 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/* global Symbol */ - -var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; -var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. - -/** - * Returns the iterator method function contained on the iterable object. - * - * Be sure to invoke the function with the iterable as context: - * - * var iteratorFn = getIteratorFn(myIterable); - * if (iteratorFn) { - * var iterator = iteratorFn.call(myIterable); - * ... - * } - * - * @param {?object} maybeIterable - * @return {?function} - */ -function getIteratorFn(maybeIterable) { - var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); - if (typeof iteratorFn === 'function') { - return iteratorFn; - } -} - -module.exports = getIteratorFn; - -/***/ }), -/* 68 */ -/***/ (function(module, exports, __webpack_require__) { - -var data = __webpack_require__(207); - -var Locale = function() { - this.data = {}; - this.data = data; -}; - -Locale.prototype = { - getSectionLocale: function(key) { - return this.data[key].locale; - }, - - getContent: function(key, handler) { - return this.data[key].getContent(handler); - }, - - getTitle: function(key) { - return this.data[key].title; - } -}; - -module.exports = Locale; - - -/***/ }), -/* 69 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var SectionHeader = React.createClass({ - displayName: "SectionHeader", - - statics: { - locale: '' - }, - - render: function render() { - var locale = SectionHeader.locale; - if (typeof window !== "undefined" && window.location.toString().indexOf(locale) === -1) { - locale = ''; - } - var fragmentid = (locale ? './' + locale + '/' : '.') + "#" + this.props.name; - return React.createElement( - "h2", - { id: this.props.name, "data-num": this.props.number }, - React.createElement( - "a", - { href: fragmentid }, - this.props.title - ) - ); - }, - componentDidMount: function componentDidMount() { - if (typeof window !== "undefined" && window.location) { - var h = window.location.hash; - if (h) { - window.location = window.location.hash; - } - } - } -}); - -module.exports = SectionHeader; - -/***/ }), -/* 70 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - A javascript Bezier curve library by Pomax. - - Based on http://pomax.github.io/bezierinfo - - This code is MIT licensed. -**/ -(function() { - "use strict"; - - // math-inlining. - var abs = Math.abs, - min = Math.min, - max = Math.max, - acos = Math.acos, - sqrt = Math.sqrt, - pi = Math.PI, - // a zero coordinate, which is surprisingly useful - ZERO = {x:0,y:0,z:0}; - - // quite needed - var utils = __webpack_require__(71); - - // not quite needed, but eventually this'll be useful... - var PolyBezier = __webpack_require__(209); - - /** - * Bezier curve constructor. The constructor argument can be one of three things: - * - * 1. array/4 of {x:..., y:..., z:...}, z optional - * 2. numerical array/8 ordered x1,y1,x2,y2,x3,y3,x4,y4 - * 3. numerical array/12 ordered x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4 - * - */ - var Bezier = function(coords) { - var args = (coords && coords.forEach) ? coords : [].slice.call(arguments); - var coordlen = false; - if(typeof args[0] === "object") { - coordlen = args.length; - var newargs = []; - args.forEach(function(point) { - ['x','y','z'].forEach(function(d) { - if(typeof point[d] !== "undefined") { - newargs.push(point[d]); - } - }); - }); - args = newargs; - } - var higher = false; - var len = args.length; - if (coordlen) { - if(coordlen>4) { - if (arguments.length !== 1) { - throw new Error("Only new Bezier(point[]) is accepted for 4th and higher order curves"); - } - higher = true; - } - } else { - if(len!==6 && len!==8 && len!==9 && len!==12) { - if (arguments.length !== 1) { - throw new Error("Only new Bezier(point[]) is accepted for 4th and higher order curves"); - } - } - } - var _3d = (!higher && (len === 9 || len === 12)) || (coords && coords[0] && typeof coords[0].z !== "undefined"); - this._3d = _3d; - var points = []; - for(var idx=0, step=(_3d ? 3 : 2); idx<len; idx+=step) { - var point = { - x: args[idx], - y: args[idx+1] - }; - if(_3d) { point.z = args[idx+2] }; - points.push(point); - } - this.order = points.length - 1; - this.points = points; - var dims = ['x','y']; - if(_3d) dims.push('z'); - this.dims = dims; - this.dimlen = dims.length; - - (function(curve) { - var order = curve.order; - var points = curve.points; - var a = utils.align(points, {p1:points[0], p2:points[order]}); - for(var i=0; i<a.length; i++) { - if(abs(a[i].y) > 0.0001) { - curve._linear = false; - return; - } - } - curve._linear = true; - }(this)); - - this._t1 = 0; - this._t2 = 1; - this.update(); - }; - - Bezier.fromSVG = function(svgString) { - var list = svgString.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/g).map(parseFloat); - var relative = /[cq]/.test(svgString); - if(!relative) return new Bezier(list); - list = list.map(function(v,i) { - return i < 2 ? v : v + list[i % 2]; - }); - return new Bezier(list); - }; - - function getABC(n,S,B,E,t) { - if(typeof t === "undefined") { t = 0.5; } - var u = utils.projectionratio(t,n), - um = 1-u, - C = { - x: u*S.x + um*E.x, - y: u*S.y + um*E.y - }, - s = utils.abcratio(t,n), - A = { - x: B.x + (B.x-C.x)/s, - y: B.y + (B.y-C.y)/s - }; - return { A:A, B:B, C:C }; - } - - Bezier.quadraticFromPoints = function(p1,p2,p3, t) { - if(typeof t === "undefined") { t = 0.5; } - // shortcuts, although they're really dumb - if(t===0) { return new Bezier(p2,p2,p3); } - if(t===1) { return new Bezier(p1,p2,p2); } - // real fitting. - var abc = getABC(2,p1,p2,p3,t); - return new Bezier(p1, abc.A, p3); - }; - - Bezier.cubicFromPoints = function(S,B,E, t,d1) { - if(typeof t === "undefined") { t = 0.5; } - var abc = getABC(3,S,B,E,t); - if(typeof d1 === "undefined") { d1 = utils.dist(B,abc.C); } - var d2 = d1 * (1-t)/t; - - var selen = utils.dist(S,E), - lx = (E.x-S.x)/selen, - ly = (E.y-S.y)/selen, - bx1 = d1 * lx, - by1 = d1 * ly, - bx2 = d2 * lx, - by2 = d2 * ly; - // derivation of new hull coordinates - var e1 = { x: B.x - bx1, y: B.y - by1 }, - e2 = { x: B.x + bx2, y: B.y + by2 }, - A = abc.A, - v1 = { x: A.x + (e1.x-A.x)/(1-t), y: A.y + (e1.y-A.y)/(1-t) }, - v2 = { x: A.x + (e2.x-A.x)/(t), y: A.y + (e2.y-A.y)/(t) }, - nc1 = { x: S.x + (v1.x-S.x)/(t), y: S.y + (v1.y-S.y)/(t) }, - nc2 = { x: E.x + (v2.x-E.x)/(1-t), y: E.y + (v2.y-E.y)/(1-t) }; - // ...done - return new Bezier(S,nc1,nc2,E); - }; - - var getUtils = function() { - return utils; - }; - - Bezier.getUtils = getUtils; - - Bezier.prototype = { - getUtils: getUtils, - valueOf: function() { - return this.toString(); - }, - toString: function() { - return utils.pointsToString(this.points); - }, - toSVG: function(relative) { - if(this._3d) return false; - var p = this.points, - x = p[0].x, - y = p[0].y, - s = ["M", x, y, (this.order===2 ? "Q":"C")]; - for(var i=1, last=p.length; i<last; i++) { - s.push(p[i].x); - s.push(p[i].y); - } - return s.join(" "); - }, - update: function() { - // one-time compute derivative coordinates - this.dpoints = []; - for(var p=this.points, d=p.length, c=d-1; d>1; d--, c--) { - var list = []; - for(var j=0, dpt; j<c; j++) { - dpt = { - x: c * (p[j+1].x - p[j].x), - y: c * (p[j+1].y - p[j].y) - }; - if(this._3d) { - dpt.z = c * (p[j+1].z - p[j].z); - } - list.push(dpt); - } - this.dpoints.push(list); - p = list; - }; - this.computedirection(); - }, - computedirection: function() { - var points = this.points; - var angle = utils.angle(points[0], points[this.order], points[1]); - this.clockwise = angle > 0; - }, - length: function() { - return utils.length(this.derivative.bind(this)); - }, - _lut: [], - getLUT: function(steps) { - steps = steps || 100; - if (this._lut.length === steps) { return this._lut; } - this._lut = []; - for(var t=0; t<=steps; t++) { - this._lut.push(this.compute(t/steps)); - } - return this._lut; - }, - on: function(point, error) { - error = error || 5; - var lut = this.getLUT(), hits = [], c, t=0; - for(var i=0; i<lut.length; i++) { - c = lut[i]; - if (utils.dist(c,point) < error) { - hits.push(c) - t += i / lut.length; - } - } - if(!hits.length) return false; - return t /= hits.length; - }, - project: function(point) { - // step 1: coarse check - var LUT = this.getLUT(), l = LUT.length-1, - closest = utils.closest(LUT, point), - mdist = closest.mdist, - mpos = closest.mpos; - if (mpos===0 || mpos===l) { - var t = mpos/l, pt = this.compute(t); - pt.t = t; - pt.d = mdist; - return pt; - } - - // step 2: fine check - var ft, t, p, d, - t1 = (mpos-1)/l, - t2 = (mpos+1)/l, - step = 0.1/l; - mdist += 1; - for(t=t1,ft=t; t<t2+step; t+=step) { - p = this.compute(t); - d = utils.dist(point, p); - if (d<mdist) { - mdist = d; - ft = t; - } - } - p = this.compute(ft); - p.t = ft; - p.d = mdist; - return p; - }, - get: function(t) { - return this.compute(t); - }, - point: function(idx) { - return this.points[idx]; - }, - compute: function(t) { - // shortcuts - if(t===0) { return this.points[0]; } - if(t===1) { return this.points[this.order]; } - - var p = this.points; - var mt = 1-t; - - // linear? - if(this.order===1) { - ret = { - x: mt*p[0].x + t*p[1].x, - y: mt*p[0].y + t*p[1].y - }; - if (this._3d) { ret.z = mt*p[0].z + t*p[1].z; } - return ret; - } - - // quadratic/cubic curve? - if(this.order<4) { - var mt2 = mt*mt, - t2 = t*t, - a,b,c,d = 0; - if(this.order===2) { - p = [p[0], p[1], p[2], ZERO]; - a = mt2; - b = mt*t*2; - c = t2; - } - else if(this.order===3) { - a = mt2*mt; - b = mt2*t*3; - c = mt*t2*3; - d = t*t2; - } - var ret = { - x: a*p[0].x + b*p[1].x + c*p[2].x + d*p[3].x, - y: a*p[0].y + b*p[1].y + c*p[2].y + d*p[3].y - }; - if(this._3d) { - ret.z = a*p[0].z + b*p[1].z + c*p[2].z + d*p[3].z; - } - return ret; - } - - // higher order curves: use de Casteljau's computation - var dCpts = JSON.parse(JSON.stringify(this.points)); - while(dCpts.length > 1) { - for (var i=0; i<dCpts.length-1; i++) { - dCpts[i] = { - x: dCpts[i].x + (dCpts[i+1].x - dCpts[i].x) * t, - y: dCpts[i].y + (dCpts[i+1].y - dCpts[i].y) * t - }; - if (typeof dCpts[i].z !== "undefined") { - dCpts[i] = dCpts[i].z + (dCpts[i+1].z - dCpts[i].z) * t - } - } - dCpts.splice(dCpts.length-1, 1); - } - return dCpts[0]; - }, - raise: function() { - var p = this.points, np = [p[0]], i, k=p.length, pi, pim; - for (var i=1; i<k; i++) { - pi = p[i]; - pim = p[i-1]; - np[i] = { - x: (k-i)/k * pi.x + i/k * pim.x, - y: (k-i)/k * pi.y + i/k * pim.y - }; - } - np[k] = p[k-1]; - return new Bezier(np); - }, - derivative: function(t) { - var mt = 1-t, - a,b,c=0, - p = this.dpoints[0]; - if(this.order===2) { p = [p[0], p[1], ZERO]; a = mt; b = t; } - if(this.order===3) { a = mt*mt; b = mt*t*2; c = t*t; } - var ret = { - x: a*p[0].x + b*p[1].x + c*p[2].x, - y: a*p[0].y + b*p[1].y + c*p[2].y - }; - if(this._3d) { - ret.z = a*p[0].z + b*p[1].z + c*p[2].z; - } - return ret; - }, - inflections: function() { - return utils.inflections(this.points); - }, - normal: function(t) { - return this._3d ? this.__normal3(t) : this.__normal2(t); - }, - __normal2: function(t) { - var d = this.derivative(t); - var q = sqrt(d.x*d.x + d.y*d.y) - return { x: -d.y/q, y: d.x/q }; - }, - __normal3: function(t) { - // see http://stackoverflow.com/questions/25453159 - var r1 = this.derivative(t), - r2 = this.derivative(t+0.01), - q1 = sqrt(r1.x*r1.x + r1.y*r1.y + r1.z*r1.z), - q2 = sqrt(r2.x*r2.x + r2.y*r2.y + r2.z*r2.z); - r1.x /= q1; r1.y /= q1; r1.z /= q1; - r2.x /= q2; r2.y /= q2; r2.z /= q2; - // cross product - var c = { - x: r2.y*r1.z - r2.z*r1.y, - y: r2.z*r1.x - r2.x*r1.z, - z: r2.x*r1.y - r2.y*r1.x - }; - var m = sqrt(c.x*c.x + c.y*c.y + c.z*c.z); - c.x /= m; c.y /= m; c.z /= m; - // rotation matrix - var R = [ c.x*c.x, c.x*c.y-c.z, c.x*c.z+c.y, - c.x*c.y+c.z, c.y*c.y, c.y*c.z-c.x, - c.x*c.z-c.y, c.y*c.z+c.x, c.z*c.z ]; - // normal vector: - var n = { - x: R[0] * r1.x + R[1] * r1.y + R[2] * r1.z, - y: R[3] * r1.x + R[4] * r1.y + R[5] * r1.z, - z: R[6] * r1.x + R[7] * r1.y + R[8] * r1.z - }; - return n; - }, - hull: function(t) { - var p = this.points, - _p = [], - pt, - q = [], - idx = 0, - i=0, - l=0; - q[idx++] = p[0]; - q[idx++] = p[1]; - q[idx++] = p[2]; - if(this.order === 3) { q[idx++] = p[3]; } - // we lerp between all points at each iteration, until we have 1 point left. - while(p.length>1) { - _p = []; - for(i=0, l=p.length-1; i<l; i++) { - pt = utils.lerp(t,p[i],p[i+1]); - q[idx++] = pt; - _p.push(pt); - } - p = _p; - } - return q; - }, - split: function(t1, t2) { - // shortcuts - if(t1===0 && !!t2) { return this.split(t2).left; } - if(t2===1) { return this.split(t1).right; } - - // no shortcut: use "de Casteljau" iteration. - var q = this.hull(t1); - var result = { - left: this.order === 2 ? new Bezier([q[0],q[3],q[5]]) : new Bezier([q[0],q[4],q[7],q[9]]), - right: this.order === 2 ? new Bezier([q[5],q[4],q[2]]) : new Bezier([q[9],q[8],q[6],q[3]]), - span: q - }; - - // make sure we bind _t1/_t2 information! - result.left._t1 = utils.map(0, 0,1, this._t1,this._t2); - result.left._t2 = utils.map(t1, 0,1, this._t1,this._t2); - result.right._t1 = utils.map(t1, 0,1, this._t1,this._t2); - result.right._t2 = utils.map(1, 0,1, this._t1,this._t2); - - // if we have no t2, we're done - if(!t2) { return result; } - - // if we have a t2, split again: - t2 = utils.map(t2,t1,1,0,1); - var subsplit = result.right.split(t2); - return subsplit.left; - }, - extrema: function() { - var dims = this.dims, - result={}, - roots=[], - p, mfn; - dims.forEach(function(dim) { - mfn = function(v) { return v[dim]; }; - p = this.dpoints[0].map(mfn); - result[dim] = utils.droots(p); - if(this.order === 3) { - p = this.dpoints[1].map(mfn); - result[dim] = result[dim].concat(utils.droots(p)); - } - result[dim] = result[dim].filter(function(t) { return (t>=0 && t<=1); }); - roots = roots.concat(result[dim].sort()); - }.bind(this)); - roots = roots.sort().filter(function(v,idx) { return (roots.indexOf(v) === idx); }); - result.values = roots; - return result; - }, - bbox: function() { - var extrema = this.extrema(), result = {}; - this.dims.forEach(function(d) { - result[d] = utils.getminmax(this, d, extrema[d]); - }.bind(this)); - return result; - }, - overlaps: function(curve) { - var lbbox = this.bbox(), - tbbox = curve.bbox(); - return utils.bboxoverlap(lbbox,tbbox); - }, - offset: function(t, d) { - if(typeof d !== "undefined") { - var c = this.get(t); - var n = this.normal(t); - var ret = { - c: c, - n: n, - x: c.x + n.x * d, - y: c.y + n.y * d - }; - if(this._3d) { - ret.z = c.z + n.z * d; - }; - return ret; - } - if(this._linear) { - var nv = this.normal(0); - var coords = this.points.map(function(p) { - var ret = { - x: p.x + t * nv.x, - y: p.y + t * nv.y - }; - if(p.z && n.z) { ret.z = p.z + t * nv.z; } - return ret; - }); - return [new Bezier(coords)]; - } - var reduced = this.reduce(); - return reduced.map(function(s) { - return s.scale(t); - }); - }, - simple: function() { - if(this.order===3) { - var a1 = utils.angle(this.points[0], this.points[3], this.points[1]); - var a2 = utils.angle(this.points[0], this.points[3], this.points[2]); - if(a1>0 && a2<0 || a1<0 && a2>0) return false; - } - var n1 = this.normal(0); - var n2 = this.normal(1); - var s = n1.x*n2.x + n1.y*n2.y; - if(this._3d) { s += n1.z*n2.z; } - var angle = abs(acos(s)); - return angle < pi/3; - }, - reduce: function() { - var i, t1=0, t2=0, step=0.01, segment, pass1=[], pass2=[]; - // first pass: split on extrema - var extrema = this.extrema().values; - if(extrema.indexOf(0)===-1) { extrema = [0].concat(extrema); } - if(extrema.indexOf(1)===-1) { extrema.push(1); } - - for(t1=extrema[0], i=1; i<extrema.length; i++) { - t2 = extrema[i]; - segment = this.split(t1,t2); - segment._t1 = t1; - segment._t2 = t2; - pass1.push(segment); - t1 = t2; - } - - // second pass: further reduce these segments to simple segments - pass1.forEach(function(p1) { - t1=0; - t2=0; - while(t2 <= 1) { - for(t2=t1+step; t2<=1+step; t2+=step) { - segment = p1.split(t1,t2); - if(!segment.simple()) { - t2 -= step; - if(abs(t1-t2)<step) { - // we can never form a reduction - return []; - } - segment = p1.split(t1,t2); - segment._t1 = utils.map(t1,0,1,p1._t1,p1._t2); - segment._t2 = utils.map(t2,0,1,p1._t1,p1._t2); - pass2.push(segment); - t1 = t2; - break; - } - } - } - if(t1<1) { - segment = p1.split(t1,1); - segment._t1 = utils.map(t1,0,1,p1._t1,p1._t2); - segment._t2 = p1._t2; - pass2.push(segment); - } - }); - return pass2; - }, - scale: function(d) { - var order = this.order; - var distanceFn = false - if(typeof d === "function") { distanceFn = d; } - if(distanceFn && order === 2) { return this.raise().scale(distanceFn); } - - // TODO: add special handling for degenerate (=linear) curves. - var clockwise = this.clockwise; - var r1 = distanceFn ? distanceFn(0) : d; - var r2 = distanceFn ? distanceFn(1) : d; - var v = [ this.offset(0,10), this.offset(1,10) ]; - var o = utils.lli4(v[0], v[0].c, v[1], v[1].c); - if(!o) { throw new Error("cannot scale this curve. Try reducing it first."); } - // move all points by distance 'd' wrt the origin 'o' - var points=this.points, np=[]; - - // move end points by fixed distance along normal. - [0,1].forEach(function(t) { - var p = np[t*order] = utils.copy(points[t*order]); - p.x += (t?r2:r1) * v[t].n.x; - p.y += (t?r2:r1) * v[t].n.y; - }.bind(this)); - - if (!distanceFn) { - // move control points to lie on the intersection of the offset - // derivative vector, and the origin-through-control vector - [0,1].forEach(function(t) { - if(this.order===2 && !!t) return; - var p = np[t*order]; - var d = this.derivative(t); - var p2 = { x: p.x + d.x, y: p.y + d.y }; - np[t+1] = utils.lli4(p, p2, o, points[t+1]); - }.bind(this)); - return new Bezier(np); - } - - // move control points by "however much necessary to - // ensure the correct tangent to endpoint". - [0,1].forEach(function(t) { - if(this.order===2 && !!t) return; - var p = points[t+1]; - var ov = { - x: p.x - o.x, - y: p.y - o.y - }; - var rc = distanceFn ? distanceFn((t+1)/order) : d; - if(distanceFn && !clockwise) rc = -rc; - var m = sqrt(ov.x*ov.x + ov.y*ov.y); - ov.x /= m; - ov.y /= m; - np[t+1] = { - x: p.x + rc*ov.x, - y: p.y + rc*ov.y - } - }.bind(this)); - return new Bezier(np); - }, - outline: function(d1, d2, d3, d4) { - d2 = (typeof d2 === "undefined") ? d1 : d2; - var reduced = this.reduce(), - len = reduced.length, - fcurves = [], - bcurves = [], - p, - alen = 0, - tlen = this.length(); - - var graduated = (typeof d3 !== "undefined" && typeof d4 !== "undefined"); - - function linearDistanceFunction(s,e, tlen,alen,slen) { - return function (v) { - var f1 = alen/tlen, f2 = (alen+slen)/tlen, d = e-s; - return utils.map(v, 0,1, s+f1*d, s+f2*d); - }; - }; - - // form curve oulines - reduced.forEach(function(segment) { - slen = segment.length(); - if (graduated) { - fcurves.push(segment.scale( linearDistanceFunction( d1, d3, tlen,alen,slen) )); - bcurves.push(segment.scale( linearDistanceFunction(-d2,-d4, tlen,alen,slen) )); - } else { - fcurves.push(segment.scale( d1)); - bcurves.push(segment.scale(-d2)); - } - alen += slen; - }); - - // reverse the "return" outline - bcurves = bcurves.map(function(s) { - p = s.points; - if(p[3]) { s.points = [p[3],p[2],p[1],p[0]]; } - else { s.points = [p[2],p[1],p[0]]; } - return s; - }).reverse(); - - // form the endcaps as lines - var fs = fcurves[0].points[0], - fe = fcurves[len-1].points[fcurves[len-1].points.length-1], - bs = bcurves[len-1].points[bcurves[len-1].points.length-1], - be = bcurves[0].points[0], - ls = utils.makeline(bs,fs), - le = utils.makeline(fe,be), - segments = [ls].concat(fcurves).concat([le]).concat(bcurves), - slen = segments.length; - - return new PolyBezier(segments); - }, - outlineshapes: function(d1, d2, curveIntersectionThreshold) { - d2 = d2 || d1; - var outline = this.outline(d1,d2).curves; - var shapes = []; - for(var i=1, len=outline.length; i < len/2; i++) { - var shape = utils.makeshape(outline[i], outline[len-i], curveIntersectionThreshold); - shape.startcap.virtual = (i > 1); - shape.endcap.virtual = (i < len/2-1); - shapes.push(shape); - } - return shapes; - }, - intersects: function(curve, curveIntersectionThreshold) { - if(!curve) return this.selfintersects(curveIntersectionThreshold); - if(curve.p1 && curve.p2) { - return this.lineIntersects(curve); - } - if(curve instanceof Bezier) { curve = curve.reduce(); } - return this.curveintersects(this.reduce(), curve, curveIntersectionThreshold); - }, - lineIntersects: function(line) { - var mx = min(line.p1.x, line.p2.x), - my = min(line.p1.y, line.p2.y), - MX = max(line.p1.x, line.p2.x), - MY = max(line.p1.y, line.p2.y), - self=this; - return utils.roots(this.points, line).filter(function(t) { - var p = self.get(t); - return utils.between(p.x, mx, MX) && utils.between(p.y, my, MY); - }); - }, - selfintersects: function(curveIntersectionThreshold) { - var reduced = this.reduce(); - // "simple" curves cannot intersect with their direct - // neighbour, so for each segment X we check whether - // it intersects [0:x-2][x+2:last]. - var i,len=reduced.length-2,results=[],result,left,right; - for(i=0; i<len; i++) { - left = reduced.slice(i,i+1); - right = reduced.slice(i+2); - result = this.curveintersects(left, right, curveIntersectionThreshold); - results = results.concat( result ); - } - return results; - }, - curveintersects: function(c1, c2, curveIntersectionThreshold) { - var pairs = []; - // step 1: pair off any overlapping segments - c1.forEach(function(l) { - c2.forEach(function(r) { - if(l.overlaps(r)) { - pairs.push({ left: l, right: r }); - } - }); - }); - // step 2: for each pairing, run through the convergence algorithm. - var intersections = []; - pairs.forEach(function(pair) { - var result = utils.pairiteration(pair.left, pair.right, curveIntersectionThreshold); - if(result.length > 0) { - intersections = intersections.concat(result); - } - }); - return intersections; - }, - arcs: function(errorThreshold) { - errorThreshold = errorThreshold || 0.5; - var circles = []; - return this._iterate(errorThreshold, circles); - }, - _error: function(pc, np1, s, e) { - var q = (e - s) / 4, - c1 = this.get(s + q), - c2 = this.get(e - q), - ref = utils.dist(pc, np1), - d1 = utils.dist(pc, c1), - d2 = utils.dist(pc, c2); - return abs(d1-ref) + abs(d2-ref); - }, - _iterate: function(errorThreshold, circles) { - var s = 0, e = 1, safety; - // we do a binary search to find the "good `t` closest to no-longer-good" - do { - safety=0; - - // step 1: start with the maximum possible arc - e = 1; - - // points: - var np1 = this.get(s), np2, np3, arc, prev_arc; - - // booleans: - var curr_good = false, prev_good = false, done; - - // numbers: - var m = e, prev_e = 1, step = 0; - - // step 2: find the best possible arc - do { - prev_good = curr_good; - prev_arc = arc; - m = (s + e)/2; - step++; - - np2 = this.get(m); - np3 = this.get(e); - - arc = utils.getccenter(np1, np2, np3); - - //also save the t values - arc.interval = { - start: s, - end: e - }; - - var error = this._error(arc, np1, s, e); - curr_good = (error <= errorThreshold); - - done = prev_good && !curr_good; - if(!done) prev_e = e; - - // this arc is fine: we can move 'e' up to see if we can find a wider arc - if(curr_good) { - // if e is already at max, then we're done for this arc. - if (e >= 1) { - prev_e = 1; - prev_arc = arc; - break; - } - // if not, move it up by half the iteration distance - e = e + (e-s)/2; - } - - // this is a bad arc: we need to move 'e' down to find a good arc - else { - e = m; - } - } - while(!done && safety++<100); - - if(safety>=100) { - console.error("arc abstraction somehow failed..."); - break; - } - - // console.log("[F] arc found", s, prev_e, prev_arc.x, prev_arc.y, prev_arc.s, prev_arc.e); - - prev_arc = (prev_arc ? prev_arc : arc); - circles.push(prev_arc); - s = prev_e; - } - while(e < 1); - return circles; - } - }; - - module.exports = Bezier; - -}()); - - -/***/ }), -/* 71 */ -/***/ (function(module, exports, __webpack_require__) { - -(function() { - "use strict"; - - // math-inlining. - var abs = Math.abs, - cos = Math.cos, - sin = Math.sin, - acos = Math.acos, - atan2 = Math.atan2, - sqrt = Math.sqrt, - pow = Math.pow, - // cube root function yielding real roots - crt = function(v) { return (v<0) ? -pow(-v,1/3) : pow(v,1/3); }, - // trig constants - pi = Math.PI, - tau = 2*pi, - quart = pi/2, - // float precision significant decimal - epsilon = 0.000001; - - // Bezier utility functions - var utils = { - // Legendre-Gauss abscissae with n=24 (x_i values, defined at i=n as the roots of the nth order Legendre polynomial Pn(x)) - Tvalues: [ - -0.0640568928626056260850430826247450385909, - 0.0640568928626056260850430826247450385909, - -0.1911188674736163091586398207570696318404, - 0.1911188674736163091586398207570696318404, - -0.3150426796961633743867932913198102407864, - 0.3150426796961633743867932913198102407864, - -0.4337935076260451384870842319133497124524, - 0.4337935076260451384870842319133497124524, - -0.5454214713888395356583756172183723700107, - 0.5454214713888395356583756172183723700107, - -0.6480936519369755692524957869107476266696, - 0.6480936519369755692524957869107476266696, - -0.7401241915785543642438281030999784255232, - 0.7401241915785543642438281030999784255232, - -0.8200019859739029219539498726697452080761, - 0.8200019859739029219539498726697452080761, - -0.8864155270044010342131543419821967550873, - 0.8864155270044010342131543419821967550873, - -0.9382745520027327585236490017087214496548, - 0.9382745520027327585236490017087214496548, - -0.9747285559713094981983919930081690617411, - 0.9747285559713094981983919930081690617411, - -0.9951872199970213601799974097007368118745, - 0.9951872199970213601799974097007368118745 - ], - - // Legendre-Gauss weights with n=24 (w_i values, defined by a function linked to in the Bezier primer article) - Cvalues: [ - 0.1279381953467521569740561652246953718517, - 0.1279381953467521569740561652246953718517, - 0.1258374563468282961213753825111836887264, - 0.1258374563468282961213753825111836887264, - 0.1216704729278033912044631534762624256070, - 0.1216704729278033912044631534762624256070, - 0.1155056680537256013533444839067835598622, - 0.1155056680537256013533444839067835598622, - 0.1074442701159656347825773424466062227946, - 0.1074442701159656347825773424466062227946, - 0.0976186521041138882698806644642471544279, - 0.0976186521041138882698806644642471544279, - 0.0861901615319532759171852029837426671850, - 0.0861901615319532759171852029837426671850, - 0.0733464814110803057340336152531165181193, - 0.0733464814110803057340336152531165181193, - 0.0592985849154367807463677585001085845412, - 0.0592985849154367807463677585001085845412, - 0.0442774388174198061686027482113382288593, - 0.0442774388174198061686027482113382288593, - 0.0285313886289336631813078159518782864491, - 0.0285313886289336631813078159518782864491, - 0.0123412297999871995468056670700372915759, - 0.0123412297999871995468056670700372915759 - ], - - arcfn: function(t, derivativeFn) { - var d = derivativeFn(t); - var l = d.x*d.x + d.y*d.y; - if(typeof d.z !== "undefined") { - l += d.z*d.z; - } - return sqrt(l); - }, - - between: function(v, m, M) { - return (m <= v && v <= M) || utils.approximately(v, m) || utils.approximately(v, M); - }, - - approximately: function(a,b,precision) { - return abs(a-b) <= (precision || epsilon); - }, - - length: function(derivativeFn) { - var z=0.5,sum=0,len=utils.Tvalues.length,i,t; - for(i=0; i<len; i++) { - t = z * utils.Tvalues[i] + z; - sum += utils.Cvalues[i] * utils.arcfn(t,derivativeFn); - } - return z * sum; - }, - - map: function(v, ds,de, ts,te) { - var d1 = de-ds, d2 = te-ts, v2 = v-ds, r = v2/d1; - return ts + d2*r; - }, - - lerp: function(r, v1, v2) { - var ret = { - x: v1.x + r*(v2.x-v1.x), - y: v1.y + r*(v2.y-v1.y) - }; - if(!!v1.z && !!v2.z) { - ret.z = v1.z + r*(v2.z-v1.z); - } - return ret; - }, - - pointToString: function(p) { - var s = p.x+"/"+p.y; - if(typeof p.z !== "undefined") { - s += "/"+p.z; - } - return s; - }, - - pointsToString: function(points) { - return "[" + points.map(utils.pointToString).join(", ") + "]"; - }, - - copy: function(obj) { - return JSON.parse(JSON.stringify(obj)); - }, - - angle: function(o,v1,v2) { - var dx1 = v1.x - o.x, - dy1 = v1.y - o.y, - dx2 = v2.x - o.x, - dy2 = v2.y - o.y, - cross = dx1*dy2 - dy1*dx2, - m1 = sqrt(dx1*dx1+dy1*dy1), - m2 = sqrt(dx2*dx2+dy2*dy2), - dot; - dx1/=m1; dy1/=m1; dx2/=m2; dy2/=m2; - dot = dx1*dx2 + dy1*dy2; - return atan2(cross, dot); - }, - - // round as string, to avoid rounding errors - round: function(v, d) { - var s = '' + v; - var pos = s.indexOf("."); - return parseFloat(s.substring(0,pos+1+d)); - }, - - dist: function(p1, p2) { - var dx = p1.x - p2.x, - dy = p1.y - p2.y; - return sqrt(dx*dx+dy*dy); - }, - - closest: function(LUT, point) { - var mdist = pow(2,63), mpos, d; - LUT.forEach(function(p, idx) { - d = utils.dist(point, p); - if (d<mdist) { - mdist = d; - mpos = idx; - } - }); - return { mdist:mdist, mpos:mpos }; - }, - - abcratio: function(t, n) { - // see ratio(t) note on http://pomax.github.io/bezierinfo/#abc - if (n!==2 && n!==3) { - return false; - } - if (typeof t === "undefined") { - t = 0.5; - } else if (t===0 || t===1) { - return t; - } - var bottom = pow(t,n) + pow(1-t,n), top = bottom - 1; - return abs(top/bottom); - }, - - projectionratio: function(t, n) { - // see u(t) note on http://pomax.github.io/bezierinfo/#abc - if (n!==2 && n!==3) { - return false; - } - if (typeof t === "undefined") { - t = 0.5; - } else if (t===0 || t===1) { - return t; - } - var top = pow(1-t, n), bottom = pow(t,n) + top; - return top/bottom; - }, - - lli8: function(x1,y1,x2,y2,x3,y3,x4,y4) { - var nx=(x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4), - ny=(x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4), - d=(x1-x2)*(y3-y4)-(y1-y2)*(x3-x4); - if(d==0) { return false; } - return { x: nx/d, y: ny/d }; - }, - - lli4: function(p1,p2,p3,p4) { - var x1 = p1.x, y1 = p1.y, - x2 = p2.x, y2 = p2.y, - x3 = p3.x, y3 = p3.y, - x4 = p4.x, y4 = p4.y; - return utils.lli8(x1,y1,x2,y2,x3,y3,x4,y4); - }, - - lli: function(v1, v2) { - return utils.lli4(v1,v1.c,v2,v2.c); - }, - - makeline: function(p1,p2) { - var Bezier = __webpack_require__(70); - var x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y, dx = (x2-x1)/3, dy = (y2-y1)/3; - return new Bezier(x1, y1, x1+dx, y1+dy, x1+2*dx, y1+2*dy, x2, y2); - }, - - findbbox: function(sections) { - var mx=99999999,my=mx,MX=-mx,MY=MX; - sections.forEach(function(s) { - var bbox = s.bbox(); - if(mx > bbox.x.min) mx = bbox.x.min; - if(my > bbox.y.min) my = bbox.y.min; - if(MX < bbox.x.max) MX = bbox.x.max; - if(MY < bbox.y.max) MY = bbox.y.max; - }); - return { - x: { min: mx, mid:(mx+MX)/2, max: MX, size:MX-mx }, - y: { min: my, mid:(my+MY)/2, max: MY, size:MY-my } - } - }, - - shapeintersections: function(s1, bbox1, s2, bbox2, curveIntersectionThreshold) { - if(!utils.bboxoverlap(bbox1, bbox2)) return []; - var intersections = []; - var a1 = [s1.startcap, s1.forward, s1.back, s1.endcap]; - var a2 = [s2.startcap, s2.forward, s2.back, s2.endcap]; - a1.forEach(function(l1) { - if(l1.virtual) return; - a2.forEach(function(l2) { - if(l2.virtual) return; - var iss = l1.intersects(l2, curveIntersectionThreshold); - if(iss.length>0) { - iss.c1 = l1; - iss.c2 = l2; - iss.s1 = s1; - iss.s2 = s2; - intersections.push(iss); - } - }); - }); - return intersections; - }, - - makeshape: function(forward, back, curveIntersectionThreshold) { - var bpl = back.points.length; - var fpl = forward.points.length; - var start = utils.makeline(back.points[bpl-1], forward.points[0]); - var end = utils.makeline(forward.points[fpl-1], back.points[0]); - var shape = { - startcap: start, - forward: forward, - back: back, - endcap: end, - bbox: utils.findbbox([start, forward, back, end]) - }; - var self = utils; - shape.intersections = function(s2) { - return self.shapeintersections(shape,shape.bbox,s2,s2.bbox, curveIntersectionThreshold); - }; - return shape; - }, - - getminmax: function(curve, d, list) { - if(!list) return { min:0, max:0 }; - var min=0xFFFFFFFFFFFFFFFF, max=-min,t,c; - if(list.indexOf(0)===-1) { list = [0].concat(list); } - if(list.indexOf(1)===-1) { list.push(1); } - for(var i=0,len=list.length; i<len; i++) { - t = list[i]; - c = curve.get(t); - if(c[d] < min) { min = c[d]; } - if(c[d] > max) { max = c[d]; } - } - return { min:min, mid:(min+max)/2, max:max, size:max-min }; - }, - - align: function(points, line) { - var tx = line.p1.x, - ty = line.p1.y, - a = -atan2(line.p2.y-ty, line.p2.x-tx), - d = function(v) { - return { - x: (v.x-tx)*cos(a) - (v.y-ty)*sin(a), - y: (v.x-tx)*sin(a) + (v.y-ty)*cos(a) - }; - }; - return points.map(d); - }, - - roots: function(points, line) { - line = line || {p1:{x:0,y:0},p2:{x:1,y:0}}; - var order = points.length - 1; - var p = utils.align(points, line); - var reduce = function(t) { return 0<=t && t <=1; }; - - if (order === 2) { - var a = p[0].y, - b = p[1].y, - c = p[2].y, - d = a - 2*b + c; - if(d!==0) { - var m1 = -sqrt(b*b-a*c), - m2 = -a+b, - v1 = -( m1+m2)/d, - v2 = -(-m1+m2)/d; - return [v1, v2].filter(reduce); - } - else if(b!==c && d===0) { - return [ (2*b-c)/2*(b-c) ].filter(reduce); - } - return []; - } - - // see http://www.trans4mind.com/personal_development/mathematics/polynomials/cubicAlgebra.htm - var pa = p[0].y, - pb = p[1].y, - pc = p[2].y, - pd = p[3].y, - d = (-pa + 3*pb - 3*pc + pd), - a = (3*pa - 6*pb + 3*pc) / d, - b = (-3*pa + 3*pb) / d, - c = pa / d, - p = (3*b - a*a)/3, - p3 = p/3, - q = (2*a*a*a - 9*a*b + 27*c)/27, - q2 = q/2, - discriminant = q2*q2 + p3*p3*p3, - u1,v1,x1,x2,x3; - if (discriminant < 0) { - var mp3 = -p/3, - mp33 = mp3*mp3*mp3, - r = sqrt( mp33 ), - t = -q/(2*r), - cosphi = t<-1 ? -1 : t>1 ? 1 : t, - phi = acos(cosphi), - crtr = crt(r), - t1 = 2*crtr; - x1 = t1 * cos(phi/3) - a/3; - x2 = t1 * cos((phi+tau)/3) - a/3; - x3 = t1 * cos((phi+2*tau)/3) - a/3; - return [x1, x2, x3].filter(reduce); - } else if(discriminant === 0) { - u1 = q2 < 0 ? crt(-q2) : -crt(q2); - x1 = 2*u1-a/3; - x2 = -u1 - a/3; - return [x1,x2].filter(reduce); - } else { - var sd = sqrt(discriminant); - u1 = crt(-q2+sd); - v1 = crt(q2+sd); - return [u1-v1-a/3].filter(reduce);; - } - }, - - droots: function(p) { - // quadratic roots are easy - if(p.length === 3) { - var a = p[0], - b = p[1], - c = p[2], - d = a - 2*b + c; - if(d!==0) { - var m1 = -sqrt(b*b-a*c), - m2 = -a+b, - v1 = -( m1+m2)/d, - v2 = -(-m1+m2)/d; - return [v1, v2]; - } - else if(b!==c && d===0) { - return [(2*b-c)/(2*(b-c))]; - } - return []; - } - - // linear roots are even easier - if(p.length === 2) { - var a = p[0], b = p[1]; - if(a!==b) { - return [a/(a-b)]; - } - return []; - } - }, - - inflections: function(points) { - if (points.length<4) return []; - - // FIXME: TODO: add in inflection abstraction for quartic+ curves? - - var p = utils.align(points, { p1: points[0], p2: points.slice(-1)[0] }), - a = p[2].x * p[1].y, - b = p[3].x * p[1].y, - c = p[1].x * p[2].y, - d = p[3].x * p[2].y, - v1 = 18 * (-3*a + 2*b + 3*c - d), - v2 = 18 * (3*a - b - 3*c), - v3 = 18 * (c - a); - - if (utils.approximately(v1,0)) return []; - - var trm = v2*v2 - 4*v1*v3, - sq = Math.sqrt(trm), - d = 2 * v1; - - if (utils.approximately(d,0)) return []; - - return [(sq-v2)/d, -(v2+sq)/d].filter(function(r) { - return (0 <= r && r <= 1); - }); - }, - - bboxoverlap: function(b1,b2) { - var dims=['x','y'],len=dims.length,i,dim,l,t,d - for(i=0; i<len; i++) { - dim = dims[i]; - l = b1[dim].mid; - t = b2[dim].mid; - d = (b1[dim].size + b2[dim].size)/2; - if(abs(l-t) >= d) return false; - } - return true; - }, - - expandbox: function(bbox, _bbox) { - if(_bbox.x.min < bbox.x.min) { bbox.x.min = _bbox.x.min; } - if(_bbox.y.min < bbox.y.min) { bbox.y.min = _bbox.y.min; } - if(_bbox.z && _bbox.z.min < bbox.z.min) { bbox.z.min = _bbox.z.min; } - if(_bbox.x.max > bbox.x.max) { bbox.x.max = _bbox.x.max; } - if(_bbox.y.max > bbox.y.max) { bbox.y.max = _bbox.y.max; } - if(_bbox.z && _bbox.z.max > bbox.z.max) { bbox.z.max = _bbox.z.max; } - bbox.x.mid = (bbox.x.min + bbox.x.max)/2; - bbox.y.mid = (bbox.y.min + bbox.y.max)/2; - if(bbox.z) { bbox.z.mid = (bbox.z.min + bbox.z.max)/2; } - bbox.x.size = bbox.x.max - bbox.x.min; - bbox.y.size = bbox.y.max - bbox.y.min; - if(bbox.z) { bbox.z.size = bbox.z.max - bbox.z.min; } - }, - - pairiteration: function(c1, c2, curveIntersectionThreshold) { - var c1b = c1.bbox(), - c2b = c2.bbox(), - r = 100000, - threshold = curveIntersectionThreshold || 0.5; - if(c1b.x.size + c1b.y.size < threshold && c2b.x.size + c2b.y.size < threshold) { - return [ ((r * (c1._t1+c1._t2)/2)|0)/r + "/" + ((r * (c2._t1+c2._t2)/2)|0)/r ]; - } - var cc1 = c1.split(0.5), - cc2 = c2.split(0.5), - pairs = [ - {left: cc1.left, right: cc2.left }, - {left: cc1.left, right: cc2.right }, - {left: cc1.right, right: cc2.right }, - {left: cc1.right, right: cc2.left }]; - pairs = pairs.filter(function(pair) { - return utils.bboxoverlap(pair.left.bbox(),pair.right.bbox()); - }); - var results = []; - if(pairs.length === 0) return results; - pairs.forEach(function(pair) { - results = results.concat( - utils.pairiteration(pair.left, pair.right, threshold) - ); - }) - results = results.filter(function(v,i) { - return results.indexOf(v) === i; - }); - return results; - }, - - getccenter: function(p1,p2,p3) { - var dx1 = (p2.x - p1.x), - dy1 = (p2.y - p1.y), - dx2 = (p3.x - p2.x), - dy2 = (p3.y - p2.y); - var dx1p = dx1 * cos(quart) - dy1 * sin(quart), - dy1p = dx1 * sin(quart) + dy1 * cos(quart), - dx2p = dx2 * cos(quart) - dy2 * sin(quart), - dy2p = dx2 * sin(quart) + dy2 * cos(quart); - // chord midpoints - var mx1 = (p1.x + p2.x)/2, - my1 = (p1.y + p2.y)/2, - mx2 = (p2.x + p3.x)/2, - my2 = (p2.y + p3.y)/2; - // midpoint offsets - var mx1n = mx1 + dx1p, - my1n = my1 + dy1p, - mx2n = mx2 + dx2p, - my2n = my2 + dy2p; - // intersection of these lines: - var arc = utils.lli8(mx1,my1,mx1n,my1n, mx2,my2,mx2n,my2n), - r = utils.dist(arc,p1), - // arc start/end values, over mid point: - s = atan2(p1.y - arc.y, p1.x - arc.x), - m = atan2(p2.y - arc.y, p2.x - arc.x), - e = atan2(p3.y - arc.y, p3.x - arc.x), - _; - // determine arc direction (cw/ccw correction) - if (s<e) { - // if s<m<e, arc(s, e) - // if m<s<e, arc(e, s + tau) - // if s<e<m, arc(e, s + tau) - if (s>m || m>e) { s += tau; } - if (s>e) { _=e; e=s; s=_; } - } else { - // if e<m<s, arc(e, s) - // if m<e<s, arc(s, e + tau) - // if e<s<m, arc(s, e + tau) - if (e<m && m<s) { _=e; e=s; s=_; } else { e += tau; } - } - // assign and done. - arc.s = s; - arc.e = e; - arc.r = r; - return arc; - } - }; - - module.exports = utils; -}()); - - -/***/ }), -/* 72 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -/** - * Copyright (c) 2013-present, Facebook, 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. - * - * @typechecks - */ - -var emptyFunction = __webpack_require__(12); - -/** - * Upstream version of event listener. Does not take into account specific - * nature of platform. - */ -var EventListener = { - /** - * Listen to DOM events during the bubble phase. - * - * @param {DOMEventTarget} target DOM element to register listener on. - * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. - * @param {function} callback Callback function. - * @return {object} Object with a `remove` method. - */ - listen: function listen(target, eventType, callback) { - if (target.addEventListener) { - target.addEventListener(eventType, callback, false); - return { - remove: function remove() { - target.removeEventListener(eventType, callback, false); - } - }; - } else if (target.attachEvent) { - target.attachEvent('on' + eventType, callback); - return { - remove: function remove() { - target.detachEvent('on' + eventType, callback); - } - }; - } - }, - - /** - * Listen to DOM events during the capture phase. - * - * @param {DOMEventTarget} target DOM element to register listener on. - * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. - * @param {function} callback Callback function. - * @return {object} Object with a `remove` method. - */ - capture: function capture(target, eventType, callback) { - if (target.addEventListener) { - target.addEventListener(eventType, callback, true); - return { - remove: function remove() { - target.removeEventListener(eventType, callback, true); - } - }; - } else { - if (process.env.NODE_ENV !== 'production') { - console.error('Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.'); - } - return { - remove: emptyFunction - }; - } - }, - - registerDefault: function registerDefault() {} -}; - -module.exports = EventListener; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 73 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * @param {DOMElement} node input/textarea to focus - */ - -function focusNode(node) { - // IE8 can throw "Can't move focus to the control because it is invisible, - // not enabled, or of a type that does not accept the focus." for all kinds of - // reasons that are too expensive and fragile to test. - try { - node.focus(); - } catch (e) {} -} - -module.exports = focusNode; - -/***/ }), -/* 74 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -/* eslint-disable fb-www/typeof-undefined */ - -/** - * Same as document.activeElement but wraps in a try-catch block. In IE it is - * not safe to call document.activeElement if there is nothing focused. - * - * The activeElement will be null only if the document or document body is not - * yet defined. - */ -function getActiveElement() /*?DOMElement*/{ - if (typeof document === 'undefined') { - return null; - } - try { - return document.activeElement || document.body; - } catch (e) { - return document.body; - } -} - -module.exports = getActiveElement; - -/***/ }), -/* 75 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.addEventListener = addEventListener; -exports.removeEventListener = removeEventListener; -exports.getHashPath = getHashPath; -exports.replaceHashPath = replaceHashPath; -exports.getWindowPath = getWindowPath; -exports.go = go; -exports.getUserConfirmation = getUserConfirmation; -exports.supportsHistory = supportsHistory; -exports.supportsGoWithoutReloadUsingHash = supportsGoWithoutReloadUsingHash; - -function addEventListener(node, event, listener) { - if (node.addEventListener) { - node.addEventListener(event, listener, false); - } else { - node.attachEvent('on' + event, listener); - } -} - -function removeEventListener(node, event, listener) { - if (node.removeEventListener) { - node.removeEventListener(event, listener, false); - } else { - node.detachEvent('on' + event, listener); - } -} - -function getHashPath() { - // We can't use window.location.hash here because it's not - // consistent across browsers - Firefox will pre-decode it! - return window.location.href.split('#')[1] || ''; -} - -function replaceHashPath(path) { - window.location.replace(window.location.pathname + window.location.search + '#' + path); -} - -function getWindowPath() { - return window.location.pathname + window.location.search + window.location.hash; -} - -function go(n) { - if (n) window.history.go(n); -} - -function getUserConfirmation(message, callback) { - callback(window.confirm(message)); -} - -/** - * Returns true if the HTML5 history API is supported. Taken from Modernizr. - * - * https://github.com/Modernizr/Modernizr/blob/master/LICENSE - * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js - * changed to avoid false negatives for Windows Phones: https://github.com/rackt/react-router/issues/586 - */ - -function supportsHistory() { - var ua = navigator.userAgent; - if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) { - return false; - } - // FIXME: Work around our browser history not working correctly on Chrome - // iOS: https://github.com/rackt/react-router/issues/2565 - if (ua.indexOf('CriOS') !== -1) { - return false; - } - return window.history && 'pushState' in window.history; -} - -/** - * Returns false if using go(n) with hash history causes a full page reload. - */ - -function supportsGoWithoutReloadUsingHash() { - var ua = navigator.userAgent; - return ua.indexOf('Firefox') === -1; -} - -/***/ }), -/* 76 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -//import warning from 'warning' - - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _deepEqual = __webpack_require__(211); - -var _deepEqual2 = _interopRequireDefault(_deepEqual); - -var _AsyncUtils = __webpack_require__(228); - -var _Actions = __webpack_require__(29); - -var _createLocation2 = __webpack_require__(232); - -var _createLocation3 = _interopRequireDefault(_createLocation2); - -var _runTransitionHook = __webpack_require__(45); - -var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook); - -var _parsePath = __webpack_require__(24); - -var _parsePath2 = _interopRequireDefault(_parsePath); - -var _deprecate = __webpack_require__(44); - -var _deprecate2 = _interopRequireDefault(_deprecate); - -function createRandomKey(length) { - return Math.random().toString(36).substr(2, length); -} - -function locationsAreEqual(a, b) { - return a.pathname === b.pathname && a.search === b.search && - //a.action === b.action && // Different action !== location change. - a.key === b.key && _deepEqual2['default'](a.state, b.state); -} - -var DefaultKeyLength = 6; - -function createHistory() { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - var getCurrentLocation = options.getCurrentLocation; - var finishTransition = options.finishTransition; - var saveState = options.saveState; - var go = options.go; - var keyLength = options.keyLength; - var getUserConfirmation = options.getUserConfirmation; - - if (typeof keyLength !== 'number') keyLength = DefaultKeyLength; - - var transitionHooks = []; - - function listenBefore(hook) { - transitionHooks.push(hook); - - return function () { - transitionHooks = transitionHooks.filter(function (item) { - return item !== hook; - }); - }; - } - - var allKeys = []; - var changeListeners = []; - var location = undefined; - - function getCurrent() { - if (pendingLocation && pendingLocation.action === _Actions.POP) { - return allKeys.indexOf(pendingLocation.key); - } else if (location) { - return allKeys.indexOf(location.key); - } else { - return -1; - } - } - - function updateLocation(newLocation) { - var current = getCurrent(); - - location = newLocation; - - if (location.action === _Actions.PUSH) { - allKeys = [].concat(allKeys.slice(0, current + 1), [location.key]); - } else if (location.action === _Actions.REPLACE) { - allKeys[current] = location.key; - } - - changeListeners.forEach(function (listener) { - listener(location); - }); - } - - function listen(listener) { - changeListeners.push(listener); - - if (location) { - listener(location); - } else { - var _location = getCurrentLocation(); - allKeys = [_location.key]; - updateLocation(_location); - } - - return function () { - changeListeners = changeListeners.filter(function (item) { - return item !== listener; - }); - }; - } - - function confirmTransitionTo(location, callback) { - _AsyncUtils.loopAsync(transitionHooks.length, function (index, next, done) { - _runTransitionHook2['default'](transitionHooks[index], location, function (result) { - if (result != null) { - done(result); - } else { - next(); - } - }); - }, function (message) { - if (getUserConfirmation && typeof message === 'string') { - getUserConfirmation(message, function (ok) { - callback(ok !== false); - }); - } else { - callback(message !== false); - } - }); - } - - var pendingLocation = undefined; - - function transitionTo(nextLocation) { - if (location && locationsAreEqual(location, nextLocation)) return; // Nothing to do. - - pendingLocation = nextLocation; - - confirmTransitionTo(nextLocation, function (ok) { - if (pendingLocation !== nextLocation) return; // Transition was interrupted. - - if (ok) { - // treat PUSH to current path like REPLACE to be consistent with browsers - if (nextLocation.action === _Actions.PUSH) { - var prevPath = createPath(location); - var nextPath = createPath(nextLocation); - - if (nextPath === prevPath) nextLocation.action = _Actions.REPLACE; - } - - if (finishTransition(nextLocation) !== false) updateLocation(nextLocation); - } else if (location && nextLocation.action === _Actions.POP) { - var prevIndex = allKeys.indexOf(location.key); - var nextIndex = allKeys.indexOf(nextLocation.key); - - if (prevIndex !== -1 && nextIndex !== -1) go(prevIndex - nextIndex); // Restore the URL. - } - }); - } - - function push(location) { - transitionTo(createLocation(location, _Actions.PUSH, createKey())); - } - - function replace(location) { - transitionTo(createLocation(location, _Actions.REPLACE, createKey())); - } - - function goBack() { - go(-1); - } - - function goForward() { - go(1); - } - - function createKey() { - return createRandomKey(keyLength); - } - - function createPath(location) { - if (location == null || typeof location === 'string') return location; - - var pathname = location.pathname; - var search = location.search; - var hash = location.hash; - - var result = pathname; - - if (search) result += search; - - if (hash) result += hash; - - return result; - } - - function createHref(location) { - return createPath(location); - } - - function createLocation(location, action) { - var key = arguments.length <= 2 || arguments[2] === undefined ? createKey() : arguments[2]; - - if (typeof action === 'object') { - //warning( - // false, - // 'The state (2nd) argument to history.createLocation is deprecated; use a ' + - // 'location descriptor instead' - //) - - if (typeof location === 'string') location = _parsePath2['default'](location); - - location = _extends({}, location, { state: action }); - - action = key; - key = arguments[3] || createKey(); - } - - return _createLocation3['default'](location, action, key); - } - - // deprecated - function setState(state) { - if (location) { - updateLocationState(location, state); - updateLocation(location); - } else { - updateLocationState(getCurrentLocation(), state); - } - } - - function updateLocationState(location, state) { - location.state = _extends({}, location.state, state); - saveState(location.key, location.state); - } - - // deprecated - function registerTransitionHook(hook) { - if (transitionHooks.indexOf(hook) === -1) transitionHooks.push(hook); - } - - // deprecated - function unregisterTransitionHook(hook) { - transitionHooks = transitionHooks.filter(function (item) { - return item !== hook; - }); - } - - // deprecated - function pushState(state, path) { - if (typeof path === 'string') path = _parsePath2['default'](path); - - push(_extends({ state: state }, path)); - } - - // deprecated - function replaceState(state, path) { - if (typeof path === 'string') path = _parsePath2['default'](path); - - replace(_extends({ state: state }, path)); - } - - return { - listenBefore: listenBefore, - listen: listen, - transitionTo: transitionTo, - push: push, - replace: replace, - go: go, - goBack: goBack, - goForward: goForward, - createKey: createKey, - createPath: createPath, - createHref: createHref, - createLocation: createLocation, - - setState: _deprecate2['default'](setState, 'setState is deprecated; use location.key to save state instead'), - registerTransitionHook: _deprecate2['default'](registerTransitionHook, 'registerTransitionHook is deprecated; use listenBefore instead'), - unregisterTransitionHook: _deprecate2['default'](unregisterTransitionHook, 'unregisterTransitionHook is deprecated; use the callback returned from listenBefore instead'), - pushState: _deprecate2['default'](pushState, 'pushState is deprecated; use push instead'), - replaceState: _deprecate2['default'](replaceState, 'replaceState is deprecated; use replace instead') - }; -} - -exports['default'] = createHistory; -module.exports = exports['default']; - -/***/ }), -/* 77 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -function extractPath(string) { - var match = string.match(/^https?:\/\/[^\/]*/); - - if (match == null) return string; - - return string.substring(match[0].length); -} - -exports["default"] = extractPath; -module.exports = exports["default"]; - -/***/ }), -/* 78 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * CSS properties which accept numbers but are not in units of "px". - */ - -var isUnitlessNumber = { - animationIterationCount: true, - borderImageOutset: true, - borderImageSlice: true, - borderImageWidth: true, - boxFlex: true, - boxFlexGroup: true, - boxOrdinalGroup: true, - columnCount: true, - flex: true, - flexGrow: true, - flexPositive: true, - flexShrink: true, - flexNegative: true, - flexOrder: true, - gridRow: true, - gridColumn: true, - fontWeight: true, - lineClamp: true, - lineHeight: true, - opacity: true, - order: true, - orphans: true, - tabSize: true, - widows: true, - zIndex: true, - zoom: true, - - // SVG-related properties - fillOpacity: true, - floodOpacity: true, - stopOpacity: true, - strokeDasharray: true, - strokeDashoffset: true, - strokeMiterlimit: true, - strokeOpacity: true, - strokeWidth: true -}; - -/** - * @param {string} prefix vendor-specific prefix, eg: Webkit - * @param {string} key style name, eg: transitionDuration - * @return {string} style name prefixed with `prefix`, properly camelCased, eg: - * WebkitTransitionDuration - */ -function prefixKey(prefix, key) { - return prefix + key.charAt(0).toUpperCase() + key.substring(1); -} - -/** - * Support style names that may come passed in prefixed by adding permutations - * of vendor prefixes. - */ -var prefixes = ['Webkit', 'ms', 'Moz', 'O']; - -// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an -// infinite loop, because it iterates over the newly added props too. -Object.keys(isUnitlessNumber).forEach(function (prop) { - prefixes.forEach(function (prefix) { - isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; - }); -}); - -/** - * Most style properties can be unset by doing .style[prop] = '' but IE8 - * doesn't like doing that with shorthand properties so for the properties that - * IE8 breaks on, which are listed here, we instead unset each of the - * individual properties. See http://bugs.jquery.com/ticket/12385. - * The 4-value 'clock' properties like margin, padding, border-width seem to - * behave without any problems. Curiously, list-style works too without any - * special prodding. - */ -var shorthandPropertyExpansions = { - background: { - backgroundAttachment: true, - backgroundColor: true, - backgroundImage: true, - backgroundPositionX: true, - backgroundPositionY: true, - backgroundRepeat: true - }, - backgroundPosition: { - backgroundPositionX: true, - backgroundPositionY: true - }, - border: { - borderWidth: true, - borderStyle: true, - borderColor: true - }, - borderBottom: { - borderBottomWidth: true, - borderBottomStyle: true, - borderBottomColor: true - }, - borderLeft: { - borderLeftWidth: true, - borderLeftStyle: true, - borderLeftColor: true - }, - borderRight: { - borderRightWidth: true, - borderRightStyle: true, - borderRightColor: true - }, - borderTop: { - borderTopWidth: true, - borderTopStyle: true, - borderTopColor: true - }, - font: { - fontStyle: true, - fontVariant: true, - fontWeight: true, - fontSize: true, - lineHeight: true, - fontFamily: true - }, - outline: { - outlineWidth: true, - outlineStyle: true, - outlineColor: true - } -}; - -var CSSProperty = { - isUnitlessNumber: isUnitlessNumber, - shorthandPropertyExpansions: shorthandPropertyExpansions -}; - -module.exports = CSSProperty; - -/***/ }), -/* 79 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var PooledClass = __webpack_require__(20); - -var invariant = __webpack_require__(2); - -/** - * A specialized pseudo-event module to help keep track of components waiting to - * be notified when their DOM representations are available for use. - * - * This implements `PooledClass`, so you should never need to instantiate this. - * Instead, use `CallbackQueue.getPooled()`. - * - * @class ReactMountReady - * @implements PooledClass - * @internal - */ - -var CallbackQueue = function () { - function CallbackQueue(arg) { - _classCallCheck(this, CallbackQueue); - - this._callbacks = null; - this._contexts = null; - this._arg = arg; - } - - /** - * Enqueues a callback to be invoked when `notifyAll` is invoked. - * - * @param {function} callback Invoked when `notifyAll` is invoked. - * @param {?object} context Context to call `callback` with. - * @internal - */ - - - CallbackQueue.prototype.enqueue = function enqueue(callback, context) { - this._callbacks = this._callbacks || []; - this._callbacks.push(callback); - this._contexts = this._contexts || []; - this._contexts.push(context); - }; - - /** - * Invokes all enqueued callbacks and clears the queue. This is invoked after - * the DOM representation of a component has been created or updated. - * - * @internal - */ - - - CallbackQueue.prototype.notifyAll = function notifyAll() { - var callbacks = this._callbacks; - var contexts = this._contexts; - var arg = this._arg; - if (callbacks && contexts) { - !(callbacks.length === contexts.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Mismatched list of contexts in callback queue') : _prodInvariant('24') : void 0; - this._callbacks = null; - this._contexts = null; - for (var i = 0; i < callbacks.length; i++) { - callbacks[i].call(contexts[i], arg); - } - callbacks.length = 0; - contexts.length = 0; - } - }; - - CallbackQueue.prototype.checkpoint = function checkpoint() { - return this._callbacks ? this._callbacks.length : 0; - }; - - CallbackQueue.prototype.rollback = function rollback(len) { - if (this._callbacks && this._contexts) { - this._callbacks.length = len; - this._contexts.length = len; - } - }; - - /** - * Resets the internal queue. - * - * @internal - */ - - - CallbackQueue.prototype.reset = function reset() { - this._callbacks = null; - this._contexts = null; - }; - - /** - * `PooledClass` looks for this. - */ - - - CallbackQueue.prototype.destructor = function destructor() { - this.reset(); - }; - - return CallbackQueue; -}(); - -module.exports = PooledClass.addPoolingTo(CallbackQueue); -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 80 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMProperty = __webpack_require__(18); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactInstrumentation = __webpack_require__(10); - -var quoteAttributeValueForBrowser = __webpack_require__(307); -var warning = __webpack_require__(3); - -var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + DOMProperty.ATTRIBUTE_NAME_START_CHAR + '][' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$'); -var illegalAttributeNameCache = {}; -var validatedAttributeNameCache = {}; - -function isAttributeNameSafe(attributeName) { - if (validatedAttributeNameCache.hasOwnProperty(attributeName)) { - return true; - } - if (illegalAttributeNameCache.hasOwnProperty(attributeName)) { - return false; - } - if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { - validatedAttributeNameCache[attributeName] = true; - return true; - } - illegalAttributeNameCache[attributeName] = true; - process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid attribute name: `%s`', attributeName) : void 0; - return false; -} - -function shouldIgnoreValue(propertyInfo, value) { - return value == null || propertyInfo.hasBooleanValue && !value || propertyInfo.hasNumericValue && isNaN(value) || propertyInfo.hasPositiveNumericValue && value < 1 || propertyInfo.hasOverloadedBooleanValue && value === false; -} - -/** - * Operations for dealing with DOM properties. - */ -var DOMPropertyOperations = { - - /** - * Creates markup for the ID property. - * - * @param {string} id Unescaped ID. - * @return {string} Markup string. - */ - createMarkupForID: function (id) { - return DOMProperty.ID_ATTRIBUTE_NAME + '=' + quoteAttributeValueForBrowser(id); - }, - - setAttributeForID: function (node, id) { - node.setAttribute(DOMProperty.ID_ATTRIBUTE_NAME, id); - }, - - createMarkupForRoot: function () { - return DOMProperty.ROOT_ATTRIBUTE_NAME + '=""'; - }, - - setAttributeForRoot: function (node) { - node.setAttribute(DOMProperty.ROOT_ATTRIBUTE_NAME, ''); - }, - - /** - * Creates markup for a property. - * - * @param {string} name - * @param {*} value - * @return {?string} Markup string, or null if the property was invalid. - */ - createMarkupForProperty: function (name, value) { - var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; - if (propertyInfo) { - if (shouldIgnoreValue(propertyInfo, value)) { - return ''; - } - var attributeName = propertyInfo.attributeName; - if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { - return attributeName + '=""'; - } - return attributeName + '=' + quoteAttributeValueForBrowser(value); - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - return ''; - } - return name + '=' + quoteAttributeValueForBrowser(value); - } - return null; - }, - - /** - * Creates markup for a custom property. - * - * @param {string} name - * @param {*} value - * @return {string} Markup string, or empty string if the property was invalid. - */ - createMarkupForCustomAttribute: function (name, value) { - if (!isAttributeNameSafe(name) || value == null) { - return ''; - } - return name + '=' + quoteAttributeValueForBrowser(value); - }, - - /** - * Sets the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - * @param {*} value - */ - setValueForProperty: function (node, name, value) { - var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; - if (propertyInfo) { - var mutationMethod = propertyInfo.mutationMethod; - if (mutationMethod) { - mutationMethod(node, value); - } else if (shouldIgnoreValue(propertyInfo, value)) { - this.deleteValueForProperty(node, name); - return; - } else if (propertyInfo.mustUseProperty) { - // Contrary to `setAttribute`, object properties are properly - // `toString`ed by IE8/9. - node[propertyInfo.propertyName] = value; - } else { - var attributeName = propertyInfo.attributeName; - var namespace = propertyInfo.attributeNamespace; - // `setAttribute` with objects becomes only `[object]` in IE8/9, - // ('' + value) makes it output the correct toString()-value. - if (namespace) { - node.setAttributeNS(namespace, attributeName, '' + value); - } else if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { - node.setAttribute(attributeName, ''); - } else { - node.setAttribute(attributeName, '' + value); - } - } - } else if (DOMProperty.isCustomAttribute(name)) { - DOMPropertyOperations.setValueForAttribute(node, name, value); - return; - } - - if (process.env.NODE_ENV !== 'production') { - var payload = {}; - payload[name] = value; - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID, - type: 'update attribute', - payload: payload - }); - } - }, - - setValueForAttribute: function (node, name, value) { - if (!isAttributeNameSafe(name)) { - return; - } - if (value == null) { - node.removeAttribute(name); - } else { - node.setAttribute(name, '' + value); - } - - if (process.env.NODE_ENV !== 'production') { - var payload = {}; - payload[name] = value; - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID, - type: 'update attribute', - payload: payload - }); - } - }, - - /** - * Deletes an attributes from a node. - * - * @param {DOMElement} node - * @param {string} name - */ - deleteValueForAttribute: function (node, name) { - node.removeAttribute(name); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID, - type: 'remove attribute', - payload: name - }); - } - }, - - /** - * Deletes the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - */ - deleteValueForProperty: function (node, name) { - var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; - if (propertyInfo) { - var mutationMethod = propertyInfo.mutationMethod; - if (mutationMethod) { - mutationMethod(node, undefined); - } else if (propertyInfo.mustUseProperty) { - var propName = propertyInfo.propertyName; - if (propertyInfo.hasBooleanValue) { - node[propName] = false; - } else { - node[propName] = ''; - } - } else { - node.removeAttribute(propertyInfo.attributeName); - } - } else if (DOMProperty.isCustomAttribute(name)) { - node.removeAttribute(name); - } - - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID, - type: 'remove attribute', - payload: name - }); - } - } - -}; - -module.exports = DOMPropertyOperations; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 81 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactDOMComponentFlags = { - hasCachedChildNodes: 1 << 0 -}; - -module.exports = ReactDOMComponentFlags; - -/***/ }), -/* 82 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var LinkedValueUtils = __webpack_require__(50); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactUpdates = __webpack_require__(14); - -var warning = __webpack_require__(3); - -var didWarnValueLink = false; -var didWarnValueDefaultValue = false; - -function updateOptionsIfPendingUpdateAndMounted() { - if (this._rootNodeID && this._wrapperState.pendingUpdate) { - this._wrapperState.pendingUpdate = false; - - var props = this._currentElement.props; - var value = LinkedValueUtils.getValue(props); - - if (value != null) { - updateOptions(this, Boolean(props.multiple), value); - } - } -} - -function getDeclarationErrorAddendum(owner) { - if (owner) { - var name = owner.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -var valuePropNames = ['value', 'defaultValue']; - -/** - * Validation function for `value` and `defaultValue`. - * @private - */ -function checkSelectPropTypes(inst, props) { - var owner = inst._currentElement._owner; - LinkedValueUtils.checkPropTypes('select', props, owner); - - if (props.valueLink !== undefined && !didWarnValueLink) { - process.env.NODE_ENV !== 'production' ? warning(false, '`valueLink` prop on `select` is deprecated; set `value` and `onChange` instead.') : void 0; - didWarnValueLink = true; - } - - for (var i = 0; i < valuePropNames.length; i++) { - var propName = valuePropNames[i]; - if (props[propName] == null) { - continue; - } - var isArray = Array.isArray(props[propName]); - if (props.multiple && !isArray) { - process.env.NODE_ENV !== 'production' ? warning(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum(owner)) : void 0; - } else if (!props.multiple && isArray) { - process.env.NODE_ENV !== 'production' ? warning(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum(owner)) : void 0; - } - } -} - -/** - * @param {ReactDOMComponent} inst - * @param {boolean} multiple - * @param {*} propValue A stringable (with `multiple`, a list of stringables). - * @private - */ -function updateOptions(inst, multiple, propValue) { - var selectedValue, i; - var options = ReactDOMComponentTree.getNodeFromInstance(inst).options; - - if (multiple) { - selectedValue = {}; - for (i = 0; i < propValue.length; i++) { - selectedValue['' + propValue[i]] = true; - } - for (i = 0; i < options.length; i++) { - var selected = selectedValue.hasOwnProperty(options[i].value); - if (options[i].selected !== selected) { - options[i].selected = selected; - } - } - } else { - // Do not set `select.value` as exact behavior isn't consistent across all - // browsers for all cases. - selectedValue = '' + propValue; - for (i = 0; i < options.length; i++) { - if (options[i].value === selectedValue) { - options[i].selected = true; - return; - } - } - if (options.length) { - options[0].selected = true; - } - } -} - -/** - * Implements a <select> host component that allows optionally setting the - * props `value` and `defaultValue`. If `multiple` is false, the prop must be a - * stringable. If `multiple` is true, the prop must be an array of stringables. - * - * If `value` is not supplied (or null/undefined), user actions that change the - * selected option will trigger updates to the rendered options. - * - * If it is supplied (and not null/undefined), the rendered options will not - * update in response to user actions. Instead, the `value` prop must change in - * order for the rendered options to update. - * - * If `defaultValue` is provided, any options with the supplied values will be - * selected. - */ -var ReactDOMSelect = { - getHostProps: function (inst, props) { - return _assign({}, props, { - onChange: inst._wrapperState.onChange, - value: undefined - }); - }, - - mountWrapper: function (inst, props) { - if (process.env.NODE_ENV !== 'production') { - checkSelectPropTypes(inst, props); - } - - var value = LinkedValueUtils.getValue(props); - inst._wrapperState = { - pendingUpdate: false, - initialValue: value != null ? value : props.defaultValue, - listeners: null, - onChange: _handleChange.bind(inst), - wasMultiple: Boolean(props.multiple) - }; - - if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0; - didWarnValueDefaultValue = true; - } - }, - - getSelectValueContext: function (inst) { - // ReactDOMOption looks at this initial value so the initial generated - // markup has correct `selected` attributes - return inst._wrapperState.initialValue; - }, - - postUpdateWrapper: function (inst) { - var props = inst._currentElement.props; - - // After the initial mount, we control selected-ness manually so don't pass - // this value down - inst._wrapperState.initialValue = undefined; - - var wasMultiple = inst._wrapperState.wasMultiple; - inst._wrapperState.wasMultiple = Boolean(props.multiple); - - var value = LinkedValueUtils.getValue(props); - if (value != null) { - inst._wrapperState.pendingUpdate = false; - updateOptions(inst, Boolean(props.multiple), value); - } else if (wasMultiple !== Boolean(props.multiple)) { - // For simplicity, reapply `defaultValue` if `multiple` is toggled. - if (props.defaultValue != null) { - updateOptions(inst, Boolean(props.multiple), props.defaultValue); - } else { - // Revert the select back to its default unselected state. - updateOptions(inst, Boolean(props.multiple), props.multiple ? [] : ''); - } - } - } -}; - -function _handleChange(event) { - var props = this._currentElement.props; - var returnValue = LinkedValueUtils.executeOnChange(props, event); - - if (this._rootNodeID) { - this._wrapperState.pendingUpdate = true; - } - ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this); - return returnValue; -} - -module.exports = ReactDOMSelect; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 83 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var emptyComponentFactory; - -var ReactEmptyComponentInjection = { - injectEmptyComponentFactory: function (factory) { - emptyComponentFactory = factory; - } -}; - -var ReactEmptyComponent = { - create: function (instantiate) { - return emptyComponentFactory(instantiate); - } -}; - -ReactEmptyComponent.injection = ReactEmptyComponentInjection; - -module.exports = ReactEmptyComponent; - -/***/ }), -/* 84 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactFeatureFlags = { - // When true, call console.time() before and .timeEnd() after each top-level - // render (both initial renders and updates). Useful when looking at prod-mode - // timeline profiles in Chrome, for example. - logTopLevelRenders: false -}; - -module.exports = ReactFeatureFlags; - -/***/ }), -/* 85 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -var genericComponentClass = null; -var textComponentClass = null; - -var ReactHostComponentInjection = { - // This accepts a class that receives the tag string. This is a catch all - // that can render any kind of tag. - injectGenericComponentClass: function (componentClass) { - genericComponentClass = componentClass; - }, - // This accepts a text component class that takes the text string to be - // rendered as props. - injectTextComponentClass: function (componentClass) { - textComponentClass = componentClass; - } -}; - -/** - * Get a host internal component class for a specific tag. - * - * @param {ReactElement} element The element to create. - * @return {function} The internal class constructor function. - */ -function createInternalComponent(element) { - !genericComponentClass ? process.env.NODE_ENV !== 'production' ? invariant(false, 'There is no registered component for the tag %s', element.type) : _prodInvariant('111', element.type) : void 0; - return new genericComponentClass(element); -} - -/** - * @param {ReactText} text - * @return {ReactComponent} - */ -function createInstanceForText(text) { - return new textComponentClass(text); -} - -/** - * @param {ReactComponent} component - * @return {boolean} - */ -function isTextComponent(component) { - return component instanceof textComponentClass; -} - -var ReactHostComponent = { - createInternalComponent: createInternalComponent, - createInstanceForText: createInstanceForText, - isTextComponent: isTextComponent, - injection: ReactHostComponentInjection -}; - -module.exports = ReactHostComponent; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 86 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactDOMSelection = __webpack_require__(261); - -var containsNode = __webpack_require__(216); -var focusNode = __webpack_require__(73); -var getActiveElement = __webpack_require__(74); - -function isInDocument(node) { - return containsNode(document.documentElement, node); -} - -/** - * @ReactInputSelection: React input selection module. Based on Selection.js, - * but modified to be suitable for react and has a couple of bug fixes (doesn't - * assume buttons have range selections allowed). - * Input selection module for React. - */ -var ReactInputSelection = { - - hasSelectionCapabilities: function (elem) { - var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); - return nodeName && (nodeName === 'input' && elem.type === 'text' || nodeName === 'textarea' || elem.contentEditable === 'true'); - }, - - getSelectionInformation: function () { - var focusedElem = getActiveElement(); - return { - focusedElem: focusedElem, - selectionRange: ReactInputSelection.hasSelectionCapabilities(focusedElem) ? ReactInputSelection.getSelection(focusedElem) : null - }; - }, - - /** - * @restoreSelection: If any selection information was potentially lost, - * restore it. This is useful when performing operations that could remove dom - * nodes and place them back in, resulting in focus being lost. - */ - restoreSelection: function (priorSelectionInformation) { - var curFocusedElem = getActiveElement(); - var priorFocusedElem = priorSelectionInformation.focusedElem; - var priorSelectionRange = priorSelectionInformation.selectionRange; - if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) { - if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) { - ReactInputSelection.setSelection(priorFocusedElem, priorSelectionRange); - } - focusNode(priorFocusedElem); - } - }, - - /** - * @getSelection: Gets the selection bounds of a focused textarea, input or - * contentEditable node. - * -@input: Look up selection bounds of this input - * -@return {start: selectionStart, end: selectionEnd} - */ - getSelection: function (input) { - var selection; - - if ('selectionStart' in input) { - // Modern browser with input or textarea. - selection = { - start: input.selectionStart, - end: input.selectionEnd - }; - } else if (document.selection && input.nodeName && input.nodeName.toLowerCase() === 'input') { - // IE8 input. - var range = document.selection.createRange(); - // There can only be one selection per document in IE, so it must - // be in our element. - if (range.parentElement() === input) { - selection = { - start: -range.moveStart('character', -input.value.length), - end: -range.moveEnd('character', -input.value.length) - }; - } - } else { - // Content editable or old IE textarea. - selection = ReactDOMSelection.getOffsets(input); - } - - return selection || { start: 0, end: 0 }; - }, - - /** - * @setSelection: Sets the selection bounds of a textarea or input and focuses - * the input. - * -@input Set selection bounds of this input or textarea - * -@offsets Object of same form that is returned from get* - */ - setSelection: function (input, offsets) { - var start = offsets.start; - var end = offsets.end; - if (end === undefined) { - end = start; - } - - if ('selectionStart' in input) { - input.selectionStart = start; - input.selectionEnd = Math.min(end, input.value.length); - } else if (document.selection && input.nodeName && input.nodeName.toLowerCase() === 'input') { - var range = input.createTextRange(); - range.collapse(true); - range.moveStart('character', start); - range.moveEnd('character', end - start); - range.select(); - } else { - ReactDOMSelection.setOffsets(input, offsets); - } - } -}; - -module.exports = ReactInputSelection; - -/***/ }), -/* 87 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var DOMLazyTree = __webpack_require__(25); -var DOMProperty = __webpack_require__(18); -var React = __webpack_require__(27); -var ReactBrowserEventEmitter = __webpack_require__(36); -var ReactCurrentOwner = __webpack_require__(15); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactDOMContainerInfo = __webpack_require__(253); -var ReactDOMFeatureFlags = __webpack_require__(255); -var ReactFeatureFlags = __webpack_require__(84); -var ReactInstanceMap = __webpack_require__(32); -var ReactInstrumentation = __webpack_require__(10); -var ReactMarkupChecksum = __webpack_require__(275); -var ReactReconciler = __webpack_require__(26); -var ReactUpdateQueue = __webpack_require__(53); -var ReactUpdates = __webpack_require__(14); - -var emptyObject = __webpack_require__(28); -var instantiateReactComponent = __webpack_require__(95); -var invariant = __webpack_require__(2); -var setInnerHTML = __webpack_require__(40); -var shouldUpdateReactComponent = __webpack_require__(59); -var warning = __webpack_require__(3); - -var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; -var ROOT_ATTR_NAME = DOMProperty.ROOT_ATTRIBUTE_NAME; - -var ELEMENT_NODE_TYPE = 1; -var DOC_NODE_TYPE = 9; -var DOCUMENT_FRAGMENT_NODE_TYPE = 11; - -var instancesByReactRootID = {}; - -/** - * Finds the index of the first character - * that's not common between the two given strings. - * - * @return {number} the index of the character where the strings diverge - */ -function firstDifferenceIndex(string1, string2) { - var minLen = Math.min(string1.length, string2.length); - for (var i = 0; i < minLen; i++) { - if (string1.charAt(i) !== string2.charAt(i)) { - return i; - } - } - return string1.length === string2.length ? -1 : minLen; -} - -/** - * @param {DOMElement|DOMDocument} container DOM element that may contain - * a React component - * @return {?*} DOM element that may have the reactRoot ID, or null. - */ -function getReactRootElementInContainer(container) { - if (!container) { - return null; - } - - if (container.nodeType === DOC_NODE_TYPE) { - return container.documentElement; - } else { - return container.firstChild; - } -} - -function internalGetID(node) { - // If node is something like a window, document, or text node, none of - // which support attributes or a .getAttribute method, gracefully return - // the empty string, as if the attribute were missing. - return node.getAttribute && node.getAttribute(ATTR_NAME) || ''; -} - -/** - * Mounts this component and inserts it into the DOM. - * - * @param {ReactComponent} componentInstance The instance to mount. - * @param {DOMElement} container DOM element to mount into. - * @param {ReactReconcileTransaction} transaction - * @param {boolean} shouldReuseMarkup If true, do not insert markup - */ -function mountComponentIntoNode(wrapperInstance, container, transaction, shouldReuseMarkup, context) { - var markerName; - if (ReactFeatureFlags.logTopLevelRenders) { - var wrappedElement = wrapperInstance._currentElement.props.child; - var type = wrappedElement.type; - markerName = 'React mount: ' + (typeof type === 'string' ? type : type.displayName || type.name); - console.time(markerName); - } - - var markup = ReactReconciler.mountComponent(wrapperInstance, transaction, null, ReactDOMContainerInfo(wrapperInstance, container), context, 0 /* parentDebugID */ - ); - - if (markerName) { - console.timeEnd(markerName); - } - - wrapperInstance._renderedComponent._topLevelWrapper = wrapperInstance; - ReactMount._mountImageIntoNode(markup, container, wrapperInstance, shouldReuseMarkup, transaction); -} - -/** - * Batched mount. - * - * @param {ReactComponent} componentInstance The instance to mount. - * @param {DOMElement} container DOM element to mount into. - * @param {boolean} shouldReuseMarkup If true, do not insert markup - */ -function batchedMountComponentIntoNode(componentInstance, container, shouldReuseMarkup, context) { - var transaction = ReactUpdates.ReactReconcileTransaction.getPooled( - /* useCreateElement */ - !shouldReuseMarkup && ReactDOMFeatureFlags.useCreateElement); - transaction.perform(mountComponentIntoNode, null, componentInstance, container, transaction, shouldReuseMarkup, context); - ReactUpdates.ReactReconcileTransaction.release(transaction); -} - -/** - * Unmounts a component and removes it from the DOM. - * - * @param {ReactComponent} instance React component instance. - * @param {DOMElement} container DOM element to unmount from. - * @final - * @internal - * @see {ReactMount.unmountComponentAtNode} - */ -function unmountComponentFromNode(instance, container, safely) { - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onBeginFlush(); - } - ReactReconciler.unmountComponent(instance, safely); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onEndFlush(); - } - - if (container.nodeType === DOC_NODE_TYPE) { - container = container.documentElement; - } - - // http://jsperf.com/emptying-a-node - while (container.lastChild) { - container.removeChild(container.lastChild); - } -} - -/** - * True if the supplied DOM node has a direct React-rendered child that is - * not a React root element. Useful for warning in `render`, - * `unmountComponentAtNode`, etc. - * - * @param {?DOMElement} node The candidate DOM node. - * @return {boolean} True if the DOM element contains a direct child that was - * rendered by React but is not a root element. - * @internal - */ -function hasNonRootReactChild(container) { - var rootEl = getReactRootElementInContainer(container); - if (rootEl) { - var inst = ReactDOMComponentTree.getInstanceFromNode(rootEl); - return !!(inst && inst._hostParent); - } -} - -/** - * True if the supplied DOM node is a React DOM element and - * it has been rendered by another copy of React. - * - * @param {?DOMElement} node The candidate DOM node. - * @return {boolean} True if the DOM has been rendered by another copy of React - * @internal - */ -function nodeIsRenderedByOtherInstance(container) { - var rootEl = getReactRootElementInContainer(container); - return !!(rootEl && isReactNode(rootEl) && !ReactDOMComponentTree.getInstanceFromNode(rootEl)); -} - -/** - * True if the supplied DOM node is a valid node element. - * - * @param {?DOMElement} node The candidate DOM node. - * @return {boolean} True if the DOM is a valid DOM node. - * @internal - */ -function isValidContainer(node) { - return !!(node && (node.nodeType === ELEMENT_NODE_TYPE || node.nodeType === DOC_NODE_TYPE || node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)); -} - -/** - * True if the supplied DOM node is a valid React node element. - * - * @param {?DOMElement} node The candidate DOM node. - * @return {boolean} True if the DOM is a valid React DOM node. - * @internal - */ -function isReactNode(node) { - return isValidContainer(node) && (node.hasAttribute(ROOT_ATTR_NAME) || node.hasAttribute(ATTR_NAME)); -} - -function getHostRootInstanceInContainer(container) { - var rootEl = getReactRootElementInContainer(container); - var prevHostInstance = rootEl && ReactDOMComponentTree.getInstanceFromNode(rootEl); - return prevHostInstance && !prevHostInstance._hostParent ? prevHostInstance : null; -} - -function getTopLevelWrapperInContainer(container) { - var root = getHostRootInstanceInContainer(container); - return root ? root._hostContainerInfo._topLevelWrapper : null; -} - -/** - * Temporary (?) hack so that we can store all top-level pending updates on - * composites instead of having to worry about different types of components - * here. - */ -var topLevelRootCounter = 1; -var TopLevelWrapper = function () { - this.rootID = topLevelRootCounter++; -}; -TopLevelWrapper.prototype.isReactComponent = {}; -if (process.env.NODE_ENV !== 'production') { - TopLevelWrapper.displayName = 'TopLevelWrapper'; -} -TopLevelWrapper.prototype.render = function () { - return this.props.child; -}; -TopLevelWrapper.isReactTopLevelWrapper = true; - -/** - * Mounting is the process of initializing a React component by creating its - * representative DOM elements and inserting them into a supplied `container`. - * Any prior content inside `container` is destroyed in the process. - * - * ReactMount.render( - * component, - * document.getElementById('container') - * ); - * - * <div id="container"> <-- Supplied `container`. - * <div data-reactid=".3"> <-- Rendered reactRoot of React - * // ... component. - * </div> - * </div> - * - * Inside of `container`, the first element rendered is the "reactRoot". - */ -var ReactMount = { - - TopLevelWrapper: TopLevelWrapper, - - /** - * Used by devtools. The keys are not important. - */ - _instancesByReactRootID: instancesByReactRootID, - - /** - * This is a hook provided to support rendering React components while - * ensuring that the apparent scroll position of its `container` does not - * change. - * - * @param {DOMElement} container The `container` being rendered into. - * @param {function} renderCallback This must be called once to do the render. - */ - scrollMonitor: function (container, renderCallback) { - renderCallback(); - }, - - /** - * Take a component that's already mounted into the DOM and replace its props - * @param {ReactComponent} prevComponent component instance already in the DOM - * @param {ReactElement} nextElement component instance to render - * @param {DOMElement} container container to render into - * @param {?function} callback function triggered on completion - */ - _updateRootComponent: function (prevComponent, nextElement, nextContext, container, callback) { - ReactMount.scrollMonitor(container, function () { - ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement, nextContext); - if (callback) { - ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback); - } - }); - - return prevComponent; - }, - - /** - * Render a new component into the DOM. Hooked by hooks! - * - * @param {ReactElement} nextElement element to render - * @param {DOMElement} container container to render into - * @param {boolean} shouldReuseMarkup if we should skip the markup insertion - * @return {ReactComponent} nextComponent - */ - _renderNewRootComponent: function (nextElement, container, shouldReuseMarkup, context) { - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. - process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, '_renderNewRootComponent(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from ' + 'render is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : void 0; - - !isValidContainer(container) ? process.env.NODE_ENV !== 'production' ? invariant(false, '_registerComponent(...): Target container is not a DOM element.') : _prodInvariant('37') : void 0; - - ReactBrowserEventEmitter.ensureScrollValueMonitoring(); - var componentInstance = instantiateReactComponent(nextElement, false); - - // The initial render is synchronous but any updates that happen during - // rendering, in componentWillMount or componentDidMount, will be batched - // according to the current batching strategy. - - ReactUpdates.batchedUpdates(batchedMountComponentIntoNode, componentInstance, container, shouldReuseMarkup, context); - - var wrapperID = componentInstance._instance.rootID; - instancesByReactRootID[wrapperID] = componentInstance; - - return componentInstance; - }, - - /** - * Renders a React component into the DOM in the supplied `container`. - * - * If the React component was previously rendered into `container`, this will - * perform an update on it and only mutate the DOM as necessary to reflect the - * latest React component. - * - * @param {ReactComponent} parentComponent The conceptual parent of this render tree. - * @param {ReactElement} nextElement Component element to render. - * @param {DOMElement} container DOM element to render into. - * @param {?function} callback function triggered on completion - * @return {ReactComponent} Component instance rendered in `container`. - */ - renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) { - !(parentComponent != null && ReactInstanceMap.has(parentComponent)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'parentComponent must be a valid React Component') : _prodInvariant('38') : void 0; - return ReactMount._renderSubtreeIntoContainer(parentComponent, nextElement, container, callback); - }, - - _renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) { - ReactUpdateQueue.validateCallback(callback, 'ReactDOM.render'); - !React.isValidElement(nextElement) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOM.render(): Invalid component element.%s', typeof nextElement === 'string' ? ' Instead of passing a string like \'div\', pass ' + 'React.createElement(\'div\') or <div />.' : typeof nextElement === 'function' ? ' Instead of passing a class like Foo, pass ' + 'React.createElement(Foo) or <Foo />.' : - // Check if it quacks like an element - nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : _prodInvariant('39', typeof nextElement === 'string' ? ' Instead of passing a string like \'div\', pass ' + 'React.createElement(\'div\') or <div />.' : typeof nextElement === 'function' ? ' Instead of passing a class like Foo, pass ' + 'React.createElement(Foo) or <Foo />.' : nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : void 0; - - process.env.NODE_ENV !== 'production' ? warning(!container || !container.tagName || container.tagName.toUpperCase() !== 'BODY', 'render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.') : void 0; - - var nextWrappedElement = React.createElement(TopLevelWrapper, { child: nextElement }); - - var nextContext; - if (parentComponent) { - var parentInst = ReactInstanceMap.get(parentComponent); - nextContext = parentInst._processChildContext(parentInst._context); - } else { - nextContext = emptyObject; - } - - var prevComponent = getTopLevelWrapperInContainer(container); - - if (prevComponent) { - var prevWrappedElement = prevComponent._currentElement; - var prevElement = prevWrappedElement.props.child; - if (shouldUpdateReactComponent(prevElement, nextElement)) { - var publicInst = prevComponent._renderedComponent.getPublicInstance(); - var updatedCallback = callback && function () { - callback.call(publicInst); - }; - ReactMount._updateRootComponent(prevComponent, nextWrappedElement, nextContext, container, updatedCallback); - return publicInst; - } else { - ReactMount.unmountComponentAtNode(container); - } - } - - var reactRootElement = getReactRootElementInContainer(container); - var containerHasReactMarkup = reactRootElement && !!internalGetID(reactRootElement); - var containerHasNonRootReactChild = hasNonRootReactChild(container); - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(!containerHasNonRootReactChild, 'render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.') : void 0; - - if (!containerHasReactMarkup || reactRootElement.nextSibling) { - var rootElementSibling = reactRootElement; - while (rootElementSibling) { - if (internalGetID(rootElementSibling)) { - process.env.NODE_ENV !== 'production' ? warning(false, 'render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.') : void 0; - break; - } - rootElementSibling = rootElementSibling.nextSibling; - } - } - } - - var shouldReuseMarkup = containerHasReactMarkup && !prevComponent && !containerHasNonRootReactChild; - var component = ReactMount._renderNewRootComponent(nextWrappedElement, container, shouldReuseMarkup, nextContext)._renderedComponent.getPublicInstance(); - if (callback) { - callback.call(component); - } - return component; - }, - - /** - * Renders a React component into the DOM in the supplied `container`. - * See https://facebook.github.io/react/docs/top-level-api.html#reactdom.render - * - * If the React component was previously rendered into `container`, this will - * perform an update on it and only mutate the DOM as necessary to reflect the - * latest React component. - * - * @param {ReactElement} nextElement Component element to render. - * @param {DOMElement} container DOM element to render into. - * @param {?function} callback function triggered on completion - * @return {ReactComponent} Component instance rendered in `container`. - */ - render: function (nextElement, container, callback) { - return ReactMount._renderSubtreeIntoContainer(null, nextElement, container, callback); - }, - - /** - * Unmounts and destroys the React component rendered in the `container`. - * See https://facebook.github.io/react/docs/top-level-api.html#reactdom.unmountcomponentatnode - * - * @param {DOMElement} container DOM element containing a React component. - * @return {boolean} True if a component was found in and unmounted from - * `container` - */ - unmountComponentAtNode: function (container) { - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. (Strictly speaking, unmounting won't cause a - // render but we still don't expect to be in a render call here.) - process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, 'unmountComponentAtNode(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from render ' + 'is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : void 0; - - !isValidContainer(container) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : _prodInvariant('40') : void 0; - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(!nodeIsRenderedByOtherInstance(container), 'unmountComponentAtNode(): The node you\'re attempting to unmount ' + 'was rendered by another copy of React.') : void 0; - } - - var prevComponent = getTopLevelWrapperInContainer(container); - if (!prevComponent) { - // Check if the node being unmounted was rendered by React, but isn't a - // root node. - var containerHasNonRootReactChild = hasNonRootReactChild(container); - - // Check if the container itself is a React root node. - var isContainerReactRoot = container.nodeType === 1 && container.hasAttribute(ROOT_ATTR_NAME); - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(!containerHasNonRootReactChild, 'unmountComponentAtNode(): The node you\'re attempting to unmount ' + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.') : void 0; - } - - return false; - } - delete instancesByReactRootID[prevComponent._instance.rootID]; - ReactUpdates.batchedUpdates(unmountComponentFromNode, prevComponent, container, false); - return true; - }, - - _mountImageIntoNode: function (markup, container, instance, shouldReuseMarkup, transaction) { - !isValidContainer(container) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mountComponentIntoNode(...): Target container is not valid.') : _prodInvariant('41') : void 0; - - if (shouldReuseMarkup) { - var rootElement = getReactRootElementInContainer(container); - if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) { - ReactDOMComponentTree.precacheNode(instance, rootElement); - return; - } else { - var checksum = rootElement.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); - rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); - - var rootMarkup = rootElement.outerHTML; - rootElement.setAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME, checksum); - - var normalizedMarkup = markup; - if (process.env.NODE_ENV !== 'production') { - // because rootMarkup is retrieved from the DOM, various normalizations - // will have occurred which will not be present in `markup`. Here, - // insert markup into a <div> or <iframe> depending on the container - // type to perform the same normalizations before comparing. - var normalizer; - if (container.nodeType === ELEMENT_NODE_TYPE) { - normalizer = document.createElement('div'); - normalizer.innerHTML = markup; - normalizedMarkup = normalizer.innerHTML; - } else { - normalizer = document.createElement('iframe'); - document.body.appendChild(normalizer); - normalizer.contentDocument.write(markup); - normalizedMarkup = normalizer.contentDocument.documentElement.outerHTML; - document.body.removeChild(normalizer); - } - } - - var diffIndex = firstDifferenceIndex(normalizedMarkup, rootMarkup); - var difference = ' (client) ' + normalizedMarkup.substring(diffIndex - 20, diffIndex + 20) + '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20); - - !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\'re trying to render a component to the document using server rendering but the checksum was invalid. This usually means you rendered a different component type or props on the client from the one on the server, or your render() methods are impure. React cannot handle this case due to cross-browser quirks by rendering at the document root. You should look for environment dependent code in your components and ensure the props are the same client and server side:\n%s', difference) : _prodInvariant('42', difference) : void 0; - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(false, 'React attempted to reuse markup in a container but the ' + 'checksum was invalid. This generally means that you are ' + 'using server rendering and the markup generated on the ' + 'server was not what the client was expecting. React injected ' + 'new markup to compensate which works but you have lost many ' + 'of the benefits of server rendering. Instead, figure out ' + 'why the markup being generated is different on the client ' + 'or server:\n%s', difference) : void 0; - } - } - } - - !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\'re trying to render a component to the document but you didn\'t use server rendering. We can\'t do this without using server rendering due to cross-browser quirks. See ReactDOMServer.renderToString() for server rendering.') : _prodInvariant('43') : void 0; - - if (transaction.useCreateElement) { - while (container.lastChild) { - container.removeChild(container.lastChild); - } - DOMLazyTree.insertTreeBefore(container, markup, null); - } else { - setInnerHTML(container, markup); - ReactDOMComponentTree.precacheNode(instance, container.firstChild); - } - - if (process.env.NODE_ENV !== 'production') { - var hostNode = ReactDOMComponentTree.getInstanceFromNode(container.firstChild); - if (hostNode._debugID !== 0) { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: hostNode._debugID, - type: 'mount', - payload: markup.toString() - }); - } - } - } -}; - -module.exports = ReactMount; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 88 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var React = __webpack_require__(27); - -var invariant = __webpack_require__(2); - -var ReactNodeTypes = { - HOST: 0, - COMPOSITE: 1, - EMPTY: 2, - - getType: function (node) { - if (node === null || node === false) { - return ReactNodeTypes.EMPTY; - } else if (React.isValidElement(node)) { - if (typeof node.type === 'function') { - return ReactNodeTypes.COMPOSITE; - } else { - return ReactNodeTypes.HOST; - } - } - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Unexpected node: %s', node) : _prodInvariant('26', node) : void 0; - } -}; - -module.exports = ReactNodeTypes; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 89 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; - -module.exports = ReactPropTypesSecret; - -/***/ }), -/* 90 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ViewportMetrics = { - - currentScrollLeft: 0, - - currentScrollTop: 0, - - refreshScrollValues: function (scrollPosition) { - ViewportMetrics.currentScrollLeft = scrollPosition.x; - ViewportMetrics.currentScrollTop = scrollPosition.y; - } - -}; - -module.exports = ViewportMetrics; - -/***/ }), -/* 91 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -/** - * Accumulates items that must not be null or undefined into the first one. This - * is used to conserve memory by avoiding array allocations, and thus sacrifices - * API cleanness. Since `current` can be null before being passed in and not - * null after this function, make sure to assign it back to `current`: - * - * `a = accumulateInto(a, b);` - * - * This API should be sparingly used. Try `accumulate` for something cleaner. - * - * @return {*|array<*>} An accumulation of items. - */ - -function accumulateInto(current, next) { - !(next != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : _prodInvariant('30') : void 0; - - if (current == null) { - return next; - } - - // Both are not empty. Warning: Never call x.concat(y) when you are not - // certain that x is an Array (x could be a string with concat method). - if (Array.isArray(current)) { - if (Array.isArray(next)) { - current.push.apply(current, next); - return current; - } - current.push(next); - return current; - } - - if (Array.isArray(next)) { - // A bit too dangerous to mutate `next`. - return [current].concat(next); - } - - return [current, next]; -} - -module.exports = accumulateInto; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 92 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/** - * @param {array} arr an "accumulation" of items which is either an Array or - * a single item. Useful when paired with the `accumulate` module. This is a - * simple utility that allows us to reason about a collection of items, but - * handling the case when there is exactly one item (and we do not need to - * allocate an array). - */ - -function forEachAccumulated(arr, cb, scope) { - if (Array.isArray(arr)) { - arr.forEach(cb, scope); - } else if (arr) { - cb.call(scope, arr); - } -} - -module.exports = forEachAccumulated; - -/***/ }), -/* 93 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactNodeTypes = __webpack_require__(88); - -function getHostComponentFromComposite(inst) { - var type; - - while ((type = inst._renderedNodeType) === ReactNodeTypes.COMPOSITE) { - inst = inst._renderedComponent; - } - - if (type === ReactNodeTypes.HOST) { - return inst._renderedComponent; - } else if (type === ReactNodeTypes.EMPTY) { - return null; - } -} - -module.exports = getHostComponentFromComposite; - -/***/ }), -/* 94 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ExecutionEnvironment = __webpack_require__(8); - -var contentKey = null; - -/** - * Gets the key used to access text content on a DOM node. - * - * @return {?string} Key used to access text content. - * @internal - */ -function getTextContentAccessor() { - if (!contentKey && ExecutionEnvironment.canUseDOM) { - // Prefer textContent to innerText because many browsers support both but - // SVG <text> elements don't support innerText even when <div> does. - contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText'; - } - return contentKey; -} - -module.exports = getTextContentAccessor; - -/***/ }), -/* 95 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var ReactCompositeComponent = __webpack_require__(250); -var ReactEmptyComponent = __webpack_require__(83); -var ReactHostComponent = __webpack_require__(85); - -var getNextDebugID = __webpack_require__(304); -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -// To avoid a cyclic dependency, we create the final class in this module -var ReactCompositeComponentWrapper = function (element) { - this.construct(element); -}; -_assign(ReactCompositeComponentWrapper.prototype, ReactCompositeComponent, { - _instantiateReactComponent: instantiateReactComponent -}); - -function getDeclarationErrorAddendum(owner) { - if (owner) { - var name = owner.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -/** - * Check if the type reference is a known internal type. I.e. not a user - * provided composite type. - * - * @param {function} type - * @return {boolean} Returns true if this is a valid internal type. - */ -function isInternalComponentType(type) { - return typeof type === 'function' && typeof type.prototype !== 'undefined' && typeof type.prototype.mountComponent === 'function' && typeof type.prototype.receiveComponent === 'function'; -} - -/** - * Given a ReactNode, create an instance that will actually be mounted. - * - * @param {ReactNode} node - * @param {boolean} shouldHaveDebugID - * @return {object} A new instance of the element's constructor. - * @protected - */ -function instantiateReactComponent(node, shouldHaveDebugID) { - var instance; - - if (node === null || node === false) { - instance = ReactEmptyComponent.create(instantiateReactComponent); - } else if (typeof node === 'object') { - var element = node; - var type = element.type; - if (typeof type !== 'function' && typeof type !== 'string') { - var info = ''; - if (process.env.NODE_ENV !== 'production') { - if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { - info += ' You likely forgot to export your component from the file ' + 'it\'s defined in.'; - } - } - info += getDeclarationErrorAddendum(element._owner); - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s', type == null ? type : typeof type, info) : _prodInvariant('130', type == null ? type : typeof type, info) : void 0; - } - - // Special case string values - if (typeof element.type === 'string') { - instance = ReactHostComponent.createInternalComponent(element); - } else if (isInternalComponentType(element.type)) { - // This is temporarily available for custom components that are not string - // representations. I.e. ART. Once those are updated to use the string - // representation, we can drop this code path. - instance = new element.type(element); - - // We renamed this. Allow the old name for compat. :( - if (!instance.getHostNode) { - instance.getHostNode = instance.getNativeNode; - } - } else { - instance = new ReactCompositeComponentWrapper(element); - } - } else if (typeof node === 'string' || typeof node === 'number') { - instance = ReactHostComponent.createInstanceForText(node); - } else { - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Encountered invalid React node of type %s', typeof node) : _prodInvariant('131', typeof node) : void 0; - } - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(typeof instance.mountComponent === 'function' && typeof instance.receiveComponent === 'function' && typeof instance.getHostNode === 'function' && typeof instance.unmountComponent === 'function', 'Only React Components can be mounted.') : void 0; - } - - // These two fields are used by the DOM and ART diffing algorithms - // respectively. Instead of using expandos on components, we should be - // storing the state needed by the diffing algorithms elsewhere. - instance._mountIndex = 0; - instance._mountImage = null; - - if (process.env.NODE_ENV !== 'production') { - instance._debugID = shouldHaveDebugID ? getNextDebugID() : 0; - } - - // Internal instances should fully constructed at this point, so they should - // not get any new fields added to them at this point. - if (process.env.NODE_ENV !== 'production') { - if (Object.preventExtensions) { - Object.preventExtensions(instance); - } - } - - return instance; -} - -module.exports = instantiateReactComponent; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 96 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/** - * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary - */ - -var supportedInputTypes = { - 'color': true, - 'date': true, - 'datetime': true, - 'datetime-local': true, - 'email': true, - 'month': true, - 'number': true, - 'password': true, - 'range': true, - 'search': true, - 'tel': true, - 'text': true, - 'time': true, - 'url': true, - 'week': true -}; - -function isTextInputElement(elem) { - var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); - - if (nodeName === 'input') { - return !!supportedInputTypes[elem.type]; - } - - if (nodeName === 'textarea') { - return true; - } - - return false; -} - -module.exports = isTextInputElement; - -/***/ }), -/* 97 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ExecutionEnvironment = __webpack_require__(8); -var escapeTextContentForBrowser = __webpack_require__(39); -var setInnerHTML = __webpack_require__(40); - -/** - * Set the textContent property of a node, ensuring that whitespace is preserved - * even in IE8. innerText is a poor substitute for textContent and, among many - * issues, inserts <br> instead of the literal newline chars. innerHTML behaves - * as it should. - * - * @param {DOMElement} node - * @param {string} text - * @internal - */ -var setTextContent = function (node, text) { - if (text) { - var firstChild = node.firstChild; - - if (firstChild && firstChild === node.lastChild && firstChild.nodeType === 3) { - firstChild.nodeValue = text; - return; - } - } - node.textContent = text; -}; - -if (ExecutionEnvironment.canUseDOM) { - if (!('textContent' in document.documentElement)) { - setTextContent = function (node, text) { - if (node.nodeType === 3) { - node.nodeValue = text; - return; - } - setInnerHTML(node, escapeTextContentForBrowser(text)); - }; - } -} - -module.exports = setTextContent; - -/***/ }), -/* 98 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var ReactCurrentOwner = __webpack_require__(15); -var REACT_ELEMENT_TYPE = __webpack_require__(269); - -var getIteratorFn = __webpack_require__(303); -var invariant = __webpack_require__(2); -var KeyEscapeUtils = __webpack_require__(49); -var warning = __webpack_require__(3); - -var SEPARATOR = '.'; -var SUBSEPARATOR = ':'; - -/** - * This is inlined from ReactElement since this file is shared between - * isomorphic and renderers. We could extract this to a - * - */ - -/** - * TODO: Test that a single child and an array with one item have the same key - * pattern. - */ - -var didWarnAboutMaps = false; - -/** - * Generate a key string that identifies a component within a set. - * - * @param {*} component A component that could contain a manual key. - * @param {number} index Index that is used if a manual key is not provided. - * @return {string} - */ -function getComponentKey(component, index) { - // Do some typechecking here since we call this blindly. We want to ensure - // that we don't block potential future ES APIs. - if (component && typeof component === 'object' && component.key != null) { - // Explicit key - return KeyEscapeUtils.escape(component.key); - } - // Implicit key determined by the index in the set - return index.toString(36); -} - -/** - * @param {?*} children Children tree container. - * @param {!string} nameSoFar Name of the key path so far. - * @param {!function} callback Callback to invoke with each child found. - * @param {?*} traverseContext Used to pass information throughout the traversal - * process. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) { - var type = typeof children; - - if (type === 'undefined' || type === 'boolean') { - // All of the above are perceived as null. - children = null; - } - - if (children === null || type === 'string' || type === 'number' || - // The following is inlined from ReactElement. This means we can optimize - // some checks. React Fiber also inlines this logic for similar purposes. - type === 'object' && children.$$typeof === REACT_ELEMENT_TYPE) { - callback(traverseContext, children, - // If it's the only child, treat the name as if it was wrapped in an array - // so that it's consistent if the number of children grows. - nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar); - return 1; - } - - var child; - var nextName; - var subtreeCount = 0; // Count of children found in the current subtree. - var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR; - - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - child = children[i]; - nextName = nextNamePrefix + getComponentKey(child, i); - subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); - } - } else { - var iteratorFn = getIteratorFn(children); - if (iteratorFn) { - var iterator = iteratorFn.call(children); - var step; - if (iteratorFn !== children.entries) { - var ii = 0; - while (!(step = iterator.next()).done) { - child = step.value; - nextName = nextNamePrefix + getComponentKey(child, ii++); - subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); - } - } else { - if (process.env.NODE_ENV !== 'production') { - var mapsAsChildrenAddendum = ''; - if (ReactCurrentOwner.current) { - var mapsAsChildrenOwnerName = ReactCurrentOwner.current.getName(); - if (mapsAsChildrenOwnerName) { - mapsAsChildrenAddendum = ' Check the render method of `' + mapsAsChildrenOwnerName + '`.'; - } - } - process.env.NODE_ENV !== 'production' ? warning(didWarnAboutMaps, 'Using Maps as children is not yet fully supported. It is an ' + 'experimental feature that might be removed. Convert it to a ' + 'sequence / iterable of keyed ReactElements instead.%s', mapsAsChildrenAddendum) : void 0; - didWarnAboutMaps = true; - } - // Iterator will provide entry [k,v] tuples rather than values. - while (!(step = iterator.next()).done) { - var entry = step.value; - if (entry) { - child = entry[1]; - nextName = nextNamePrefix + KeyEscapeUtils.escape(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0); - subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); - } - } - } - } else if (type === 'object') { - var addendum = ''; - if (process.env.NODE_ENV !== 'production') { - addendum = ' If you meant to render a collection of children, use an array ' + 'instead or wrap the object using createFragment(object) from the ' + 'React add-ons.'; - if (children._isReactElement) { - addendum = ' It looks like you\'re using an element created by a different ' + 'version of React. Make sure to use only one copy of React.'; - } - if (ReactCurrentOwner.current) { - var name = ReactCurrentOwner.current.getName(); - if (name) { - addendum += ' Check the render method of `' + name + '`.'; - } - } - } - var childrenString = String(children); - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : _prodInvariant('31', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : void 0; - } - } - - return subtreeCount; -} - -/** - * Traverses children that are typically specified as `props.children`, but - * might also be specified through attributes: - * - * - `traverseAllChildren(this.props.children, ...)` - * - `traverseAllChildren(this.props.leftPanelChildren, ...)` - * - * The `traverseContext` is an optional argument that is passed through the - * entire traversal. It can be used to store accumulations or anything else that - * the callback might find relevant. - * - * @param {?*} children Children tree object. - * @param {!function} callback To invoke upon traversing each child. - * @param {?*} traverseContext Context for traversal. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildren(children, callback, traverseContext) { - if (children == null) { - return 0; - } - - return traverseAllChildrenImpl(children, '', callback, traverseContext); -} - -module.exports = traverseAllChildren; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 99 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _React$PropTypes = _react2['default'].PropTypes; -var bool = _React$PropTypes.bool; -var object = _React$PropTypes.object; -var string = _React$PropTypes.string; -var func = _React$PropTypes.func; - -function isLeftClickEvent(event) { - return event.button === 0; -} - -function isModifiedEvent(event) { - return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); -} - -function isEmptyObject(object) { - for (var p in object) { - if (object.hasOwnProperty(p)) return false; - }return true; -} - -/** - * A <Link> is used to create an <a> element that links to a route. - * When that route is active, the link gets the value of its - * `activeClassName` prop - * - * For example, assuming you have the following route: - * - * <Route path="/posts/:postID" component={Post} /> - * - * You could use the following component to link to that route: - * - * <Link to={`/posts/${post.id}`} /> - * - * Links may pass along location state and/or query string parameters - * in the state/query props, respectively. - * - * <Link ... query={{ show: true }} state={{ the: 'state' }} /> - */ - -var Link = (function (_Component) { - _inherits(Link, _Component); - - function Link() { - _classCallCheck(this, Link); - - _Component.apply(this, arguments); - } - - Link.prototype.handleClick = function handleClick(event) { - var allowTransition = true; - - if (this.props.onClick) this.props.onClick(event); - - if (isModifiedEvent(event) || !isLeftClickEvent(event)) return; - - if (event.defaultPrevented === true) allowTransition = false; - - // If target prop is set (e.g. to "_blank") let browser handle link. - /* istanbul ignore if: untestable with Karma */ - if (this.props.target) { - if (!allowTransition) event.preventDefault(); - - return; - } - - event.preventDefault(); - - if (allowTransition) { - var _props = this.props; - var state = _props.state; - var to = _props.to; - var query = _props.query; - var hash = _props.hash; - - if (hash) to += hash; - - this.context.history.pushState(state, to, query); - } - }; - - Link.prototype.render = function render() { - var _this = this; - - var _props2 = this.props; - var to = _props2.to; - var query = _props2.query; - var hash = _props2.hash; - var state = _props2.state; - var activeClassName = _props2.activeClassName; - var activeStyle = _props2.activeStyle; - var onlyActiveOnIndex = _props2.onlyActiveOnIndex; - - var props = _objectWithoutProperties(_props2, ['to', 'query', 'hash', 'state', 'activeClassName', 'activeStyle', 'onlyActiveOnIndex']); - - // Manually override onClick. - props.onClick = function (e) { - return _this.handleClick(e); - }; - - // Ignore if rendered outside the context of history, simplifies unit testing. - var history = this.context.history; - - if (history) { - props.href = history.createHref(to, query); - - if (hash) props.href += hash; - - if (activeClassName || activeStyle != null && !isEmptyObject(activeStyle)) { - if (history.isActive(to, query, onlyActiveOnIndex)) { - if (activeClassName) props.className += props.className === '' ? activeClassName : ' ' + activeClassName; - - if (activeStyle) props.style = _extends({}, props.style, activeStyle); - } - } - } - - return _react2['default'].createElement('a', props); - }; - - return Link; -})(_react.Component); - -Link.contextTypes = { - history: object -}; - -Link.propTypes = { - to: string.isRequired, - query: object, - hash: string, - state: object, - activeStyle: object, - activeClassName: string, - onlyActiveOnIndex: bool.isRequired, - onClick: func -}; - -Link.defaultProps = { - onlyActiveOnIndex: false, - className: '', - style: {} -}; - -exports['default'] = Link; -module.exports = exports['default']; - -/***/ }), -/* 100 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _RouteUtils = __webpack_require__(19); - -var _PatternUtils = __webpack_require__(34); - -var _PropTypes = __webpack_require__(21); - -var _React$PropTypes = _react2['default'].PropTypes; -var string = _React$PropTypes.string; -var object = _React$PropTypes.object; - -/** - * A <Redirect> is used to declare another URL path a client should - * be sent to when they request a given URL. - * - * Redirects are placed alongside routes in the route configuration - * and are traversed in the same manner. - */ - -var Redirect = (function (_Component) { - _inherits(Redirect, _Component); - - function Redirect() { - _classCallCheck(this, Redirect); - - _Component.apply(this, arguments); - } - - /* istanbul ignore next: sanity check */ - - Redirect.prototype.render = function render() { - true ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, '<Redirect> elements are for router configuration only and should not be rendered') : _invariant2['default'](false) : undefined; - }; - - return Redirect; -})(_react.Component); - -Redirect.createRouteFromReactElement = function (element) { - var route = _RouteUtils.createRouteFromReactElement(element); - - if (route.from) route.path = route.from; - - route.onEnter = function (nextState, replaceState) { - var location = nextState.location; - var params = nextState.params; - - var pathname = undefined; - if (route.to.charAt(0) === '/') { - pathname = _PatternUtils.formatPattern(route.to, params); - } else if (!route.to) { - pathname = location.pathname; - } else { - var routeIndex = nextState.routes.indexOf(route); - var parentPattern = Redirect.getRoutePattern(nextState.routes, routeIndex - 1); - var pattern = parentPattern.replace(/\/*$/, '/') + route.to; - pathname = _PatternUtils.formatPattern(pattern, params); - } - - replaceState(route.state || location.state, pathname, route.query || location.query); - }; - - return route; -}; - -Redirect.getRoutePattern = function (routes, routeIndex) { - var parentPattern = ''; - - for (var i = routeIndex; i >= 0; i--) { - var route = routes[i]; - var pattern = route.path || ''; - parentPattern = pattern.replace(/\/*$/, '/') + parentPattern; - - if (pattern.indexOf('/') === 0) break; - } - - return '/' + parentPattern; -}; - -Redirect.propTypes = { - path: string, - from: string, // Alias for path - to: string.isRequired, - query: object, - state: object, - onEnter: _PropTypes.falsy, - children: _PropTypes.falsy -}; - -exports['default'] = Redirect; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 101 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _RouteUtils = __webpack_require__(19); - -var _getRouteParams = __webpack_require__(320); - -var _getRouteParams2 = _interopRequireDefault(_getRouteParams); - -var _React$PropTypes = _react2['default'].PropTypes; -var array = _React$PropTypes.array; -var func = _React$PropTypes.func; -var object = _React$PropTypes.object; - -/** - * A <RoutingContext> renders the component tree for a given router state - * and sets the history object and the current location in context. - */ - -var RoutingContext = (function (_Component) { - _inherits(RoutingContext, _Component); - - function RoutingContext() { - _classCallCheck(this, RoutingContext); - - _Component.apply(this, arguments); - } - - RoutingContext.prototype.getChildContext = function getChildContext() { - var _props = this.props; - var history = _props.history; - var location = _props.location; - - return { history: history, location: location }; - }; - - RoutingContext.prototype.createElement = function createElement(component, props) { - return component == null ? null : this.props.createElement(component, props); - }; - - RoutingContext.prototype.render = function render() { - var _this = this; - - var _props2 = this.props; - var history = _props2.history; - var location = _props2.location; - var routes = _props2.routes; - var params = _props2.params; - var components = _props2.components; - - var element = null; - - if (components) { - element = components.reduceRight(function (element, components, index) { - if (components == null) return element; // Don't create new children; use the grandchildren. - - var route = routes[index]; - var routeParams = _getRouteParams2['default'](route, params); - var props = { - history: history, - location: location, - params: params, - route: route, - routeParams: routeParams, - routes: routes - }; - - if (_RouteUtils.isReactChildren(element)) { - props.children = element; - } else if (element) { - for (var prop in element) { - if (element.hasOwnProperty(prop)) props[prop] = element[prop]; - } - } - - if (typeof components === 'object') { - var elements = {}; - - for (var key in components) { - if (components.hasOwnProperty(key)) { - // Pass through the key as a prop to createElement to allow - // custom createElement functions to know which named component - // they're rendering, for e.g. matching up to fetched data. - elements[key] = _this.createElement(components[key], _extends({ - key: key }, props)); - } - } - - return elements; - } - - return _this.createElement(components, props); - }, element); - } - - !(element === null || element === false || _react2['default'].isValidElement(element)) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'The root route must render a single element') : _invariant2['default'](false) : undefined; - - return element; - }; - - return RoutingContext; -})(_react.Component); - -RoutingContext.propTypes = { - history: object.isRequired, - createElement: func.isRequired, - location: object.isRequired, - routes: array.isRequired, - params: object.isRequired, - components: array.isRequired -}; - -RoutingContext.defaultProps = { - createElement: _react2['default'].createElement -}; - -RoutingContext.childContextTypes = { - history: object.isRequired, - location: object.isRequired -}; - -exports['default'] = RoutingContext; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 102 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* components */ - - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _Router2 = __webpack_require__(316); - -var _Router3 = _interopRequireDefault(_Router2); - -exports.Router = _Router3['default']; - -var _Link2 = __webpack_require__(99); - -var _Link3 = _interopRequireDefault(_Link2); - -exports.Link = _Link3['default']; - -var _IndexLink2 = __webpack_require__(310); - -var _IndexLink3 = _interopRequireDefault(_IndexLink2); - -exports.IndexLink = _IndexLink3['default']; - -/* components (configuration) */ - -var _IndexRedirect2 = __webpack_require__(311); - -var _IndexRedirect3 = _interopRequireDefault(_IndexRedirect2); - -exports.IndexRedirect = _IndexRedirect3['default']; - -var _IndexRoute2 = __webpack_require__(312); - -var _IndexRoute3 = _interopRequireDefault(_IndexRoute2); - -exports.IndexRoute = _IndexRoute3['default']; - -var _Redirect2 = __webpack_require__(100); - -var _Redirect3 = _interopRequireDefault(_Redirect2); - -exports.Redirect = _Redirect3['default']; - -var _Route2 = __webpack_require__(314); - -var _Route3 = _interopRequireDefault(_Route2); - -exports.Route = _Route3['default']; - -/* mixins */ - -var _History2 = __webpack_require__(309); - -var _History3 = _interopRequireDefault(_History2); - -exports.History = _History3['default']; - -var _Lifecycle2 = __webpack_require__(313); - -var _Lifecycle3 = _interopRequireDefault(_Lifecycle2); - -exports.Lifecycle = _Lifecycle3['default']; - -var _RouteContext2 = __webpack_require__(315); - -var _RouteContext3 = _interopRequireDefault(_RouteContext2); - -exports.RouteContext = _RouteContext3['default']; - -/* utils */ - -var _useRoutes2 = __webpack_require__(62); - -var _useRoutes3 = _interopRequireDefault(_useRoutes2); - -exports.useRoutes = _useRoutes3['default']; - -var _RouteUtils = __webpack_require__(19); - -exports.createRoutes = _RouteUtils.createRoutes; - -var _RoutingContext2 = __webpack_require__(101); - -var _RoutingContext3 = _interopRequireDefault(_RoutingContext2); - -exports.RoutingContext = _RoutingContext3['default']; - -var _PropTypes2 = __webpack_require__(21); - -var _PropTypes3 = _interopRequireDefault(_PropTypes2); - -exports.PropTypes = _PropTypes3['default']; - -var _match2 = __webpack_require__(322); - -var _match3 = _interopRequireDefault(_match2); - -exports.match = _match3['default']; - -var _Router4 = _interopRequireDefault(_Router2); - -exports['default'] = _Router4['default']; - -/***/ }), -/* 103 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -// The Symbol used to tag the ReactElement type. If there is no native Symbol -// nor polyfill, then a plain number is used for performance. - -var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7; - -module.exports = REACT_ELEMENT_TYPE; - -/***/ }), -/* 104 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -/** - * ReactElementValidator provides a wrapper around a element factory - * which validates the props passed to the element. This is intended to be - * used only in DEV and could be replaced by a static type checker for languages - * that support it. - */ - - - -var ReactCurrentOwner = __webpack_require__(15); -var ReactComponentTreeHook = __webpack_require__(9); -var ReactElement = __webpack_require__(22); - -var checkReactTypeSpec = __webpack_require__(332); - -var canDefineProperty = __webpack_require__(66); -var getIteratorFn = __webpack_require__(67); -var warning = __webpack_require__(3); - -function getDeclarationErrorAddendum() { - if (ReactCurrentOwner.current) { - var name = ReactCurrentOwner.current.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -/** - * Warn if there's no key explicitly set on dynamic arrays of children or - * object keys are not valid. This allows us to keep track of children between - * updates. - */ -var ownerHasKeyUseWarning = {}; - -function getCurrentComponentErrorInfo(parentType) { - var info = getDeclarationErrorAddendum(); - - if (!info) { - var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name; - if (parentName) { - info = ' Check the top-level render call using <' + parentName + '>.'; - } - } - return info; -} - -/** - * Warn if the element doesn't have an explicit key assigned to it. - * This element is in an array. The array could grow and shrink or be - * reordered. All children that haven't already been validated are required to - * have a "key" property assigned to it. Error statuses are cached so a warning - * will only be shown once. - * - * @internal - * @param {ReactElement} element Element that requires a key. - * @param {*} parentType element's parent's type. - */ -function validateExplicitKey(element, parentType) { - if (!element._store || element._store.validated || element.key != null) { - return; - } - element._store.validated = true; - - var memoizer = ownerHasKeyUseWarning.uniqueKey || (ownerHasKeyUseWarning.uniqueKey = {}); - - var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType); - if (memoizer[currentComponentErrorInfo]) { - return; - } - memoizer[currentComponentErrorInfo] = true; - - // Usually the current owner is the offender, but if it accepts children as a - // property, it may be the creator of the child that's responsible for - // assigning it a key. - var childOwner = ''; - if (element && element._owner && element._owner !== ReactCurrentOwner.current) { - // Give the component that originally created this child. - childOwner = ' It was passed a child from ' + element._owner.getName() + '.'; - } - - process.env.NODE_ENV !== 'production' ? warning(false, 'Each child in an array or iterator should have a unique "key" prop.' + '%s%s See https://fb.me/react-warning-keys for more information.%s', currentComponentErrorInfo, childOwner, ReactComponentTreeHook.getCurrentStackAddendum(element)) : void 0; -} - -/** - * Ensure that every element either is passed in a static location, in an - * array with an explicit keys property defined, or in an object literal - * with valid key property. - * - * @internal - * @param {ReactNode} node Statically passed child of any type. - * @param {*} parentType node's parent's type. - */ -function validateChildKeys(node, parentType) { - if (typeof node !== 'object') { - return; - } - if (Array.isArray(node)) { - for (var i = 0; i < node.length; i++) { - var child = node[i]; - if (ReactElement.isValidElement(child)) { - validateExplicitKey(child, parentType); - } - } - } else if (ReactElement.isValidElement(node)) { - // This element was passed in a valid location. - if (node._store) { - node._store.validated = true; - } - } else if (node) { - var iteratorFn = getIteratorFn(node); - // Entry iterators provide implicit keys. - if (iteratorFn) { - if (iteratorFn !== node.entries) { - var iterator = iteratorFn.call(node); - var step; - while (!(step = iterator.next()).done) { - if (ReactElement.isValidElement(step.value)) { - validateExplicitKey(step.value, parentType); - } - } - } - } - } -} - -/** - * Given an element, validate that its props follow the propTypes definition, - * provided by the type. - * - * @param {ReactElement} element - */ -function validatePropTypes(element) { - var componentClass = element.type; - if (typeof componentClass !== 'function') { - return; - } - var name = componentClass.displayName || componentClass.name; - if (componentClass.propTypes) { - checkReactTypeSpec(componentClass.propTypes, element.props, 'prop', name, element, null); - } - if (typeof componentClass.getDefaultProps === 'function') { - process.env.NODE_ENV !== 'production' ? warning(componentClass.getDefaultProps.isReactClassApproved, 'getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.') : void 0; - } -} - -var ReactElementValidator = { - - createElement: function (type, props, children) { - var validType = typeof type === 'string' || typeof type === 'function'; - // We warn in this case but don't throw. We expect the element creation to - // succeed and there will likely be errors in render. - if (!validType) { - if (typeof type !== 'function' && typeof type !== 'string') { - var info = ''; - if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { - info += ' You likely forgot to export your component from the file ' + 'it\'s defined in.'; - } - info += getDeclarationErrorAddendum(); - process.env.NODE_ENV !== 'production' ? warning(false, 'React.createElement: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', type == null ? type : typeof type, info) : void 0; - } - } - - var element = ReactElement.createElement.apply(this, arguments); - - // The result can be nullish if a mock or a custom function is used. - // TODO: Drop this when these are no longer allowed as the type argument. - if (element == null) { - return element; - } - - // Skip key warning if the type isn't valid since our key validation logic - // doesn't expect a non-string/function type and can throw confusing errors. - // We don't want exception behavior to differ between dev and prod. - // (Rendering will throw with a helpful message and as soon as the type is - // fixed, the key warnings will appear.) - if (validType) { - for (var i = 2; i < arguments.length; i++) { - validateChildKeys(arguments[i], type); - } - } - - validatePropTypes(element); - - return element; - }, - - createFactory: function (type) { - var validatedFactory = ReactElementValidator.createElement.bind(null, type); - // Legacy hook TODO: Warn if this is accessed - validatedFactory.type = type; - - if (process.env.NODE_ENV !== 'production') { - if (canDefineProperty) { - Object.defineProperty(validatedFactory, 'type', { - enumerable: false, - get: function () { - process.env.NODE_ENV !== 'production' ? warning(false, 'Factory.type is deprecated. Access the class directly ' + 'before passing it to createFactory.') : void 0; - Object.defineProperty(this, 'type', { - value: type - }); - return type; - } - }); - } - } - - return validatedFactory; - }, - - cloneElement: function (element, props, children) { - var newElement = ReactElement.cloneElement.apply(this, arguments); - for (var i = 2; i < arguments.length; i++) { - validateChildKeys(arguments[i], newElement.type); - } - validatePropTypes(newElement); - return newElement; - } - -}; - -module.exports = ReactElementValidator; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 105 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; - -module.exports = ReactPropTypesSecret; - -/***/ }), -/* 106 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); -var ReactDOM = __webpack_require__(237); -var FullArticle = __webpack_require__(112); - -// in the browser, do: -if (typeof document !== "undefined") { - ReactDOM.render(React.createElement(FullArticle, null), document.getElementById("article")); -} - -// in not-the browser, do: -module.exports = { FullArticle: FullArticle }; - -/***/ }), -/* 107 */ -/***/ (function(module, exports) { - -module.exports = function(){}; - - -/***/ }), -/* 108 */ -/***/ (function(module, exports) { - -// https://github.com/thibauts/b-spline -module.exports = function interpolate(t, degree, points, knots, weights, result, scaled) { - - var i,j,s,l; // function-scoped iteration variables - var n = points.length; // points count - var d = points[0].length; // point dimensionality - - if(degree < 1) throw new Error('degree must be at least 1 (linear)'); - if(degree > (n-1)) throw new Error('degree must be less than or equal to point count - 1'); - - if(!weights) { - // build weight vector of length [n] - weights = []; - for(i=0; i<n; i++) { - weights[i] = 1; - } - } - - if(!knots) { - // build knot vector of length [n + degree + 1] - var knots = []; - for(i=0; i<n+degree+1; i++) { - knots[i] = i; - } - } else { - if(knots.length !== n+degree+1) throw new Error('bad knot vector length'); - } - - var domain = [ - degree, - knots.length-1 - degree - ]; - - var low = knots[domain[0]]; - var high = knots[domain[1]]; - - // remap t to the domain where the spline is defined - if (!scaled) { - t = t * (high - low) + low; - } - - if(t < low || t > high) throw new Error('out of bounds'); - - // find s (the spline segment) for the [t] value provided - for(s=domain[0]; s<domain[1]; s++) { - if(t >= knots[s] && t <= knots[s+1]) { - break; - } - } - - // convert points to homogeneous coordinates - var v = []; - for(i=0; i<n; i++) { - v[i] = []; - for(j=0; j<d; j++) { - v[i][j] = points[i][j] * weights[i]; - } - v[i][d] = weights[i]; - } - - // l (level) goes from 1 to the curve degree + 1 - var alpha; - for(l=1; l<=degree+1; l++) { - // build level l of the pyramid - for(i=s; i>s-degree-1+l; i--) { - alpha = (t - knots[i]) / (knots[i+degree+1-l] - knots[i]); - - // interpolate each component - for(j=0; j<d+1; j++) { - v[i][j] = (1 - alpha) * v[i-1][j] + alpha * v[i][j]; - } - } - } - - // convert back to cartesian and return - var result = result || []; - for(i=0; i<d; i++) { - result[i] = v[s][i] / v[s][d]; - } - - return result; -}; - - -/***/ }), -/* 109 */ -/***/ (function(module, exports, __webpack_require__) { - -var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! - * Paper.js v0.9.25 - The Swiss Army Knife of Vector Graphics Scripting. - * http://paperjs.org/ - * - * Copyright (c) 2011 - 2014, Juerg Lehni & Jonathan Puckey - * http://scratchdisk.com/ & http://jonathanpuckey.com/ - * - * Distributed under the MIT license. See LICENSE file for details. - * - * All rights reserved. - * - * Date: Sun Oct 25 11:23:38 2015 +0100 - * - *** - * - * Straps.js - Class inheritance library with support for bean-style accessors - * - * Copyright (c) 2006 - 2013 Juerg Lehni - * http://scratchdisk.com/ - * - * Distributed under the MIT license. - * - *** - * - * Acorn.js - * http://marijnhaverbeke.nl/acorn/ - * - * Acorn is a tiny, fast JavaScript parser written in JavaScript, - * created by Marijn Haverbeke and released under an MIT license. - * - */ - -var paper = new function(undefined) { - -var Base = new function() { - var hidden = /^(statics|enumerable|beans|preserve)$/, - - forEach = [].forEach || function(iter, bind) { - for (var i = 0, l = this.length; i < l; i++) - iter.call(bind, this[i], i, this); - }, - - forIn = function(iter, bind) { - for (var i in this) - if (this.hasOwnProperty(i)) - iter.call(bind, this[i], i, this); - }, - - create = Object.create || function(proto) { - return { __proto__: proto }; - }, - - describe = Object.getOwnPropertyDescriptor || function(obj, name) { - var get = obj.__lookupGetter__ && obj.__lookupGetter__(name); - return get - ? { get: get, set: obj.__lookupSetter__(name), - enumerable: true, configurable: true } - : obj.hasOwnProperty(name) - ? { value: obj[name], enumerable: true, - configurable: true, writable: true } - : null; - }, - - _define = Object.defineProperty || function(obj, name, desc) { - if ((desc.get || desc.set) && obj.__defineGetter__) { - if (desc.get) - obj.__defineGetter__(name, desc.get); - if (desc.set) - obj.__defineSetter__(name, desc.set); - } else { - obj[name] = desc.value; - } - return obj; - }, - - define = function(obj, name, desc) { - delete obj[name]; - return _define(obj, name, desc); - }; - - function inject(dest, src, enumerable, beans, preserve) { - var beansNames = {}; - - function field(name, val) { - val = val || (val = describe(src, name)) - && (val.get ? val : val.value); - if (typeof val === 'string' && val[0] === '#') - val = dest[val.substring(1)] || val; - var isFunc = typeof val === 'function', - res = val, - prev = preserve || isFunc && !val.base - ? (val && val.get ? name in dest : dest[name]) - : null, - bean; - if (!preserve || !prev) { - if (isFunc && prev) - val.base = prev; - if (isFunc && beans !== false - && (bean = name.match(/^([gs]et|is)(([A-Z])(.*))$/))) - beansNames[bean[3].toLowerCase() + bean[4]] = bean[2]; - if (!res || isFunc || !res.get || typeof res.get !== 'function' - || !Base.isPlainObject(res)) - res = { value: res, writable: true }; - if ((describe(dest, name) - || { configurable: true }).configurable) { - res.configurable = true; - res.enumerable = enumerable; - } - define(dest, name, res); - } - } - if (src) { - for (var name in src) { - if (src.hasOwnProperty(name) && !hidden.test(name)) - field(name); - } - for (var name in beansNames) { - var part = beansNames[name], - set = dest['set' + part], - get = dest['get' + part] || set && dest['is' + part]; - if (get && (beans === true || get.length === 0)) - field(name, { get: get, set: set }); - } - } - return dest; - } - - function each(obj, iter, bind) { - if (obj) - ('length' in obj && !obj.getLength - && typeof obj.length === 'number' - ? forEach - : forIn).call(obj, iter, bind = bind || obj); - return bind; - } - - function set(obj, props, exclude) { - for (var key in props) - if (props.hasOwnProperty(key) && !(exclude && exclude[key])) - obj[key] = props[key]; - return obj; - } - - return inject(function Base() { - for (var i = 0, l = arguments.length; i < l; i++) - set(this, arguments[i]); - }, { - inject: function(src) { - if (src) { - var statics = src.statics === true ? src : src.statics, - beans = src.beans, - preserve = src.preserve; - if (statics !== src) - inject(this.prototype, src, src.enumerable, beans, preserve); - inject(this, statics, true, beans, preserve); - } - for (var i = 1, l = arguments.length; i < l; i++) - this.inject(arguments[i]); - return this; - }, - - extend: function() { - var base = this, - ctor, - proto; - for (var i = 0, l = arguments.length; i < l; i++) - if (ctor = arguments[i].initialize) - break; - ctor = ctor || function() { - base.apply(this, arguments); - }; - proto = ctor.prototype = create(this.prototype); - define(proto, 'constructor', - { value: ctor, writable: true, configurable: true }); - inject(ctor, this, true); - if (arguments.length) - this.inject.apply(ctor, arguments); - ctor.base = base; - return ctor; - } - }, true).inject({ - inject: function() { - for (var i = 0, l = arguments.length; i < l; i++) { - var src = arguments[i]; - if (src) - inject(this, src, src.enumerable, src.beans, src.preserve); - } - return this; - }, - - extend: function() { - var res = create(this); - return res.inject.apply(res, arguments); - }, - - each: function(iter, bind) { - return each(this, iter, bind); - }, - - set: function(props) { - return set(this, props); - }, - - clone: function() { - return new this.constructor(this); - }, - - statics: { - each: each, - create: create, - define: define, - describe: describe, - set: set, - - clone: function(obj) { - return set(new obj.constructor(), obj); - }, - - isPlainObject: function(obj) { - var ctor = obj != null && obj.constructor; - return ctor && (ctor === Object || ctor === Base - || ctor.name === 'Object'); - }, - - pick: function(a, b) { - return a !== undefined ? a : b; - } - } - }); -}; - -if (true) - module.exports = Base; - -Base.inject({ - toString: function() { - return this._id != null - ? (this._class || 'Object') + (this._name - ? " '" + this._name + "'" - : ' @' + this._id) - : '{ ' + Base.each(this, function(value, key) { - if (!/^_/.test(key)) { - var type = typeof value; - this.push(key + ': ' + (type === 'number' - ? Formatter.instance.number(value) - : type === 'string' ? "'" + value + "'" : value)); - } - }, []).join(', ') + ' }'; - }, - - getClassName: function() { - return this._class || ''; - }, - - exportJSON: function(options) { - return Base.exportJSON(this, options); - }, - - toJSON: function() { - return Base.serialize(this); - }, - - _set: function(props, exclude, dontCheck) { - if (props && (dontCheck || Base.isPlainObject(props))) { - var keys = Object.keys(props._filtering || props); - for (var i = 0, l = keys.length; i < l; i++) { - var key = keys[i]; - if (!(exclude && exclude[key])) { - var value = props[key]; - if (value !== undefined) - this[key] = value; - } - } - return true; - } - }, - - statics: { - - exports: { - enumerable: true - }, - - extend: function extend() { - var res = extend.base.apply(this, arguments), - name = res.prototype._class; - if (name && !Base.exports[name]) - Base.exports[name] = res; - return res; - }, - - equals: function(obj1, obj2) { - if (obj1 === obj2) - return true; - if (obj1 && obj1.equals) - return obj1.equals(obj2); - if (obj2 && obj2.equals) - return obj2.equals(obj1); - if (obj1 && obj2 - && typeof obj1 === 'object' && typeof obj2 === 'object') { - if (Array.isArray(obj1) && Array.isArray(obj2)) { - var length = obj1.length; - if (length !== obj2.length) - return false; - while (length--) { - if (!Base.equals(obj1[length], obj2[length])) - return false; - } - } else { - var keys = Object.keys(obj1), - length = keys.length; - if (length !== Object.keys(obj2).length) - return false; - while (length--) { - var key = keys[length]; - if (!(obj2.hasOwnProperty(key) - && Base.equals(obj1[key], obj2[key]))) - return false; - } - } - return true; - } - return false; - }, - - read: function(list, start, options, length) { - if (this === Base) { - var value = this.peek(list, start); - list.__index++; - return value; - } - var proto = this.prototype, - readIndex = proto._readIndex, - index = start || readIndex && list.__index || 0; - if (!length) - length = list.length - index; - var obj = list[index]; - if (obj instanceof this - || options && options.readNull && obj == null && length <= 1) { - if (readIndex) - list.__index = index + 1; - return obj && options && options.clone ? obj.clone() : obj; - } - obj = Base.create(this.prototype); - if (readIndex) - obj.__read = true; - obj = obj.initialize.apply(obj, index > 0 || length < list.length - ? Array.prototype.slice.call(list, index, index + length) - : list) || obj; - if (readIndex) { - list.__index = index + obj.__read; - obj.__read = undefined; - } - return obj; - }, - - peek: function(list, start) { - return list[list.__index = start || list.__index || 0]; - }, - - remain: function(list) { - return list.length - (list.__index || 0); - }, - - readAll: function(list, start, options) { - var res = [], - entry; - for (var i = start || 0, l = list.length; i < l; i++) { - res.push(Array.isArray(entry = list[i]) - ? this.read(entry, 0, options) - : this.read(list, i, options, 1)); - } - return res; - }, - - readNamed: function(list, name, start, options, length) { - var value = this.getNamed(list, name), - hasObject = value !== undefined; - if (hasObject) { - var filtered = list._filtered; - if (!filtered) { - filtered = list._filtered = Base.create(list[0]); - filtered._filtering = list[0]; - } - filtered[name] = undefined; - } - return this.read(hasObject ? [value] : list, start, options, length); - }, - - getNamed: function(list, name) { - var arg = list[0]; - if (list._hasObject === undefined) - list._hasObject = list.length === 1 && Base.isPlainObject(arg); - if (list._hasObject) - return name ? arg[name] : list._filtered || arg; - }, - - hasNamed: function(list, name) { - return !!this.getNamed(list, name); - }, - - isPlainValue: function(obj, asString) { - return this.isPlainObject(obj) || Array.isArray(obj) - || asString && typeof obj === 'string'; - }, - - serialize: function(obj, options, compact, dictionary) { - options = options || {}; - - var root = !dictionary, - res; - if (root) { - options.formatter = new Formatter(options.precision); - dictionary = { - length: 0, - definitions: {}, - references: {}, - add: function(item, create) { - var id = '#' + item._id, - ref = this.references[id]; - if (!ref) { - this.length++; - var res = create.call(item), - name = item._class; - if (name && res[0] !== name) - res.unshift(name); - this.definitions[id] = res; - ref = this.references[id] = [id]; - } - return ref; - } - }; - } - if (obj && obj._serialize) { - res = obj._serialize(options, dictionary); - var name = obj._class; - if (name && !compact && !res._compact && res[0] !== name) - res.unshift(name); - } else if (Array.isArray(obj)) { - res = []; - for (var i = 0, l = obj.length; i < l; i++) - res[i] = Base.serialize(obj[i], options, compact, - dictionary); - if (compact) - res._compact = true; - } else if (Base.isPlainObject(obj)) { - res = {}; - var keys = Object.keys(obj); - for (var i = 0, l = keys.length; i < l; i++) { - var key = keys[i]; - res[key] = Base.serialize(obj[key], options, compact, - dictionary); - } - } else if (typeof obj === 'number') { - res = options.formatter.number(obj, options.precision); - } else { - res = obj; - } - return root && dictionary.length > 0 - ? [['dictionary', dictionary.definitions], res] - : res; - }, - - deserialize: function(json, create, _data, _isDictionary) { - var res = json, - isRoot = !_data; - _data = _data || {}; - if (Array.isArray(json)) { - var type = json[0], - isDictionary = type === 'dictionary'; - if (json.length == 1 && /^#/.test(type)) - return _data.dictionary[type]; - type = Base.exports[type]; - res = []; - if (_isDictionary) - _data.dictionary = res; - for (var i = type ? 1 : 0, l = json.length; i < l; i++) - res.push(Base.deserialize(json[i], create, _data, - isDictionary)); - if (type) { - var args = res; - if (create) { - res = create(type, args); - } else { - res = Base.create(type.prototype); - type.apply(res, args); - } - } - } else if (Base.isPlainObject(json)) { - res = {}; - if (_isDictionary) - _data.dictionary = res; - for (var key in json) - res[key] = Base.deserialize(json[key], create, _data); - } - return isRoot && json && json.length && json[0][0] === 'dictionary' - ? res[1] - : res; - }, - - exportJSON: function(obj, options) { - var json = Base.serialize(obj, options); - return options && options.asString === false - ? json - : JSON.stringify(json); - }, - - importJSON: function(json, target) { - return Base.deserialize( - typeof json === 'string' ? JSON.parse(json) : json, - function(type, args) { - var obj = target && target.constructor === type - ? target - : Base.create(type.prototype), - isTarget = obj === target; - if (args.length === 1 && obj instanceof Item - && (isTarget || !(obj instanceof Layer))) { - var arg = args[0]; - if (Base.isPlainObject(arg)) - arg.insert = false; - } - type.apply(obj, args); - if (isTarget) - target = null; - return obj; - }); - }, - - splice: function(list, items, index, remove) { - var amount = items && items.length, - append = index === undefined; - index = append ? list.length : index; - if (index > list.length) - index = list.length; - for (var i = 0; i < amount; i++) - items[i]._index = index + i; - if (append) { - list.push.apply(list, items); - return []; - } else { - var args = [index, remove]; - if (items) - args.push.apply(args, items); - var removed = list.splice.apply(list, args); - for (var i = 0, l = removed.length; i < l; i++) - removed[i]._index = undefined; - for (var i = index + amount, l = list.length; i < l; i++) - list[i]._index = i; - return removed; - } - }, - - capitalize: function(str) { - return str.replace(/\b[a-z]/g, function(match) { - return match.toUpperCase(); - }); - }, - - camelize: function(str) { - return str.replace(/-(.)/g, function(all, chr) { - return chr.toUpperCase(); - }); - }, - - hyphenate: function(str) { - return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); - } - } -}); - -var Emitter = { - on: function(type, func) { - if (typeof type !== 'string') { - Base.each(type, function(value, key) { - this.on(key, value); - }, this); - } else { - var types = this._eventTypes, - entry = types && types[type], - handlers = this._callbacks = this._callbacks || {}; - handlers = handlers[type] = handlers[type] || []; - if (handlers.indexOf(func) === -1) { - handlers.push(func); - if (entry && entry.install && handlers.length === 1) - entry.install.call(this, type); - } - } - return this; - }, - - off: function(type, func) { - if (typeof type !== 'string') { - Base.each(type, function(value, key) { - this.off(key, value); - }, this); - return; - } - var types = this._eventTypes, - entry = types && types[type], - handlers = this._callbacks && this._callbacks[type], - index; - if (handlers) { - if (!func || (index = handlers.indexOf(func)) !== -1 - && handlers.length === 1) { - if (entry && entry.uninstall) - entry.uninstall.call(this, type); - delete this._callbacks[type]; - } else if (index !== -1) { - handlers.splice(index, 1); - } - } - return this; - }, - - once: function(type, func) { - return this.on(type, function() { - func.apply(this, arguments); - this.off(type, func); - }); - }, - - emit: function(type, event) { - var handlers = this._callbacks && this._callbacks[type]; - if (!handlers) - return false; - var args = [].slice.call(arguments, 1); - handlers = handlers.slice(); - for (var i = 0, l = handlers.length; i < l; i++) { - if (handlers[i].apply(this, args) === false) { - if (event && event.stop) - event.stop(); - break; - } - } - return true; - }, - - responds: function(type) { - return !!(this._callbacks && this._callbacks[type]); - }, - - attach: '#on', - detach: '#off', - fire: '#emit', - - _installEvents: function(install) { - var handlers = this._callbacks, - key = install ? 'install' : 'uninstall'; - for (var type in handlers) { - if (handlers[type].length > 0) { - var types = this._eventTypes, - entry = types && types[type], - func = entry && entry[key]; - if (func) - func.call(this, type); - } - } - }, - - statics: { - inject: function inject(src) { - var events = src._events; - if (events) { - var types = {}; - Base.each(events, function(entry, key) { - var isString = typeof entry === 'string', - name = isString ? entry : key, - part = Base.capitalize(name), - type = name.substring(2).toLowerCase(); - types[type] = isString ? {} : entry; - name = '_' + name; - src['get' + part] = function() { - return this[name]; - }; - src['set' + part] = function(func) { - var prev = this[name]; - if (prev) - this.off(type, prev); - if (func) - this.on(type, func); - this[name] = func; - }; - }); - src._eventTypes = types; - } - return inject.base.apply(this, arguments); - } - } -}; - -var PaperScope = Base.extend({ - _class: 'PaperScope', - - initialize: function PaperScope() { - paper = this; - this.settings = new Base({ - applyMatrix: true, - handleSize: 4, - hitTolerance: 0 - }); - this.project = null; - this.projects = []; - this.tools = []; - this.palettes = []; - this._id = PaperScope._id++; - PaperScope._scopes[this._id] = this; - var proto = PaperScope.prototype; - if (!this.support) { - var ctx = CanvasProvider.getContext(1, 1); - proto.support = { - nativeDash: 'setLineDash' in ctx || 'mozDash' in ctx, - nativeBlendModes: BlendMode.nativeModes - }; - CanvasProvider.release(ctx); - } - - if (!this.browser) { - var agent = navigator.userAgent.toLowerCase(), - platform = (/(win)/.exec(agent) - || /(mac)/.exec(agent) - || /(linux)/.exec(agent) - || [])[0], - browser = proto.browser = { platform: platform }; - if (platform) - browser[platform] = true; - agent.replace( - /(opera|chrome|safari|webkit|firefox|msie|trident|atom)\/?\s*([.\d]+)(?:.*version\/([.\d]+))?(?:.*rv\:([.\d]+))?/g, - function(all, n, v1, v2, rv) { - if (!browser.chrome) { - var v = n === 'opera' ? v2 : v1; - if (n === 'trident') { - v = rv; - n = 'msie'; - } - browser.version = v; - browser.versionNumber = parseFloat(v); - browser.name = n; - browser[n] = true; - } - } - ); - if (browser.chrome) - delete browser.webkit; - if (browser.atom) - delete browser.chrome; - } - }, - - version: "0.9.25", - - getView: function() { - return this.project && this.project.getView(); - }, - - getPaper: function() { - return this; - }, - - execute: function(code, url, options) { - paper.PaperScript.execute(code, this, url, options); - View.updateFocus(); - }, - - install: function(scope) { - var that = this; - Base.each(['project', 'view', 'tool'], function(key) { - Base.define(scope, key, { - configurable: true, - get: function() { - return that[key]; - } - }); - }); - for (var key in this) - if (!/^_/.test(key) && this[key]) - scope[key] = this[key]; - }, - - setup: function(element) { - paper = this; - this.project = new Project(element); - return this; - }, - - activate: function() { - paper = this; - }, - - clear: function() { - for (var i = this.projects.length - 1; i >= 0; i--) - this.projects[i].remove(); - for (var i = this.tools.length - 1; i >= 0; i--) - this.tools[i].remove(); - for (var i = this.palettes.length - 1; i >= 0; i--) - this.palettes[i].remove(); - }, - - remove: function() { - this.clear(); - delete PaperScope._scopes[this._id]; - }, - - statics: new function() { - function handleAttribute(name) { - name += 'Attribute'; - return function(el, attr) { - return el[name](attr) || el[name]('data-paper-' + attr); - }; - } - - return { - _scopes: {}, - _id: 0, - - get: function(id) { - return this._scopes[id] || null; - }, - - getAttribute: handleAttribute('get'), - hasAttribute: handleAttribute('has') - }; - } -}); - -var PaperScopeItem = Base.extend(Emitter, { - - initialize: function(activate) { - this._scope = paper; - this._index = this._scope[this._list].push(this) - 1; - if (activate || !this._scope[this._reference]) - this.activate(); - }, - - activate: function() { - if (!this._scope) - return false; - var prev = this._scope[this._reference]; - if (prev && prev !== this) - prev.emit('deactivate'); - this._scope[this._reference] = this; - this.emit('activate', prev); - return true; - }, - - isActive: function() { - return this._scope[this._reference] === this; - }, - - remove: function() { - if (this._index == null) - return false; - Base.splice(this._scope[this._list], null, this._index, 1); - if (this._scope[this._reference] == this) - this._scope[this._reference] = null; - this._scope = null; - return true; - } -}); - -var Formatter = Base.extend({ - initialize: function(precision) { - this.precision = precision || 5; - this.multiplier = Math.pow(10, this.precision); - }, - - number: function(val) { - return Math.round(val * this.multiplier) / this.multiplier; - }, - - pair: function(val1, val2, separator) { - return this.number(val1) + (separator || ',') + this.number(val2); - }, - - point: function(val, separator) { - return this.number(val.x) + (separator || ',') + this.number(val.y); - }, - - size: function(val, separator) { - return this.number(val.width) + (separator || ',') - + this.number(val.height); - }, - - rectangle: function(val, separator) { - return this.point(val, separator) + (separator || ',') - + this.size(val, separator); - } -}); - -Formatter.instance = new Formatter(); - -var Numerical = new function() { - - var abscissas = [ - [ 0.5773502691896257645091488], - [0,0.7745966692414833770358531], - [ 0.3399810435848562648026658,0.8611363115940525752239465], - [0,0.5384693101056830910363144,0.9061798459386639927976269], - [ 0.2386191860831969086305017,0.6612093864662645136613996,0.9324695142031520278123016], - [0,0.4058451513773971669066064,0.7415311855993944398638648,0.9491079123427585245261897], - [ 0.1834346424956498049394761,0.5255324099163289858177390,0.7966664774136267395915539,0.9602898564975362316835609], - [0,0.3242534234038089290385380,0.6133714327005903973087020,0.8360311073266357942994298,0.9681602395076260898355762], - [ 0.1488743389816312108848260,0.4333953941292471907992659,0.6794095682990244062343274,0.8650633666889845107320967,0.9739065285171717200779640], - [0,0.2695431559523449723315320,0.5190961292068118159257257,0.7301520055740493240934163,0.8870625997680952990751578,0.9782286581460569928039380], - [ 0.1252334085114689154724414,0.3678314989981801937526915,0.5873179542866174472967024,0.7699026741943046870368938,0.9041172563704748566784659,0.9815606342467192506905491], - [0,0.2304583159551347940655281,0.4484927510364468528779129,0.6423493394403402206439846,0.8015780907333099127942065,0.9175983992229779652065478,0.9841830547185881494728294], - [ 0.1080549487073436620662447,0.3191123689278897604356718,0.5152486363581540919652907,0.6872929048116854701480198,0.8272013150697649931897947,0.9284348836635735173363911,0.9862838086968123388415973], - [0,0.2011940939974345223006283,0.3941513470775633698972074,0.5709721726085388475372267,0.7244177313601700474161861,0.8482065834104272162006483,0.9372733924007059043077589,0.9879925180204854284895657], - [ 0.0950125098376374401853193,0.2816035507792589132304605,0.4580167776572273863424194,0.6178762444026437484466718,0.7554044083550030338951012,0.8656312023878317438804679,0.9445750230732325760779884,0.9894009349916499325961542] - ]; - - var weights = [ - [1], - [0.8888888888888888888888889,0.5555555555555555555555556], - [0.6521451548625461426269361,0.3478548451374538573730639], - [0.5688888888888888888888889,0.4786286704993664680412915,0.2369268850561890875142640], - [0.4679139345726910473898703,0.3607615730481386075698335,0.1713244923791703450402961], - [0.4179591836734693877551020,0.3818300505051189449503698,0.2797053914892766679014678,0.1294849661688696932706114], - [0.3626837833783619829651504,0.3137066458778872873379622,0.2223810344533744705443560,0.1012285362903762591525314], - [0.3302393550012597631645251,0.3123470770400028400686304,0.2606106964029354623187429,0.1806481606948574040584720,0.0812743883615744119718922], - [0.2955242247147528701738930,0.2692667193099963550912269,0.2190863625159820439955349,0.1494513491505805931457763,0.0666713443086881375935688], - [0.2729250867779006307144835,0.2628045445102466621806889,0.2331937645919904799185237,0.1862902109277342514260976,0.1255803694649046246346943,0.0556685671161736664827537], - [0.2491470458134027850005624,0.2334925365383548087608499,0.2031674267230659217490645,0.1600783285433462263346525,0.1069393259953184309602547,0.0471753363865118271946160], - [0.2325515532308739101945895,0.2262831802628972384120902,0.2078160475368885023125232,0.1781459807619457382800467,0.1388735102197872384636018,0.0921214998377284479144218,0.0404840047653158795200216], - [0.2152638534631577901958764,0.2051984637212956039659241,0.1855383974779378137417166,0.1572031671581935345696019,0.1215185706879031846894148,0.0801580871597602098056333,0.0351194603317518630318329], - [0.2025782419255612728806202,0.1984314853271115764561183,0.1861610000155622110268006,0.1662692058169939335532009,0.1395706779261543144478048,0.1071592204671719350118695,0.0703660474881081247092674,0.0307532419961172683546284], - [0.1894506104550684962853967,0.1826034150449235888667637,0.1691565193950025381893121,0.1495959888165767320815017,0.1246289712555338720524763,0.0951585116824927848099251,0.0622535239386478928628438,0.0271524594117540948517806] - ]; - - var abs = Math.abs, - sqrt = Math.sqrt, - pow = Math.pow, - EPSILON = 1e-12, - MACHINE_EPSILON = 1.12e-16; - - function clip(value, min, max) { - return value < min ? min : value > max ? max : value; - } - - return { - TOLERANCE: 1e-6, - EPSILON: EPSILON, - MACHINE_EPSILON: MACHINE_EPSILON, - CURVETIME_EPSILON: 4e-7, - GEOMETRIC_EPSILON: 2e-7, - WINDING_EPSILON: 2e-7, - TRIGONOMETRIC_EPSILON: 1e-7, - CLIPPING_EPSILON: 1e-7, - KAPPA: 4 * (sqrt(2) - 1) / 3, - - isZero: function(val) { - return val >= -EPSILON && val <= EPSILON; - }, - - integrate: function(f, a, b, n) { - var x = abscissas[n - 2], - w = weights[n - 2], - A = (b - a) * 0.5, - B = A + a, - i = 0, - m = (n + 1) >> 1, - sum = n & 1 ? w[i++] * f(B) : 0; - while (i < m) { - var Ax = A * x[i]; - sum += w[i++] * (f(B + Ax) + f(B - Ax)); - } - return A * sum; - }, - - findRoot: function(f, df, x, a, b, n, tolerance) { - for (var i = 0; i < n; i++) { - var fx = f(x), - dx = fx / df(x), - nx = x - dx; - if (abs(dx) < tolerance) - return nx; - if (fx > 0) { - b = x; - x = nx <= a ? (a + b) * 0.5 : nx; - } else { - a = x; - x = nx >= b ? (a + b) * 0.5 : nx; - } - } - return x; - }, - - solveQuadratic: function(a, b, c, roots, min, max) { - var count = 0, - eMin = min - EPSILON, - eMax = max + EPSILON, - x1, x2 = Infinity, - B = b, - D; - b /= -2; - D = b * b - a * c; - if (D !== 0 && abs(D) < MACHINE_EPSILON) { - var gmC = pow(abs(a * b * c), 1 / 3); - if (gmC < 1e-8) { - var mult = pow(10, - abs(Math.floor(Math.log(gmC) * Math.LOG10E))); - if (!isFinite(mult)) - mult = 0; - a *= mult; - b *= mult; - c *= mult; - D = b * b - a * c; - } - } - if (abs(a) < EPSILON) { - if (abs(B) < EPSILON) - return abs(c) < EPSILON ? -1 : 0; - x1 = -c / B; - } else if (D >= -MACHINE_EPSILON) { - var Q = D < 0 ? 0 : sqrt(D), - R = b + (b < 0 ? -Q : Q); - if (R === 0) { - x1 = c / a; - x2 = -x1; - } else { - x1 = R / a; - x2 = c / R; - } - } - if (isFinite(x1) && (min == null || x1 > eMin && x1 < eMax)) - roots[count++] = min == null ? x1 : clip(x1, min, max); - if (x2 !== x1 - && isFinite(x2) && (min == null || x2 > eMin && x2 < eMax)) - roots[count++] = min == null ? x2 : clip(x2, min, max); - return count; - }, - - solveCubic: function(a, b, c, d, roots, min, max) { - var count = 0, - x, b1, c2; - if (abs(a) < EPSILON) { - a = b; - b1 = c; - c2 = d; - x = Infinity; - } else if (abs(d) < EPSILON) { - b1 = b; - c2 = c; - x = 0; - } else { - var ec = 1 + MACHINE_EPSILON, - x0, q, qd, t, r, s, tmp; - x = -(b / a) / 3; - tmp = a * x, - b1 = tmp + b, - c2 = b1 * x + c, - qd = (tmp + b1) * x + c2, - q = c2 * x + d; - t = q /a; - r = pow(abs(t), 1/3); - s = t < 0 ? -1 : 1; - t = -qd / a; - r = t > 0 ? 1.3247179572 * Math.max(r, sqrt(t)) : r; - x0 = x - s * r; - if (x0 !== x) { - do { - x = x0; - tmp = a * x, - b1 = tmp + b, - c2 = b1 * x + c, - qd = (tmp + b1) * x + c2, - q = c2 * x + d; - x0 = qd === 0 ? x : x - q / qd / ec; - if (x0 === x) { - x = x0; - break; - } - } while (s * x0 > s * x); - if (abs(a) * x * x > abs(d / x)) { - c2 = -d / x; - b1 = (c2 - c) / x; - } - } - } - var count = Numerical.solveQuadratic(a, b1, c2, roots, min, max); - if (isFinite(x) && (count === 0 || x !== roots[count - 1]) - && (min == null || x > min - EPSILON && x < max + EPSILON)) - roots[count++] = min == null ? x : clip(x, min, max); - return count; - } - }; -}; - -var UID = { - _id: 1, - _pools: {}, - - get: function(ctor) { - if (ctor) { - var name = ctor._class, - pool = this._pools[name]; - if (!pool) - pool = this._pools[name] = { _id: 1 }; - return pool._id++; - } else { - return this._id++; - } - } -}; - -var Point = Base.extend({ - _class: 'Point', - _readIndex: true, - - initialize: function Point(arg0, arg1) { - var type = typeof arg0; - if (type === 'number') { - var hasY = typeof arg1 === 'number'; - this.x = arg0; - this.y = hasY ? arg1 : arg0; - if (this.__read) - this.__read = hasY ? 2 : 1; - } else if (type === 'undefined' || arg0 === null) { - this.x = this.y = 0; - if (this.__read) - this.__read = arg0 === null ? 1 : 0; - } else { - if (Array.isArray(arg0)) { - this.x = arg0[0]; - this.y = arg0.length > 1 ? arg0[1] : arg0[0]; - } else if (arg0.x != null) { - this.x = arg0.x; - this.y = arg0.y; - } else if (arg0.width != null) { - this.x = arg0.width; - this.y = arg0.height; - } else if (arg0.angle != null) { - this.x = arg0.length; - this.y = 0; - this.setAngle(arg0.angle); - } else { - this.x = this.y = 0; - if (this.__read) - this.__read = 0; - } - if (this.__read) - this.__read = 1; - } - }, - - set: function(x, y) { - this.x = x; - this.y = y; - return this; - }, - - equals: function(point) { - return this === point || point - && (this.x === point.x && this.y === point.y - || Array.isArray(point) - && this.x === point[0] && this.y === point[1]) - || false; - }, - - clone: function() { - return new Point(this.x, this.y); - }, - - toString: function() { - var f = Formatter.instance; - return '{ x: ' + f.number(this.x) + ', y: ' + f.number(this.y) + ' }'; - }, - - _serialize: function(options) { - var f = options.formatter; - return [f.number(this.x), f.number(this.y)]; - }, - - getLength: function() { - return Math.sqrt(this.x * this.x + this.y * this.y); - }, - - setLength: function(length) { - if (this.isZero()) { - var angle = this._angle || 0; - this.set( - Math.cos(angle) * length, - Math.sin(angle) * length - ); - } else { - var scale = length / this.getLength(); - if (Numerical.isZero(scale)) - this.getAngle(); - this.set( - this.x * scale, - this.y * scale - ); - } - }, - getAngle: function() { - return this.getAngleInRadians.apply(this, arguments) * 180 / Math.PI; - }, - - setAngle: function(angle) { - this.setAngleInRadians.call(this, angle * Math.PI / 180); - }, - - getAngleInDegrees: '#getAngle', - setAngleInDegrees: '#setAngle', - - getAngleInRadians: function() { - if (!arguments.length) { - return this.isZero() - ? this._angle || 0 - : this._angle = Math.atan2(this.y, this.x); - } else { - var point = Point.read(arguments), - div = this.getLength() * point.getLength(); - if (Numerical.isZero(div)) { - return NaN; - } else { - var a = this.dot(point) / div; - return Math.acos(a < -1 ? -1 : a > 1 ? 1 : a); - } - } - }, - - setAngleInRadians: function(angle) { - this._angle = angle; - if (!this.isZero()) { - var length = this.getLength(); - this.set( - Math.cos(angle) * length, - Math.sin(angle) * length - ); - } - }, - - getQuadrant: function() { - return this.x >= 0 ? this.y >= 0 ? 1 : 4 : this.y >= 0 ? 2 : 3; - } -}, { - beans: false, - - getDirectedAngle: function() { - var point = Point.read(arguments); - return Math.atan2(this.cross(point), this.dot(point)) * 180 / Math.PI; - }, - - getDistance: function() { - var point = Point.read(arguments), - x = point.x - this.x, - y = point.y - this.y, - d = x * x + y * y, - squared = Base.read(arguments); - return squared ? d : Math.sqrt(d); - }, - - normalize: function(length) { - if (length === undefined) - length = 1; - var current = this.getLength(), - scale = current !== 0 ? length / current : 0, - point = new Point(this.x * scale, this.y * scale); - if (scale >= 0) - point._angle = this._angle; - return point; - }, - - rotate: function(angle, center) { - if (angle === 0) - return this.clone(); - angle = angle * Math.PI / 180; - var point = center ? this.subtract(center) : this, - sin = Math.sin(angle), - cos = Math.cos(angle); - point = new Point( - point.x * cos - point.y * sin, - point.x * sin + point.y * cos - ); - return center ? point.add(center) : point; - }, - - transform: function(matrix) { - return matrix ? matrix._transformPoint(this) : this; - }, - - add: function() { - var point = Point.read(arguments); - return new Point(this.x + point.x, this.y + point.y); - }, - - subtract: function() { - var point = Point.read(arguments); - return new Point(this.x - point.x, this.y - point.y); - }, - - multiply: function() { - var point = Point.read(arguments); - return new Point(this.x * point.x, this.y * point.y); - }, - - divide: function() { - var point = Point.read(arguments); - return new Point(this.x / point.x, this.y / point.y); - }, - - modulo: function() { - var point = Point.read(arguments); - return new Point(this.x % point.x, this.y % point.y); - }, - - negate: function() { - return new Point(-this.x, -this.y); - }, - - isInside: function() { - return Rectangle.read(arguments).contains(this); - }, - - isClose: function() { - var point = Point.read(arguments), - tolerance = Base.read(arguments); - return this.getDistance(point) < tolerance; - }, - - isCollinear: function() { - var point = Point.read(arguments); - return Point.isCollinear(this.x, this.y, point.x, point.y); - }, - - isColinear: '#isCollinear', - - isOrthogonal: function() { - var point = Point.read(arguments); - return Point.isOrthogonal(this.x, this.y, point.x, point.y); - }, - - isZero: function() { - return Numerical.isZero(this.x) && Numerical.isZero(this.y); - }, - - isNaN: function() { - return isNaN(this.x) || isNaN(this.y); - }, - - dot: function() { - var point = Point.read(arguments); - return this.x * point.x + this.y * point.y; - }, - - cross: function() { - var point = Point.read(arguments); - return this.x * point.y - this.y * point.x; - }, - - project: function() { - var point = Point.read(arguments), - scale = point.isZero() ? 0 : this.dot(point) / point.dot(point); - return new Point( - point.x * scale, - point.y * scale - ); - }, - - statics: { - min: function() { - var point1 = Point.read(arguments), - point2 = Point.read(arguments); - return new Point( - Math.min(point1.x, point2.x), - Math.min(point1.y, point2.y) - ); - }, - - max: function() { - var point1 = Point.read(arguments), - point2 = Point.read(arguments); - return new Point( - Math.max(point1.x, point2.x), - Math.max(point1.y, point2.y) - ); - }, - - random: function() { - return new Point(Math.random(), Math.random()); - }, - - isCollinear: function(x1, y1, x2, y2) { - return Math.abs(x1 * y2 - y1 * x2) - <= Math.sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2)) - * 1e-7; - }, - - isOrthogonal: function(x1, y1, x2, y2) { - return Math.abs(x1 * x2 + y1 * y2) - <= Math.sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2)) - * 1e-7; - } - } -}, Base.each(['round', 'ceil', 'floor', 'abs'], function(name) { - var op = Math[name]; - this[name] = function() { - return new Point(op(this.x), op(this.y)); - }; -}, {})); - -var LinkedPoint = Point.extend({ - initialize: function Point(x, y, owner, setter) { - this._x = x; - this._y = y; - this._owner = owner; - this._setter = setter; - }, - - set: function(x, y, _dontNotify) { - this._x = x; - this._y = y; - if (!_dontNotify) - this._owner[this._setter](this); - return this; - }, - - getX: function() { - return this._x; - }, - - setX: function(x) { - this._x = x; - this._owner[this._setter](this); - }, - - getY: function() { - return this._y; - }, - - setY: function(y) { - this._y = y; - this._owner[this._setter](this); - } -}); - -var Size = Base.extend({ - _class: 'Size', - _readIndex: true, - - initialize: function Size(arg0, arg1) { - var type = typeof arg0; - if (type === 'number') { - var hasHeight = typeof arg1 === 'number'; - this.width = arg0; - this.height = hasHeight ? arg1 : arg0; - if (this.__read) - this.__read = hasHeight ? 2 : 1; - } else if (type === 'undefined' || arg0 === null) { - this.width = this.height = 0; - if (this.__read) - this.__read = arg0 === null ? 1 : 0; - } else { - if (Array.isArray(arg0)) { - this.width = arg0[0]; - this.height = arg0.length > 1 ? arg0[1] : arg0[0]; - } else if (arg0.width != null) { - this.width = arg0.width; - this.height = arg0.height; - } else if (arg0.x != null) { - this.width = arg0.x; - this.height = arg0.y; - } else { - this.width = this.height = 0; - if (this.__read) - this.__read = 0; - } - if (this.__read) - this.__read = 1; - } - }, - - set: function(width, height) { - this.width = width; - this.height = height; - return this; - }, - - equals: function(size) { - return size === this || size && (this.width === size.width - && this.height === size.height - || Array.isArray(size) && this.width === size[0] - && this.height === size[1]) || false; - }, - - clone: function() { - return new Size(this.width, this.height); - }, - - toString: function() { - var f = Formatter.instance; - return '{ width: ' + f.number(this.width) - + ', height: ' + f.number(this.height) + ' }'; - }, - - _serialize: function(options) { - var f = options.formatter; - return [f.number(this.width), - f.number(this.height)]; - }, - - add: function() { - var size = Size.read(arguments); - return new Size(this.width + size.width, this.height + size.height); - }, - - subtract: function() { - var size = Size.read(arguments); - return new Size(this.width - size.width, this.height - size.height); - }, - - multiply: function() { - var size = Size.read(arguments); - return new Size(this.width * size.width, this.height * size.height); - }, - - divide: function() { - var size = Size.read(arguments); - return new Size(this.width / size.width, this.height / size.height); - }, - - modulo: function() { - var size = Size.read(arguments); - return new Size(this.width % size.width, this.height % size.height); - }, - - negate: function() { - return new Size(-this.width, -this.height); - }, - - isZero: function() { - return Numerical.isZero(this.width) && Numerical.isZero(this.height); - }, - - isNaN: function() { - return isNaN(this.width) || isNaN(this.height); - }, - - statics: { - min: function(size1, size2) { - return new Size( - Math.min(size1.width, size2.width), - Math.min(size1.height, size2.height)); - }, - - max: function(size1, size2) { - return new Size( - Math.max(size1.width, size2.width), - Math.max(size1.height, size2.height)); - }, - - random: function() { - return new Size(Math.random(), Math.random()); - } - } -}, Base.each(['round', 'ceil', 'floor', 'abs'], function(name) { - var op = Math[name]; - this[name] = function() { - return new Size(op(this.width), op(this.height)); - }; -}, {})); - -var LinkedSize = Size.extend({ - initialize: function Size(width, height, owner, setter) { - this._width = width; - this._height = height; - this._owner = owner; - this._setter = setter; - }, - - set: function(width, height, _dontNotify) { - this._width = width; - this._height = height; - if (!_dontNotify) - this._owner[this._setter](this); - return this; - }, - - getWidth: function() { - return this._width; - }, - - setWidth: function(width) { - this._width = width; - this._owner[this._setter](this); - }, - - getHeight: function() { - return this._height; - }, - - setHeight: function(height) { - this._height = height; - this._owner[this._setter](this); - } -}); - -var Rectangle = Base.extend({ - _class: 'Rectangle', - _readIndex: true, - beans: true, - - initialize: function Rectangle(arg0, arg1, arg2, arg3) { - var type = typeof arg0, - read = 0; - if (type === 'number') { - this.x = arg0; - this.y = arg1; - this.width = arg2; - this.height = arg3; - read = 4; - } else if (type === 'undefined' || arg0 === null) { - this.x = this.y = this.width = this.height = 0; - read = arg0 === null ? 1 : 0; - } else if (arguments.length === 1) { - if (Array.isArray(arg0)) { - this.x = arg0[0]; - this.y = arg0[1]; - this.width = arg0[2]; - this.height = arg0[3]; - read = 1; - } else if (arg0.x !== undefined || arg0.width !== undefined) { - this.x = arg0.x || 0; - this.y = arg0.y || 0; - this.width = arg0.width || 0; - this.height = arg0.height || 0; - read = 1; - } else if (arg0.from === undefined && arg0.to === undefined) { - this.x = this.y = this.width = this.height = 0; - this._set(arg0); - read = 1; - } - } - if (!read) { - var point = Point.readNamed(arguments, 'from'), - next = Base.peek(arguments); - this.x = point.x; - this.y = point.y; - if (next && next.x !== undefined || Base.hasNamed(arguments, 'to')) { - var to = Point.readNamed(arguments, 'to'); - this.width = to.x - point.x; - this.height = to.y - point.y; - if (this.width < 0) { - this.x = to.x; - this.width = -this.width; - } - if (this.height < 0) { - this.y = to.y; - this.height = -this.height; - } - } else { - var size = Size.read(arguments); - this.width = size.width; - this.height = size.height; - } - read = arguments.__index; - } - if (this.__read) - this.__read = read; - }, - - set: function(x, y, width, height) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - return this; - }, - - clone: function() { - return new Rectangle(this.x, this.y, this.width, this.height); - }, - - equals: function(rect) { - var rt = Base.isPlainValue(rect) - ? Rectangle.read(arguments) - : rect; - return rt === this - || rt && this.x === rt.x && this.y === rt.y - && this.width === rt.width && this.height === rt.height - || false; - }, - - toString: function() { - var f = Formatter.instance; - return '{ x: ' + f.number(this.x) - + ', y: ' + f.number(this.y) - + ', width: ' + f.number(this.width) - + ', height: ' + f.number(this.height) - + ' }'; - }, - - _serialize: function(options) { - var f = options.formatter; - return [f.number(this.x), - f.number(this.y), - f.number(this.width), - f.number(this.height)]; - }, - - getPoint: function(_dontLink) { - var ctor = _dontLink ? Point : LinkedPoint; - return new ctor(this.x, this.y, this, 'setPoint'); - }, - - setPoint: function() { - var point = Point.read(arguments); - this.x = point.x; - this.y = point.y; - }, - - getSize: function(_dontLink) { - var ctor = _dontLink ? Size : LinkedSize; - return new ctor(this.width, this.height, this, 'setSize'); - }, - - setSize: function() { - var size = Size.read(arguments); - if (this._fixX) - this.x += (this.width - size.width) * this._fixX; - if (this._fixY) - this.y += (this.height - size.height) * this._fixY; - this.width = size.width; - this.height = size.height; - this._fixW = 1; - this._fixH = 1; - }, - - getLeft: function() { - return this.x; - }, - - setLeft: function(left) { - if (!this._fixW) - this.width -= left - this.x; - this.x = left; - this._fixX = 0; - }, - - getTop: function() { - return this.y; - }, - - setTop: function(top) { - if (!this._fixH) - this.height -= top - this.y; - this.y = top; - this._fixY = 0; - }, - - getRight: function() { - return this.x + this.width; - }, - - setRight: function(right) { - if (this._fixX !== undefined && this._fixX !== 1) - this._fixW = 0; - if (this._fixW) - this.x = right - this.width; - else - this.width = right - this.x; - this._fixX = 1; - }, - - getBottom: function() { - return this.y + this.height; - }, - - setBottom: function(bottom) { - if (this._fixY !== undefined && this._fixY !== 1) - this._fixH = 0; - if (this._fixH) - this.y = bottom - this.height; - else - this.height = bottom - this.y; - this._fixY = 1; - }, - - getCenterX: function() { - return this.x + this.width * 0.5; - }, - - setCenterX: function(x) { - this.x = x - this.width * 0.5; - this._fixX = 0.5; - }, - - getCenterY: function() { - return this.y + this.height * 0.5; - }, - - setCenterY: function(y) { - this.y = y - this.height * 0.5; - this._fixY = 0.5; - }, - - getCenter: function(_dontLink) { - var ctor = _dontLink ? Point : LinkedPoint; - return new ctor(this.getCenterX(), this.getCenterY(), this, 'setCenter'); - }, - - setCenter: function() { - var point = Point.read(arguments); - this.setCenterX(point.x); - this.setCenterY(point.y); - return this; - }, - - getArea: function() { - return this.width * this.height; - }, - - isEmpty: function() { - return this.width === 0 || this.height === 0; - }, - - contains: function(arg) { - return arg && arg.width !== undefined - || (Array.isArray(arg) ? arg : arguments).length == 4 - ? this._containsRectangle(Rectangle.read(arguments)) - : this._containsPoint(Point.read(arguments)); - }, - - _containsPoint: function(point) { - var x = point.x, - y = point.y; - return x >= this.x && y >= this.y - && x <= this.x + this.width - && y <= this.y + this.height; - }, - - _containsRectangle: function(rect) { - var x = rect.x, - y = rect.y; - return x >= this.x && y >= this.y - && x + rect.width <= this.x + this.width - && y + rect.height <= this.y + this.height; - }, - - intersects: function() { - var rect = Rectangle.read(arguments); - return rect.x + rect.width > this.x - && rect.y + rect.height > this.y - && rect.x < this.x + this.width - && rect.y < this.y + this.height; - }, - - touches: function() { - var rect = Rectangle.read(arguments); - return rect.x + rect.width >= this.x - && rect.y + rect.height >= this.y - && rect.x <= this.x + this.width - && rect.y <= this.y + this.height; - }, - - intersect: function() { - var rect = Rectangle.read(arguments), - x1 = Math.max(this.x, rect.x), - y1 = Math.max(this.y, rect.y), - x2 = Math.min(this.x + this.width, rect.x + rect.width), - y2 = Math.min(this.y + this.height, rect.y + rect.height); - return new Rectangle(x1, y1, x2 - x1, y2 - y1); - }, - - unite: function() { - var rect = Rectangle.read(arguments), - x1 = Math.min(this.x, rect.x), - y1 = Math.min(this.y, rect.y), - x2 = Math.max(this.x + this.width, rect.x + rect.width), - y2 = Math.max(this.y + this.height, rect.y + rect.height); - return new Rectangle(x1, y1, x2 - x1, y2 - y1); - }, - - include: function() { - var point = Point.read(arguments); - var x1 = Math.min(this.x, point.x), - y1 = Math.min(this.y, point.y), - x2 = Math.max(this.x + this.width, point.x), - y2 = Math.max(this.y + this.height, point.y); - return new Rectangle(x1, y1, x2 - x1, y2 - y1); - }, - - expand: function() { - var amount = Size.read(arguments), - hor = amount.width, - ver = amount.height; - return new Rectangle(this.x - hor / 2, this.y - ver / 2, - this.width + hor, this.height + ver); - }, - - scale: function(hor, ver) { - return this.expand(this.width * hor - this.width, - this.height * (ver === undefined ? hor : ver) - this.height); - } -}, Base.each([ - ['Top', 'Left'], ['Top', 'Right'], - ['Bottom', 'Left'], ['Bottom', 'Right'], - ['Left', 'Center'], ['Top', 'Center'], - ['Right', 'Center'], ['Bottom', 'Center'] - ], - function(parts, index) { - var part = parts.join(''); - var xFirst = /^[RL]/.test(part); - if (index >= 4) - parts[1] += xFirst ? 'Y' : 'X'; - var x = parts[xFirst ? 0 : 1], - y = parts[xFirst ? 1 : 0], - getX = 'get' + x, - getY = 'get' + y, - setX = 'set' + x, - setY = 'set' + y, - get = 'get' + part, - set = 'set' + part; - this[get] = function(_dontLink) { - var ctor = _dontLink ? Point : LinkedPoint; - return new ctor(this[getX](), this[getY](), this, set); - }; - this[set] = function() { - var point = Point.read(arguments); - this[setX](point.x); - this[setY](point.y); - }; - }, { - beans: true - } -)); - -var LinkedRectangle = Rectangle.extend({ - initialize: function Rectangle(x, y, width, height, owner, setter) { - this.set(x, y, width, height, true); - this._owner = owner; - this._setter = setter; - }, - - set: function(x, y, width, height, _dontNotify) { - this._x = x; - this._y = y; - this._width = width; - this._height = height; - if (!_dontNotify) - this._owner[this._setter](this); - return this; - } -}, -new function() { - var proto = Rectangle.prototype; - - return Base.each(['x', 'y', 'width', 'height'], function(key) { - var part = Base.capitalize(key); - var internal = '_' + key; - this['get' + part] = function() { - return this[internal]; - }; - - this['set' + part] = function(value) { - this[internal] = value; - if (!this._dontNotify) - this._owner[this._setter](this); - }; - }, Base.each(['Point', 'Size', 'Center', - 'Left', 'Top', 'Right', 'Bottom', 'CenterX', 'CenterY', - 'TopLeft', 'TopRight', 'BottomLeft', 'BottomRight', - 'LeftCenter', 'TopCenter', 'RightCenter', 'BottomCenter'], - function(key) { - var name = 'set' + key; - this[name] = function() { - this._dontNotify = true; - proto[name].apply(this, arguments); - this._dontNotify = false; - this._owner[this._setter](this); - }; - }, { - isSelected: function() { - return this._owner._boundsSelected; - }, - - setSelected: function(selected) { - var owner = this._owner; - if (owner.setSelected) { - owner._boundsSelected = selected; - owner.setSelected(selected || owner._selectedSegmentState > 0); - } - } - }) - ); -}); - -var Matrix = Base.extend({ - _class: 'Matrix', - - initialize: function Matrix(arg) { - var count = arguments.length, - ok = true; - if (count === 6) { - this.set.apply(this, arguments); - } else if (count === 1) { - if (arg instanceof Matrix) { - this.set(arg._a, arg._c, arg._b, arg._d, arg._tx, arg._ty); - } else if (Array.isArray(arg)) { - this.set.apply(this, arg); - } else { - ok = false; - } - } else if (count === 0) { - this.reset(); - } else { - ok = false; - } - if (!ok) - throw new Error('Unsupported matrix parameters'); - }, - - set: function(a, c, b, d, tx, ty, _dontNotify) { - this._a = a; - this._c = c; - this._b = b; - this._d = d; - this._tx = tx; - this._ty = ty; - if (!_dontNotify) - this._changed(); - return this; - }, - - _serialize: function(options) { - return Base.serialize(this.getValues(), options); - }, - - _changed: function() { - var owner = this._owner; - if (owner) { - if (owner._applyMatrix) { - owner.transform(null, true); - } else { - owner._changed(9); - } - } - }, - - clone: function() { - return new Matrix(this._a, this._c, this._b, this._d, - this._tx, this._ty); - }, - - equals: function(mx) { - return mx === this || mx && this._a === mx._a && this._b === mx._b - && this._c === mx._c && this._d === mx._d - && this._tx === mx._tx && this._ty === mx._ty - || false; - }, - - toString: function() { - var f = Formatter.instance; - return '[[' + [f.number(this._a), f.number(this._b), - f.number(this._tx)].join(', ') + '], [' - + [f.number(this._c), f.number(this._d), - f.number(this._ty)].join(', ') + ']]'; - }, - - reset: function(_dontNotify) { - this._a = this._d = 1; - this._c = this._b = this._tx = this._ty = 0; - if (!_dontNotify) - this._changed(); - return this; - }, - - apply: function(recursively, _setApplyMatrix) { - var owner = this._owner; - if (owner) { - owner.transform(null, true, Base.pick(recursively, true), - _setApplyMatrix); - return this.isIdentity(); - } - return false; - }, - - translate: function() { - var point = Point.read(arguments), - x = point.x, - y = point.y; - this._tx += x * this._a + y * this._b; - this._ty += x * this._c + y * this._d; - this._changed(); - return this; - }, - - scale: function() { - var scale = Point.read(arguments), - center = Point.read(arguments, 0, { readNull: true }); - if (center) - this.translate(center); - this._a *= scale.x; - this._c *= scale.x; - this._b *= scale.y; - this._d *= scale.y; - if (center) - this.translate(center.negate()); - this._changed(); - return this; - }, - - rotate: function(angle ) { - angle *= Math.PI / 180; - var center = Point.read(arguments, 1), - x = center.x, - y = center.y, - cos = Math.cos(angle), - sin = Math.sin(angle), - tx = x - x * cos + y * sin, - ty = y - x * sin - y * cos, - a = this._a, - b = this._b, - c = this._c, - d = this._d; - this._a = cos * a + sin * b; - this._b = -sin * a + cos * b; - this._c = cos * c + sin * d; - this._d = -sin * c + cos * d; - this._tx += tx * a + ty * b; - this._ty += tx * c + ty * d; - this._changed(); - return this; - }, - - shear: function() { - var shear = Point.read(arguments), - center = Point.read(arguments, 0, { readNull: true }); - if (center) - this.translate(center); - var a = this._a, - c = this._c; - this._a += shear.y * this._b; - this._c += shear.y * this._d; - this._b += shear.x * a; - this._d += shear.x * c; - if (center) - this.translate(center.negate()); - this._changed(); - return this; - }, - - skew: function() { - var skew = Point.read(arguments), - center = Point.read(arguments, 0, { readNull: true }), - toRadians = Math.PI / 180, - shear = new Point(Math.tan(skew.x * toRadians), - Math.tan(skew.y * toRadians)); - return this.shear(shear, center); - }, - - concatenate: function(mx) { - var a1 = this._a, - b1 = this._b, - c1 = this._c, - d1 = this._d, - a2 = mx._a, - b2 = mx._b, - c2 = mx._c, - d2 = mx._d, - tx2 = mx._tx, - ty2 = mx._ty; - this._a = a2 * a1 + c2 * b1; - this._b = b2 * a1 + d2 * b1; - this._c = a2 * c1 + c2 * d1; - this._d = b2 * c1 + d2 * d1; - this._tx += tx2 * a1 + ty2 * b1; - this._ty += tx2 * c1 + ty2 * d1; - this._changed(); - return this; - }, - - preConcatenate: function(mx) { - var a1 = this._a, - b1 = this._b, - c1 = this._c, - d1 = this._d, - tx1 = this._tx, - ty1 = this._ty, - a2 = mx._a, - b2 = mx._b, - c2 = mx._c, - d2 = mx._d, - tx2 = mx._tx, - ty2 = mx._ty; - this._a = a2 * a1 + b2 * c1; - this._b = a2 * b1 + b2 * d1; - this._c = c2 * a1 + d2 * c1; - this._d = c2 * b1 + d2 * d1; - this._tx = a2 * tx1 + b2 * ty1 + tx2; - this._ty = c2 * tx1 + d2 * ty1 + ty2; - this._changed(); - return this; - }, - - chain: function(mx) { - var a1 = this._a, - b1 = this._b, - c1 = this._c, - d1 = this._d, - tx1 = this._tx, - ty1 = this._ty, - a2 = mx._a, - b2 = mx._b, - c2 = mx._c, - d2 = mx._d, - tx2 = mx._tx, - ty2 = mx._ty; - return new Matrix( - a2 * a1 + c2 * b1, - a2 * c1 + c2 * d1, - b2 * a1 + d2 * b1, - b2 * c1 + d2 * d1, - tx1 + tx2 * a1 + ty2 * b1, - ty1 + tx2 * c1 + ty2 * d1); - }, - - isIdentity: function() { - return this._a === 1 && this._c === 0 && this._b === 0 && this._d === 1 - && this._tx === 0 && this._ty === 0; - }, - - orNullIfIdentity: function() { - return this.isIdentity() ? null : this; - }, - - isInvertible: function() { - return !!this._getDeterminant(); - }, - - isSingular: function() { - return !this._getDeterminant(); - }, - - transform: function( src, dst, count) { - return arguments.length < 3 - ? this._transformPoint(Point.read(arguments)) - : this._transformCoordinates(src, dst, count); - }, - - _transformPoint: function(point, dest, _dontNotify) { - var x = point.x, - y = point.y; - if (!dest) - dest = new Point(); - return dest.set( - x * this._a + y * this._b + this._tx, - x * this._c + y * this._d + this._ty, - _dontNotify - ); - }, - - _transformCoordinates: function(src, dst, count) { - var i = 0, - j = 0, - max = 2 * count; - while (i < max) { - var x = src[i++], - y = src[i++]; - dst[j++] = x * this._a + y * this._b + this._tx; - dst[j++] = x * this._c + y * this._d + this._ty; - } - return dst; - }, - - _transformCorners: function(rect) { - var x1 = rect.x, - y1 = rect.y, - x2 = x1 + rect.width, - y2 = y1 + rect.height, - coords = [ x1, y1, x2, y1, x2, y2, x1, y2 ]; - return this._transformCoordinates(coords, coords, 4); - }, - - _transformBounds: function(bounds, dest, _dontNotify) { - var coords = this._transformCorners(bounds), - min = coords.slice(0, 2), - max = min.slice(); - for (var i = 2; i < 8; i++) { - var val = coords[i], - j = i & 1; - if (val < min[j]) - min[j] = val; - else if (val > max[j]) - max[j] = val; - } - if (!dest) - dest = new Rectangle(); - return dest.set(min[0], min[1], max[0] - min[0], max[1] - min[1], - _dontNotify); - }, - - inverseTransform: function() { - return this._inverseTransform(Point.read(arguments)); - }, - - _getDeterminant: function() { - var det = this._a * this._d - this._b * this._c; - return isFinite(det) && !Numerical.isZero(det) - && isFinite(this._tx) && isFinite(this._ty) - ? det : null; - }, - - _inverseTransform: function(point, dest, _dontNotify) { - var det = this._getDeterminant(); - if (!det) - return null; - var x = point.x - this._tx, - y = point.y - this._ty; - if (!dest) - dest = new Point(); - return dest.set( - (x * this._d - y * this._b) / det, - (y * this._a - x * this._c) / det, - _dontNotify - ); - }, - - decompose: function() { - var a = this._a, b = this._b, c = this._c, d = this._d; - if (Numerical.isZero(a * d - b * c)) - return null; - - var scaleX = Math.sqrt(a * a + b * b); - a /= scaleX; - b /= scaleX; - - var shear = a * c + b * d; - c -= a * shear; - d -= b * shear; - - var scaleY = Math.sqrt(c * c + d * d); - c /= scaleY; - d /= scaleY; - shear /= scaleY; - - if (a * d < b * c) { - a = -a; - b = -b; - shear = -shear; - scaleX = -scaleX; - } - - return { - scaling: new Point(scaleX, scaleY), - rotation: -Math.atan2(b, a) * 180 / Math.PI, - shearing: shear - }; - }, - - getValues: function() { - return [ this._a, this._c, this._b, this._d, this._tx, this._ty ]; - }, - - getTranslation: function() { - return new Point(this._tx, this._ty); - }, - - getScaling: function() { - return (this.decompose() || {}).scaling; - }, - - getRotation: function() { - return (this.decompose() || {}).rotation; - }, - - inverted: function() { - var det = this._getDeterminant(); - return det && new Matrix( - this._d / det, - -this._c / det, - -this._b / det, - this._a / det, - (this._b * this._ty - this._d * this._tx) / det, - (this._c * this._tx - this._a * this._ty) / det); - }, - - shiftless: function() { - return new Matrix(this._a, this._c, this._b, this._d, 0, 0); - }, - - applyToContext: function(ctx) { - ctx.transform(this._a, this._c, this._b, this._d, this._tx, this._ty); - } -}, Base.each(['a', 'c', 'b', 'd', 'tx', 'ty'], function(name) { - var part = Base.capitalize(name), - prop = '_' + name; - this['get' + part] = function() { - return this[prop]; - }; - this['set' + part] = function(value) { - this[prop] = value; - this._changed(); - }; -}, {})); - -var Line = Base.extend({ - _class: 'Line', - - initialize: function Line(arg0, arg1, arg2, arg3, arg4) { - var asVector = false; - if (arguments.length >= 4) { - this._px = arg0; - this._py = arg1; - this._vx = arg2; - this._vy = arg3; - asVector = arg4; - } else { - this._px = arg0.x; - this._py = arg0.y; - this._vx = arg1.x; - this._vy = arg1.y; - asVector = arg2; - } - if (!asVector) { - this._vx -= this._px; - this._vy -= this._py; - } - }, - - getPoint: function() { - return new Point(this._px, this._py); - }, - - getVector: function() { - return new Point(this._vx, this._vy); - }, - - getLength: function() { - return this.getVector().getLength(); - }, - - intersect: function(line, isInfinite) { - return Line.intersect( - this._px, this._py, this._vx, this._vy, - line._px, line._py, line._vx, line._vy, - true, isInfinite); - }, - - getSide: function(point, isInfinite) { - return Line.getSide( - this._px, this._py, this._vx, this._vy, - point.x, point.y, true, isInfinite); - }, - - getDistance: function(point) { - return Math.abs(Line.getSignedDistance( - this._px, this._py, this._vx, this._vy, - point.x, point.y, true)); - }, - - isCollinear: function(line) { - return Point.isCollinear(this._vx, this._vy, line._vx, line._vy); - }, - - isOrthogonal: function(line) { - return Point.isOrthogonal(this._vx, this._vy, line._vx, line._vy); - }, - - statics: { - intersect: function(p1x, p1y, v1x, v1y, p2x, p2y, v2x, v2y, asVector, - isInfinite) { - if (!asVector) { - v1x -= p1x; - v1y -= p1y; - v2x -= p2x; - v2y -= p2y; - } - var cross = v1x * v2y - v1y * v2x; - if (!Numerical.isZero(cross)) { - var dx = p1x - p2x, - dy = p1y - p2y, - u1 = (v2x * dy - v2y * dx) / cross, - u2 = (v1x * dy - v1y * dx) / cross, - epsilon = 1e-12, - uMin = -epsilon, - uMax = 1 + epsilon; - if (isInfinite - || uMin < u1 && u1 < uMax && uMin < u2 && u2 < uMax) { - if (!isInfinite) { - u1 = u1 <= 0 ? 0 : u1 >= 1 ? 1 : u1; - } - return new Point( - p1x + u1 * v1x, - p1y + u1 * v1y); - } - } - }, - - getSide: function(px, py, vx, vy, x, y, asVector, isInfinite) { - if (!asVector) { - vx -= px; - vy -= py; - } - var v2x = x - px, - v2y = y - py, - ccw = v2x * vy - v2y * vx; - if (ccw === 0 && !isInfinite) { - ccw = (v2x * vx + v2x * vx) / (vx * vx + vy * vy); - if (ccw >= 0 && ccw <= 1) - ccw = 0; - } - return ccw < 0 ? -1 : ccw > 0 ? 1 : 0; - }, - - getSignedDistance: function(px, py, vx, vy, x, y, asVector) { - if (!asVector) { - vx -= px; - vy -= py; - } - return vx === 0 ? vy > 0 ? x - px : px - x - : vy === 0 ? vx < 0 ? y - py : py - y - : ((x-px) * vy - (y-py) * vx) / Math.sqrt(vx * vx + vy * vy); - } - } -}); - -var Project = PaperScopeItem.extend({ - _class: 'Project', - _list: 'projects', - _reference: 'project', - - initialize: function Project(element) { - PaperScopeItem.call(this, true); - this.layers = []; - this._activeLayer = null; - this.symbols = []; - this._currentStyle = new Style(null, null, this); - this._view = View.create(this, - element || CanvasProvider.getCanvas(1, 1)); - this._selectedItems = {}; - this._selectedItemCount = 0; - this._updateVersion = 0; - }, - - _serialize: function(options, dictionary) { - return Base.serialize(this.layers, options, true, dictionary); - }, - - clear: function() { - for (var i = this.layers.length - 1; i >= 0; i--) - this.layers[i].remove(); - this.symbols = []; - }, - - isEmpty: function() { - return this.layers.length === 0; - }, - - remove: function remove() { - if (!remove.base.call(this)) - return false; - if (this._view) - this._view.remove(); - return true; - }, - - getView: function() { - return this._view; - }, - - getCurrentStyle: function() { - return this._currentStyle; - }, - - setCurrentStyle: function(style) { - this._currentStyle.initialize(style); - }, - - getIndex: function() { - return this._index; - }, - - getOptions: function() { - return this._scope.settings; - }, - - getActiveLayer: function() { - return this._activeLayer || new Layer({ project: this }); - }, - - getSelectedItems: function() { - var items = []; - for (var id in this._selectedItems) { - var item = this._selectedItems[id]; - if (item.isInserted()) - items.push(item); - } - return items; - }, - - insertChild: function(index, item, _preserve) { - if (item instanceof Layer) { - item._remove(false, true); - Base.splice(this.layers, [item], index, 0); - item._setProject(this, true); - if (this._changes) - item._changed(5); - if (!this._activeLayer) - this._activeLayer = item; - } else if (item instanceof Item) { - (this._activeLayer - || this.insertChild(index, new Layer(Item.NO_INSERT))) - .insertChild(index, item, _preserve); - } else { - item = null; - } - return item; - }, - - addChild: function(item, _preserve) { - return this.insertChild(undefined, item, _preserve); - }, - - _updateSelection: function(item) { - var id = item._id, - selectedItems = this._selectedItems; - if (item._selected) { - if (selectedItems[id] !== item) { - this._selectedItemCount++; - selectedItems[id] = item; - } - } else if (selectedItems[id] === item) { - this._selectedItemCount--; - delete selectedItems[id]; - } - }, - - selectAll: function() { - var layers = this.layers; - for (var i = 0, l = layers.length; i < l; i++) - layers[i].setFullySelected(true); - }, - - deselectAll: function() { - var selectedItems = this._selectedItems; - for (var i in selectedItems) - selectedItems[i].setFullySelected(false); - }, - - hitTest: function() { - var point = Point.read(arguments), - options = HitResult.getOptions(Base.read(arguments)); - for (var i = this.layers.length - 1; i >= 0; i--) { - var res = this.layers[i]._hitTest(point, options); - if (res) return res; - } - return null; - }, - - getItems: function(match) { - return Item._getItems(this.layers, match); - }, - - getItem: function(match) { - return Item._getItems(this.layers, match, null, null, true)[0] || null; - }, - - importJSON: function(json) { - this.activate(); - var layer = this._activeLayer; - return Base.importJSON(json, layer && layer.isEmpty() && layer); - }, - - draw: function(ctx, matrix, pixelRatio) { - this._updateVersion++; - ctx.save(); - matrix.applyToContext(ctx); - var param = new Base({ - offset: new Point(0, 0), - pixelRatio: pixelRatio, - viewMatrix: matrix.isIdentity() ? null : matrix, - matrices: [new Matrix()], - updateMatrix: true - }); - for (var i = 0, layers = this.layers, l = layers.length; i < l; i++) - layers[i].draw(ctx, param); - ctx.restore(); - - if (this._selectedItemCount > 0) { - ctx.save(); - ctx.strokeWidth = 1; - var items = this._selectedItems, - size = this._scope.settings.handleSize, - version = this._updateVersion; - for (var id in items) - items[id]._drawSelection(ctx, matrix, size, items, version); - ctx.restore(); - } - } -}); - -var Symbol = Base.extend({ - _class: 'Symbol', - - initialize: function Symbol(item, dontCenter) { - this._id = UID.get(); - this.project = paper.project; - this.project.symbols.push(this); - if (item) - this.setDefinition(item, dontCenter); - }, - - _serialize: function(options, dictionary) { - return dictionary.add(this, function() { - return Base.serialize([this._class, this._definition], - options, false, dictionary); - }); - }, - - _changed: function(flags) { - if (flags & 8) { - Item._clearBoundsCache(this); - } - if (flags & 1) { - this.project._needsUpdate = true; - } - }, - - getDefinition: function() { - return this._definition; - }, - - setDefinition: function(item, _dontCenter) { - if (item._parentSymbol) - item = item.clone(); - if (this._definition) - this._definition._parentSymbol = null; - this._definition = item; - item.remove(); - item.setSelected(false); - if (!_dontCenter) - item.setPosition(new Point()); - item._parentSymbol = this; - this._changed(9); - }, - - place: function(position) { - return new PlacedSymbol(this, position); - }, - - clone: function() { - return new Symbol(this._definition.clone(false)); - }, - - equals: function(symbol) { - return symbol === this - || symbol && this.definition.equals(symbol.definition) - || false; - } -}); - -var Item = Base.extend(Emitter, { - statics: { - extend: function extend(src) { - if (src._serializeFields) - src._serializeFields = new Base( - this.prototype._serializeFields, src._serializeFields); - return extend.base.apply(this, arguments); - }, - - NO_INSERT: { insert: false } - }, - - _class: 'Item', - _applyMatrix: true, - _canApplyMatrix: true, - _boundsSelected: false, - _selectChildren: false, - _serializeFields: { - name: null, - applyMatrix: null, - matrix: new Matrix(), - pivot: null, - locked: false, - visible: true, - blendMode: 'normal', - opacity: 1, - guide: false, - selected: false, - clipMask: false, - data: {} - }, - - initialize: function Item() { - }, - - _initialize: function(props, point) { - var hasProps = props && Base.isPlainObject(props), - internal = hasProps && props.internal === true, - matrix = this._matrix = new Matrix(), - project = hasProps && props.project || paper.project; - if (!internal) - this._id = UID.get(); - this._applyMatrix = this._canApplyMatrix && paper.settings.applyMatrix; - if (point) - matrix.translate(point); - matrix._owner = this; - this._style = new Style(project._currentStyle, this, project); - if (!this._project) { - if (internal || hasProps && props.insert === false) { - this._setProject(project); - } else if (hasProps && props.parent) { - this.setParent(props.parent); - } else { - (project._activeLayer || new Layer()).addChild(this); - } - } - if (hasProps && props !== Item.NO_INSERT) - this._set(props, { insert: true, project: true, parent: true }, - true); - return hasProps; - }, - - _events: Base.each(['onMouseDown', 'onMouseUp', 'onMouseDrag', 'onClick', - 'onDoubleClick', 'onMouseMove', 'onMouseEnter', 'onMouseLeave'], - function(name) { - this[name] = { - install: function(type) { - this.getView()._installEvent(type); - }, - - uninstall: function(type) { - this.getView()._uninstallEvent(type); - } - }; - }, { - onFrame: { - install: function() { - this.getView()._animateItem(this, true); - }, - - uninstall: function() { - this.getView()._animateItem(this, false); - } - }, - - onLoad: {} - } - ), - - _serialize: function(options, dictionary) { - var props = {}, - that = this; - - function serialize(fields) { - for (var key in fields) { - var value = that[key]; - if (!Base.equals(value, key === 'leading' - ? fields.fontSize * 1.2 : fields[key])) { - props[key] = Base.serialize(value, options, - key !== 'data', dictionary); - } - } - } - - serialize(this._serializeFields); - if (!(this instanceof Group)) - serialize(this._style._defaults); - return [ this._class, props ]; - }, - - _changed: function(flags) { - var symbol = this._parentSymbol, - cacheParent = this._parent || symbol, - project = this._project; - if (flags & 8) { - this._bounds = this._position = this._decomposed = - this._globalMatrix = this._currentPath = undefined; - } - if (cacheParent - && (flags & 40)) { - Item._clearBoundsCache(cacheParent); - } - if (flags & 2) { - Item._clearBoundsCache(this); - } - if (project) { - if (flags & 1) { - project._needsUpdate = true; - } - if (project._changes) { - var entry = project._changesById[this._id]; - if (entry) { - entry.flags |= flags; - } else { - entry = { item: this, flags: flags }; - project._changesById[this._id] = entry; - project._changes.push(entry); - } - } - } - if (symbol) - symbol._changed(flags); - }, - - set: function(props) { - if (props) - this._set(props); - return this; - }, - - getId: function() { - return this._id; - }, - - getName: function() { - return this._name; - }, - - setName: function(name, unique) { - - if (this._name) - this._removeNamed(); - if (name === (+name) + '') - throw new Error( - 'Names consisting only of numbers are not supported.'); - var parent = this._parent; - if (name && parent) { - var children = parent._children, - namedChildren = parent._namedChildren, - orig = name, - i = 1; - while (unique && children[name]) - name = orig + ' ' + (i++); - (namedChildren[name] = namedChildren[name] || []).push(this); - children[name] = this; - } - this._name = name || undefined; - this._changed(128); - }, - - getStyle: function() { - return this._style; - }, - - setStyle: function(style) { - this.getStyle().set(style); - } -}, Base.each(['locked', 'visible', 'blendMode', 'opacity', 'guide'], - function(name) { - var part = Base.capitalize(name), - name = '_' + name; - this['get' + part] = function() { - return this[name]; - }; - this['set' + part] = function(value) { - if (value != this[name]) { - this[name] = value; - this._changed(name === '_locked' - ? 128 : 129); - } - }; - }, -{}), { - beans: true, - - _locked: false, - - _visible: true, - - _blendMode: 'normal', - - _opacity: 1, - - _guide: false, - - isSelected: function() { - if (this._selectChildren) { - var children = this._children; - for (var i = 0, l = children.length; i < l; i++) - if (children[i].isSelected()) - return true; - } - return this._selected; - }, - - setSelected: function(selected, noChildren) { - if (!noChildren && this._selectChildren) { - var children = this._children; - for (var i = 0, l = children.length; i < l; i++) - children[i].setSelected(selected); - } - if ((selected = !!selected) ^ this._selected) { - this._selected = selected; - this._project._updateSelection(this); - this._changed(129); - } - }, - - _selected: false, - - isFullySelected: function() { - var children = this._children; - if (children && this._selected) { - for (var i = 0, l = children.length; i < l; i++) - if (!children[i].isFullySelected()) - return false; - return true; - } - return this._selected; - }, - - setFullySelected: function(selected) { - var children = this._children; - if (children) { - for (var i = 0, l = children.length; i < l; i++) - children[i].setFullySelected(selected); - } - this.setSelected(selected, true); - }, - - isClipMask: function() { - return this._clipMask; - }, - - setClipMask: function(clipMask) { - if (this._clipMask != (clipMask = !!clipMask)) { - this._clipMask = clipMask; - if (clipMask) { - this.setFillColor(null); - this.setStrokeColor(null); - } - this._changed(129); - if (this._parent) - this._parent._changed(1024); - } - }, - - _clipMask: false, - - getData: function() { - if (!this._data) - this._data = {}; - return this._data; - }, - - setData: function(data) { - this._data = data; - }, - - getPosition: function(_dontLink) { - var position = this._position, - ctor = _dontLink ? Point : LinkedPoint; - if (!position) { - var pivot = this._pivot; - position = this._position = pivot - ? this._matrix._transformPoint(pivot) - : this.getBounds().getCenter(true); - } - return new ctor(position.x, position.y, this, 'setPosition'); - }, - - setPosition: function() { - this.translate(Point.read(arguments).subtract(this.getPosition(true))); - }, - - getPivot: function(_dontLink) { - var pivot = this._pivot; - if (pivot) { - var ctor = _dontLink ? Point : LinkedPoint; - pivot = new ctor(pivot.x, pivot.y, this, 'setPivot'); - } - return pivot; - }, - - setPivot: function() { - this._pivot = Point.read(arguments, 0, { clone: true, readNull: true }); - this._position = undefined; - }, - - _pivot: null, -}, Base.each(['bounds', 'strokeBounds', 'handleBounds', 'roughBounds', - 'internalBounds', 'internalRoughBounds'], - function(key) { - var getter = 'get' + Base.capitalize(key), - match = key.match(/^internal(.*)$/), - internalGetter = match ? 'get' + match[1] : null; - this[getter] = function(_matrix) { - var boundsGetter = this._boundsGetter, - name = !internalGetter && (typeof boundsGetter === 'string' - ? boundsGetter : boundsGetter && boundsGetter[getter]) - || getter, - bounds = this._getCachedBounds(name, _matrix, this, - internalGetter); - return key === 'bounds' - ? new LinkedRectangle(bounds.x, bounds.y, bounds.width, - bounds.height, this, 'setBounds') - : bounds; - }; - }, -{ - beans: true, - - _getBounds: function(getter, matrix, cacheItem) { - var children = this._children; - if (!children || children.length == 0) - return new Rectangle(); - Item._updateBoundsCache(this, cacheItem); - var x1 = Infinity, - x2 = -x1, - y1 = x1, - y2 = x2; - for (var i = 0, l = children.length; i < l; i++) { - var child = children[i]; - if (child._visible && !child.isEmpty()) { - var rect = child._getCachedBounds(getter, - matrix && matrix.chain(child._matrix), cacheItem); - x1 = Math.min(rect.x, x1); - y1 = Math.min(rect.y, y1); - x2 = Math.max(rect.x + rect.width, x2); - y2 = Math.max(rect.y + rect.height, y2); - } - } - return isFinite(x1) - ? new Rectangle(x1, y1, x2 - x1, y2 - y1) - : new Rectangle(); - }, - - setBounds: function() { - var rect = Rectangle.read(arguments), - bounds = this.getBounds(), - matrix = new Matrix(), - center = rect.getCenter(); - matrix.translate(center); - if (rect.width != bounds.width || rect.height != bounds.height) { - matrix.scale( - bounds.width != 0 ? rect.width / bounds.width : 1, - bounds.height != 0 ? rect.height / bounds.height : 1); - } - center = bounds.getCenter(); - matrix.translate(-center.x, -center.y); - this.transform(matrix); - }, - - _getCachedBounds: function(getter, matrix, cacheItem, internalGetter) { - matrix = matrix && matrix.orNullIfIdentity(); - var _matrix = internalGetter ? null : this._matrix.orNullIfIdentity(), - cache = (!matrix || matrix.equals(_matrix)) && getter; - Item._updateBoundsCache(this._parent || this._parentSymbol, cacheItem); - if (cache && this._bounds && this._bounds[cache]) - return this._bounds[cache].clone(); - var bounds = this._getBounds(internalGetter || getter, - matrix || _matrix, cacheItem); - if (cache) { - if (!this._bounds) - this._bounds = {}; - var cached = this._bounds[cache] = bounds.clone(); - cached._internal = !!internalGetter; - } - return bounds; - }, - - statics: { - _updateBoundsCache: function(parent, item) { - if (parent) { - var id = item._id, - ref = parent._boundsCache = parent._boundsCache || { - ids: {}, - list: [] - }; - if (!ref.ids[id]) { - ref.list.push(item); - ref.ids[id] = item; - } - } - }, - - _clearBoundsCache: function(item) { - var cache = item._boundsCache; - if (cache) { - item._bounds = item._position = item._boundsCache = undefined; - for (var i = 0, list = cache.list, l = list.length; i < l; i++){ - var other = list[i]; - if (other !== item) { - other._bounds = other._position = undefined; - if (other._boundsCache) - Item._clearBoundsCache(other); - } - } - } - } - } - -}), { - beans: true, - - _decompose: function() { - return this._decomposed = this._matrix.decompose(); - }, - - getRotation: function() { - var decomposed = this._decomposed || this._decompose(); - return decomposed && decomposed.rotation; - }, - - setRotation: function(rotation) { - var current = this.getRotation(); - if (current != null && rotation != null) { - var decomposed = this._decomposed; - this.rotate(rotation - current); - decomposed.rotation = rotation; - this._decomposed = decomposed; - } - }, - - getScaling: function(_dontLink) { - var decomposed = this._decomposed || this._decompose(), - scaling = decomposed && decomposed.scaling, - ctor = _dontLink ? Point : LinkedPoint; - return scaling && new ctor(scaling.x, scaling.y, this, 'setScaling'); - }, - - setScaling: function() { - var current = this.getScaling(); - if (current) { - var scaling = Point.read(arguments, 0, { clone: true }), - decomposed = this._decomposed; - this.scale(scaling.x / current.x, scaling.y / current.y); - decomposed.scaling = scaling; - this._decomposed = decomposed; - } - }, - - getMatrix: function() { - return this._matrix; - }, - - setMatrix: function() { - var matrix = this._matrix; - matrix.initialize.apply(matrix, arguments); - if (this._applyMatrix) { - this.transform(null, true); - } else { - this._changed(9); - } - }, - - getGlobalMatrix: function(_dontClone) { - var matrix = this._globalMatrix, - updateVersion = this._project._updateVersion; - if (matrix && matrix._updateVersion !== updateVersion) - matrix = null; - if (!matrix) { - matrix = this._globalMatrix = this._matrix.clone(); - var parent = this._parent; - if (parent) - matrix.preConcatenate(parent.getGlobalMatrix(true)); - matrix._updateVersion = updateVersion; - } - return _dontClone ? matrix : matrix.clone(); - }, - - getApplyMatrix: function() { - return this._applyMatrix; - }, - - setApplyMatrix: function(apply) { - if (this._applyMatrix = this._canApplyMatrix && !!apply) - this.transform(null, true); - }, - - getTransformContent: '#getApplyMatrix', - setTransformContent: '#setApplyMatrix', -}, { - getProject: function() { - return this._project; - }, - - _setProject: function(project, installEvents) { - if (this._project !== project) { - if (this._project) - this._installEvents(false); - this._project = project; - var children = this._children; - for (var i = 0, l = children && children.length; i < l; i++) - children[i]._setProject(project); - installEvents = true; - } - if (installEvents) - this._installEvents(true); - }, - - getView: function() { - return this._project.getView(); - }, - - _installEvents: function _installEvents(install) { - _installEvents.base.call(this, install); - var children = this._children; - for (var i = 0, l = children && children.length; i < l; i++) - children[i]._installEvents(install); - }, - - getLayer: function() { - var parent = this; - while (parent = parent._parent) { - if (parent instanceof Layer) - return parent; - } - return null; - }, - - getParent: function() { - return this._parent; - }, - - setParent: function(item) { - return item.addChild(this); - }, - - getChildren: function() { - return this._children; - }, - - setChildren: function(items) { - this.removeChildren(); - this.addChildren(items); - }, - - getFirstChild: function() { - return this._children && this._children[0] || null; - }, - - getLastChild: function() { - return this._children && this._children[this._children.length - 1] - || null; - }, - - getNextSibling: function() { - return this._parent && this._parent._children[this._index + 1] || null; - }, - - getPreviousSibling: function() { - return this._parent && this._parent._children[this._index - 1] || null; - }, - - getIndex: function() { - return this._index; - }, - - equals: function(item) { - return item === this || item && this._class === item._class - && this._style.equals(item._style) - && this._matrix.equals(item._matrix) - && this._locked === item._locked - && this._visible === item._visible - && this._blendMode === item._blendMode - && this._opacity === item._opacity - && this._clipMask === item._clipMask - && this._guide === item._guide - && this._equals(item) - || false; - }, - - _equals: function(item) { - return Base.equals(this._children, item._children); - }, - - clone: function(insert) { - return this._clone(new this.constructor(Item.NO_INSERT), insert); - }, - - _clone: function(copy, insert, includeMatrix) { - var keys = ['_locked', '_visible', '_blendMode', '_opacity', - '_clipMask', '_guide'], - children = this._children; - copy.setStyle(this._style); - for (var i = 0, l = children && children.length; i < l; i++) { - copy.addChild(children[i].clone(false), true); - } - for (var i = 0, l = keys.length; i < l; i++) { - var key = keys[i]; - if (this.hasOwnProperty(key)) - copy[key] = this[key]; - } - if (includeMatrix !== false) - copy._matrix.initialize(this._matrix); - copy.setApplyMatrix(this._applyMatrix); - copy.setPivot(this._pivot); - copy.setSelected(this._selected); - copy._data = this._data ? Base.clone(this._data) : null; - if (insert || insert === undefined) - copy.insertAbove(this); - if (this._name) - copy.setName(this._name, true); - return copy; - }, - - copyTo: function(itemOrProject) { - return itemOrProject.addChild(this.clone(false)); - }, - - rasterize: function(resolution) { - var bounds = this.getStrokeBounds(), - scale = (resolution || this.getView().getResolution()) / 72, - topLeft = bounds.getTopLeft().floor(), - bottomRight = bounds.getBottomRight().ceil(), - size = new Size(bottomRight.subtract(topLeft)), - canvas = CanvasProvider.getCanvas(size.multiply(scale)), - ctx = canvas.getContext('2d'), - matrix = new Matrix().scale(scale).translate(topLeft.negate()); - ctx.save(); - matrix.applyToContext(ctx); - this.draw(ctx, new Base({ matrices: [matrix] })); - ctx.restore(); - var raster = new Raster(Item.NO_INSERT); - raster.setCanvas(canvas); - raster.transform(new Matrix().translate(topLeft.add(size.divide(2))) - .scale(1 / scale)); - raster.insertAbove(this); - return raster; - }, - - contains: function() { - return !!this._contains( - this._matrix._inverseTransform(Point.read(arguments))); - }, - - _contains: function(point) { - if (this._children) { - for (var i = this._children.length - 1; i >= 0; i--) { - if (this._children[i].contains(point)) - return true; - } - return false; - } - return point.isInside(this.getInternalBounds()); - }, - - isInside: function() { - return Rectangle.read(arguments).contains(this.getBounds()); - }, - - _asPathItem: function() { - return new Path.Rectangle({ - rectangle: this.getInternalBounds(), - matrix: this._matrix, - insert: false, - }); - }, - - intersects: function(item, _matrix) { - if (!(item instanceof Item)) - return false; - return this._asPathItem().getIntersections(item._asPathItem(), null, - _matrix || item._matrix, true).length > 0; - }, - - hitTest: function() { - return this._hitTest( - Point.read(arguments), - HitResult.getOptions(Base.read(arguments))); - }, - - _hitTest: function(point, options) { - if (this._locked || !this._visible || this._guide && !options.guides - || this.isEmpty()) - return null; - - var matrix = this._matrix, - parentTotalMatrix = options._totalMatrix, - view = this.getView(), - totalMatrix = options._totalMatrix = parentTotalMatrix - ? parentTotalMatrix.chain(matrix) - : this.getGlobalMatrix().preConcatenate(view._matrix), - tolerancePadding = options._tolerancePadding = new Size( - Path._getPenPadding(1, totalMatrix.inverted()) - ).multiply( - Math.max(options.tolerance, 1e-6) - ); - point = matrix._inverseTransform(point); - - if (!this._children && !this.getInternalRoughBounds() - .expand(tolerancePadding.multiply(2))._containsPoint(point)) - return null; - var checkSelf = !(options.guides && !this._guide - || options.selected && !this._selected - || options.type && options.type !== Base.hyphenate(this._class) - || options.class && !(this instanceof options.class)), - that = this, - res; - - function checkBounds(type, part) { - var pt = bounds['get' + part](); - if (point.subtract(pt).divide(tolerancePadding).length <= 1) - return new HitResult(type, that, - { name: Base.hyphenate(part), point: pt }); - } - - if (checkSelf && (options.center || options.bounds) && this._parent) { - var bounds = this.getInternalBounds(); - if (options.center) - res = checkBounds('center', 'Center'); - if (!res && options.bounds) { - var points = [ - 'TopLeft', 'TopRight', 'BottomLeft', 'BottomRight', - 'LeftCenter', 'TopCenter', 'RightCenter', 'BottomCenter' - ]; - for (var i = 0; i < 8 && !res; i++) - res = checkBounds('bounds', points[i]); - } - } - - var children = !res && this._children; - if (children) { - var opts = this._getChildHitTestOptions(options); - for (var i = children.length - 1; i >= 0 && !res; i--) - res = children[i]._hitTest(point, opts); - } - if (!res && checkSelf) - res = this._hitTestSelf(point, options); - if (res && res.point) - res.point = matrix.transform(res.point); - options._totalMatrix = parentTotalMatrix; - return res; - }, - - _getChildHitTestOptions: function(options) { - return options; - }, - - _hitTestSelf: function(point, options) { - if (options.fill && this.hasFill() && this._contains(point)) - return new HitResult('fill', this); - }, - - matches: function(name, compare) { - function matchObject(obj1, obj2) { - for (var i in obj1) { - if (obj1.hasOwnProperty(i)) { - var val1 = obj1[i], - val2 = obj2[i]; - if (Base.isPlainObject(val1) && Base.isPlainObject(val2)) { - if (!matchObject(val1, val2)) - return false; - } else if (!Base.equals(val1, val2)) { - return false; - } - } - } - return true; - } - var type = typeof name; - if (type === 'object') { - for (var key in name) { - if (name.hasOwnProperty(key) && !this.matches(key, name[key])) - return false; - } - } else if (type === 'function') { - return name(this); - } else { - var value = /^(empty|editable)$/.test(name) - ? this['is' + Base.capitalize(name)]() - : name === 'type' - ? Base.hyphenate(this._class) - : this[name]; - if (/^(constructor|class)$/.test(name)) { - if (!(this instanceof compare)) - return false; - } else if (compare instanceof RegExp) { - if (!compare.test(value)) - return false; - } else if (typeof compare === 'function') { - if (!compare(value)) - return false; - } else if (Base.isPlainObject(compare)) { - if (!matchObject(compare, value)) - return false; - } else if (!Base.equals(value, compare)) { - return false; - } - } - return true; - }, - - getItems: function(match) { - return Item._getItems(this._children, match, this._matrix); - }, - - getItem: function(match) { - return Item._getItems(this._children, match, this._matrix, null, true) - [0] || null; - }, - - statics: { - _getItems: function _getItems(children, match, matrix, param, - firstOnly) { - if (!param && typeof match === 'object') { - var overlapping = match.overlapping, - inside = match.inside, - bounds = overlapping || inside, - rect = bounds && Rectangle.read([bounds]); - param = { - items: [], - inside: !!inside, - overlapping: !!overlapping, - rect: rect, - path: overlapping && new Path.Rectangle({ - rectangle: rect, - insert: false - }) - }; - if (bounds) - match = Base.set({}, match, - { inside: true, overlapping: true }); - } - var items = param && param.items, - rect = param && param.rect; - matrix = rect && (matrix || new Matrix()); - for (var i = 0, l = children && children.length; i < l; i++) { - var child = children[i], - childMatrix = matrix && matrix.chain(child._matrix), - add = true; - if (rect) { - var bounds = child.getBounds(childMatrix); - if (!rect.intersects(bounds)) - continue; - if (!(param.inside && rect.contains(bounds)) - && !(param.overlapping && (bounds.contains(rect) - || param.path.intersects(child, childMatrix)))) - add = false; - } - if (add && child.matches(match)) { - items.push(child); - if (firstOnly) - break; - } - _getItems(child._children, match, - childMatrix, param, - firstOnly); - if (firstOnly && items.length > 0) - break; - } - return items; - } - } -}, { - - importJSON: function(json) { - var res = Base.importJSON(json, this); - return res !== this - ? this.addChild(res) - : res; - }, - - addChild: function(item, _preserve) { - return this.insertChild(undefined, item, _preserve); - }, - - insertChild: function(index, item, _preserve) { - var res = item ? this.insertChildren(index, [item], _preserve) : null; - return res && res[0]; - }, - - addChildren: function(items, _preserve) { - return this.insertChildren(this._children.length, items, _preserve); - }, - - insertChildren: function(index, items, _preserve, _proto) { - var children = this._children; - if (children && items && items.length > 0) { - items = Array.prototype.slice.apply(items); - for (var i = items.length - 1; i >= 0; i--) { - var item = items[i]; - if (_proto && !(item instanceof _proto)) { - items.splice(i, 1); - } else { - var shift = item._parent === this && item._index < index; - if (item._remove(false, true) && shift) - index--; - } - } - Base.splice(children, items, index, 0); - var project = this._project, - notifySelf = project && project._changes; - for (var i = 0, l = items.length; i < l; i++) { - var item = items[i]; - item._parent = this; - item._setProject(this._project, true); - if (item._name) - item.setName(item._name); - if (notifySelf) - this._changed(5); - } - this._changed(11); - } else { - items = null; - } - return items; - }, - - _insertSibling: function(index, item, _preserve) { - return this._parent - ? this._parent.insertChild(index, item, _preserve) - : null; - }, - - insertAbove: function(item, _preserve) { - return item._insertSibling(item._index + 1, this, _preserve); - }, - - insertBelow: function(item, _preserve) { - return item._insertSibling(item._index, this, _preserve); - }, - - sendToBack: function() { - return (this._parent || this instanceof Layer && this._project) - .insertChild(0, this); - }, - - bringToFront: function() { - return (this._parent || this instanceof Layer && this._project) - .addChild(this); - }, - - appendTop: '#addChild', - - appendBottom: function(item) { - return this.insertChild(0, item); - }, - - moveAbove: '#insertAbove', - - moveBelow: '#insertBelow', - - reduce: function() { - if (this._children && this._children.length === 1) { - var child = this._children[0].reduce(); - child.insertAbove(this); - child.setStyle(this._style); - this.remove(); - return child; - } - return this; - }, - - _removeNamed: function() { - var parent = this._parent; - if (parent) { - var children = parent._children, - namedChildren = parent._namedChildren, - name = this._name, - namedArray = namedChildren[name], - index = namedArray ? namedArray.indexOf(this) : -1; - if (index !== -1) { - if (children[name] == this) - delete children[name]; - namedArray.splice(index, 1); - if (namedArray.length) { - children[name] = namedArray[namedArray.length - 1]; - } else { - delete namedChildren[name]; - } - } - } - }, - - _remove: function(notifySelf, notifyParent) { - var parent = this._parent; - if (parent) { - if (this._name) - this._removeNamed(); - if (this._index != null) - Base.splice(parent._children, null, this._index, 1); - this._installEvents(false); - if (notifySelf) { - var project = this._project; - if (project && project._changes) - this._changed(5); - } - if (notifyParent) - parent._changed(11); - this._parent = null; - return true; - } - return false; - }, - - remove: function() { - return this._remove(true, true); - }, - - replaceWith: function(item) { - var ok = item && item.insertBelow(this); - if (ok) - this.remove(); - return ok; - }, - - removeChildren: function(from, to) { - if (!this._children) - return null; - from = from || 0; - to = Base.pick(to, this._children.length); - var removed = Base.splice(this._children, null, from, to - from); - for (var i = removed.length - 1; i >= 0; i--) { - removed[i]._remove(true, false); - } - if (removed.length > 0) - this._changed(11); - return removed; - }, - - clear: '#removeChildren', - - reverseChildren: function() { - if (this._children) { - this._children.reverse(); - for (var i = 0, l = this._children.length; i < l; i++) - this._children[i]._index = i; - this._changed(11); - } - }, - - isEmpty: function() { - return !this._children || this._children.length === 0; - }, - - isEditable: function() { - var item = this; - while (item) { - if (!item._visible || item._locked) - return false; - item = item._parent; - } - return true; - }, - - hasFill: function() { - return this.getStyle().hasFill(); - }, - - hasStroke: function() { - return this.getStyle().hasStroke(); - }, - - hasShadow: function() { - return this.getStyle().hasShadow(); - }, - - _getOrder: function(item) { - function getList(item) { - var list = []; - do { - list.unshift(item); - } while (item = item._parent); - return list; - } - var list1 = getList(this), - list2 = getList(item); - for (var i = 0, l = Math.min(list1.length, list2.length); i < l; i++) { - if (list1[i] != list2[i]) { - return list1[i]._index < list2[i]._index ? 1 : -1; - } - } - return 0; - }, - - hasChildren: function() { - return this._children && this._children.length > 0; - }, - - isInserted: function() { - return this._parent ? this._parent.isInserted() : false; - }, - - isAbove: function(item) { - return this._getOrder(item) === -1; - }, - - isBelow: function(item) { - return this._getOrder(item) === 1; - }, - - isParent: function(item) { - return this._parent === item; - }, - - isChild: function(item) { - return item && item._parent === this; - }, - - isDescendant: function(item) { - var parent = this; - while (parent = parent._parent) { - if (parent == item) - return true; - } - return false; - }, - - isAncestor: function(item) { - return item ? item.isDescendant(this) : false; - }, - - isSibling: function(item) { - return this._parent === item._parent; - }, - - isGroupedWith: function(item) { - var parent = this._parent; - while (parent) { - if (parent._parent - && /^(Group|Layer|CompoundPath)$/.test(parent._class) - && item.isDescendant(parent)) - return true; - parent = parent._parent; - } - return false; - }, - - translate: function() { - var mx = new Matrix(); - return this.transform(mx.translate.apply(mx, arguments)); - }, - - rotate: function(angle ) { - return this.transform(new Matrix().rotate(angle, - Point.read(arguments, 1, { readNull: true }) - || this.getPosition(true))); - } -}, Base.each(['scale', 'shear', 'skew'], function(name) { - this[name] = function() { - var point = Point.read(arguments), - center = Point.read(arguments, 0, { readNull: true }); - return this.transform(new Matrix()[name](point, - center || this.getPosition(true))); - }; -}, { - -}), { - transform: function(matrix, _applyMatrix, _applyRecursively, - _setApplyMatrix) { - if (matrix && matrix.isIdentity()) - matrix = null; - var _matrix = this._matrix, - applyMatrix = (_applyMatrix || this._applyMatrix) - && ((!_matrix.isIdentity() || matrix) - || _applyMatrix && _applyRecursively && this._children); - if (!matrix && !applyMatrix) - return this; - if (matrix) - _matrix.preConcatenate(matrix); - if (applyMatrix = applyMatrix && this._transformContent(_matrix, - _applyRecursively, _setApplyMatrix)) { - var pivot = this._pivot, - style = this._style, - fillColor = style.getFillColor(true), - strokeColor = style.getStrokeColor(true); - if (pivot) - _matrix._transformPoint(pivot, pivot, true); - if (fillColor) - fillColor.transform(_matrix); - if (strokeColor) - strokeColor.transform(_matrix); - _matrix.reset(true); - if (_setApplyMatrix && this._canApplyMatrix) - this._applyMatrix = true; - } - var bounds = this._bounds, - position = this._position; - this._changed(9); - var decomp = bounds && matrix && matrix.decompose(); - if (decomp && !decomp.shearing && decomp.rotation % 90 === 0) { - for (var key in bounds) { - var rect = bounds[key]; - if (applyMatrix || !rect._internal) - matrix._transformBounds(rect, rect); - } - var getter = this._boundsGetter, - rect = bounds[getter && getter.getBounds || getter || 'getBounds']; - if (rect) - this._position = rect.getCenter(true); - this._bounds = bounds; - } else if (matrix && position) { - this._position = matrix._transformPoint(position, position); - } - return this; - }, - - _transformContent: function(matrix, applyRecursively, setApplyMatrix) { - var children = this._children; - if (children) { - for (var i = 0, l = children.length; i < l; i++) - children[i].transform(matrix, true, applyRecursively, - setApplyMatrix); - return true; - } - }, - - globalToLocal: function() { - return this.getGlobalMatrix(true)._inverseTransform( - Point.read(arguments)); - }, - - localToGlobal: function() { - return this.getGlobalMatrix(true)._transformPoint( - Point.read(arguments)); - }, - - parentToLocal: function() { - return this._matrix._inverseTransform(Point.read(arguments)); - }, - - localToParent: function() { - return this._matrix._transformPoint(Point.read(arguments)); - }, - - fitBounds: function(rectangle, fill) { - rectangle = Rectangle.read(arguments); - var bounds = this.getBounds(), - itemRatio = bounds.height / bounds.width, - rectRatio = rectangle.height / rectangle.width, - scale = (fill ? itemRatio > rectRatio : itemRatio < rectRatio) - ? rectangle.width / bounds.width - : rectangle.height / bounds.height, - newBounds = new Rectangle(new Point(), - new Size(bounds.width * scale, bounds.height * scale)); - newBounds.setCenter(rectangle.getCenter()); - this.setBounds(newBounds); - }, - - _setStyles: function(ctx) { - var style = this._style, - fillColor = style.getFillColor(), - strokeColor = style.getStrokeColor(), - shadowColor = style.getShadowColor(); - if (fillColor) - ctx.fillStyle = fillColor.toCanvasStyle(ctx); - if (strokeColor) { - var strokeWidth = style.getStrokeWidth(); - if (strokeWidth > 0) { - ctx.strokeStyle = strokeColor.toCanvasStyle(ctx); - ctx.lineWidth = strokeWidth; - var strokeJoin = style.getStrokeJoin(), - strokeCap = style.getStrokeCap(), - miterLimit = style.getMiterLimit(); - if (strokeJoin) - ctx.lineJoin = strokeJoin; - if (strokeCap) - ctx.lineCap = strokeCap; - if (miterLimit) - ctx.miterLimit = miterLimit; - if (paper.support.nativeDash) { - var dashArray = style.getDashArray(), - dashOffset = style.getDashOffset(); - if (dashArray && dashArray.length) { - if ('setLineDash' in ctx) { - ctx.setLineDash(dashArray); - ctx.lineDashOffset = dashOffset; - } else { - ctx.mozDash = dashArray; - ctx.mozDashOffset = dashOffset; - } - } - } - } - } - if (shadowColor) { - var shadowBlur = style.getShadowBlur(); - if (shadowBlur > 0) { - ctx.shadowColor = shadowColor.toCanvasStyle(ctx); - ctx.shadowBlur = shadowBlur; - var offset = this.getShadowOffset(); - ctx.shadowOffsetX = offset.x; - ctx.shadowOffsetY = offset.y; - } - } - }, - - draw: function(ctx, param, parentStrokeMatrix) { - var updateVersion = this._updateVersion = this._project._updateVersion; - if (!this._visible || this._opacity === 0) - return; - var matrices = param.matrices, - viewMatrix = param.viewMatrix, - matrix = this._matrix, - globalMatrix = matrices[matrices.length - 1].chain(matrix); - if (!globalMatrix.isInvertible()) - return; - - function getViewMatrix(matrix) { - return viewMatrix ? viewMatrix.chain(matrix) : matrix; - } - - matrices.push(globalMatrix); - if (param.updateMatrix) { - globalMatrix._updateVersion = updateVersion; - this._globalMatrix = globalMatrix; - } - - var blendMode = this._blendMode, - opacity = this._opacity, - normalBlend = blendMode === 'normal', - nativeBlend = BlendMode.nativeModes[blendMode], - direct = normalBlend && opacity === 1 - || param.dontStart - || param.clip - || (nativeBlend || normalBlend && opacity < 1) - && this._canComposite(), - pixelRatio = param.pixelRatio || 1, - mainCtx, itemOffset, prevOffset; - if (!direct) { - var bounds = this.getStrokeBounds(getViewMatrix(globalMatrix)); - if (!bounds.width || !bounds.height) - return; - prevOffset = param.offset; - itemOffset = param.offset = bounds.getTopLeft().floor(); - mainCtx = ctx; - ctx = CanvasProvider.getContext(bounds.getSize().ceil().add(1) - .multiply(pixelRatio)); - if (pixelRatio !== 1) - ctx.scale(pixelRatio, pixelRatio); - } - ctx.save(); - var strokeMatrix = parentStrokeMatrix - ? parentStrokeMatrix.chain(matrix) - : !this.getStrokeScaling(true) && getViewMatrix(globalMatrix), - clip = !direct && param.clipItem, - transform = !strokeMatrix || clip; - if (direct) { - ctx.globalAlpha = opacity; - if (nativeBlend) - ctx.globalCompositeOperation = blendMode; - } else if (transform) { - ctx.translate(-itemOffset.x, -itemOffset.y); - } - if (transform) - (direct ? matrix : getViewMatrix(globalMatrix)).applyToContext(ctx); - if (clip) - param.clipItem.draw(ctx, param.extend({ clip: true })); - if (strokeMatrix) { - ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); - var offset = param.offset; - if (offset) - ctx.translate(-offset.x, -offset.y); - } - this._draw(ctx, param, strokeMatrix); - ctx.restore(); - matrices.pop(); - if (param.clip && !param.dontFinish) - ctx.clip(); - if (!direct) { - BlendMode.process(blendMode, ctx, mainCtx, opacity, - itemOffset.subtract(prevOffset).multiply(pixelRatio)); - CanvasProvider.release(ctx); - param.offset = prevOffset; - } - }, - - _isUpdated: function(updateVersion) { - var parent = this._parent; - if (parent instanceof CompoundPath) - return parent._isUpdated(updateVersion); - var updated = this._updateVersion === updateVersion; - if (!updated && parent && parent._visible - && parent._isUpdated(updateVersion)) { - this._updateVersion = updateVersion; - updated = true; - } - return updated; - }, - - _drawSelection: function(ctx, matrix, size, selectedItems, updateVersion) { - if ((this._drawSelected || this._boundsSelected) - && this._isUpdated(updateVersion)) { - var color = this.getSelectedColor(true) - || this.getLayer().getSelectedColor(true), - mx = matrix.chain(this.getGlobalMatrix(true)); - ctx.strokeStyle = ctx.fillStyle = color - ? color.toCanvasStyle(ctx) : '#009dec'; - if (this._drawSelected) - this._drawSelected(ctx, mx, selectedItems); - if (this._boundsSelected) { - var half = size / 2, - coords = mx._transformCorners(this.getInternalBounds()); - ctx.beginPath(); - for (var i = 0; i < 8; i++) - ctx[i === 0 ? 'moveTo' : 'lineTo'](coords[i], coords[++i]); - ctx.closePath(); - ctx.stroke(); - for (var i = 0; i < 8; i++) - ctx.fillRect(coords[i] - half, coords[++i] - half, - size, size); - } - } - }, - - _canComposite: function() { - return false; - } -}, Base.each(['down', 'drag', 'up', 'move'], function(name) { - this['removeOn' + Base.capitalize(name)] = function() { - var hash = {}; - hash[name] = true; - return this.removeOn(hash); - }; -}, { - - removeOn: function(obj) { - for (var name in obj) { - if (obj[name]) { - var key = 'mouse' + name, - project = this._project, - sets = project._removeSets = project._removeSets || {}; - sets[key] = sets[key] || {}; - sets[key][this._id] = this; - } - } - return this; - } -})); - -var Group = Item.extend({ - _class: 'Group', - _selectChildren: true, - _serializeFields: { - children: [] - }, - - initialize: function Group(arg) { - this._children = []; - this._namedChildren = {}; - if (!this._initialize(arg)) - this.addChildren(Array.isArray(arg) ? arg : arguments); - }, - - _changed: function _changed(flags) { - _changed.base.call(this, flags); - if (flags & 1026) { - this._clipItem = undefined; - } - }, - - _getClipItem: function() { - var clipItem = this._clipItem; - if (clipItem === undefined) { - clipItem = null; - for (var i = 0, l = this._children.length; i < l; i++) { - var child = this._children[i]; - if (child._clipMask) { - clipItem = child; - break; - } - } - this._clipItem = clipItem; - } - return clipItem; - }, - - isClipped: function() { - return !!this._getClipItem(); - }, - - setClipped: function(clipped) { - var child = this.getFirstChild(); - if (child) - child.setClipMask(clipped); - }, - - _draw: function(ctx, param) { - var clip = param.clip, - clipItem = !clip && this._getClipItem(), - draw = true; - param = param.extend({ clipItem: clipItem, clip: false }); - if (clip) { - if (this._currentPath) { - ctx.currentPath = this._currentPath; - draw = false; - } else { - ctx.beginPath(); - param.dontStart = param.dontFinish = true; - } - } else if (clipItem) { - clipItem.draw(ctx, param.extend({ clip: true })); - } - if (draw) { - for (var i = 0, l = this._children.length; i < l; i++) { - var item = this._children[i]; - if (item !== clipItem) - item.draw(ctx, param); - } - } - if (clip) { - this._currentPath = ctx.currentPath; - } - } -}); - -var Layer = Group.extend({ - _class: 'Layer', - - initialize: function Layer(arg) { - var props = Base.isPlainObject(arg) - ? new Base(arg) - : { children: Array.isArray(arg) ? arg : arguments }, - insert = props.insert; - props.insert = false; - Group.call(this, props); - if (insert || insert === undefined) { - this._project.addChild(this); - this.activate(); - } - }, - - _remove: function _remove(notifySelf, notifyParent) { - if (this._parent) - return _remove.base.call(this, notifySelf, notifyParent); - if (this._index != null) { - var project = this._project; - if (project._activeLayer === this) - project._activeLayer = this.getNextSibling() - || this.getPreviousSibling(); - Base.splice(project.layers, null, this._index, 1); - this._installEvents(false); - if (notifySelf && project._changes) - this._changed(5); - if (notifyParent) { - project._needsUpdate = true; - } - return true; - } - return false; - }, - - getNextSibling: function getNextSibling() { - return this._parent ? getNextSibling.base.call(this) - : this._project.layers[this._index + 1] || null; - }, - - getPreviousSibling: function getPreviousSibling() { - return this._parent ? getPreviousSibling.base.call(this) - : this._project.layers[this._index - 1] || null; - }, - - isInserted: function isInserted() { - return this._parent ? isInserted.base.call(this) : this._index != null; - }, - - activate: function() { - this._project._activeLayer = this; - }, - - _insertSibling: function _insertSibling(index, item, _preserve) { - return !this._parent - ? this._project.insertChild(index, item, _preserve) - : _insertSibling.base.call(this, index, item, _preserve); - } -}); - -var Shape = Item.extend({ - _class: 'Shape', - _applyMatrix: false, - _canApplyMatrix: false, - _boundsSelected: true, - _serializeFields: { - type: null, - size: null, - radius: null - }, - - initialize: function Shape(props) { - this._initialize(props); - }, - - _equals: function(item) { - return this._type === item._type - && this._size.equals(item._size) - && Base.equals(this._radius, item._radius); - }, - - clone: function(insert) { - var copy = new Shape(Item.NO_INSERT); - copy.setType(this._type); - copy.setSize(this._size); - copy.setRadius(this._radius); - return this._clone(copy, insert); - }, - - getType: function() { - return this._type; - }, - - setType: function(type) { - this._type = type; - }, - - getShape: '#getType', - setShape: '#setType', - - getSize: function() { - var size = this._size; - return new LinkedSize(size.width, size.height, this, 'setSize'); - }, - - setSize: function() { - var size = Size.read(arguments); - if (!this._size) { - this._size = size.clone(); - } else if (!this._size.equals(size)) { - var type = this._type, - width = size.width, - height = size.height; - if (type === 'rectangle') { - var radius = Size.min(this._radius, size.divide(2)); - this._radius.set(radius.width, radius.height); - } else if (type === 'circle') { - width = height = (width + height) / 2; - this._radius = width / 2; - } else if (type === 'ellipse') { - this._radius.set(width / 2, height / 2); - } - this._size.set(width, height); - this._changed(9); - } - }, - - getRadius: function() { - var rad = this._radius; - return this._type === 'circle' - ? rad - : new LinkedSize(rad.width, rad.height, this, 'setRadius'); - }, - - setRadius: function(radius) { - var type = this._type; - if (type === 'circle') { - if (radius === this._radius) - return; - var size = radius * 2; - this._radius = radius; - this._size.set(size, size); - } else { - radius = Size.read(arguments); - if (!this._radius) { - this._radius = radius.clone(); - } else { - if (this._radius.equals(radius)) - return; - this._radius.set(radius.width, radius.height); - if (type === 'rectangle') { - var size = Size.max(this._size, radius.multiply(2)); - this._size.set(size.width, size.height); - } else if (type === 'ellipse') { - this._size.set(radius.width * 2, radius.height * 2); - } - } - } - this._changed(9); - }, - - isEmpty: function() { - return false; - }, - - toPath: function(insert) { - var path = this._clone(new Path[Base.capitalize(this._type)]({ - center: new Point(), - size: this._size, - radius: this._radius, - insert: false - }), insert); - if (paper.settings.applyMatrix) - path.setApplyMatrix(true); - return path; - }, - - _draw: function(ctx, param, strokeMatrix) { - var style = this._style, - hasFill = style.hasFill(), - hasStroke = style.hasStroke(), - dontPaint = param.dontFinish || param.clip, - untransformed = !strokeMatrix; - if (hasFill || hasStroke || dontPaint) { - var type = this._type, - radius = this._radius, - isCircle = type === 'circle'; - if (!param.dontStart) - ctx.beginPath(); - if (untransformed && isCircle) { - ctx.arc(0, 0, radius, 0, Math.PI * 2, true); - } else { - var rx = isCircle ? radius : radius.width, - ry = isCircle ? radius : radius.height, - size = this._size, - width = size.width, - height = size.height; - if (untransformed && type === 'rectangle' && rx === 0 && ry === 0) { - ctx.rect(-width / 2, -height / 2, width, height); - } else { - var x = width / 2, - y = height / 2, - kappa = 1 - 0.5522847498307936, - cx = rx * kappa, - cy = ry * kappa, - c = [ - -x, -y + ry, - -x, -y + cy, - -x + cx, -y, - -x + rx, -y, - x - rx, -y, - x - cx, -y, - x, -y + cy, - x, -y + ry, - x, y - ry, - x, y - cy, - x - cx, y, - x - rx, y, - -x + rx, y, - -x + cx, y, - -x, y - cy, - -x, y - ry - ]; - if (strokeMatrix) - strokeMatrix.transform(c, c, 32); - ctx.moveTo(c[0], c[1]); - ctx.bezierCurveTo(c[2], c[3], c[4], c[5], c[6], c[7]); - if (x !== rx) - ctx.lineTo(c[8], c[9]); - ctx.bezierCurveTo(c[10], c[11], c[12], c[13], c[14], c[15]); - if (y !== ry) - ctx.lineTo(c[16], c[17]); - ctx.bezierCurveTo(c[18], c[19], c[20], c[21], c[22], c[23]); - if (x !== rx) - ctx.lineTo(c[24], c[25]); - ctx.bezierCurveTo(c[26], c[27], c[28], c[29], c[30], c[31]); - } - } - ctx.closePath(); - } - if (!dontPaint && (hasFill || hasStroke)) { - this._setStyles(ctx); - if (hasFill) { - ctx.fill(style.getWindingRule()); - ctx.shadowColor = 'rgba(0,0,0,0)'; - } - if (hasStroke) - ctx.stroke(); - } - }, - - _canComposite: function() { - return !(this.hasFill() && this.hasStroke()); - }, - - _getBounds: function(getter, matrix) { - var rect = new Rectangle(this._size).setCenter(0, 0); - if (getter !== 'getBounds' && this.hasStroke()) - rect = rect.expand(this.getStrokeWidth()); - return matrix ? matrix._transformBounds(rect) : rect; - } -}, -new function() { - function getCornerCenter(that, point, expand) { - var radius = that._radius; - if (!radius.isZero()) { - var halfSize = that._size.divide(2); - for (var i = 0; i < 4; i++) { - var dir = new Point(i & 1 ? 1 : -1, i > 1 ? 1 : -1), - corner = dir.multiply(halfSize), - center = corner.subtract(dir.multiply(radius)), - rect = new Rectangle(corner, center); - if ((expand ? rect.expand(expand) : rect).contains(point)) - return center; - } - } - } - - function getEllipseRadius(point, radius) { - var angle = point.getAngleInRadians(), - width = radius.width * 2, - height = radius.height * 2, - x = width * Math.sin(angle), - y = height * Math.cos(angle); - return width * height / (2 * Math.sqrt(x * x + y * y)); - } - - return { - _contains: function _contains(point) { - if (this._type === 'rectangle') { - var center = getCornerCenter(this, point); - return center - ? point.subtract(center).divide(this._radius) - .getLength() <= 1 - : _contains.base.call(this, point); - } else { - return point.divide(this.size).getLength() <= 0.5; - } - }, - - _hitTestSelf: function _hitTestSelf(point, options) { - var hit = false; - if (this.hasStroke()) { - var type = this._type, - radius = this._radius, - strokeWidth = this.getStrokeWidth() + 2 * options.tolerance; - if (type === 'rectangle') { - var center = getCornerCenter(this, point, strokeWidth); - if (center) { - var pt = point.subtract(center); - hit = 2 * Math.abs(pt.getLength() - - getEllipseRadius(pt, radius)) <= strokeWidth; - } else { - var rect = new Rectangle(this._size).setCenter(0, 0), - outer = rect.expand(strokeWidth), - inner = rect.expand(-strokeWidth); - hit = outer._containsPoint(point) - && !inner._containsPoint(point); - } - } else { - if (type === 'ellipse') - radius = getEllipseRadius(point, radius); - hit = 2 * Math.abs(point.getLength() - radius) - <= strokeWidth; - } - } - return hit - ? new HitResult('stroke', this) - : _hitTestSelf.base.apply(this, arguments); - } - }; -}, { - -statics: new function() { - function createShape(type, point, size, radius, args) { - var item = new Shape(Base.getNamed(args)); - item._type = type; - item._size = size; - item._radius = radius; - return item.translate(point); - } - - return { - Circle: function() { - var center = Point.readNamed(arguments, 'center'), - radius = Base.readNamed(arguments, 'radius'); - return createShape('circle', center, new Size(radius * 2), radius, - arguments); - }, - - Rectangle: function() { - var rect = Rectangle.readNamed(arguments, 'rectangle'), - radius = Size.min(Size.readNamed(arguments, 'radius'), - rect.getSize(true).divide(2)); - return createShape('rectangle', rect.getCenter(true), - rect.getSize(true), radius, arguments); - }, - - Ellipse: function() { - var ellipse = Shape._readEllipse(arguments), - radius = ellipse.radius; - return createShape('ellipse', ellipse.center, radius.multiply(2), - radius, arguments); - }, - - _readEllipse: function(args) { - var center, - radius; - if (Base.hasNamed(args, 'radius')) { - center = Point.readNamed(args, 'center'); - radius = Size.readNamed(args, 'radius'); - } else { - var rect = Rectangle.readNamed(args, 'rectangle'); - center = rect.getCenter(true); - radius = rect.getSize(true).divide(2); - } - return { center: center, radius: radius }; - } - }; -}}); - -var Raster = Item.extend({ - _class: 'Raster', - _applyMatrix: false, - _canApplyMatrix: false, - _boundsGetter: 'getBounds', - _boundsSelected: true, - _serializeFields: { - crossOrigin: null, - source: null - }, - - initialize: function Raster(object, position) { - if (!this._initialize(object, - position !== undefined && Point.read(arguments, 1))) { - if (typeof object === 'string') { - this.setSource(object); - } else { - this.setImage(object); - } - } - if (!this._size) { - this._size = new Size(); - this._loaded = false; - } - }, - - _equals: function(item) { - return this.getSource() === item.getSource(); - }, - - clone: function(insert) { - var copy = new Raster(Item.NO_INSERT), - image = this._image, - canvas = this._canvas; - if (image) { - copy.setImage(image); - } else if (canvas) { - var copyCanvas = CanvasProvider.getCanvas(this._size); - copyCanvas.getContext('2d').drawImage(canvas, 0, 0); - copy.setImage(copyCanvas); - } - copy._crossOrigin = this._crossOrigin; - return this._clone(copy, insert); - }, - - getSize: function() { - var size = this._size; - return new LinkedSize(size ? size.width : 0, size ? size.height : 0, - this, 'setSize'); - }, - - setSize: function() { - var size = Size.read(arguments); - if (!size.equals(this._size)) { - if (size.width > 0 && size.height > 0) { - var element = this.getElement(); - this.setImage(CanvasProvider.getCanvas(size)); - if (element) - this.getContext(true).drawImage(element, 0, 0, - size.width, size.height); - } else { - if (this._canvas) - CanvasProvider.release(this._canvas); - this._size = size.clone(); - } - } - }, - - getWidth: function() { - return this._size ? this._size.width : 0; - }, - - setWidth: function(width) { - this.setSize(width, this.getHeight()); - }, - - getHeight: function() { - return this._size ? this._size.height : 0; - }, - - setHeight: function(height) { - this.setSize(this.getWidth(), height); - }, - - isEmpty: function() { - var size = this._size; - return !size || size.width === 0 && size.height === 0; - }, - - getResolution: function() { - var matrix = this._matrix, - orig = new Point(0, 0).transform(matrix), - u = new Point(1, 0).transform(matrix).subtract(orig), - v = new Point(0, 1).transform(matrix).subtract(orig); - return new Size( - 72 / u.getLength(), - 72 / v.getLength() - ); - }, - - getPpi: '#getResolution', - - getImage: function() { - return this._image; - }, - - setImage: function(image) { - if (this._canvas) - CanvasProvider.release(this._canvas); - if (image && image.getContext) { - this._image = null; - this._canvas = image; - this._loaded = true; - } else { - this._image = image; - this._canvas = null; - this._loaded = image && image.complete; - } - this._size = new Size( - image ? image.naturalWidth || image.width : 0, - image ? image.naturalHeight || image.height : 0); - this._context = null; - this._changed(521); - }, - - getCanvas: function() { - if (!this._canvas) { - var ctx = CanvasProvider.getContext(this._size); - try { - if (this._image) - ctx.drawImage(this._image, 0, 0); - this._canvas = ctx.canvas; - } catch (e) { - CanvasProvider.release(ctx); - } - } - return this._canvas; - }, - - setCanvas: '#setImage', - - getContext: function(modify) { - if (!this._context) - this._context = this.getCanvas().getContext('2d'); - if (modify) { - this._image = null; - this._changed(513); - } - return this._context; - }, - - setContext: function(context) { - this._context = context; - }, - - getSource: function() { - return this._image && this._image.src || this.toDataURL(); - }, - - setSource: function(src) { - var that = this, - crossOrigin = this._crossOrigin, - image; - - function loaded() { - var view = that.getView(); - if (view) { - paper = view._scope; - that.setImage(image); - that.emit('load'); - view.update(); - } - } - - image = document.getElementById(src) || new Image(); - if (crossOrigin) - image.crossOrigin = crossOrigin; - if (image.naturalWidth && image.naturalHeight) { - setTimeout(loaded, 0); - } else { - DomEvent.add(image, { load: loaded }); - if (!image.src) - image.src = src; - } - this.setImage(image); - }, - - getCrossOrigin: function() { - return this._image && this._image.crossOrigin || this._crossOrigin || ''; - }, - - setCrossOrigin: function(crossOrigin) { - this._crossOrigin = crossOrigin; - if (this._image) - this._image.crossOrigin = crossOrigin; - }, - - getElement: function() { - return this._canvas || this._loaded && this._image; - } -}, { - beans: false, - - getSubCanvas: function() { - var rect = Rectangle.read(arguments), - ctx = CanvasProvider.getContext(rect.getSize()); - ctx.drawImage(this.getCanvas(), rect.x, rect.y, - rect.width, rect.height, 0, 0, rect.width, rect.height); - return ctx.canvas; - }, - - getSubRaster: function() { - var rect = Rectangle.read(arguments), - raster = new Raster(Item.NO_INSERT); - raster.setImage(this.getSubCanvas(rect)); - raster.translate(rect.getCenter().subtract(this.getSize().divide(2))); - raster._matrix.preConcatenate(this._matrix); - raster.insertAbove(this); - return raster; - }, - - toDataURL: function() { - var src = this._image && this._image.src; - if (/^data:/.test(src)) - return src; - var canvas = this.getCanvas(); - return canvas ? canvas.toDataURL.apply(canvas, arguments) : null; - }, - - drawImage: function(image ) { - var point = Point.read(arguments, 1); - this.getContext(true).drawImage(image, point.x, point.y); - }, - - getAverageColor: function(object) { - var bounds, path; - if (!object) { - bounds = this.getBounds(); - } else if (object instanceof PathItem) { - path = object; - bounds = object.getBounds(); - } else if (object.width) { - bounds = new Rectangle(object); - } else if (object.x) { - bounds = new Rectangle(object.x - 0.5, object.y - 0.5, 1, 1); - } - var sampleSize = 32, - width = Math.min(bounds.width, sampleSize), - height = Math.min(bounds.height, sampleSize); - var ctx = Raster._sampleContext; - if (!ctx) { - ctx = Raster._sampleContext = CanvasProvider.getContext( - new Size(sampleSize)); - } else { - ctx.clearRect(0, 0, sampleSize + 1, sampleSize + 1); - } - ctx.save(); - var matrix = new Matrix() - .scale(width / bounds.width, height / bounds.height) - .translate(-bounds.x, -bounds.y); - matrix.applyToContext(ctx); - if (path) - path.draw(ctx, new Base({ clip: true, matrices: [matrix] })); - this._matrix.applyToContext(ctx); - var element = this.getElement(), - size = this._size; - if (element) - ctx.drawImage(element, -size.width / 2, -size.height / 2); - ctx.restore(); - var pixels = ctx.getImageData(0.5, 0.5, Math.ceil(width), - Math.ceil(height)).data, - channels = [0, 0, 0], - total = 0; - for (var i = 0, l = pixels.length; i < l; i += 4) { - var alpha = pixels[i + 3]; - total += alpha; - alpha /= 255; - channels[0] += pixels[i] * alpha; - channels[1] += pixels[i + 1] * alpha; - channels[2] += pixels[i + 2] * alpha; - } - for (var i = 0; i < 3; i++) - channels[i] /= total; - return total ? Color.read(channels) : null; - }, - - getPixel: function() { - var point = Point.read(arguments); - var data = this.getContext().getImageData(point.x, point.y, 1, 1).data; - return new Color('rgb', [data[0] / 255, data[1] / 255, data[2] / 255], - data[3] / 255); - }, - - setPixel: function() { - var point = Point.read(arguments), - color = Color.read(arguments), - components = color._convert('rgb'), - alpha = color._alpha, - ctx = this.getContext(true), - imageData = ctx.createImageData(1, 1), - data = imageData.data; - data[0] = components[0] * 255; - data[1] = components[1] * 255; - data[2] = components[2] * 255; - data[3] = alpha != null ? alpha * 255 : 255; - ctx.putImageData(imageData, point.x, point.y); - }, - - createImageData: function() { - var size = Size.read(arguments); - return this.getContext().createImageData(size.width, size.height); - }, - - getImageData: function() { - var rect = Rectangle.read(arguments); - if (rect.isEmpty()) - rect = new Rectangle(this._size); - return this.getContext().getImageData(rect.x, rect.y, - rect.width, rect.height); - }, - - setImageData: function(data ) { - var point = Point.read(arguments, 1); - this.getContext(true).putImageData(data, point.x, point.y); - }, - - _getBounds: function(getter, matrix) { - var rect = new Rectangle(this._size).setCenter(0, 0); - return matrix ? matrix._transformBounds(rect) : rect; - }, - - _hitTestSelf: function(point) { - if (this._contains(point)) { - var that = this; - return new HitResult('pixel', that, { - offset: point.add(that._size.divide(2)).round(), - color: { - get: function() { - return that.getPixel(this.offset); - } - } - }); - } - }, - - _draw: function(ctx) { - var element = this.getElement(); - if (element) { - ctx.globalAlpha = this._opacity; - ctx.drawImage(element, - -this._size.width / 2, -this._size.height / 2); - } - }, - - _canComposite: function() { - return true; - } -}); - -var PlacedSymbol = Item.extend({ - _class: 'PlacedSymbol', - _applyMatrix: false, - _canApplyMatrix: false, - _boundsGetter: { getBounds: 'getStrokeBounds' }, - _boundsSelected: true, - _serializeFields: { - symbol: null - }, - - initialize: function PlacedSymbol(arg0, arg1) { - if (!this._initialize(arg0, - arg1 !== undefined && Point.read(arguments, 1))) - this.setSymbol(arg0 instanceof Symbol ? arg0 : new Symbol(arg0)); - }, - - _equals: function(item) { - return this._symbol === item._symbol; - }, - - getSymbol: function() { - return this._symbol; - }, - - setSymbol: function(symbol) { - this._symbol = symbol; - this._changed(9); - }, - - clone: function(insert) { - var copy = new PlacedSymbol(Item.NO_INSERT); - copy.setSymbol(this._symbol); - return this._clone(copy, insert); - }, - - isEmpty: function() { - return this._symbol._definition.isEmpty(); - }, - - _getBounds: function(getter, matrix, cacheItem) { - var definition = this.symbol._definition; - return definition._getCachedBounds(getter, - matrix && matrix.chain(definition._matrix), cacheItem); - }, - - _hitTestSelf: function(point, options) { - var res = this._symbol._definition._hitTest(point, options); - if (res) - res.item = this; - return res; - }, - - _draw: function(ctx, param) { - this.symbol._definition.draw(ctx, param); - } - -}); - -var HitResult = Base.extend({ - _class: 'HitResult', - - initialize: function HitResult(type, item, values) { - this.type = type; - this.item = item; - if (values) { - values.enumerable = true; - this.inject(values); - } - }, - - statics: { - getOptions: function(options) { - return new Base({ - type: null, - tolerance: paper.settings.hitTolerance, - fill: !options, - stroke: !options, - segments: !options, - handles: false, - ends: false, - center: false, - bounds: false, - guides: false, - selected: false - }, options); - } - } -}); - -var Segment = Base.extend({ - _class: 'Segment', - beans: true, - - initialize: function Segment(arg0, arg1, arg2, arg3, arg4, arg5) { - var count = arguments.length, - point, handleIn, handleOut; - if (count === 0) { - } else if (count === 1) { - if ('point' in arg0) { - point = arg0.point; - handleIn = arg0.handleIn; - handleOut = arg0.handleOut; - } else { - point = arg0; - } - } else if (count === 2 && typeof arg0 === 'number') { - point = arguments; - } else if (count <= 3) { - point = arg0; - handleIn = arg1; - handleOut = arg2; - } else { - point = arg0 !== undefined ? [ arg0, arg1 ] : null; - handleIn = arg2 !== undefined ? [ arg2, arg3 ] : null; - handleOut = arg4 !== undefined ? [ arg4, arg5 ] : null; - } - new SegmentPoint(point, this, '_point'); - new SegmentPoint(handleIn, this, '_handleIn'); - new SegmentPoint(handleOut, this, '_handleOut'); - }, - - _serialize: function(options) { - return Base.serialize(this.hasHandles() - ? [this._point, this._handleIn, this._handleOut] - : this._point, - options, true); - }, - - _changed: function(point) { - var path = this._path; - if (!path) - return; - var curves = path._curves, - index = this._index, - curve; - if (curves) { - if ((!point || point === this._point || point === this._handleIn) - && (curve = index > 0 ? curves[index - 1] : path._closed - ? curves[curves.length - 1] : null)) - curve._changed(); - if ((!point || point === this._point || point === this._handleOut) - && (curve = curves[index])) - curve._changed(); - } - path._changed(25); - }, - - getPoint: function() { - return this._point; - }, - - setPoint: function() { - var point = Point.read(arguments); - this._point.set(point.x, point.y); - }, - - getHandleIn: function() { - return this._handleIn; - }, - - setHandleIn: function() { - var point = Point.read(arguments); - this._handleIn.set(point.x, point.y); - }, - - getHandleOut: function() { - return this._handleOut; - }, - - setHandleOut: function() { - var point = Point.read(arguments); - this._handleOut.set(point.x, point.y); - }, - - hasHandles: function() { - return !this._handleIn.isZero() || !this._handleOut.isZero(); - }, - - clearHandles: function() { - this._handleIn.set(0, 0); - this._handleOut.set(0, 0); - }, - - _selectionState: 0, - - isSelected: function(_point) { - var state = this._selectionState; - return !_point ? !!(state & 7) - : _point === this._point ? !!(state & 4) - : _point === this._handleIn ? !!(state & 1) - : _point === this._handleOut ? !!(state & 2) - : false; - }, - - setSelected: function(selected, _point) { - var path = this._path, - selected = !!selected, - state = this._selectionState, - oldState = state, - flag = !_point ? 7 - : _point === this._point ? 4 - : _point === this._handleIn ? 1 - : _point === this._handleOut ? 2 - : 0; - if (selected) { - state |= flag; - } else { - state &= ~flag; - } - this._selectionState = state; - if (path && state !== oldState) { - path._updateSelection(this, oldState, state); - path._changed(129); - } - }, - - getIndex: function() { - return this._index !== undefined ? this._index : null; - }, - - getPath: function() { - return this._path || null; - }, - - getCurve: function() { - var path = this._path, - index = this._index; - if (path) { - if (index > 0 && !path._closed - && index === path._segments.length - 1) - index--; - return path.getCurves()[index] || null; - } - return null; - }, - - getLocation: function() { - var curve = this.getCurve(); - return curve - ? new CurveLocation(curve, this === curve._segment1 ? 0 : 1) - : null; - }, - - getNext: function() { - var segments = this._path && this._path._segments; - return segments && (segments[this._index + 1] - || this._path._closed && segments[0]) || null; - }, - - getPrevious: function() { - var segments = this._path && this._path._segments; - return segments && (segments[this._index - 1] - || this._path._closed && segments[segments.length - 1]) || null; - }, - - isFirst: function() { - return this._index === 0; - }, - - isLast: function() { - var path = this._path; - return path && this._index === path._segments.length - 1 || false; - }, - - reverse: function() { - var handleIn = this._handleIn, - handleOut = this._handleOut, - inX = handleIn._x, - inY = handleIn._y; - handleIn.set(handleOut._x, handleOut._y); - handleOut.set(inX, inY); - }, - - reversed: function() { - return new Segment(this._point, this._handleOut, this._handleIn); - }, - - remove: function() { - return this._path ? !!this._path.removeSegment(this._index) : false; - }, - - clone: function() { - return new Segment(this._point, this._handleIn, this._handleOut); - }, - - equals: function(segment) { - return segment === this || segment && this._class === segment._class - && this._point.equals(segment._point) - && this._handleIn.equals(segment._handleIn) - && this._handleOut.equals(segment._handleOut) - || false; - }, - - toString: function() { - var parts = [ 'point: ' + this._point ]; - if (!this._handleIn.isZero()) - parts.push('handleIn: ' + this._handleIn); - if (!this._handleOut.isZero()) - parts.push('handleOut: ' + this._handleOut); - return '{ ' + parts.join(', ') + ' }'; - }, - - transform: function(matrix) { - this._transformCoordinates(matrix, new Array(6), true); - this._changed(); - }, - - _transformCoordinates: function(matrix, coords, change) { - var point = this._point, - handleIn = !change || !this._handleIn.isZero() - ? this._handleIn : null, - handleOut = !change || !this._handleOut.isZero() - ? this._handleOut : null, - x = point._x, - y = point._y, - i = 2; - coords[0] = x; - coords[1] = y; - if (handleIn) { - coords[i++] = handleIn._x + x; - coords[i++] = handleIn._y + y; - } - if (handleOut) { - coords[i++] = handleOut._x + x; - coords[i++] = handleOut._y + y; - } - if (matrix) { - matrix._transformCoordinates(coords, coords, i / 2); - x = coords[0]; - y = coords[1]; - if (change) { - point._x = x; - point._y = y; - i = 2; - if (handleIn) { - handleIn._x = coords[i++] - x; - handleIn._y = coords[i++] - y; - } - if (handleOut) { - handleOut._x = coords[i++] - x; - handleOut._y = coords[i++] - y; - } - } else { - if (!handleIn) { - coords[i++] = x; - coords[i++] = y; - } - if (!handleOut) { - coords[i++] = x; - coords[i++] = y; - } - } - } - return coords; - } -}); - -var SegmentPoint = Point.extend({ - initialize: function SegmentPoint(point, owner, key) { - var x, y, selected; - if (!point) { - x = y = 0; - } else if ((x = point[0]) !== undefined) { - y = point[1]; - } else { - var pt = point; - if ((x = pt.x) === undefined) { - pt = Point.read(arguments); - x = pt.x; - } - y = pt.y; - selected = pt.selected; - } - this._x = x; - this._y = y; - this._owner = owner; - owner[key] = this; - if (selected) - this.setSelected(true); - }, - - set: function(x, y) { - this._x = x; - this._y = y; - this._owner._changed(this); - return this; - }, - - _serialize: function(options) { - var f = options.formatter, - x = f.number(this._x), - y = f.number(this._y); - return this.isSelected() - ? { x: x, y: y, selected: true } - : [x, y]; - }, - - getX: function() { - return this._x; - }, - - setX: function(x) { - this._x = x; - this._owner._changed(this); - }, - - getY: function() { - return this._y; - }, - - setY: function(y) { - this._y = y; - this._owner._changed(this); - }, - - isZero: function() { - return Numerical.isZero(this._x) && Numerical.isZero(this._y); - }, - - setSelected: function(selected) { - this._owner.setSelected(selected, this); - }, - - isSelected: function() { - return this._owner.isSelected(this); - } -}); - -var Curve = Base.extend({ - _class: 'Curve', - - initialize: function Curve(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) { - var count = arguments.length, - seg1, seg2, - point1, point2, - handle1, handle2; - if (count === 3) { - this._path = arg0; - seg1 = arg1; - seg2 = arg2; - } else if (count === 0) { - seg1 = new Segment(); - seg2 = new Segment(); - } else if (count === 1) { - if ('segment1' in arg0) { - seg1 = new Segment(arg0.segment1); - seg2 = new Segment(arg0.segment2); - } else if ('point1' in arg0) { - point1 = arg0.point1; - handle1 = arg0.handle1; - handle2 = arg0.handle2; - point2 = arg0.point2; - } else if (Array.isArray(arg0)) { - point1 = [arg0[0], arg0[1]]; - point2 = [arg0[6], arg0[7]]; - handle1 = [arg0[2] - arg0[0], arg0[3] - arg0[1]]; - handle2 = [arg0[4] - arg0[6], arg0[5] - arg0[7]]; - } - } else if (count === 2) { - seg1 = new Segment(arg0); - seg2 = new Segment(arg1); - } else if (count === 4) { - point1 = arg0; - handle1 = arg1; - handle2 = arg2; - point2 = arg3; - } else if (count === 8) { - point1 = [arg0, arg1]; - point2 = [arg6, arg7]; - handle1 = [arg2 - arg0, arg3 - arg1]; - handle2 = [arg4 - arg6, arg5 - arg7]; - } - this._segment1 = seg1 || new Segment(point1, null, handle1); - this._segment2 = seg2 || new Segment(point2, handle2, null); - }, - - _serialize: function(options) { - return Base.serialize(this.hasHandles() - ? [this.getPoint1(), this.getHandle1(), this.getHandle2(), - this.getPoint2()] - : [this.getPoint1(), this.getPoint2()], - options, true); - }, - - _changed: function() { - this._length = this._bounds = undefined; - }, - - clone: function() { - return new Curve(this._segment1, this._segment2); - }, - - toString: function() { - var parts = [ 'point1: ' + this._segment1._point ]; - if (!this._segment1._handleOut.isZero()) - parts.push('handle1: ' + this._segment1._handleOut); - if (!this._segment2._handleIn.isZero()) - parts.push('handle2: ' + this._segment2._handleIn); - parts.push('point2: ' + this._segment2._point); - return '{ ' + parts.join(', ') + ' }'; - }, - - remove: function() { - var removed = false; - if (this._path) { - var segment2 = this._segment2, - handleOut = segment2._handleOut; - removed = segment2.remove(); - if (removed) - this._segment1._handleOut.set(handleOut.x, handleOut.y); - } - return removed; - }, - - getPoint1: function() { - return this._segment1._point; - }, - - setPoint1: function() { - var point = Point.read(arguments); - this._segment1._point.set(point.x, point.y); - }, - - getPoint2: function() { - return this._segment2._point; - }, - - setPoint2: function() { - var point = Point.read(arguments); - this._segment2._point.set(point.x, point.y); - }, - - getHandle1: function() { - return this._segment1._handleOut; - }, - - setHandle1: function() { - var point = Point.read(arguments); - this._segment1._handleOut.set(point.x, point.y); - }, - - getHandle2: function() { - return this._segment2._handleIn; - }, - - setHandle2: function() { - var point = Point.read(arguments); - this._segment2._handleIn.set(point.x, point.y); - }, - - getSegment1: function() { - return this._segment1; - }, - - getSegment2: function() { - return this._segment2; - }, - - getPath: function() { - return this._path; - }, - - getIndex: function() { - return this._segment1._index; - }, - - getNext: function() { - var curves = this._path && this._path._curves; - return curves && (curves[this._segment1._index + 1] - || this._path._closed && curves[0]) || null; - }, - - getPrevious: function() { - var curves = this._path && this._path._curves; - return curves && (curves[this._segment1._index - 1] - || this._path._closed && curves[curves.length - 1]) || null; - }, - - isFirst: function() { - return this._segment1._index === 0; - }, - - isLast: function() { - var path = this._path; - return path && this._segment1._index === path._curves.length - 1 - || false; - }, - - isSelected: function() { - return this.getPoint1().isSelected() - && this.getHandle2().isSelected() - && this.getHandle2().isSelected() - && this.getPoint2().isSelected(); - }, - - setSelected: function(selected) { - this.getPoint1().setSelected(selected); - this.getHandle1().setSelected(selected); - this.getHandle2().setSelected(selected); - this.getPoint2().setSelected(selected); - }, - - getValues: function(matrix) { - return Curve.getValues(this._segment1, this._segment2, matrix); - }, - - getPoints: function() { - var coords = this.getValues(), - points = []; - for (var i = 0; i < 8; i += 2) - points.push(new Point(coords[i], coords[i + 1])); - return points; - }, - - getLength: function() { - if (this._length == null) - this._length = Curve.getLength(this.getValues(), 0, 1); - return this._length; - }, - - getArea: function() { - return Curve.getArea(this.getValues()); - }, - - getLine: function() { - return new Line(this._segment1._point, this._segment2._point); - }, - - getPart: function(from, to) { - return new Curve(Curve.getPart(this.getValues(), from, to)); - }, - - getPartLength: function(from, to) { - return Curve.getLength(this.getValues(), from, to); - }, - - getIntersections: function(curve) { - return Curve._getIntersections(this.getValues(), - curve && curve !== this ? curve.getValues() : null, - this, curve, [], {}); - }, - - _getParameter: function(offset, isParameter) { - return isParameter - ? offset - : offset && offset.curve === this - ? offset.parameter - : offset === undefined && isParameter === undefined - ? 0.5 - : this.getParameterAt(offset, 0); - }, - - divide: function(offset, isParameter, _setHandles) { - var parameter = this._getParameter(offset, isParameter), - tMin = 4e-7, - tMax = 1 - tMin, - res = null; - if (parameter >= tMin && parameter <= tMax) { - var parts = Curve.subdivide(this.getValues(), parameter), - left = parts[0], - right = parts[1], - setHandles = _setHandles || this.hasHandles(), - segment1 = this._segment1, - segment2 = this._segment2, - path = this._path; - if (setHandles) { - segment1._handleOut.set(left[2] - left[0], - left[3] - left[1]); - segment2._handleIn.set(right[4] - right[6], - right[5] - right[7]); - } - var x = left[6], y = left[7], - segment = new Segment(new Point(x, y), - setHandles && new Point(left[4] - x, left[5] - y), - setHandles && new Point(right[2] - x, right[3] - y)); - if (path) { - path.insert(segment1._index + 1, segment); - res = this.getNext(); - } else { - this._segment2 = segment; - res = new Curve(segment, segment2); - } - } - return res; - }, - - split: function(offset, isParameter) { - return this._path - ? this._path.split(this._segment1._index, - this._getParameter(offset, isParameter)) - : null; - }, - - reversed: function() { - return new Curve(this._segment2.reversed(), this._segment1.reversed()); - }, - - clearHandles: function() { - this._segment1._handleOut.set(0, 0); - this._segment2._handleIn.set(0, 0); - }, - -statics: { - getValues: function(segment1, segment2, matrix) { - var p1 = segment1._point, - h1 = segment1._handleOut, - h2 = segment2._handleIn, - p2 = segment2._point, - values = [ - p1._x, p1._y, - p1._x + h1._x, p1._y + h1._y, - p2._x + h2._x, p2._y + h2._y, - p2._x, p2._y - ]; - if (matrix) - matrix._transformCoordinates(values, values, 4); - return values; - }, - - subdivide: function(v, t) { - var p1x = v[0], p1y = v[1], - c1x = v[2], c1y = v[3], - c2x = v[4], c2y = v[5], - p2x = v[6], p2y = v[7]; - if (t === undefined) - t = 0.5; - var u = 1 - t, - p3x = u * p1x + t * c1x, p3y = u * p1y + t * c1y, - p4x = u * c1x + t * c2x, p4y = u * c1y + t * c2y, - p5x = u * c2x + t * p2x, p5y = u * c2y + t * p2y, - p6x = u * p3x + t * p4x, p6y = u * p3y + t * p4y, - p7x = u * p4x + t * p5x, p7y = u * p4y + t * p5y, - p8x = u * p6x + t * p7x, p8y = u * p6y + t * p7y; - return [ - [p1x, p1y, p3x, p3y, p6x, p6y, p8x, p8y], - [p8x, p8y, p7x, p7y, p5x, p5y, p2x, p2y] - ]; - }, - - solveCubic: function (v, coord, val, roots, min, max) { - var p1 = v[coord], - c1 = v[coord + 2], - c2 = v[coord + 4], - p2 = v[coord + 6], - c = 3 * (c1 - p1), - b = 3 * (c2 - c1) - c, - a = p2 - p1 - c - b; - return Numerical.solveCubic(a, b, c, p1 - val, roots, min, max); - }, - - getParameterOf: function(v, point) { - var p1 = new Point(v[0], v[1]), - p2 = new Point(v[6], v[7]), - epsilon = 1e-12, - t = point.isClose(p1, epsilon) ? 0 - : point.isClose(p2, epsilon) ? 1 - : null; - if (t !== null) - return t; - var coords = [point.x, point.y], - roots = [], - geomEpsilon = 2e-7; - for (var c = 0; c < 2; c++) { - var count = Curve.solveCubic(v, c, coords[c], roots, 0, 1); - for (var i = 0; i < count; i++) { - t = roots[i]; - if (point.isClose(Curve.getPoint(v, t), geomEpsilon)) - return t; - } - } - return point.isClose(p1, geomEpsilon) ? 0 - : point.isClose(p2, geomEpsilon) ? 1 - : null; - }, - - getNearestParameter: function(v, point) { - if (Curve.isStraight(v)) { - var p1x = v[0], p1y = v[1], - p2x = v[6], p2y = v[7], - vx = p2x - p1x, vy = p2y - p1y, - det = vx * vx + vy * vy; - if (det === 0) - return 0; - var u = ((point.x - p1x) * vx + (point.y - p1y) * vy) / det; - return u < 1e-12 ? 0 - : u > 0.999999999999 ? 1 - : Curve.getParameterOf(v, - new Point(p1x + u * vx, p1y + u * vy)); - } - - var count = 100, - minDist = Infinity, - minT = 0; - - function refine(t) { - if (t >= 0 && t <= 1) { - var dist = point.getDistance(Curve.getPoint(v, t), true); - if (dist < minDist) { - minDist = dist; - minT = t; - return true; - } - } - } - - for (var i = 0; i <= count; i++) - refine(i / count); - - var step = 1 / (count * 2); - while (step > 4e-7) { - if (!refine(minT - step) && !refine(minT + step)) - step /= 2; - } - return minT; - }, - - getPart: function(v, from, to) { - var flip = from > to; - if (flip) { - var tmp = from; - from = to; - to = tmp; - } - if (from > 0) - v = Curve.subdivide(v, from)[1]; - if (to < 1) - v = Curve.subdivide(v, (to - from) / (1 - from))[0]; - return flip - ? [v[6], v[7], v[4], v[5], v[2], v[3], v[0], v[1]] - : v; - }, - - hasHandles: function(v) { - var isZero = Numerical.isZero; - return !(isZero(v[0] - v[2]) && isZero(v[1] - v[3]) - && isZero(v[4] - v[6]) && isZero(v[5] - v[7])); - }, - - isFlatEnough: function(v, tolerance) { - var p1x = v[0], p1y = v[1], - c1x = v[2], c1y = v[3], - c2x = v[4], c2y = v[5], - p2x = v[6], p2y = v[7], - ux = 3 * c1x - 2 * p1x - p2x, - uy = 3 * c1y - 2 * p1y - p2y, - vx = 3 * c2x - 2 * p2x - p1x, - vy = 3 * c2y - 2 * p2y - p1y; - return Math.max(ux * ux, vx * vx) + Math.max(uy * uy, vy * vy) - < 10 * tolerance * tolerance; - }, - - getArea: function(v) { - var p1x = v[0], p1y = v[1], - p2x = v[6], p2y = v[7], - h1x = (v[2] + p1x) / 2, - h1y = (v[3] + p1y) / 2, - h2x = (v[4] + v[6]) / 2, - h2y = (v[5] + v[7]) / 2; - return 6 * ((p1x - h1x) * (h1y + p1y) - + (h1x - h2x) * (h2y + h1y) - + (h2x - p2x) * (p2y + h2y)) / 10; - }, - - getBounds: function(v) { - var min = v.slice(0, 2), - max = min.slice(), - roots = [0, 0]; - for (var i = 0; i < 2; i++) - Curve._addBounds(v[i], v[i + 2], v[i + 4], v[i + 6], - i, 0, min, max, roots); - return new Rectangle(min[0], min[1], max[0] - min[0], max[1] - min[1]); - }, - - _addBounds: function(v0, v1, v2, v3, coord, padding, min, max, roots) { - function add(value, padding) { - var left = value - padding, - right = value + padding; - if (left < min[coord]) - min[coord] = left; - if (right > max[coord]) - max[coord] = right; - } - var a = 3 * (v1 - v2) - v0 + v3, - b = 2 * (v0 + v2) - 4 * v1, - c = v1 - v0, - count = Numerical.solveQuadratic(a, b, c, roots), - tMin = 4e-7, - tMax = 1 - tMin; - add(v3, 0); - for (var i = 0; i < count; i++) { - var t = roots[i], - u = 1 - t; - if (tMin < t && t < tMax) - add(u * u * u * v0 - + 3 * u * u * t * v1 - + 3 * u * t * t * v2 - + t * t * t * v3, - padding); - } - } -}}, Base.each( - ['getBounds', 'getStrokeBounds', 'getHandleBounds', 'getRoughBounds'], - function(name) { - this[name] = function() { - if (!this._bounds) - this._bounds = {}; - var bounds = this._bounds[name]; - if (!bounds) { - var path = this._path; - bounds = this._bounds[name] = Path[name]( - [this._segment1, this._segment2], false, - path && path.getStyle()); - } - return bounds.clone(); - }; - }, -{ - -}), Base.each({ - isStraight: function(l, h1, h2) { - if (h1.isZero() && h2.isZero()) { - return true; - } else if (l.isZero()) { - return false; - } else if (h1.isCollinear(l) && h2.isCollinear(l)) { - var div = l.dot(l), - p1 = l.dot(h1) / div, - p2 = l.dot(h2) / div; - return p1 >= 0 && p1 <= 1 && p2 <= 0 && p2 >= -1; - } - return false; - }, - - isLinear: function(l, h1, h2) { - var third = l.divide(3); - return h1.equals(third) && h2.negate().equals(third); - } -}, function(test, name) { - this[name] = function() { - var seg1 = this._segment1, - seg2 = this._segment2; - return test(seg2._point.subtract(seg1._point), - seg1._handleOut, seg2._handleIn); - }; - - this.statics[name] = function(v) { - var p1x = v[0], p1y = v[1], - p2x = v[6], p2y = v[7]; - return test(new Point(p2x - p1x, p2y - p1y), - new Point(v[2] - p1x, v[3] - p1y), - new Point(v[4] - p2x, v[5] - p2y)); - }; -}, { - statics: {}, - - hasHandles: function() { - return !this._segment1._handleOut.isZero() - || !this._segment2._handleIn.isZero(); - }, - - isCollinear: function(curve) { - return curve && this.isStraight() && curve.isStraight() - && this.getLine().isCollinear(curve.getLine()); - }, - - isHorizontal: function() { - return this.isStraight() && Math.abs(this.getTangentAt(0.5, true).y) - < 1e-7; - }, - - isVertical: function() { - return this.isStraight() && Math.abs(this.getTangentAt(0.5, true).x) - < 1e-7; - } -}), { - beans: false, - - getParameterAt: function(offset, start) { - return Curve.getParameterAt(this.getValues(), offset, start); - }, - - getParameterOf: function() { - return Curve.getParameterOf(this.getValues(), Point.read(arguments)); - }, - - getLocationAt: function(offset, isParameter) { - var t = isParameter ? offset : this.getParameterAt(offset); - return t != null && t >= 0 && t <= 1 - ? new CurveLocation(this, t) - : null; - }, - - getLocationOf: function() { - return this.getLocationAt(this.getParameterOf(Point.read(arguments)), - true); - }, - - getOffsetOf: function() { - var loc = this.getLocationOf.apply(this, arguments); - return loc ? loc.getOffset() : null; - }, - - getNearestLocation: function() { - var point = Point.read(arguments), - values = this.getValues(), - t = Curve.getNearestParameter(values, point), - pt = Curve.getPoint(values, t); - return new CurveLocation(this, t, pt, null, point.getDistance(pt)); - }, - - getNearestPoint: function() { - return this.getNearestLocation.apply(this, arguments).getPoint(); - } - -}, -new function() { - var methods = ['getPoint', 'getTangent', 'getNormal', 'getWeightedTangent', - 'getWeightedNormal', 'getCurvature']; - return Base.each(methods, - function(name) { - this[name + 'At'] = function(offset, isParameter) { - var values = this.getValues(); - return Curve[name](values, isParameter ? offset - : Curve.getParameterAt(values, offset, 0)); - }; - }, { - statics: { - evaluateMethods: methods - } - }) -}, -new function() { - - function getLengthIntegrand(v) { - var p1x = v[0], p1y = v[1], - c1x = v[2], c1y = v[3], - c2x = v[4], c2y = v[5], - p2x = v[6], p2y = v[7], - - ax = 9 * (c1x - c2x) + 3 * (p2x - p1x), - bx = 6 * (p1x + c2x) - 12 * c1x, - cx = 3 * (c1x - p1x), - - ay = 9 * (c1y - c2y) + 3 * (p2y - p1y), - by = 6 * (p1y + c2y) - 12 * c1y, - cy = 3 * (c1y - p1y); - - return function(t) { - var dx = (ax * t + bx) * t + cx, - dy = (ay * t + by) * t + cy; - return Math.sqrt(dx * dx + dy * dy); - }; - } - - function getIterations(a, b) { - return Math.max(2, Math.min(16, Math.ceil(Math.abs(b - a) * 32))); - } - - function evaluate(v, t, type, normalized) { - if (t == null || t < 0 || t > 1) - return null; - var p1x = v[0], p1y = v[1], - c1x = v[2], c1y = v[3], - c2x = v[4], c2y = v[5], - p2x = v[6], p2y = v[7], - tMin = 4e-7, - tMax = 1 - tMin, - x, y; - - if (type === 0 && (t < tMin || t > tMax)) { - var isZero = t < tMin; - x = isZero ? p1x : p2x; - y = isZero ? p1y : p2y; - } else { - var cx = 3 * (c1x - p1x), - bx = 3 * (c2x - c1x) - cx, - ax = p2x - p1x - cx - bx, - - cy = 3 * (c1y - p1y), - by = 3 * (c2y - c1y) - cy, - ay = p2y - p1y - cy - by; - if (type === 0) { - x = ((ax * t + bx) * t + cx) * t + p1x; - y = ((ay * t + by) * t + cy) * t + p1y; - } else { - if (t < tMin) { - x = cx; - y = cy; - } else if (t > tMax) { - x = 3 * (p2x - c2x); - y = 3 * (p2y - c2y); - } else { - x = (3 * ax * t + 2 * bx) * t + cx; - y = (3 * ay * t + 2 * by) * t + cy; - } - if (normalized) { - if (x === 0 && y === 0 && (t < tMin || t > tMax)) { - x = c2x - c1x; - y = c2y - c1y; - } - var len = Math.sqrt(x * x + y * y); - if (len) { - x /= len; - y /= len; - } - } - if (type === 3) { - var x2 = 6 * ax * t + 2 * bx, - y2 = 6 * ay * t + 2 * by, - d = Math.pow(x * x + y * y, 3 / 2); - x = d !== 0 ? (x * y2 - y * x2) / d : 0; - y = 0; - } - } - } - return type === 2 ? new Point(y, -x) : new Point(x, y); - } - - return { statics: { - - getLength: function(v, a, b) { - if (a === undefined) - a = 0; - if (b === undefined) - b = 1; - if (a === 0 && b === 1 && Curve.isStraight(v)) { - var dx = v[6] - v[0], - dy = v[7] - v[1]; - return Math.sqrt(dx * dx + dy * dy); - } - var ds = getLengthIntegrand(v); - return Numerical.integrate(ds, a, b, getIterations(a, b)); - }, - - getParameterAt: function(v, offset, start) { - if (start === undefined) - start = offset < 0 ? 1 : 0 - if (offset === 0) - return start; - var abs = Math.abs, - forward = offset > 0, - a = forward ? start : 0, - b = forward ? 1 : start, - ds = getLengthIntegrand(v), - rangeLength = Numerical.integrate(ds, a, b, - getIterations(a, b)); - if (abs(offset - rangeLength) < 1e-12) { - return forward ? b : a; - } else if (abs(offset) > rangeLength) { - return null; - } - var guess = offset / rangeLength, - length = 0; - function f(t) { - length += Numerical.integrate(ds, start, t, - getIterations(start, t)); - start = t; - return length - offset; - } - return Numerical.findRoot(f, ds, start + guess, a, b, 32, - 1e-12); - }, - - getPoint: function(v, t) { - return evaluate(v, t, 0, false); - }, - - getTangent: function(v, t) { - return evaluate(v, t, 1, true); - }, - - getWeightedTangent: function(v, t) { - return evaluate(v, t, 1, false); - }, - - getNormal: function(v, t) { - return evaluate(v, t, 2, true); - }, - - getWeightedNormal: function(v, t) { - return evaluate(v, t, 2, false); - }, - - getCurvature: function(v, t) { - return evaluate(v, t, 3, false).x; - } - }}; -}, -new function() { - - function addLocation(locations, param, v1, c1, t1, p1, v2, c2, t2, p2, - overlap) { - var startConnected = param.startConnected, - endConnected = param.endConnected, - tMin = 4e-7, - tMax = 1 - tMin; - if (t1 == null) - t1 = Curve.getParameterOf(v1, p1); - if (t1 !== null && t1 >= (startConnected ? tMin : 0) && - t1 <= (endConnected ? tMax : 1)) { - if (t2 == null) - t2 = Curve.getParameterOf(v2, p2); - if (t2 !== null && t2 >= (endConnected ? tMin : 0) && - t2 <= (startConnected ? tMax : 1)) { - var renormalize = param.renormalize; - if (renormalize) { - var res = renormalize(t1, t2); - t1 = res[0]; - t2 = res[1]; - } - var loc1 = new CurveLocation(c1, t1, - p1 || Curve.getPoint(v1, t1), overlap), - loc2 = new CurveLocation(c2, t2, - p2 || Curve.getPoint(v2, t2), overlap), - flip = loc1.getPath() === loc2.getPath() - && loc1.getIndex() > loc2.getIndex(), - loc = flip ? loc2 : loc1, - include = param.include; - loc1._intersection = loc2; - loc2._intersection = loc1; - if (!include || include(loc)) { - CurveLocation.insert(locations, loc, true); - } - } - } - } - - function addCurveIntersections(v1, v2, c1, c2, locations, param, - tMin, tMax, uMin, uMax, oldTDiff, reverse, recursion) { - if (++recursion >= 24) - return; - var q0x = v2[0], q0y = v2[1], q3x = v2[6], q3y = v2[7], - getSignedDistance = Line.getSignedDistance, - d1 = getSignedDistance(q0x, q0y, q3x, q3y, v2[2], v2[3]), - d2 = getSignedDistance(q0x, q0y, q3x, q3y, v2[4], v2[5]), - factor = d1 * d2 > 0 ? 3 / 4 : 4 / 9, - dMin = factor * Math.min(0, d1, d2), - dMax = factor * Math.max(0, d1, d2), - dp0 = getSignedDistance(q0x, q0y, q3x, q3y, v1[0], v1[1]), - dp1 = getSignedDistance(q0x, q0y, q3x, q3y, v1[2], v1[3]), - dp2 = getSignedDistance(q0x, q0y, q3x, q3y, v1[4], v1[5]), - dp3 = getSignedDistance(q0x, q0y, q3x, q3y, v1[6], v1[7]), - hull = getConvexHull(dp0, dp1, dp2, dp3), - top = hull[0], - bottom = hull[1], - tMinClip, - tMaxClip; - if ((tMinClip = clipConvexHull(top, bottom, dMin, dMax)) == null || - (tMaxClip = clipConvexHull(top.reverse(), bottom.reverse(), - dMin, dMax)) == null) - return; - v1 = Curve.getPart(v1, tMinClip, tMaxClip); - var tDiff = tMaxClip - tMinClip, - tMinNew = tMin + (tMax - tMin) * tMinClip, - tMaxNew = tMin + (tMax - tMin) * tMaxClip; - if (oldTDiff > 0.5 && tDiff > 0.5) { - if (tMaxNew - tMinNew > uMax - uMin) { - var parts = Curve.subdivide(v1, 0.5), - t = tMinNew + (tMaxNew - tMinNew) / 2; - addCurveIntersections( - v2, parts[0], c2, c1, locations, param, - uMin, uMax, tMinNew, t, tDiff, !reverse, recursion); - addCurveIntersections( - v2, parts[1], c2, c1, locations, param, - uMin, uMax, t, tMaxNew, tDiff, !reverse, recursion); - } else { - var parts = Curve.subdivide(v2, 0.5), - t = uMin + (uMax - uMin) / 2; - addCurveIntersections( - parts[0], v1, c2, c1, locations, param, - uMin, t, tMinNew, tMaxNew, tDiff, !reverse, recursion); - addCurveIntersections( - parts[1], v1, c2, c1, locations, param, - t, uMax, tMinNew, tMaxNew, tDiff, !reverse, recursion); - } - } else if (Math.max(uMax - uMin, tMaxNew - tMinNew) - < 1e-7) { - var t1 = tMinNew + (tMaxNew - tMinNew) / 2, - t2 = uMin + (uMax - uMin) / 2; - v1 = c1.getValues(); - v2 = c2.getValues(); - addLocation(locations, param, - reverse ? v2 : v1, reverse ? c2 : c1, reverse ? t2 : t1, null, - reverse ? v1 : v2, reverse ? c1 : c2, reverse ? t1 : t2, null); - } else if (tDiff > 1e-12) { - addCurveIntersections(v2, v1, c2, c1, locations, param, - uMin, uMax, tMinNew, tMaxNew, tDiff, !reverse, recursion); - } - } - - function getConvexHull(dq0, dq1, dq2, dq3) { - var p0 = [ 0, dq0 ], - p1 = [ 1 / 3, dq1 ], - p2 = [ 2 / 3, dq2 ], - p3 = [ 1, dq3 ], - dist1 = dq1 - (2 * dq0 + dq3) / 3, - dist2 = dq2 - (dq0 + 2 * dq3) / 3, - hull; - if (dist1 * dist2 < 0) { - hull = [[p0, p1, p3], [p0, p2, p3]]; - } else { - var distRatio = dist1 / dist2; - hull = [ - distRatio >= 2 ? [p0, p1, p3] - : distRatio <= .5 ? [p0, p2, p3] - : [p0, p1, p2, p3], - [p0, p3] - ]; - } - return (dist1 || dist2) < 0 ? hull.reverse() : hull; - } - - function clipConvexHull(hullTop, hullBottom, dMin, dMax) { - if (hullTop[0][1] < dMin) { - return clipConvexHullPart(hullTop, true, dMin); - } else if (hullBottom[0][1] > dMax) { - return clipConvexHullPart(hullBottom, false, dMax); - } else { - return hullTop[0][0]; - } - } - - function clipConvexHullPart(part, top, threshold) { - var px = part[0][0], - py = part[0][1]; - for (var i = 1, l = part.length; i < l; i++) { - var qx = part[i][0], - qy = part[i][1]; - if (top ? qy >= threshold : qy <= threshold) { - return qy === threshold ? qx - : px + (threshold - py) * (qx - px) / (qy - py); - } - px = qx; - py = qy; - } - return null; - } - - function addCurveLineIntersections(v1, v2, c1, c2, locations, param) { - var flip = Curve.isStraight(v1), - vc = flip ? v2 : v1, - vl = flip ? v1 : v2, - lx1 = vl[0], ly1 = vl[1], - lx2 = vl[6], ly2 = vl[7], - ldx = lx2 - lx1, - ldy = ly2 - ly1, - angle = Math.atan2(-ldy, ldx), - sin = Math.sin(angle), - cos = Math.cos(angle), - rvc = []; - for(var i = 0; i < 8; i += 2) { - var x = vc[i] - lx1, - y = vc[i + 1] - ly1; - rvc.push( - x * cos - y * sin, - x * sin + y * cos); - } - var roots = [], - count = Curve.solveCubic(rvc, 1, 0, roots, 0, 1); - for (var i = 0; i < count; i++) { - var tc = roots[i], - pc = Curve.getPoint(vc, tc), - tl = Curve.getParameterOf(vl, pc); - if (tl !== null) { - var pl = Curve.getPoint(vl, tl), - t1 = flip ? tl : tc, - t2 = flip ? tc : tl; - if (!param.endConnected || t2 > Numerical.CURVETIME_EPSILON) { - addLocation(locations, param, - v1, c1, t1, flip ? pl : pc, - v2, c2, t2, flip ? pc : pl); - } - } - } - } - - function addLineIntersection(v1, v2, c1, c2, locations, param) { - var pt = Line.intersect( - v1[0], v1[1], v1[6], v1[7], - v2[0], v2[1], v2[6], v2[7]); - if (pt) { - addLocation(locations, param, v1, c1, null, pt, v2, c2, null, pt); - } - } - - return { statics: { - _getIntersections: function(v1, v2, c1, c2, locations, param) { - if (!v2) { - return Curve._getSelfIntersection(v1, c1, locations, param); - } - var c1p1x = v1[0], c1p1y = v1[1], - c1p2x = v1[6], c1p2y = v1[7], - c2p1x = v2[0], c2p1y = v2[1], - c2p2x = v2[6], c2p2y = v2[7], - c1s1x = (3 * v1[2] + c1p1x) / 4, - c1s1y = (3 * v1[3] + c1p1y) / 4, - c1s2x = (3 * v1[4] + c1p2x) / 4, - c1s2y = (3 * v1[5] + c1p2y) / 4, - c2s1x = (3 * v2[2] + c2p1x) / 4, - c2s1y = (3 * v2[3] + c2p1y) / 4, - c2s2x = (3 * v2[4] + c2p2x) / 4, - c2s2y = (3 * v2[5] + c2p2y) / 4, - min = Math.min, - max = Math.max; - if (!( max(c1p1x, c1s1x, c1s2x, c1p2x) >= - min(c2p1x, c2s1x, c2s2x, c2p2x) && - min(c1p1x, c1s1x, c1s2x, c1p2x) <= - max(c2p1x, c2s1x, c2s2x, c2p2x) && - max(c1p1y, c1s1y, c1s2y, c1p2y) >= - min(c2p1y, c2s1y, c2s2y, c2p2y) && - min(c1p1y, c1s1y, c1s2y, c1p2y) <= - max(c2p1y, c2s1y, c2s2y, c2p2y))) - return locations; - if (!param.startConnected && !param.endConnected) { - var overlaps = Curve.getOverlaps(v1, v2); - if (overlaps) { - for (var i = 0; i < 2; i++) { - var overlap = overlaps[i]; - addLocation(locations, param, - v1, c1, overlap[0], null, - v2, c2, overlap[1], null, true); - } - return locations; - } - } - - var straight1 = Curve.isStraight(v1), - straight2 = Curve.isStraight(v2), - straight = straight1 && straight2, - epsilon = 1e-12, - before = locations.length; - (straight - ? addLineIntersection - : straight1 || straight2 - ? addCurveLineIntersections - : addCurveIntersections)( - v1, v2, c1, c2, locations, param, - 0, 1, 0, 1, 0, false, 0); - if (straight && locations.length > before) - return locations; - var c1p1 = new Point(c1p1x, c1p1y), - c1p2 = new Point(c1p2x, c1p2y), - c2p1 = new Point(c2p1x, c2p1y), - c2p2 = new Point(c2p2x, c2p2y); - if (c1p1.isClose(c2p1, epsilon)) - addLocation(locations, param, v1, c1, 0, c1p1, v2, c2, 0, c2p1); - if (!param.startConnected && c1p1.isClose(c2p2, epsilon)) - addLocation(locations, param, v1, c1, 0, c1p1, v2, c2, 1, c2p2); - if (!param.endConnected && c1p2.isClose(c2p1, epsilon)) - addLocation(locations, param, v1, c1, 1, c1p2, v2, c2, 0, c2p1); - if (c1p2.isClose(c2p2, epsilon)) - addLocation(locations, param, v1, c1, 1, c1p2, v2, c2, 1, c2p2); - return locations; - }, - - _getSelfIntersection: function(v1, c1, locations, param) { - var p1x = v1[0], p1y = v1[1], - h1x = v1[2], h1y = v1[3], - h2x = v1[4], h2y = v1[5], - p2x = v1[6], p2y = v1[7]; - var line = new Line(p1x, p1y, p2x, p2y, false), - side1 = line.getSide(new Point(h1x, h1y), true), - side2 = line.getSide(new Point(h2x, h2y), true); - if (side1 === side2) { - var edgeSum = (p1x - h2x) * (h1y - p2y) - + (h1x - p2x) * (h2y - p1y); - if (edgeSum * side1 > 0) - return locations; - } - var ax = p2x - 3 * h2x + 3 * h1x - p1x, - bx = h2x - 2 * h1x + p1x, - cx = h1x - p1x, - ay = p2y - 3 * h2y + 3 * h1y - p1y, - by = h2y - 2 * h1y + p1y, - cy = h1y - p1y, - ac = ay * cx - ax * cy, - ab = ay * bx - ax * by, - bc = by * cx - bx * cy; - if (ac * ac - 4 * ab * bc < 0) { - var roots = [], - tSplit, - count = Numerical.solveCubic( - ax * ax + ay * ay, - 3 * (ax * bx + ay * by), - 2 * (bx * bx + by * by) + ax * cx + ay * cy, - bx * cx + by * cy, - roots, 0, 1); - if (count > 0) { - for (var i = 0, maxCurvature = 0; i < count; i++) { - var curvature = Math.abs( - c1.getCurvatureAt(roots[i], true)); - if (curvature > maxCurvature) { - maxCurvature = curvature; - tSplit = roots[i]; - } - } - var parts = Curve.subdivide(v1, tSplit); - param.endConnected = true; - param.renormalize = function(t1, t2) { - return [t1 * tSplit, t2 * (1 - tSplit) + tSplit]; - }; - Curve._getIntersections(parts[0], parts[1], c1, c1, - locations, param); - } - } - return locations; - }, - - getOverlaps: function(v1, v2) { - var abs = Math.abs, - timeEpsilon = 4e-7, - geomEpsilon = 2e-7, - straight1 = Curve.isStraight(v1), - straight2 = Curve.isStraight(v2), - straight = straight1 && straight2; - - function getLineLengthSquared(v) { - var x = v[6] - v[0], - y = v[7] - v[1]; - return x * x + y * y; - } - - if (straight) { - var flip = getLineLengthSquared(v1) < getLineLengthSquared(v2), - l1 = flip ? v2 : v1, - l2 = flip ? v1 : v2, - line = new Line(l1[0], l1[1], l1[6], l1[7]); - if (line.getDistance(new Point(l2[0], l2[1])) > geomEpsilon || - line.getDistance(new Point(l2[6], l2[7])) > geomEpsilon) - return null; - } else if (straight1 ^ straight2) { - return null; - } - - var v = [v1, v2], - pairs = []; - for (var i = 0, t1 = 0; - i < 2 && pairs.length < 2; - i += t1 === 0 ? 0 : 1, t1 = t1 ^ 1) { - var t2 = Curve.getParameterOf(v[i ^ 1], new Point( - v[i][t1 === 0 ? 0 : 6], - v[i][t1 === 0 ? 1 : 7])); - if (t2 != null) { - var pair = i === 0 ? [t1, t2] : [t2, t1]; - if (pairs.length === 0 || - abs(pair[0] - pairs[0][0]) > timeEpsilon && - abs(pair[1] - pairs[0][1]) > timeEpsilon) - pairs.push(pair); - } - if (i === 1 && pairs.length === 0) - break; - } - if (pairs.length !== 2) { - pairs = null; - } else if (!straight) { - var o1 = Curve.getPart(v1, pairs[0][0], pairs[1][0]), - o2 = Curve.getPart(v2, pairs[0][1], pairs[1][1]); - if (abs(o2[2] - o1[2]) > geomEpsilon || - abs(o2[3] - o1[3]) > geomEpsilon || - abs(o2[4] - o1[4]) > geomEpsilon || - abs(o2[5] - o1[5]) > geomEpsilon) - pairs = null; - } - return pairs; - } - }}; -}); - -var CurveLocation = Base.extend({ - _class: 'CurveLocation', - beans: true, - - initialize: function CurveLocation(curve, parameter, point, - _overlap, _distance) { - if (parameter > 0.9999996) { - var next = curve.getNext(); - if (next) { - parameter = 0; - curve = next; - } - } - this._id = UID.get(CurveLocation); - this._setCurve(curve); - this._parameter = parameter; - this._point = point || curve.getPointAt(parameter, true); - this._overlap = _overlap; - this._distance = _distance; - this._intersection = this._next = this._prev = null; - }, - - _setCurve: function(curve) { - var path = curve._path; - this._version = path ? path._version : 0; - this._curve = curve; - this._segment = null; - this._segment1 = curve._segment1; - this._segment2 = curve._segment2; - }, - - _setSegment: function(segment) { - this._setCurve(segment.getCurve()); - this._segment = segment; - this._parameter = segment === this._segment1 ? 0 : 1; - this._point = segment._point.clone(); - }, - - getSegment: function() { - var curve = this.getCurve(), - segment = this._segment; - if (!segment) { - var parameter = this.getParameter(); - if (parameter === 0) { - segment = curve._segment1; - } else if (parameter === 1) { - segment = curve._segment2; - } else if (parameter != null) { - segment = curve.getPartLength(0, parameter) - < curve.getPartLength(parameter, 1) - ? curve._segment1 - : curve._segment2; - } - this._segment = segment; - } - return segment; - }, - - getCurve: function() { - var curve = this._curve, - path = curve && curve._path, - that = this; - if (path && path._version !== this._version) { - curve = this._parameter = this._curve = this._offset = null; - } - - function trySegment(segment) { - var curve = segment && segment.getCurve(); - if (curve && (that._parameter = curve.getParameterOf(that._point)) - != null) { - that._setCurve(curve); - that._segment = segment; - return curve; - } - } - - return curve - || trySegment(this._segment) - || trySegment(this._segment1) - || trySegment(this._segment2.getPrevious()); - }, - - getPath: function() { - var curve = this.getCurve(); - return curve && curve._path; - }, - - getIndex: function() { - var curve = this.getCurve(); - return curve && curve.getIndex(); - }, - - getParameter: function() { - var curve = this.getCurve(), - parameter = this._parameter; - return curve && parameter == null - ? this._parameter = curve.getParameterOf(this._point) - : parameter; - }, - - getPoint: function() { - return this._point; - }, - - getOffset: function() { - var offset = this._offset; - if (offset == null) { - offset = 0; - var path = this.getPath(), - index = this.getIndex(); - if (path && index != null) { - var curves = path.getCurves(); - for (var i = 0; i < index; i++) - offset += curves[i].getLength(); - } - this._offset = offset += this.getCurveOffset(); - } - return offset; - }, - - getCurveOffset: function() { - var curve = this.getCurve(), - parameter = this.getParameter(); - return parameter != null && curve && curve.getPartLength(0, parameter); - }, - - getIntersection: function() { - return this._intersection; - }, - - getDistance: function() { - return this._distance; - }, - - divide: function() { - var curve = this.getCurve(), - res = null; - if (curve) { - res = curve.divide(this.getParameter(), true); - if (res) - this._setSegment(res._segment1); - } - return res; - }, - - split: function() { - var curve = this.getCurve(); - return curve ? curve.split(this.getParameter(), true) : null; - }, - - equals: function(loc, _ignoreOther) { - var res = this === loc, - epsilon = 2e-7; - if (!res && loc instanceof CurveLocation - && this.getPath() === loc.getPath() - && this.getPoint().isClose(loc.getPoint(), epsilon)) { - var c1 = this.getCurve(), - c2 = loc.getCurve(), - abs = Math.abs, - diff = abs( - ((c1.isLast() && c2.isFirst() ? -1 : c1.getIndex()) - + this.getParameter()) - - ((c2.isLast() && c1.isFirst() ? -1 : c2.getIndex()) - + loc.getParameter())); - res = (diff < 4e-7 - || ((diff = abs(this.getOffset() - loc.getOffset())) < epsilon - || abs(this.getPath().getLength() - diff) < epsilon)) - && (_ignoreOther - || (!this._intersection && !loc._intersection - || this._intersection && this._intersection.equals( - loc._intersection, true))); - } - return res; - }, - - toString: function() { - var parts = [], - point = this.getPoint(), - f = Formatter.instance; - if (point) - parts.push('point: ' + point); - var index = this.getIndex(); - if (index != null) - parts.push('index: ' + index); - var parameter = this.getParameter(); - if (parameter != null) - parts.push('parameter: ' + f.number(parameter)); - if (this._distance != null) - parts.push('distance: ' + f.number(this._distance)); - return '{ ' + parts.join(', ') + ' }'; - }, - - isTouching: function() { - var inter = this._intersection; - if (inter && this.getTangent().isCollinear(inter.getTangent())) { - var curve1 = this.getCurve(), - curve2 = inter.getCurve(); - return !(curve1.isStraight() && curve2.isStraight() - && curve1.getLine().intersect(curve2.getLine())); - } - return false; - }, - - isCrossing: function() { - var inter = this._intersection; - if (!inter) - return false; - var t1 = this.getParameter(), - t2 = inter.getParameter(), - tMin = 4e-7, - tMax = 1 - tMin; - if (t1 >= tMin && t1 <= tMax || t2 >= tMin && t2 <= tMax) - return !this.isTouching(); - var c2 = this.getCurve(), - c1 = c2.getPrevious(), - c4 = inter.getCurve(), - c3 = c4.getPrevious(), - PI = Math.PI; - if (!c1 || !c3) - return false; - - function isInRange(angle, min, max) { - return min < max - ? angle > min && angle < max - : angle > min && angle <= PI || angle >= -PI && angle < max; - } - - var a1 = c1.getTangentAt(tMax, true).negate().getAngleInRadians(), - a2 = c2.getTangentAt(tMin, true).getAngleInRadians(), - a3 = c3.getTangentAt(tMax, true).negate().getAngleInRadians(), - a4 = c4.getTangentAt(tMin, true).getAngleInRadians(); - - return (isInRange(a3, a1, a2) ^ isInRange(a4, a1, a2)) - && (isInRange(a3, a2, a1) ^ isInRange(a4, a2, a1)); - }, - - isOverlap: function() { - return !!this._overlap; - } -}, Base.each(Curve.evaluateMethods, function(name) { - var get = name + 'At'; - this[name] = function() { - var parameter = this.getParameter(), - curve = this.getCurve(); - return parameter != null && curve && curve[get](parameter, true); - }; -}, { - preserve: true -}), -new function() { - - function insert(locations, loc, merge) { - var length = locations.length, - l = 0, - r = length - 1; - - function search(index, dir) { - for (var i = index + dir; i >= -1 && i <= length; i += dir) { - var loc2 = locations[((i % length) + length) % length]; - if (!loc.getPoint().isClose(loc2.getPoint(), - 2e-7)) - break; - if (loc.equals(loc2)) - return loc2; - } - return null; - } - - while (l <= r) { - var m = (l + r) >>> 1, - loc2 = locations[m], - found; - if (merge && (found = loc.equals(loc2) ? loc2 - : (search(m, -1) || search(m, 1)))) { - if (loc._overlap) { - found._overlap = found._intersection._overlap = true; - } - return found; - } - var path1 = loc.getPath(), - path2 = loc2.getPath(), - diff = path1 === path2 - ? (loc.getIndex() + loc.getParameter()) - - (loc2.getIndex() + loc2.getParameter()) - : path1._id - path2._id; - if (diff < 0) { - r = m - 1; - } else { - l = m + 1; - } - } - locations.splice(l, 0, loc); - return loc; - } - - return { statics: { - insert: insert, - - expand: function(locations) { - var expanded = locations.slice(); - for (var i = 0, l = locations.length; i < l; i++) { - insert(expanded, locations[i]._intersection, false); - } - return expanded; - } - }}; -}); - -var PathItem = Item.extend({ - _class: 'PathItem', - - initialize: function PathItem() { - }, - - getIntersections: function(path, include, _matrix, _returnFirst) { - var self = this === path || !path, - matrix1 = this._matrix.orNullIfIdentity(), - matrix2 = self ? matrix1 - : (_matrix || path._matrix).orNullIfIdentity(); - if (!self && !this.getBounds(matrix1).touches(path.getBounds(matrix2))) - return []; - var curves1 = this.getCurves(), - curves2 = self ? curves1 : path.getCurves(), - length1 = curves1.length, - length2 = self ? length1 : curves2.length, - values2 = [], - arrays = [], - locations, - path; - for (var i = 0; i < length2; i++) - values2[i] = curves2[i].getValues(matrix2); - for (var i = 0; i < length1; i++) { - var curve1 = curves1[i], - values1 = self ? values2[i] : curve1.getValues(matrix1), - path1 = curve1.getPath(); - if (path1 !== path) { - path = path1; - locations = []; - arrays.push(locations); - } - if (self) { - Curve._getSelfIntersection(values1, curve1, locations, { - include: include, - startConnected: length1 === 1 && - curve1.getPoint1().equals(curve1.getPoint2()) - }); - } - for (var j = self ? i + 1 : 0; j < length2; j++) { - if (_returnFirst && locations.length) - return locations; - var curve2 = curves2[j]; - Curve._getIntersections( - values1, values2[j], curve1, curve2, locations, - { - include: include, - startConnected: self && curve1.getPrevious() === curve2, - endConnected: self && curve1.getNext() === curve2 - } - ); - } - } - locations = []; - for (var i = 0, l = arrays.length; i < l; i++) { - locations.push.apply(locations, arrays[i]); - } - return locations; - }, - - getCrossings: function(path) { - return this.getIntersections(path, function(inter) { - return inter.isCrossing(); - }); - }, - - _asPathItem: function() { - return this; - }, - - setPathData: function(data) { - - var parts = data.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig), - coords, - relative = false, - previous, - control, - current = new Point(), - start = new Point(); - - function getCoord(index, coord) { - var val = +coords[index]; - if (relative) - val += current[coord]; - return val; - } - - function getPoint(index) { - return new Point( - getCoord(index, 'x'), - getCoord(index + 1, 'y') - ); - } - - this.clear(); - - for (var i = 0, l = parts && parts.length; i < l; i++) { - var part = parts[i], - command = part[0], - lower = command.toLowerCase(); - coords = part.match(/[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g); - var length = coords && coords.length; - relative = command === lower; - if (previous === 'z' && !/[mz]/.test(lower)) - this.moveTo(current = start); - switch (lower) { - case 'm': - case 'l': - var move = lower === 'm'; - for (var j = 0; j < length; j += 2) - this[j === 0 && move ? 'moveTo' : 'lineTo']( - current = getPoint(j)); - control = current; - if (move) - start = current; - break; - case 'h': - case 'v': - var coord = lower === 'h' ? 'x' : 'y'; - for (var j = 0; j < length; j++) { - current[coord] = getCoord(j, coord); - this.lineTo(current); - } - control = current; - break; - case 'c': - for (var j = 0; j < length; j += 6) { - this.cubicCurveTo( - getPoint(j), - control = getPoint(j + 2), - current = getPoint(j + 4)); - } - break; - case 's': - for (var j = 0; j < length; j += 4) { - this.cubicCurveTo( - /[cs]/.test(previous) - ? current.multiply(2).subtract(control) - : current, - control = getPoint(j), - current = getPoint(j + 2)); - previous = lower; - } - break; - case 'q': - for (var j = 0; j < length; j += 4) { - this.quadraticCurveTo( - control = getPoint(j), - current = getPoint(j + 2)); - } - break; - case 't': - for (var j = 0; j < length; j += 2) { - this.quadraticCurveTo( - control = (/[qt]/.test(previous) - ? current.multiply(2).subtract(control) - : current), - current = getPoint(j)); - previous = lower; - } - break; - case 'a': - for (var j = 0; j < length; j += 7) { - this.arcTo(current = getPoint(j + 5), - new Size(+coords[j], +coords[j + 1]), - +coords[j + 2], +coords[j + 4], +coords[j + 3]); - } - break; - case 'z': - this.closePath(true); - break; - } - previous = lower; - } - }, - - _canComposite: function() { - return !(this.hasFill() && this.hasStroke()); - }, - - _contains: function(point) { - var winding = this._getWinding(point, false, true); - return !!(this.getWindingRule() === 'evenodd' ? winding & 1 : winding); - } - -}); - -var Path = PathItem.extend({ - _class: 'Path', - _serializeFields: { - segments: [], - closed: false - }, - - initialize: function Path(arg) { - this._closed = false; - this._segments = []; - this._version = 0; - var segments = Array.isArray(arg) - ? typeof arg[0] === 'object' - ? arg - : arguments - : arg && (arg.size === undefined && (arg.x !== undefined - || arg.point !== undefined)) - ? arguments - : null; - if (segments && segments.length > 0) { - this.setSegments(segments); - } else { - this._curves = undefined; - this._selectedSegmentState = 0; - if (!segments && typeof arg === 'string') { - this.setPathData(arg); - arg = null; - } - } - this._initialize(!segments && arg); - }, - - _equals: function(item) { - return this._closed === item._closed - && Base.equals(this._segments, item._segments); - }, - - clone: function(insert) { - var copy = new Path(Item.NO_INSERT); - copy.setSegments(this._segments); - copy._closed = this._closed; - if (this._clockwise !== undefined) - copy._clockwise = this._clockwise; - return this._clone(copy, insert); - }, - - _changed: function _changed(flags) { - _changed.base.call(this, flags); - if (flags & 8) { - var parent = this._parent; - if (parent) - parent._currentPath = undefined; - this._length = this._area = this._clockwise = this._monoCurves = - undefined; - if (flags & 16) { - this._version++; - } else if (this._curves) { - for (var i = 0, l = this._curves.length; i < l; i++) - this._curves[i]._changed(); - } - } else if (flags & 32) { - this._bounds = undefined; - } - }, - - getStyle: function() { - var parent = this._parent; - return (parent instanceof CompoundPath ? parent : this)._style; - }, - - getSegments: function() { - return this._segments; - }, - - setSegments: function(segments) { - var fullySelected = this.isFullySelected(); - this._segments.length = 0; - this._selectedSegmentState = 0; - this._curves = undefined; - if (segments && segments.length > 0) - this._add(Segment.readAll(segments)); - if (fullySelected) - this.setFullySelected(true); - }, - - getFirstSegment: function() { - return this._segments[0]; - }, - - getLastSegment: function() { - return this._segments[this._segments.length - 1]; - }, - - getCurves: function() { - var curves = this._curves, - segments = this._segments; - if (!curves) { - var length = this._countCurves(); - curves = this._curves = new Array(length); - for (var i = 0; i < length; i++) - curves[i] = new Curve(this, segments[i], - segments[i + 1] || segments[0]); - } - return curves; - }, - - getFirstCurve: function() { - return this.getCurves()[0]; - }, - - getLastCurve: function() { - var curves = this.getCurves(); - return curves[curves.length - 1]; - }, - - isClosed: function() { - return this._closed; - }, - - setClosed: function(closed) { - if (this._closed != (closed = !!closed)) { - this._closed = closed; - if (this._curves) { - var length = this._curves.length = this._countCurves(); - if (closed) - this._curves[length - 1] = new Curve(this, - this._segments[length - 1], this._segments[0]); - } - this._changed(25); - } - } -}, { - beans: true, - - getPathData: function(_matrix, _precision) { - var segments = this._segments, - length = segments.length, - f = new Formatter(_precision), - coords = new Array(6), - first = true, - curX, curY, - prevX, prevY, - inX, inY, - outX, outY, - parts = []; - - function addSegment(segment, skipLine) { - segment._transformCoordinates(_matrix, coords, false); - curX = coords[0]; - curY = coords[1]; - if (first) { - parts.push('M' + f.pair(curX, curY)); - first = false; - } else { - inX = coords[2]; - inY = coords[3]; - if (inX === curX && inY === curY - && outX === prevX && outY === prevY) { - if (!skipLine) - parts.push('l' + f.pair(curX - prevX, curY - prevY)); - } else { - parts.push('c' + f.pair(outX - prevX, outY - prevY) - + ' ' + f.pair(inX - prevX, inY - prevY) - + ' ' + f.pair(curX - prevX, curY - prevY)); - } - } - prevX = curX; - prevY = curY; - outX = coords[4]; - outY = coords[5]; - } - - if (length === 0) - return ''; - - for (var i = 0; i < length; i++) - addSegment(segments[i]); - if (this._closed && length > 0) { - addSegment(segments[0], true); - parts.push('z'); - } - return parts.join(''); - } -}, { - - isEmpty: function() { - return this._segments.length === 0; - }, - - _transformContent: function(matrix) { - var coords = new Array(6); - for (var i = 0, l = this._segments.length; i < l; i++) - this._segments[i]._transformCoordinates(matrix, coords, true); - return true; - }, - - _add: function(segs, index) { - var segments = this._segments, - curves = this._curves, - amount = segs.length, - append = index == null, - index = append ? segments.length : index; - for (var i = 0; i < amount; i++) { - var segment = segs[i]; - if (segment._path) - segment = segs[i] = segment.clone(); - segment._path = this; - segment._index = index + i; - if (segment._selectionState) - this._updateSelection(segment, 0, segment._selectionState); - } - if (append) { - segments.push.apply(segments, segs); - } else { - segments.splice.apply(segments, [index, 0].concat(segs)); - for (var i = index + amount, l = segments.length; i < l; i++) - segments[i]._index = i; - } - if (curves) { - var total = this._countCurves(), - from = index + amount - 1 === total ? index - 1 : index, - start = from, - to = Math.min(from + amount, total); - if (segs._curves) { - curves.splice.apply(curves, [from, 0].concat(segs._curves)); - start += segs._curves.length; - } - for (var i = start; i < to; i++) - curves.splice(i, 0, new Curve(this, null, null)); - this._adjustCurves(from, to); - } - this._changed(25); - return segs; - }, - - _adjustCurves: function(from, to) { - var segments = this._segments, - curves = this._curves, - curve; - for (var i = from; i < to; i++) { - curve = curves[i]; - curve._path = this; - curve._segment1 = segments[i]; - curve._segment2 = segments[i + 1] || segments[0]; - curve._changed(); - } - if (curve = curves[this._closed && from === 0 ? segments.length - 1 - : from - 1]) { - curve._segment2 = segments[from] || segments[0]; - curve._changed(); - } - if (curve = curves[to]) { - curve._segment1 = segments[to]; - curve._changed(); - } - }, - - _countCurves: function() { - var length = this._segments.length; - return !this._closed && length > 0 ? length - 1 : length; - }, - - add: function(segment1 ) { - return arguments.length > 1 && typeof segment1 !== 'number' - ? this._add(Segment.readAll(arguments)) - : this._add([ Segment.read(arguments) ])[0]; - }, - - insert: function(index, segment1 ) { - return arguments.length > 2 && typeof segment1 !== 'number' - ? this._add(Segment.readAll(arguments, 1), index) - : this._add([ Segment.read(arguments, 1) ], index)[0]; - }, - - addSegment: function() { - return this._add([ Segment.read(arguments) ])[0]; - }, - - insertSegment: function(index ) { - return this._add([ Segment.read(arguments, 1) ], index)[0]; - }, - - addSegments: function(segments) { - return this._add(Segment.readAll(segments)); - }, - - insertSegments: function(index, segments) { - return this._add(Segment.readAll(segments), index); - }, - - removeSegment: function(index) { - return this.removeSegments(index, index + 1)[0] || null; - }, - - removeSegments: function(from, to, _includeCurves) { - from = from || 0; - to = Base.pick(to, this._segments.length); - var segments = this._segments, - curves = this._curves, - count = segments.length, - removed = segments.splice(from, to - from), - amount = removed.length; - if (!amount) - return removed; - for (var i = 0; i < amount; i++) { - var segment = removed[i]; - if (segment._selectionState) - this._updateSelection(segment, segment._selectionState, 0); - segment._index = segment._path = null; - } - for (var i = from, l = segments.length; i < l; i++) - segments[i]._index = i; - if (curves) { - var index = from > 0 && to === count + (this._closed ? 1 : 0) - ? from - 1 - : from, - curves = curves.splice(index, amount); - if (_includeCurves) - removed._curves = curves.slice(1); - this._adjustCurves(index, index); - } - this._changed(25); - return removed; - }, - - clear: '#removeSegments', - - hasHandles: function() { - var segments = this._segments; - for (var i = 0, l = segments.length; i < l; i++) { - if (segments[i].hasHandles()) - return true; - } - return false; - }, - - clearHandles: function() { - var segments = this._segments; - for (var i = 0, l = segments.length; i < l; i++) - segments[i].clearHandles(); - }, - - getLength: function() { - if (this._length == null) { - var curves = this.getCurves(), - length = 0; - for (var i = 0, l = curves.length; i < l; i++) - length += curves[i].getLength(); - this._length = length; - } - return this._length; - }, - - getArea: function() { - if (this._area == null) { - var segments = this._segments, - count = segments.length, - last = count - 1, - area = 0; - for (var i = 0, l = this._closed ? count : last; i < l; i++) { - area += Curve.getArea(Curve.getValues( - segments[i], segments[i < last ? i + 1 : 0])); - } - this._area = area; - } - return this._area; - }, - - isClockwise: function() { - if (this._clockwise !== undefined) - return this._clockwise; - return this.getArea() >= 0; - }, - - setClockwise: function(clockwise) { - if (this.isClockwise() != (clockwise = !!clockwise)) - this.reverse(); - this._clockwise = clockwise; - }, - - isFullySelected: function() { - var length = this._segments.length; - return this._selected && length > 0 && this._selectedSegmentState - === length * 7; - }, - - setFullySelected: function(selected) { - if (selected) - this._selectSegments(true); - this.setSelected(selected); - }, - - setSelected: function setSelected(selected) { - if (!selected) - this._selectSegments(false); - setSelected.base.call(this, selected); - }, - - _selectSegments: function(selected) { - var length = this._segments.length; - this._selectedSegmentState = selected - ? length * 7 : 0; - for (var i = 0; i < length; i++) - this._segments[i]._selectionState = selected - ? 7 : 0; - }, - - _updateSelection: function(segment, oldState, newState) { - segment._selectionState = newState; - var total = this._selectedSegmentState += newState - oldState; - if (total > 0) - this.setSelected(true); - }, - - flatten: function(maxDistance) { - var iterator = new PathIterator(this, 64, 0.1), - pos = 0, - step = iterator.length / Math.ceil(iterator.length / maxDistance), - end = iterator.length + (this._closed ? -step : step) / 2; - var segments = []; - while (pos <= end) { - segments.push(new Segment(iterator.getPointAt(pos))); - pos += step; - } - this.setSegments(segments); - }, - - reduce: function() { - var curves = this.getCurves(); - for (var i = curves.length - 1; i >= 0; i--) { - var curve = curves[i]; - if (!curve.hasHandles() && (curve.getLength() === 0 - || curve.isCollinear(curve.getNext()))) - curve.remove(); - } - return this; - }, - - simplify: function(tolerance) { - if (this._segments.length > 2) { - var fitter = new PathFitter(this, tolerance || 2.5); - this.setSegments(fitter.fit()); - } - }, - - split: function(index, parameter) { - if (parameter === null) - return null; - if (arguments.length === 1) { - var arg = index; - if (typeof arg === 'number') - arg = this.getLocationAt(arg); - if (!arg) - return null - index = arg.index; - parameter = arg.parameter; - } - var tMin = 4e-7, - tMax = 1 - tMin; - if (parameter >= tMax) { - index++; - parameter--; - } - var curves = this.getCurves(); - if (index >= 0 && index < curves.length) { - if (parameter >= tMin) { - curves[index++].divide(parameter, true); - } - var segs = this.removeSegments(index, this._segments.length, true), - path; - if (this._closed) { - this.setClosed(false); - path = this; - } else { - path = new Path(Item.NO_INSERT); - path.insertAbove(this, true); - this._clone(path); - } - path._add(segs, 0); - this.addSegment(segs[0]); - return path; - } - return null; - }, - - reverse: function() { - this._segments.reverse(); - for (var i = 0, l = this._segments.length; i < l; i++) { - var segment = this._segments[i]; - var handleIn = segment._handleIn; - segment._handleIn = segment._handleOut; - segment._handleOut = handleIn; - segment._index = i; - } - this._curves = null; - if (this._clockwise !== undefined) - this._clockwise = !this._clockwise; - this._changed(9); - }, - - join: function(path) { - if (path) { - var segments = path._segments, - last1 = this.getLastSegment(), - last2 = path.getLastSegment(); - if (!last2) - return this; - if (last1 && last1._point.equals(last2._point)) - path.reverse(); - var first2 = path.getFirstSegment(); - if (last1 && last1._point.equals(first2._point)) { - last1.setHandleOut(first2._handleOut); - this._add(segments.slice(1)); - } else { - var first1 = this.getFirstSegment(); - if (first1 && first1._point.equals(first2._point)) - path.reverse(); - last2 = path.getLastSegment(); - if (first1 && first1._point.equals(last2._point)) { - first1.setHandleIn(last2._handleIn); - this._add(segments.slice(0, segments.length - 1), 0); - } else { - this._add(segments.slice()); - } - } - if (path._closed) - this._add([segments[0]]); - path.remove(); - } - var first = this.getFirstSegment(), - last = this.getLastSegment(); - if (first !== last && first._point.equals(last._point)) { - first.setHandleIn(last._handleIn); - last.remove(); - this.setClosed(true); - } - return this; - }, - - toShape: function(insert) { - if (!this._closed) - return null; - - var segments = this._segments, - type, - size, - radius, - topCenter; - - function isCollinear(i, j) { - var seg1 = segments[i], - seg2 = seg1.getNext(), - seg3 = segments[j], - seg4 = seg3.getNext(); - return seg1._handleOut.isZero() && seg2._handleIn.isZero() - && seg3._handleOut.isZero() && seg4._handleIn.isZero() - && seg2._point.subtract(seg1._point).isCollinear( - seg4._point.subtract(seg3._point)); - } - - function isOrthogonal(i) { - var seg2 = segments[i], - seg1 = seg2.getPrevious(), - seg3 = seg2.getNext(); - return seg1._handleOut.isZero() && seg2._handleIn.isZero() - && seg2._handleOut.isZero() && seg3._handleIn.isZero() - && seg2._point.subtract(seg1._point).isOrthogonal( - seg3._point.subtract(seg2._point)); - } - - function isArc(i) { - var seg1 = segments[i], - seg2 = seg1.getNext(), - handle1 = seg1._handleOut, - handle2 = seg2._handleIn, - kappa = 0.5522847498307936; - if (handle1.isOrthogonal(handle2)) { - var pt1 = seg1._point, - pt2 = seg2._point, - corner = new Line(pt1, handle1, true).intersect( - new Line(pt2, handle2, true), true); - return corner && Numerical.isZero(handle1.getLength() / - corner.subtract(pt1).getLength() - kappa) - && Numerical.isZero(handle2.getLength() / - corner.subtract(pt2).getLength() - kappa); - } - return false; - } - - function getDistance(i, j) { - return segments[i]._point.getDistance(segments[j]._point); - } - - if (!this.hasHandles() && segments.length === 4 - && isCollinear(0, 2) && isCollinear(1, 3) && isOrthogonal(1)) { - type = Shape.Rectangle; - size = new Size(getDistance(0, 3), getDistance(0, 1)); - topCenter = segments[1]._point.add(segments[2]._point).divide(2); - } else if (segments.length === 8 && isArc(0) && isArc(2) && isArc(4) - && isArc(6) && isCollinear(1, 5) && isCollinear(3, 7)) { - type = Shape.Rectangle; - size = new Size(getDistance(1, 6), getDistance(0, 3)); - radius = size.subtract(new Size(getDistance(0, 7), - getDistance(1, 2))).divide(2); - topCenter = segments[3]._point.add(segments[4]._point).divide(2); - } else if (segments.length === 4 - && isArc(0) && isArc(1) && isArc(2) && isArc(3)) { - if (Numerical.isZero(getDistance(0, 2) - getDistance(1, 3))) { - type = Shape.Circle; - radius = getDistance(0, 2) / 2; - } else { - type = Shape.Ellipse; - radius = new Size(getDistance(2, 0) / 2, getDistance(3, 1) / 2); - } - topCenter = segments[1]._point; - } - - if (type) { - var center = this.getPosition(true), - shape = this._clone(new type({ - center: center, - size: size, - radius: radius, - insert: false - }), insert, false); - shape.rotate(topCenter.subtract(center).getAngle() + 90); - return shape; - } - return null; - }, - - _hitTestSelf: function(point, options) { - var that = this, - style = this.getStyle(), - segments = this._segments, - numSegments = segments.length, - closed = this._closed, - tolerancePadding = options._tolerancePadding, - strokePadding = tolerancePadding, - join, cap, miterLimit, - area, loc, res, - hitStroke = options.stroke && style.hasStroke(), - hitFill = options.fill && style.hasFill(), - hitCurves = options.curves, - radius = hitStroke - ? style.getStrokeWidth() / 2 - : hitFill && options.tolerance > 0 || hitCurves - ? 0 : null; - if (radius !== null) { - if (radius > 0) { - join = style.getStrokeJoin(); - cap = style.getStrokeCap(); - miterLimit = radius * style.getMiterLimit(); - strokePadding = tolerancePadding.add(new Point(radius, radius)); - } else { - join = cap = 'round'; - } - } - - function isCloseEnough(pt, padding) { - return point.subtract(pt).divide(padding).length <= 1; - } - - function checkSegmentPoint(seg, pt, name) { - if (!options.selected || pt.isSelected()) { - var anchor = seg._point; - if (pt !== anchor) - pt = pt.add(anchor); - if (isCloseEnough(pt, strokePadding)) { - return new HitResult(name, that, { - segment: seg, - point: pt - }); - } - } - } - - function checkSegmentPoints(seg, ends) { - return (ends || options.segments) - && checkSegmentPoint(seg, seg._point, 'segment') - || (!ends && options.handles) && ( - checkSegmentPoint(seg, seg._handleIn, 'handle-in') || - checkSegmentPoint(seg, seg._handleOut, 'handle-out')); - } - - function addToArea(point) { - area.add(point); - } - - function checkSegmentStroke(segment) { - if (join !== 'round' || cap !== 'round') { - area = new Path({ internal: true, closed: true }); - if (closed || segment._index > 0 - && segment._index < numSegments - 1) { - if (join !== 'round' && (segment._handleIn.isZero() - || segment._handleOut.isZero())) - Path._addBevelJoin(segment, join, radius, miterLimit, - addToArea, true); - } else if (cap !== 'round') { - Path._addSquareCap(segment, cap, radius, addToArea, true); - } - if (!area.isEmpty()) { - var loc; - return area.contains(point) - || (loc = area.getNearestLocation(point)) - && isCloseEnough(loc.getPoint(), tolerancePadding); - } - } - return isCloseEnough(segment._point, strokePadding); - } - - if (options.ends && !options.segments && !closed) { - if (res = checkSegmentPoints(segments[0], true) - || checkSegmentPoints(segments[numSegments - 1], true)) - return res; - } else if (options.segments || options.handles) { - for (var i = 0; i < numSegments; i++) - if (res = checkSegmentPoints(segments[i])) - return res; - } - if (radius !== null) { - loc = this.getNearestLocation(point); - if (loc) { - var parameter = loc.getParameter(); - if (parameter === 0 || parameter === 1 && numSegments > 1) { - if (!checkSegmentStroke(loc.getSegment())) - loc = null; - } else if (!isCloseEnough(loc.getPoint(), strokePadding)) { - loc = null; - } - } - if (!loc && join === 'miter' && numSegments > 1) { - for (var i = 0; i < numSegments; i++) { - var segment = segments[i]; - if (point.getDistance(segment._point) <= miterLimit - && checkSegmentStroke(segment)) { - loc = segment.getLocation(); - break; - } - } - } - } - return !loc && hitFill && this._contains(point) - || loc && !hitStroke && !hitCurves - ? new HitResult('fill', this) - : loc - ? new HitResult(hitStroke ? 'stroke' : 'curve', this, { - location: loc, - point: loc.getPoint() - }) - : null; - } - -}, Base.each(Curve.evaluateMethods, - function(name) { - this[name + 'At'] = function(offset, isParameter) { - var loc = this.getLocationAt(offset, isParameter); - return loc && loc[name](); - }; - }, -{ - beans: false, - - getLocationOf: function() { - var point = Point.read(arguments), - curves = this.getCurves(); - for (var i = 0, l = curves.length; i < l; i++) { - var loc = curves[i].getLocationOf(point); - if (loc) - return loc; - } - return null; - }, - - getOffsetOf: function() { - var loc = this.getLocationOf.apply(this, arguments); - return loc ? loc.getOffset() : null; - }, - - getLocationAt: function(offset, isParameter) { - var curves = this.getCurves(), - length = 0; - if (isParameter) { - var index = ~~offset, - curve = curves[index]; - return curve ? curve.getLocationAt(offset - index, true) : null; - } - for (var i = 0, l = curves.length; i < l; i++) { - var start = length, - curve = curves[i]; - length += curve.getLength(); - if (length > offset) { - return curve.getLocationAt(offset - start); - } - } - if (curves.length > 0 && offset <= this.getLength()) - return new CurveLocation(curves[curves.length - 1], 1); - return null; - }, - - getNearestLocation: function() { - var point = Point.read(arguments), - curves = this.getCurves(), - minDist = Infinity, - minLoc = null; - for (var i = 0, l = curves.length; i < l; i++) { - var loc = curves[i].getNearestLocation(point); - if (loc._distance < minDist) { - minDist = loc._distance; - minLoc = loc; - } - } - return minLoc; - }, - - getNearestPoint: function() { - return this.getNearestLocation.apply(this, arguments).getPoint(); - } -}), -new function() { - - function drawHandles(ctx, segments, matrix, size) { - var half = size / 2; - - function drawHandle(index) { - var hX = coords[index], - hY = coords[index + 1]; - if (pX != hX || pY != hY) { - ctx.beginPath(); - ctx.moveTo(pX, pY); - ctx.lineTo(hX, hY); - ctx.stroke(); - ctx.beginPath(); - ctx.arc(hX, hY, half, 0, Math.PI * 2, true); - ctx.fill(); - } - } - - var coords = new Array(6); - for (var i = 0, l = segments.length; i < l; i++) { - var segment = segments[i]; - segment._transformCoordinates(matrix, coords, false); - var state = segment._selectionState, - pX = coords[0], - pY = coords[1]; - if (state & 1) - drawHandle(2); - if (state & 2) - drawHandle(4); - ctx.fillRect(pX - half, pY - half, size, size); - if (!(state & 4)) { - var fillStyle = ctx.fillStyle; - ctx.fillStyle = '#ffffff'; - ctx.fillRect(pX - half + 1, pY - half + 1, size - 2, size - 2); - ctx.fillStyle = fillStyle; - } - } - } - - function drawSegments(ctx, path, matrix) { - var segments = path._segments, - length = segments.length, - coords = new Array(6), - first = true, - curX, curY, - prevX, prevY, - inX, inY, - outX, outY; - - function drawSegment(segment) { - if (matrix) { - segment._transformCoordinates(matrix, coords, false); - curX = coords[0]; - curY = coords[1]; - } else { - var point = segment._point; - curX = point._x; - curY = point._y; - } - if (first) { - ctx.moveTo(curX, curY); - first = false; - } else { - if (matrix) { - inX = coords[2]; - inY = coords[3]; - } else { - var handle = segment._handleIn; - inX = curX + handle._x; - inY = curY + handle._y; - } - if (inX === curX && inY === curY - && outX === prevX && outY === prevY) { - ctx.lineTo(curX, curY); - } else { - ctx.bezierCurveTo(outX, outY, inX, inY, curX, curY); - } - } - prevX = curX; - prevY = curY; - if (matrix) { - outX = coords[4]; - outY = coords[5]; - } else { - var handle = segment._handleOut; - outX = prevX + handle._x; - outY = prevY + handle._y; - } - } - - for (var i = 0; i < length; i++) - drawSegment(segments[i]); - if (path._closed && length > 0) - drawSegment(segments[0]); - } - - return { - _draw: function(ctx, param, strokeMatrix) { - var dontStart = param.dontStart, - dontPaint = param.dontFinish || param.clip, - style = this.getStyle(), - hasFill = style.hasFill(), - hasStroke = style.hasStroke(), - dashArray = style.getDashArray(), - dashLength = !paper.support.nativeDash && hasStroke - && dashArray && dashArray.length; - - if (!dontStart) - ctx.beginPath(); - - if (!dontStart && this._currentPath) { - ctx.currentPath = this._currentPath; - } else if (hasFill || hasStroke && !dashLength || dontPaint) { - drawSegments(ctx, this, strokeMatrix); - if (this._closed) - ctx.closePath(); - if (!dontStart) - this._currentPath = ctx.currentPath; - } - - function getOffset(i) { - return dashArray[((i % dashLength) + dashLength) % dashLength]; - } - - if (!dontPaint && (hasFill || hasStroke)) { - this._setStyles(ctx); - if (hasFill) { - ctx.fill(style.getWindingRule()); - ctx.shadowColor = 'rgba(0,0,0,0)'; - } - if (hasStroke) { - if (dashLength) { - if (!dontStart) - ctx.beginPath(); - var iterator = new PathIterator(this, 32, 0.25, - strokeMatrix), - length = iterator.length, - from = -style.getDashOffset(), to, - i = 0; - from = from % length; - while (from > 0) { - from -= getOffset(i--) + getOffset(i--); - } - while (from < length) { - to = from + getOffset(i++); - if (from > 0 || to > 0) - iterator.drawPart(ctx, - Math.max(from, 0), Math.max(to, 0)); - from = to + getOffset(i++); - } - } - ctx.stroke(); - } - } - }, - - _drawSelected: function(ctx, matrix) { - ctx.beginPath(); - drawSegments(ctx, this, matrix); - ctx.stroke(); - drawHandles(ctx, this._segments, matrix, paper.settings.handleSize); - } - }; -}, -new function() { - function getFirstControlPoints(rhs) { - var n = rhs.length, - x = [], - tmp = [], - b = 2; - x[0] = rhs[0] / b; - for (var i = 1; i < n; i++) { - tmp[i] = 1 / b; - b = (i < n - 1 ? 4 : 2) - tmp[i]; - x[i] = (rhs[i] - x[i - 1]) / b; - } - for (var i = 1; i < n; i++) { - x[n - i - 1] -= tmp[n - i] * x[n - i]; - } - return x; - } - - return { - smooth: function() { - var segments = this._segments, - size = segments.length, - closed = this._closed, - n = size, - overlap = 0; - if (size <= 2) - return; - if (closed) { - overlap = Math.min(size, 4); - n += Math.min(size, overlap) * 2; - } - var knots = []; - for (var i = 0; i < size; i++) - knots[i + overlap] = segments[i]._point; - if (closed) { - for (var i = 0; i < overlap; i++) { - knots[i] = segments[i + size - overlap]._point; - knots[i + size + overlap] = segments[i]._point; - } - } else { - n--; - } - var rhs = []; - - for (var i = 1; i < n - 1; i++) - rhs[i] = 4 * knots[i]._x + 2 * knots[i + 1]._x; - rhs[0] = knots[0]._x + 2 * knots[1]._x; - rhs[n - 1] = 3 * knots[n - 1]._x; - var x = getFirstControlPoints(rhs); - - for (var i = 1; i < n - 1; i++) - rhs[i] = 4 * knots[i]._y + 2 * knots[i + 1]._y; - rhs[0] = knots[0]._y + 2 * knots[1]._y; - rhs[n - 1] = 3 * knots[n - 1]._y; - var y = getFirstControlPoints(rhs); - - if (closed) { - for (var i = 0, j = size; i < overlap; i++, j++) { - var f1 = i / overlap, - f2 = 1 - f1, - ie = i + overlap, - je = j + overlap; - x[j] = x[i] * f1 + x[j] * f2; - y[j] = y[i] * f1 + y[j] * f2; - x[je] = x[ie] * f2 + x[je] * f1; - y[je] = y[ie] * f2 + y[je] * f1; - } - n--; - } - var handleIn = null; - for (var i = overlap; i <= n - overlap; i++) { - var segment = segments[i - overlap]; - if (handleIn) - segment.setHandleIn(handleIn.subtract(segment._point)); - if (i < n) { - segment.setHandleOut( - new Point(x[i], y[i]).subtract(segment._point)); - handleIn = i < n - 1 - ? new Point( - 2 * knots[i + 1]._x - x[i + 1], - 2 * knots[i + 1]._y - y[i + 1]) - : new Point( - (knots[n]._x + x[n - 1]) / 2, - (knots[n]._y + y[n - 1]) / 2); - } - } - if (closed && handleIn) { - var segment = this._segments[0]; - segment.setHandleIn(handleIn.subtract(segment._point)); - } - } - }; -}, -new function() { - function getCurrentSegment(that) { - var segments = that._segments; - if (segments.length === 0) - throw new Error('Use a moveTo() command first'); - return segments[segments.length - 1]; - } - - return { - moveTo: function() { - var segments = this._segments; - if (segments.length === 1) - this.removeSegment(0); - if (!segments.length) - this._add([ new Segment(Point.read(arguments)) ]); - }, - - moveBy: function() { - throw new Error('moveBy() is unsupported on Path items.'); - }, - - lineTo: function() { - this._add([ new Segment(Point.read(arguments)) ]); - }, - - cubicCurveTo: function() { - var handle1 = Point.read(arguments), - handle2 = Point.read(arguments), - to = Point.read(arguments), - current = getCurrentSegment(this); - current.setHandleOut(handle1.subtract(current._point)); - this._add([ new Segment(to, handle2.subtract(to)) ]); - }, - - quadraticCurveTo: function() { - var handle = Point.read(arguments), - to = Point.read(arguments), - current = getCurrentSegment(this)._point; - this.cubicCurveTo( - handle.add(current.subtract(handle).multiply(1 / 3)), - handle.add(to.subtract(handle).multiply(1 / 3)), - to - ); - }, - - curveTo: function() { - var through = Point.read(arguments), - to = Point.read(arguments), - t = Base.pick(Base.read(arguments), 0.5), - t1 = 1 - t, - current = getCurrentSegment(this)._point, - handle = through.subtract(current.multiply(t1 * t1)) - .subtract(to.multiply(t * t)).divide(2 * t * t1); - if (handle.isNaN()) - throw new Error( - 'Cannot put a curve through points with parameter = ' + t); - this.quadraticCurveTo(handle, to); - }, - - arcTo: function() { - var current = getCurrentSegment(this), - from = current._point, - to = Point.read(arguments), - through, - peek = Base.peek(arguments), - clockwise = Base.pick(peek, true), - center, extent, vector, matrix; - if (typeof clockwise === 'boolean') { - var middle = from.add(to).divide(2), - through = middle.add(middle.subtract(from).rotate( - clockwise ? -90 : 90)); - } else if (Base.remain(arguments) <= 2) { - through = to; - to = Point.read(arguments); - } else { - var radius = Size.read(arguments); - if (radius.isZero()) - return this.lineTo(to); - var rotation = Base.read(arguments), - clockwise = !!Base.read(arguments), - large = !!Base.read(arguments), - middle = from.add(to).divide(2), - pt = from.subtract(middle).rotate(-rotation), - x = pt.x, - y = pt.y, - abs = Math.abs, - rx = abs(radius.width), - ry = abs(radius.height), - rxSq = rx * rx, - rySq = ry * ry, - xSq = x * x, - ySq = y * y; - var factor = Math.sqrt(xSq / rxSq + ySq / rySq); - if (factor > 1) { - rx *= factor; - ry *= factor; - rxSq = rx * rx; - rySq = ry * ry; - } - factor = (rxSq * rySq - rxSq * ySq - rySq * xSq) / - (rxSq * ySq + rySq * xSq); - if (abs(factor) < 1e-12) - factor = 0; - if (factor < 0) - throw new Error( - 'Cannot create an arc with the given arguments'); - center = new Point(rx * y / ry, -ry * x / rx) - .multiply((large === clockwise ? -1 : 1) - * Math.sqrt(factor)) - .rotate(rotation).add(middle); - matrix = new Matrix().translate(center).rotate(rotation) - .scale(rx, ry); - vector = matrix._inverseTransform(from); - extent = vector.getDirectedAngle(matrix._inverseTransform(to)); - if (!clockwise && extent > 0) - extent -= 360; - else if (clockwise && extent < 0) - extent += 360; - } - if (through) { - var l1 = new Line(from.add(through).divide(2), - through.subtract(from).rotate(90), true), - l2 = new Line(through.add(to).divide(2), - to.subtract(through).rotate(90), true), - line = new Line(from, to), - throughSide = line.getSide(through); - center = l1.intersect(l2, true); - if (!center) { - if (!throughSide) - return this.lineTo(to); - throw new Error( - 'Cannot create an arc with the given arguments'); - } - vector = from.subtract(center); - extent = vector.getDirectedAngle(to.subtract(center)); - var centerSide = line.getSide(center); - if (centerSide === 0) { - extent = throughSide * Math.abs(extent); - } else if (throughSide === centerSide) { - extent += extent < 0 ? 360 : -360; - } - } - var ext = Math.abs(extent), - count = ext >= 360 ? 4 : Math.ceil(ext / 90), - inc = extent / count, - half = inc * Math.PI / 360, - z = 4 / 3 * Math.sin(half) / (1 + Math.cos(half)), - segments = []; - for (var i = 0; i <= count; i++) { - var pt = to, - out = null; - if (i < count) { - out = vector.rotate(90).multiply(z); - if (matrix) { - pt = matrix._transformPoint(vector); - out = matrix._transformPoint(vector.add(out)) - .subtract(pt); - } else { - pt = center.add(vector); - } - } - if (i === 0) { - current.setHandleOut(out); - } else { - var _in = vector.rotate(-90).multiply(z); - if (matrix) { - _in = matrix._transformPoint(vector.add(_in)) - .subtract(pt); - } - segments.push(new Segment(pt, _in, out)); - } - vector = vector.rotate(inc); - } - this._add(segments); - }, - - lineBy: function() { - var to = Point.read(arguments), - current = getCurrentSegment(this)._point; - this.lineTo(current.add(to)); - }, - - curveBy: function() { - var through = Point.read(arguments), - to = Point.read(arguments), - parameter = Base.read(arguments), - current = getCurrentSegment(this)._point; - this.curveTo(current.add(through), current.add(to), parameter); - }, - - cubicCurveBy: function() { - var handle1 = Point.read(arguments), - handle2 = Point.read(arguments), - to = Point.read(arguments), - current = getCurrentSegment(this)._point; - this.cubicCurveTo(current.add(handle1), current.add(handle2), - current.add(to)); - }, - - quadraticCurveBy: function() { - var handle = Point.read(arguments), - to = Point.read(arguments), - current = getCurrentSegment(this)._point; - this.quadraticCurveTo(current.add(handle), current.add(to)); - }, - - arcBy: function() { - var current = getCurrentSegment(this)._point, - point = current.add(Point.read(arguments)), - clockwise = Base.pick(Base.peek(arguments), true); - if (typeof clockwise === 'boolean') { - this.arcTo(point, clockwise); - } else { - this.arcTo(point, current.add(Point.read(arguments))); - } - }, - - closePath: function(join) { - this.setClosed(true); - if (join) - this.join(); - } - }; -}, { - - _getBounds: function(getter, matrix) { - return Path[getter](this._segments, this._closed, this.getStyle(), - matrix); - }, - -statics: { - getBounds: function(segments, closed, style, matrix, strokePadding) { - var first = segments[0]; - if (!first) - return new Rectangle(); - var coords = new Array(6), - prevCoords = first._transformCoordinates(matrix, new Array(6), false), - min = prevCoords.slice(0, 2), - max = min.slice(), - roots = new Array(2); - - function processSegment(segment) { - segment._transformCoordinates(matrix, coords, false); - for (var i = 0; i < 2; i++) { - Curve._addBounds( - prevCoords[i], - prevCoords[i + 4], - coords[i + 2], - coords[i], - i, strokePadding ? strokePadding[i] : 0, min, max, roots); - } - var tmp = prevCoords; - prevCoords = coords; - coords = tmp; - } - - for (var i = 1, l = segments.length; i < l; i++) - processSegment(segments[i]); - if (closed) - processSegment(first); - return new Rectangle(min[0], min[1], max[0] - min[0], max[1] - min[1]); - }, - - getStrokeBounds: function(segments, closed, style, matrix) { - if (!style.hasStroke()) - return Path.getBounds(segments, closed, style, matrix); - var length = segments.length - (closed ? 0 : 1), - radius = style.getStrokeWidth() / 2, - padding = Path._getPenPadding(radius, matrix), - bounds = Path.getBounds(segments, closed, style, matrix, padding), - join = style.getStrokeJoin(), - cap = style.getStrokeCap(), - miterLimit = radius * style.getMiterLimit(); - var joinBounds = new Rectangle(new Size(padding).multiply(2)); - - function add(point) { - bounds = bounds.include(matrix - ? matrix._transformPoint(point, point) : point); - } - - function addRound(segment) { - bounds = bounds.unite(joinBounds.setCenter(matrix - ? matrix._transformPoint(segment._point) : segment._point)); - } - - function addJoin(segment, join) { - var handleIn = segment._handleIn, - handleOut = segment._handleOut; - if (join === 'round' || !handleIn.isZero() && !handleOut.isZero() - && handleIn.isCollinear(handleOut)) { - addRound(segment); - } else { - Path._addBevelJoin(segment, join, radius, miterLimit, add); - } - } - - function addCap(segment, cap) { - if (cap === 'round') { - addRound(segment); - } else { - Path._addSquareCap(segment, cap, radius, add); - } - } - - for (var i = 1; i < length; i++) - addJoin(segments[i], join); - if (closed) { - addJoin(segments[0], join); - } else if (length > 0) { - addCap(segments[0], cap); - addCap(segments[segments.length - 1], cap); - } - return bounds; - }, - - _getPenPadding: function(radius, matrix) { - if (!matrix) - return [radius, radius]; - var mx = matrix.shiftless(), - hor = mx.transform(new Point(radius, 0)), - ver = mx.transform(new Point(0, radius)), - phi = hor.getAngleInRadians(), - a = hor.getLength(), - b = ver.getLength(); - var sin = Math.sin(phi), - cos = Math.cos(phi), - tan = Math.tan(phi), - tx = -Math.atan(b * tan / a), - ty = Math.atan(b / (tan * a)); - return [Math.abs(a * Math.cos(tx) * cos - b * Math.sin(tx) * sin), - Math.abs(b * Math.sin(ty) * cos + a * Math.cos(ty) * sin)]; - }, - - _addBevelJoin: function(segment, join, radius, miterLimit, addPoint, area) { - var curve2 = segment.getCurve(), - curve1 = curve2.getPrevious(), - point = curve2.getPointAt(0, true), - normal1 = curve1.getNormalAt(1, true), - normal2 = curve2.getNormalAt(0, true), - step = normal1.getDirectedAngle(normal2) < 0 ? -radius : radius; - normal1.setLength(step); - normal2.setLength(step); - if (area) { - addPoint(point); - addPoint(point.add(normal1)); - } - if (join === 'miter') { - var corner = new Line( - point.add(normal1), - new Point(-normal1.y, normal1.x), true - ).intersect(new Line( - point.add(normal2), - new Point(-normal2.y, normal2.x), true - ), true); - if (corner && point.getDistance(corner) <= miterLimit) { - addPoint(corner); - if (!area) - return; - } - } - if (!area) - addPoint(point.add(normal1)); - addPoint(point.add(normal2)); - }, - - _addSquareCap: function(segment, cap, radius, addPoint, area) { - var point = segment._point, - loc = segment.getLocation(), - normal = loc.getNormal().multiply(radius); - if (area) { - addPoint(point.subtract(normal)); - addPoint(point.add(normal)); - } - if (cap === 'square') - point = point.add(normal.rotate(loc.getParameter() === 0 ? -90 : 90)); - addPoint(point.add(normal)); - addPoint(point.subtract(normal)); - }, - - getHandleBounds: function(segments, closed, style, matrix, strokePadding, - joinPadding) { - var coords = new Array(6), - x1 = Infinity, - x2 = -x1, - y1 = x1, - y2 = x2; - for (var i = 0, l = segments.length; i < l; i++) { - var segment = segments[i]; - segment._transformCoordinates(matrix, coords, false); - for (var j = 0; j < 6; j += 2) { - var padding = j === 0 ? joinPadding : strokePadding, - paddingX = padding ? padding[0] : 0, - paddingY = padding ? padding[1] : 0, - x = coords[j], - y = coords[j + 1], - xn = x - paddingX, - xx = x + paddingX, - yn = y - paddingY, - yx = y + paddingY; - if (xn < x1) x1 = xn; - if (xx > x2) x2 = xx; - if (yn < y1) y1 = yn; - if (yx > y2) y2 = yx; - } - } - return new Rectangle(x1, y1, x2 - x1, y2 - y1); - }, - - getRoughBounds: function(segments, closed, style, matrix) { - var strokeRadius = style.hasStroke() ? style.getStrokeWidth() / 2 : 0, - joinRadius = strokeRadius; - if (strokeRadius > 0) { - if (style.getStrokeJoin() === 'miter') - joinRadius = strokeRadius * style.getMiterLimit(); - if (style.getStrokeCap() === 'square') - joinRadius = Math.max(joinRadius, strokeRadius * Math.sqrt(2)); - } - return Path.getHandleBounds(segments, closed, style, matrix, - Path._getPenPadding(strokeRadius, matrix), - Path._getPenPadding(joinRadius, matrix)); - } -}}); - -Path.inject({ statics: new function() { - - var kappa = 0.5522847498307936, - ellipseSegments = [ - new Segment([-1, 0], [0, kappa ], [0, -kappa]), - new Segment([0, -1], [-kappa, 0], [kappa, 0 ]), - new Segment([1, 0], [0, -kappa], [0, kappa ]), - new Segment([0, 1], [kappa, 0 ], [-kappa, 0]) - ]; - - function createPath(segments, closed, args) { - var props = Base.getNamed(args), - path = new Path(props && props.insert === false && Item.NO_INSERT); - path._add(segments); - path._closed = closed; - return path.set(props); - } - - function createEllipse(center, radius, args) { - var segments = new Array(4); - for (var i = 0; i < 4; i++) { - var segment = ellipseSegments[i]; - segments[i] = new Segment( - segment._point.multiply(radius).add(center), - segment._handleIn.multiply(radius), - segment._handleOut.multiply(radius) - ); - } - return createPath(segments, true, args); - } - - return { - Line: function() { - return createPath([ - new Segment(Point.readNamed(arguments, 'from')), - new Segment(Point.readNamed(arguments, 'to')) - ], false, arguments); - }, - - Circle: function() { - var center = Point.readNamed(arguments, 'center'), - radius = Base.readNamed(arguments, 'radius'); - return createEllipse(center, new Size(radius), arguments); - }, - - Rectangle: function() { - var rect = Rectangle.readNamed(arguments, 'rectangle'), - radius = Size.readNamed(arguments, 'radius', 0, - { readNull: true }), - bl = rect.getBottomLeft(true), - tl = rect.getTopLeft(true), - tr = rect.getTopRight(true), - br = rect.getBottomRight(true), - segments; - if (!radius || radius.isZero()) { - segments = [ - new Segment(bl), - new Segment(tl), - new Segment(tr), - new Segment(br) - ]; - } else { - radius = Size.min(radius, rect.getSize(true).divide(2)); - var rx = radius.width, - ry = radius.height, - hx = rx * kappa, - hy = ry * kappa; - segments = [ - new Segment(bl.add(rx, 0), null, [-hx, 0]), - new Segment(bl.subtract(0, ry), [0, hy]), - new Segment(tl.add(0, ry), null, [0, -hy]), - new Segment(tl.add(rx, 0), [-hx, 0], null), - new Segment(tr.subtract(rx, 0), null, [hx, 0]), - new Segment(tr.add(0, ry), [0, -hy], null), - new Segment(br.subtract(0, ry), null, [0, hy]), - new Segment(br.subtract(rx, 0), [hx, 0]) - ]; - } - return createPath(segments, true, arguments); - }, - - RoundRectangle: '#Rectangle', - - Ellipse: function() { - var ellipse = Shape._readEllipse(arguments); - return createEllipse(ellipse.center, ellipse.radius, arguments); - }, - - Oval: '#Ellipse', - - Arc: function() { - var from = Point.readNamed(arguments, 'from'), - through = Point.readNamed(arguments, 'through'), - to = Point.readNamed(arguments, 'to'), - props = Base.getNamed(arguments), - path = new Path(props && props.insert === false - && Item.NO_INSERT); - path.moveTo(from); - path.arcTo(through, to); - return path.set(props); - }, - - RegularPolygon: function() { - var center = Point.readNamed(arguments, 'center'), - sides = Base.readNamed(arguments, 'sides'), - radius = Base.readNamed(arguments, 'radius'), - step = 360 / sides, - three = !(sides % 3), - vector = new Point(0, three ? -radius : radius), - offset = three ? -1 : 0.5, - segments = new Array(sides); - for (var i = 0; i < sides; i++) - segments[i] = new Segment(center.add( - vector.rotate((i + offset) * step))); - return createPath(segments, true, arguments); - }, - - Star: function() { - var center = Point.readNamed(arguments, 'center'), - points = Base.readNamed(arguments, 'points') * 2, - radius1 = Base.readNamed(arguments, 'radius1'), - radius2 = Base.readNamed(arguments, 'radius2'), - step = 360 / points, - vector = new Point(0, -1), - segments = new Array(points); - for (var i = 0; i < points; i++) - segments[i] = new Segment(center.add(vector.rotate(step * i) - .multiply(i % 2 ? radius2 : radius1))); - return createPath(segments, true, arguments); - } - }; -}}); - -var CompoundPath = PathItem.extend({ - _class: 'CompoundPath', - _serializeFields: { - children: [] - }, - - initialize: function CompoundPath(arg) { - this._children = []; - this._namedChildren = {}; - if (!this._initialize(arg)) { - if (typeof arg === 'string') { - this.setPathData(arg); - } else { - this.addChildren(Array.isArray(arg) ? arg : arguments); - } - } - }, - - insertChildren: function insertChildren(index, items, _preserve) { - for (var i = items.length - 1; i >= 0; i--) { - var item = items[i]; - if (item instanceof CompoundPath) { - items.splice.apply(items, [i, 1].concat(item.removeChildren())); - item.remove(); - } - } - items = insertChildren.base.call(this, index, items, _preserve, Path); - for (var i = 0, l = !_preserve && items && items.length; i < l; i++) { - var item = items[i]; - if (item._clockwise === undefined) - item.setClockwise(item._index === 0); - } - return items; - }, - - reverse: function() { - var children = this._children; - for (var i = 0, l = children.length; i < l; i++) - children[i].reverse(); - }, - - smooth: function() { - for (var i = 0, l = this._children.length; i < l; i++) - this._children[i].smooth(); - }, - - reduce: function reduce() { - var children = this._children; - for (var i = children.length - 1; i >= 0; i--) { - var path = children[i].reduce(); - if (path.isEmpty()) - children.splice(i, 1); - } - if (children.length === 0) { - var path = new Path(Item.NO_INSERT); - path.insertAbove(this); - path.setStyle(this._style); - this.remove(); - return path; - } - return reduce.base.call(this); - }, - - isClockwise: function() { - var child = this.getFirstChild(); - return child && child.isClockwise(); - }, - - setClockwise: function(clockwise) { - if (this.isClockwise() !== !!clockwise) - this.reverse(); - }, - - getFirstSegment: function() { - var first = this.getFirstChild(); - return first && first.getFirstSegment(); - }, - - getLastSegment: function() { - var last = this.getLastChild(); - return last && last.getLastSegment(); - }, - - getCurves: function() { - var children = this._children, - curves = []; - for (var i = 0, l = children.length; i < l; i++) - curves.push.apply(curves, children[i].getCurves()); - return curves; - }, - - getFirstCurve: function() { - var first = this.getFirstChild(); - return first && first.getFirstCurve(); - }, - - getLastCurve: function() { - var last = this.getLastChild(); - return last && last.getFirstCurve(); - }, - - getArea: function() { - var children = this._children, - area = 0; - for (var i = 0, l = children.length; i < l; i++) - area += children[i].getArea(); - return area; - } -}, { - beans: true, - - getPathData: function(_matrix, _precision) { - var children = this._children, - paths = []; - for (var i = 0, l = children.length; i < l; i++) { - var child = children[i], - mx = child._matrix; - paths.push(child.getPathData(_matrix && !mx.isIdentity() - ? _matrix.chain(mx) : _matrix, _precision)); - } - return paths.join(' '); - } -}, { - _getChildHitTestOptions: function(options) { - return options.class === Path || options.type === 'path' - ? options - : new Base(options, { fill: false }); - }, - - _draw: function(ctx, param, strokeMatrix) { - var children = this._children; - if (children.length === 0) - return; - - if (this._currentPath) { - ctx.currentPath = this._currentPath; - } else { - param = param.extend({ dontStart: true, dontFinish: true }); - ctx.beginPath(); - for (var i = 0, l = children.length; i < l; i++) - children[i].draw(ctx, param, strokeMatrix); - this._currentPath = ctx.currentPath; - } - - if (!param.clip) { - this._setStyles(ctx); - var style = this._style; - if (style.hasFill()) { - ctx.fill(style.getWindingRule()); - ctx.shadowColor = 'rgba(0,0,0,0)'; - } - if (style.hasStroke()) - ctx.stroke(); - } - }, - - _drawSelected: function(ctx, matrix, selectedItems) { - var children = this._children; - for (var i = 0, l = children.length; i < l; i++) { - var child = children[i], - mx = child._matrix; - if (!selectedItems[child._id]) - child._drawSelected(ctx, mx.isIdentity() ? matrix - : matrix.chain(mx)); - } - } -}, -new function() { - function getCurrentPath(that, check) { - var children = that._children; - if (check && children.length === 0) - throw new Error('Use a moveTo() command first'); - return children[children.length - 1]; - } - - var fields = { - moveTo: function() { - var current = getCurrentPath(this), - path = current && current.isEmpty() ? current - : new Path(Item.NO_INSERT); - if (path !== current) - this.addChild(path); - path.moveTo.apply(path, arguments); - }, - - moveBy: function() { - var current = getCurrentPath(this, true), - last = current && current.getLastSegment(), - point = Point.read(arguments); - this.moveTo(last ? point.add(last._point) : point); - }, - - closePath: function(join) { - getCurrentPath(this, true).closePath(join); - } - }; - - Base.each(['lineTo', 'cubicCurveTo', 'quadraticCurveTo', 'curveTo', 'arcTo', - 'lineBy', 'cubicCurveBy', 'quadraticCurveBy', 'curveBy', 'arcBy'], - function(key) { - fields[key] = function() { - var path = getCurrentPath(this, true); - path[key].apply(path, arguments); - }; - } - ); - - return fields; -}); - -PathItem.inject(new function() { - var operators = { - unite: function(w) { - return w === 1 || w === 0; - }, - - intersect: function(w) { - return w === 2; - }, - - subtract: function(w) { - return w === 1; - }, - - exclude: function(w) { - return w === 1; - } - }; - - function preparePath(path, resolve) { - var res = path.clone(false).reduce().transform(null, true, true); - return resolve ? res.resolveCrossings().reorient() : res; - } - - function finishBoolean(ctor, paths, path1, path2, reduce) { - var result = new ctor(Item.NO_INSERT); - result.addChildren(paths, true); - if (reduce) - result = result.reduce(); - result.insertAbove(path2 && path1.isSibling(path2) - && path1.getIndex() < path2.getIndex() - ? path2 : path1); - result.setStyle(path1._style); - return result; - } - - function computeBoolean(path1, path2, operation) { - if (!path1._children && !path1._closed) - return computeOpenBoolean(path1, path2, operation); - var _path1 = preparePath(path1, true), - _path2 = path2 && path1 !== path2 && preparePath(path2, true); - if (_path2 && /^(subtract|exclude)$/.test(operation) - ^ (_path2.isClockwise() !== _path1.isClockwise())) - _path2.reverse(); - var intersections = CurveLocation.expand( - _path1.getIntersections(_path2, function(inter) { - return _path2 && inter.isOverlap() || inter.isCrossing(); - }) - ); - divideLocations(intersections); - - var segments = [], - monoCurves = []; - - function collect(paths) { - for (var i = 0, l = paths.length; i < l; i++) { - var path = paths[i]; - segments.push.apply(segments, path._segments); - monoCurves.push.apply(monoCurves, path._getMonoCurves()); - } - } - - collect(_path1._children || [_path1]); - if (_path2) - collect(_path2._children || [_path2]); - for (var i = 0, l = intersections.length; i < l; i++) { - propagateWinding(intersections[i]._segment, _path1, _path2, - monoCurves, operation); - } - for (var i = 0, l = segments.length; i < l; i++) { - var segment = segments[i]; - if (segment._winding == null) { - propagateWinding(segment, _path1, _path2, monoCurves, - operation); - } - } - return finishBoolean(CompoundPath, tracePaths(segments, operation), - path1, path2, true); - } - - function computeOpenBoolean(path1, path2, operation) { - if (!path2 || !path2._children && !path2._closed - || !/^(subtract|intersect)$/.test(operation)) - return null; - var _path1 = preparePath(path1, false), - _path2 = preparePath(path2, false), - intersections = _path1.getIntersections(_path2, function(inter) { - return inter.isOverlap() || inter.isCrossing(); - }), - sub = operation === 'subtract', - paths = []; - - function addPath(path) { - if (_path2.contains(path.getPointAt(path.getLength() / 2)) ^ sub) { - paths.unshift(path); - return true; - } - } - - for (var i = intersections.length - 1; i >= 0; i--) { - var path = intersections[i].split(); - if (path) { - if (addPath(path)) - path.getFirstSegment().setHandleIn(0, 0); - _path1.getLastSegment().setHandleOut(0, 0); - } - } - addPath(_path1); - return finishBoolean(Group, paths, path1, path2); - } - - function linkIntersections(from, to) { - var prev = from; - while (prev) { - if (prev === to) - return; - prev = prev._prev; - } - while (from._next && from._next !== to) - from = from._next; - if (!from._next) { - while (to._prev) - to = to._prev; - from._next = to; - to._prev = from; - } - } - - function divideLocations(locations) { - var tMin = 4e-7, - tMax = 1 - tMin, - noHandles = false, - clearSegments = [], - prevCurve, - prevT; - - for (var i = locations.length - 1; i >= 0; i--) { - var loc = locations[i], - curve = loc._curve, - t = loc._parameter, - origT = t; - if (curve !== prevCurve) { - noHandles = !curve.hasHandles(); - } else if (prevT > 0) { - t /= prevT; - } - var segment; - if (t < tMin) { - segment = curve._segment1; - } else if (t > tMax) { - segment = curve._segment2; - } else { - segment = curve.divide(t, true, true)._segment1; - if (noHandles) - clearSegments.push(segment); - } - loc._setSegment(segment); - var inter = segment._intersection, - dest = loc._intersection; - if (inter) { - linkIntersections(inter, dest); - var other = inter; - while (other) { - linkIntersections(other._intersection, inter); - other = other._next; - } - } else { - segment._intersection = dest; - } - prevCurve = curve; - prevT = origT; - } - for (var i = 0, l = clearSegments.length; i < l; i++) { - clearSegments[i].clearHandles(); - } - } - - function getWinding(point, curves, horizontal, testContains) { - var epsilon = 2e-7, - tMin = 4e-7, - tMax = 1 - tMin, - px = point.x, - py = point.y, - windLeft = 0, - windRight = 0, - roots = [], - abs = Math.abs; - if (horizontal) { - var yTop = -Infinity, - yBottom = Infinity, - yBefore = py - epsilon, - yAfter = py + epsilon; - for (var i = 0, l = curves.length; i < l; i++) { - var values = curves[i].values; - if (Curve.solveCubic(values, 0, px, roots, 0, 1) > 0) { - for (var j = roots.length - 1; j >= 0; j--) { - var y = Curve.getPoint(values, roots[j]).y; - if (y < yBefore && y > yTop) { - yTop = y; - } else if (y > yAfter && y < yBottom) { - yBottom = y; - } - } - } - } - yTop = (yTop + py) / 2; - yBottom = (yBottom + py) / 2; - if (yTop > -Infinity) - windLeft = getWinding(new Point(px, yTop), curves, false, - testContains); - if (yBottom < Infinity) - windRight = getWinding(new Point(px, yBottom), curves, false, - testContains); - } else { - var xBefore = px - epsilon, - xAfter = px + epsilon; - var startCounted = false, - prevCurve, - prevT; - for (var i = 0, l = curves.length; i < l; i++) { - var curve = curves[i], - values = curve.values, - winding = curve.winding; - if (winding && (winding === 1 - && py >= values[1] && py <= values[7] - || py >= values[7] && py <= values[1]) - && Curve.solveCubic(values, 1, py, roots, 0, 1) === 1) { - var t = roots[0]; - if (!( - t > tMax && startCounted && curve.next !== curves[i + 1] - || t < tMin && prevT > tMax - && curve.previous === prevCurve)) { - var x = Curve.getPoint(values, t).x, - slope = Curve.getTangent(values, t).y, - counted = false; - if (Numerical.isZero(slope) && !Curve.isStraight(values) - || t < tMin && slope * Curve.getTangent( - curve.previous.values, 1).y < 0 - || t > tMax && slope * Curve.getTangent( - curve.next.values, 0).y < 0) { - if (testContains && x >= xBefore && x <= xAfter) { - ++windLeft; - ++windRight; - counted = true; - } - } else if (x <= xBefore) { - windLeft += winding; - counted = true; - } else if (x >= xAfter) { - windRight += winding; - counted = true; - } - if (curve.previous !== curves[i - 1]) - startCounted = t < tMin && counted; - } - prevCurve = curve; - prevT = t; - } - } - } - return Math.max(abs(windLeft), abs(windRight)); - } - - function propagateWinding(segment, path1, path2, monoCurves, operation) { - var epsilon = 2e-7, - chain = [], - start = segment, - totalLength = 0, - windingSum = 0; - do { - var curve = segment.getCurve(), - length = curve.getLength(); - chain.push({ segment: segment, curve: curve, length: length }); - totalLength += length; - segment = segment.getNext(); - } while (segment && !segment._intersection && segment !== start); - for (var i = 0; i < 3; i++) { - var length = totalLength * (i + 1) / 4; - for (var k = 0, m = chain.length; k < m; k++) { - var node = chain[k], - curveLength = node.length; - if (length <= curveLength) { - if (length < epsilon || curveLength - length < epsilon) - length = curveLength / 2; - var curve = node.curve, - path = curve._path, - parent = path._parent, - pt = curve.getPointAt(length), - hor = curve.isHorizontal(); - if (parent instanceof CompoundPath) - path = parent; - windingSum += operation === 'subtract' && path2 - && (path === path1 && path2._getWinding(pt, hor) - || path === path2 && !path1._getWinding(pt, hor)) - ? 0 - : getWinding(pt, monoCurves, hor); - break; - } - length -= curveLength; - } - } - var winding = Math.round(windingSum / 3); - for (var j = chain.length - 1; j >= 0; j--) - chain[j].segment._winding = winding; - } - - function tracePaths(segments, operation) { - var paths = [], - start, - otherStart, - operator = operators[operation], - overlapWinding = { - unite: { 1: 2 }, - intersect: { 2: 1 } - }[operation]; - - function isValid(seg, adjusted) { - if (seg._visited) - return false; - if (!operator) - return true; - var winding = seg._winding, - inter = seg._intersection; - if (inter && adjusted && overlapWinding && inter.isOverlap()) - winding = overlapWinding[winding] || winding; - return operator(winding); - } - - function isStart(seg) { - return seg === start || seg === otherStart; - } - - function findBestIntersection(inter, strict) { - if (!inter._next) - return inter; - while (inter) { - var seg = inter._segment, - nextSeg = seg.getNext(), - nextInter = nextSeg._intersection; - if (isStart(nextSeg) - || !seg._visited && !nextSeg._visited - && (!operator - || (!strict || isValid(seg)) - && (!(strict && nextInter && nextInter.isOverlap()) - && isValid(nextSeg) - || !strict && nextInter - && isValid(nextInter._segment)) - )) - return inter; - inter = inter._next; - } - return null; - } - - function findStartSegment(inter, next) { - while (inter) { - var seg = inter._segment; - if (isStart(seg)) - return seg; - inter = inter[next ? '_next' : '_prev']; - } - } - - for (var i = 0, l = segments.length; i < l; i++) { - var seg = segments[i], - path = null, - finished = false; - if (!isValid(seg, true)) - continue; - start = otherStart = null; - while (!finished) { - var inter = seg._intersection, - handleIn = path && seg._handleIn; - inter = inter && (findBestIntersection(inter, true) - || findBestIntersection(inter, false)) || inter; - var other = inter && inter._segment; - if (other && isValid(other)) - seg = other; - if (seg._visited) { - finished = isStart(seg); - if (!finished && inter) { - var found = findStartSegment(inter, true) - || findStartSegment(inter, false); - if (found) { - seg = found; - finished = true; - } - } - break; - } - if (!path) { - path = new Path(Item.NO_INSERT); - start = seg; - otherStart = other; - } - path.add(new Segment(seg._point, handleIn, seg._handleOut)); - seg._visited = true; - seg = seg.getNext(); - finished = isStart(seg); - } - if (finished) { - path.firstSegment.setHandleIn(seg._handleIn); - path.setClosed(true); - } else if (path) { - console.error('Boolean operation resulted in open path', - 'segments =', path._segments.length, - 'length =', path.getLength()); - path = null; - } - if (path && (path._segments.length > 8 - || !Numerical.isZero(path.getArea()))) { - paths.push(path); - path = null; - } - } - return paths; - } - - return { - _getWinding: function(point, horizontal, testContains) { - return getWinding(point, this._getMonoCurves(), - horizontal, testContains); - }, - - unite: function(path) { - return computeBoolean(this, path, 'unite'); - }, - - intersect: function(path) { - return computeBoolean(this, path, 'intersect'); - }, - - subtract: function(path) { - return computeBoolean(this, path, 'subtract'); - }, - - exclude: function(path) { - return computeBoolean(this, path, 'exclude'); - }, - - divide: function(path) { - return finishBoolean(Group, - [this.subtract(path), this.intersect(path)], - this, path, true); - }, - - resolveCrossings: function() { - var crossings = this.getCrossings(); - if (!crossings.length) - return this; - divideLocations(CurveLocation.expand(crossings)); - var paths = this._children || [this], - segments = []; - for (var i = 0, l = paths.length; i < l; i++) { - segments.push.apply(segments, paths[i]._segments); - } - return finishBoolean(CompoundPath, tracePaths(segments), - this, null, false); - } - }; -}); - -Path.inject({ - _getMonoCurves: function() { - var monoCurves = this._monoCurves, - prevCurve; - - function insertCurve(v) { - var y0 = v[1], - y1 = v[7], - curve = { - values: v, - winding: y0 === y1 - ? 0 - : y0 > y1 - ? -1 - : 1, - previous: prevCurve, - next: null - }; - if (prevCurve) - prevCurve.next = curve; - monoCurves.push(curve); - prevCurve = curve; - } - - function handleCurve(v) { - if (Curve.getLength(v) === 0) - return; - var y0 = v[1], - y1 = v[3], - y2 = v[5], - y3 = v[7]; - if (Curve.isStraight(v)) { - insertCurve(v); - } else { - var a = 3 * (y1 - y2) - y0 + y3, - b = 2 * (y0 + y2) - 4 * y1, - c = y1 - y0, - tMin = 4e-7, - tMax = 1 - tMin, - roots = [], - n = Numerical.solveQuadratic(a, b, c, roots, tMin, tMax); - if (n === 0) { - insertCurve(v); - } else { - roots.sort(); - var t = roots[0], - parts = Curve.subdivide(v, t); - insertCurve(parts[0]); - if (n > 1) { - t = (roots[1] - t) / (1 - t); - parts = Curve.subdivide(parts[1], t); - insertCurve(parts[0]); - } - insertCurve(parts[1]); - } - } - } - - if (!monoCurves) { - monoCurves = this._monoCurves = []; - var curves = this.getCurves(), - segments = this._segments; - for (var i = 0, l = curves.length; i < l; i++) - handleCurve(curves[i].getValues()); - if (!this._closed && segments.length > 1) { - var p1 = segments[segments.length - 1]._point, - p2 = segments[0]._point, - p1x = p1._x, p1y = p1._y, - p2x = p2._x, p2y = p2._y; - handleCurve([p1x, p1y, p1x, p1y, p2x, p2y, p2x, p2y]); - } - if (monoCurves.length > 0) { - var first = monoCurves[0], - last = monoCurves[monoCurves.length - 1]; - first.previous = last; - last.next = first; - } - } - return monoCurves; - }, - - getInteriorPoint: function() { - var bounds = this.getBounds(), - point = bounds.getCenter(true); - if (!this.contains(point)) { - var curves = this._getMonoCurves(), - roots = [], - y = point.y, - xIntercepts = []; - for (var i = 0, l = curves.length; i < l; i++) { - var values = curves[i].values; - if ((curves[i].winding === 1 - && y >= values[1] && y <= values[7] - || y >= values[7] && y <= values[1]) - && Curve.solveCubic(values, 1, y, roots, 0, 1) > 0) { - for (var j = roots.length - 1; j >= 0; j--) - xIntercepts.push(Curve.getPoint(values, roots[j]).x); - } - if (xIntercepts.length > 1) - break; - } - point.x = (xIntercepts[0] + xIntercepts[1]) / 2; - } - return point; - }, - - reorient: function() { - this.setClockwise(true); - return this; - } -}); - -CompoundPath.inject({ - _getMonoCurves: function() { - var children = this._children, - monoCurves = []; - for (var i = 0, l = children.length; i < l; i++) - monoCurves.push.apply(monoCurves, children[i]._getMonoCurves()); - return monoCurves; - }, - - reorient: function() { - var children = this.removeChildren().sort(function(a, b) { - return b.getBounds().getArea() - a.getBounds().getArea(); - }); - if (children.length > 0) { - this.addChildren(children); - var clockwise = children[0].isClockwise(); - for (var i = 1, l = children.length; i < l; i++) { - var point = children[i].getInteriorPoint(), - counters = 0; - for (var j = i - 1; j >= 0; j--) { - if (children[j].contains(point)) - counters++; - } - children[i].setClockwise(counters % 2 === 0 && clockwise); - } - } - return this; - } -}); - -var PathIterator = Base.extend({ - _class: 'PathIterator', - - initialize: function(path, maxRecursion, tolerance, matrix) { - var curves = [], - parts = [], - length = 0, - minDifference = 1 / (maxRecursion || 32), - segments = path._segments, - segment1 = segments[0], - segment2; - - function addCurve(segment1, segment2) { - var curve = Curve.getValues(segment1, segment2, matrix); - curves.push(curve); - computeParts(curve, segment1._index, 0, 1); - } - - function computeParts(curve, index, minT, maxT) { - if ((maxT - minT) > minDifference - && !Curve.isFlatEnough(curve, tolerance || 0.25)) { - var split = Curve.subdivide(curve, 0.5), - halfT = (minT + maxT) / 2; - computeParts(split[0], index, minT, halfT); - computeParts(split[1], index, halfT, maxT); - } else { - var x = curve[6] - curve[0], - y = curve[7] - curve[1], - dist = Math.sqrt(x * x + y * y); - if (dist > 1e-6) { - length += dist; - parts.push({ - offset: length, - value: maxT, - index: index - }); - } - } - } - - for (var i = 1, l = segments.length; i < l; i++) { - segment2 = segments[i]; - addCurve(segment1, segment2); - segment1 = segment2; - } - if (path._closed) - addCurve(segment2, segments[0]); - - this.curves = curves; - this.parts = parts; - this.length = length; - this.index = 0; - }, - - getParameterAt: function(offset) { - var i, j = this.index; - for (;;) { - i = j; - if (j == 0 || this.parts[--j].offset < offset) - break; - } - for (var l = this.parts.length; i < l; i++) { - var part = this.parts[i]; - if (part.offset >= offset) { - this.index = i; - var prev = this.parts[i - 1]; - var prevVal = prev && prev.index == part.index ? prev.value : 0, - prevLen = prev ? prev.offset : 0; - return { - value: prevVal + (part.value - prevVal) - * (offset - prevLen) / (part.offset - prevLen), - index: part.index - }; - } - } - var part = this.parts[this.parts.length - 1]; - return { - value: 1, - index: part.index - }; - }, - - drawPart: function(ctx, from, to) { - from = this.getParameterAt(from); - to = this.getParameterAt(to); - for (var i = from.index; i <= to.index; i++) { - var curve = Curve.getPart(this.curves[i], - i == from.index ? from.value : 0, - i == to.index ? to.value : 1); - if (i == from.index) - ctx.moveTo(curve[0], curve[1]); - ctx.bezierCurveTo.apply(ctx, curve.slice(2)); - } - } -}, Base.each(Curve.evaluateMethods, - function(name) { - this[name + 'At'] = function(offset, weighted) { - var param = this.getParameterAt(offset); - return Curve[name](this.curves[param.index], param.value, weighted); - }; - }, {}) -); - -var PathFitter = Base.extend({ - initialize: function(path, error) { - var points = this.points = [], - segments = path._segments, - prev; - for (var i = 0, l = segments.length; i < l; i++) { - var point = segments[i].point.clone(); - if (!prev || !prev.equals(point)) { - points.push(point); - prev = point; - } - } - - if (path._closed) { - this.closed = true; - points.unshift(points[points.length - 1]); - points.push(points[1]); - } - - this.error = error; - }, - - fit: function() { - var points = this.points, - length = points.length, - segments = this.segments = length > 0 - ? [new Segment(points[0])] : []; - if (length > 1) - this.fitCubic(0, length - 1, - points[1].subtract(points[0]).normalize(), - points[length - 2].subtract(points[length - 1]).normalize()); - - if (this.closed) { - segments.shift(); - segments.pop(); - } - - return segments; - }, - - fitCubic: function(first, last, tan1, tan2) { - if (last - first == 1) { - var pt1 = this.points[first], - pt2 = this.points[last], - dist = pt1.getDistance(pt2) / 3; - this.addCurve([pt1, pt1.add(tan1.normalize(dist)), - pt2.add(tan2.normalize(dist)), pt2]); - return; - } - var uPrime = this.chordLengthParameterize(first, last), - maxError = Math.max(this.error, this.error * this.error), - split, - parametersInOrder = true; - for (var i = 0; i <= 4; i++) { - var curve = this.generateBezier(first, last, uPrime, tan1, tan2); - var max = this.findMaxError(first, last, curve, uPrime); - if (max.error < this.error && parametersInOrder) { - this.addCurve(curve); - return; - } - split = max.index; - if (max.error >= maxError) - break; - parametersInOrder = this.reparameterize(first, last, uPrime, curve); - maxError = max.error; - } - var V1 = this.points[split - 1].subtract(this.points[split]), - V2 = this.points[split].subtract(this.points[split + 1]), - tanCenter = V1.add(V2).divide(2).normalize(); - this.fitCubic(first, split, tan1, tanCenter); - this.fitCubic(split, last, tanCenter.negate(), tan2); - }, - - addCurve: function(curve) { - var prev = this.segments[this.segments.length - 1]; - prev.setHandleOut(curve[1].subtract(curve[0])); - this.segments.push( - new Segment(curve[3], curve[2].subtract(curve[3]))); - }, - - generateBezier: function(first, last, uPrime, tan1, tan2) { - var epsilon = 1e-12, - pt1 = this.points[first], - pt2 = this.points[last], - C = [[0, 0], [0, 0]], - X = [0, 0]; - - for (var i = 0, l = last - first + 1; i < l; i++) { - var u = uPrime[i], - t = 1 - u, - b = 3 * u * t, - b0 = t * t * t, - b1 = b * t, - b2 = b * u, - b3 = u * u * u, - a1 = tan1.normalize(b1), - a2 = tan2.normalize(b2), - tmp = this.points[first + i] - .subtract(pt1.multiply(b0 + b1)) - .subtract(pt2.multiply(b2 + b3)); - C[0][0] += a1.dot(a1); - C[0][1] += a1.dot(a2); - C[1][0] = C[0][1]; - C[1][1] += a2.dot(a2); - X[0] += a1.dot(tmp); - X[1] += a2.dot(tmp); - } - - var detC0C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1], - alpha1, alpha2; - if (Math.abs(detC0C1) > epsilon) { - var detC0X = C[0][0] * X[1] - C[1][0] * X[0], - detXC1 = X[0] * C[1][1] - X[1] * C[0][1]; - alpha1 = detXC1 / detC0C1; - alpha2 = detC0X / detC0C1; - } else { - var c0 = C[0][0] + C[0][1], - c1 = C[1][0] + C[1][1]; - if (Math.abs(c0) > epsilon) { - alpha1 = alpha2 = X[0] / c0; - } else if (Math.abs(c1) > epsilon) { - alpha1 = alpha2 = X[1] / c1; - } else { - alpha1 = alpha2 = 0; - } - } - - var segLength = pt2.getDistance(pt1), - eps = epsilon * segLength, - handle1, - handle2; - if (alpha1 < eps || alpha2 < eps) { - alpha1 = alpha2 = segLength / 3; - } else { - var line = pt2.subtract(pt1); - handle1 = tan1.normalize(alpha1); - handle2 = tan2.normalize(alpha2); - if (handle1.dot(line) - handle2.dot(line) > segLength * segLength) { - alpha1 = alpha2 = segLength / 3; - handle1 = handle2 = null; - } - } - - return [pt1, pt1.add(handle1 || tan1.normalize(alpha1)), - pt2.add(handle2 || tan2.normalize(alpha2)), pt2]; - }, - - reparameterize: function(first, last, u, curve) { - for (var i = first; i <= last; i++) { - u[i - first] = this.findRoot(curve, this.points[i], u[i - first]); - } - for (var i = 1, l = u.length; i < l; i++) { - if (u[i] <= u[i - 1]) - return false; - } - return true; - }, - - findRoot: function(curve, point, u) { - var curve1 = [], - curve2 = []; - for (var i = 0; i <= 2; i++) { - curve1[i] = curve[i + 1].subtract(curve[i]).multiply(3); - } - for (var i = 0; i <= 1; i++) { - curve2[i] = curve1[i + 1].subtract(curve1[i]).multiply(2); - } - var pt = this.evaluate(3, curve, u), - pt1 = this.evaluate(2, curve1, u), - pt2 = this.evaluate(1, curve2, u), - diff = pt.subtract(point), - df = pt1.dot(pt1) + diff.dot(pt2); - if (Math.abs(df) < 1e-6) - return u; - return u - diff.dot(pt1) / df; - }, - - evaluate: function(degree, curve, t) { - var tmp = curve.slice(); - for (var i = 1; i <= degree; i++) { - for (var j = 0; j <= degree - i; j++) { - tmp[j] = tmp[j].multiply(1 - t).add(tmp[j + 1].multiply(t)); - } - } - return tmp[0]; - }, - - chordLengthParameterize: function(first, last) { - var u = [0]; - for (var i = first + 1; i <= last; i++) { - u[i - first] = u[i - first - 1] - + this.points[i].getDistance(this.points[i - 1]); - } - for (var i = 1, m = last - first; i <= m; i++) { - u[i] /= u[m]; - } - return u; - }, - - findMaxError: function(first, last, curve, u) { - var index = Math.floor((last - first + 1) / 2), - maxDist = 0; - for (var i = first + 1; i < last; i++) { - var P = this.evaluate(3, curve, u[i - first]); - var v = P.subtract(this.points[i]); - var dist = v.x * v.x + v.y * v.y; - if (dist >= maxDist) { - maxDist = dist; - index = i; - } - } - return { - error: maxDist, - index: index - }; - } -}); - -var TextItem = Item.extend({ - _class: 'TextItem', - _boundsSelected: true, - _applyMatrix: false, - _canApplyMatrix: false, - _serializeFields: { - content: null - }, - _boundsGetter: 'getBounds', - - initialize: function TextItem(arg) { - this._content = ''; - this._lines = []; - var hasProps = arg && Base.isPlainObject(arg) - && arg.x === undefined && arg.y === undefined; - this._initialize(hasProps && arg, !hasProps && Point.read(arguments)); - }, - - _equals: function(item) { - return this._content === item._content; - }, - - _clone: function _clone(copy, insert, includeMatrix) { - copy.setContent(this._content); - return _clone.base.call(this, copy, insert, includeMatrix); - }, - - getContent: function() { - return this._content; - }, - - setContent: function(content) { - this._content = '' + content; - this._lines = this._content.split(/\r\n|\n|\r/mg); - this._changed(265); - }, - - isEmpty: function() { - return !this._content; - }, - - getCharacterStyle: '#getStyle', - setCharacterStyle: '#setStyle', - - getParagraphStyle: '#getStyle', - setParagraphStyle: '#setStyle' -}); - -var PointText = TextItem.extend({ - _class: 'PointText', - - initialize: function PointText() { - TextItem.apply(this, arguments); - }, - - clone: function(insert) { - return this._clone(new PointText(Item.NO_INSERT), insert); - }, - - getPoint: function() { - var point = this._matrix.getTranslation(); - return new LinkedPoint(point.x, point.y, this, 'setPoint'); - }, - - setPoint: function() { - var point = Point.read(arguments); - this.translate(point.subtract(this._matrix.getTranslation())); - }, - - _draw: function(ctx) { - if (!this._content) - return; - this._setStyles(ctx); - var style = this._style, - lines = this._lines, - leading = style.getLeading(), - shadowColor = ctx.shadowColor; - ctx.font = style.getFontStyle(); - ctx.textAlign = style.getJustification(); - for (var i = 0, l = lines.length; i < l; i++) { - ctx.shadowColor = shadowColor; - var line = lines[i]; - if (style.hasFill()) { - ctx.fillText(line, 0, 0); - ctx.shadowColor = 'rgba(0,0,0,0)'; - } - if (style.hasStroke()) - ctx.strokeText(line, 0, 0); - ctx.translate(0, leading); - } - }, - - _getBounds: function(getter, matrix) { - var style = this._style, - lines = this._lines, - numLines = lines.length, - justification = style.getJustification(), - leading = style.getLeading(), - width = this.getView().getTextWidth(style.getFontStyle(), lines), - x = 0; - if (justification !== 'left') - x -= width / (justification === 'center' ? 2: 1); - var bounds = new Rectangle(x, - numLines ? - 0.75 * leading : 0, - width, numLines * leading); - return matrix ? matrix._transformBounds(bounds, bounds) : bounds; - } -}); - -var Color = Base.extend(new function() { - var types = { - gray: ['gray'], - rgb: ['red', 'green', 'blue'], - hsb: ['hue', 'saturation', 'brightness'], - hsl: ['hue', 'saturation', 'lightness'], - gradient: ['gradient', 'origin', 'destination', 'highlight'] - }; - - var componentParsers = {}, - colorCache = {}, - colorCtx; - - function fromCSS(string) { - var match = string.match(/^#(\w{1,2})(\w{1,2})(\w{1,2})$/), - components; - if (match) { - components = [0, 0, 0]; - for (var i = 0; i < 3; i++) { - var value = match[i + 1]; - components[i] = parseInt(value.length == 1 - ? value + value : value, 16) / 255; - } - } else if (match = string.match(/^rgba?\((.*)\)$/)) { - components = match[1].split(','); - for (var i = 0, l = components.length; i < l; i++) { - var value = +components[i]; - components[i] = i < 3 ? value / 255 : value; - } - } else { - var cached = colorCache[string]; - if (!cached) { - if (!colorCtx) { - colorCtx = CanvasProvider.getContext(1, 1); - colorCtx.globalCompositeOperation = 'copy'; - } - colorCtx.fillStyle = 'rgba(0,0,0,0)'; - colorCtx.fillStyle = string; - colorCtx.fillRect(0, 0, 1, 1); - var data = colorCtx.getImageData(0, 0, 1, 1).data; - cached = colorCache[string] = [ - data[0] / 255, - data[1] / 255, - data[2] / 255 - ]; - } - components = cached.slice(); - } - return components; - } - - var hsbIndices = [ - [0, 3, 1], - [2, 0, 1], - [1, 0, 3], - [1, 2, 0], - [3, 1, 0], - [0, 1, 2] - ]; - - var converters = { - 'rgb-hsb': function(r, g, b) { - var max = Math.max(r, g, b), - min = Math.min(r, g, b), - delta = max - min, - h = delta === 0 ? 0 - : ( max == r ? (g - b) / delta + (g < b ? 6 : 0) - : max == g ? (b - r) / delta + 2 - : (r - g) / delta + 4) * 60; - return [h, max === 0 ? 0 : delta / max, max]; - }, - - 'hsb-rgb': function(h, s, b) { - h = (((h / 60) % 6) + 6) % 6; - var i = Math.floor(h), - f = h - i, - i = hsbIndices[i], - v = [ - b, - b * (1 - s), - b * (1 - s * f), - b * (1 - s * (1 - f)) - ]; - return [v[i[0]], v[i[1]], v[i[2]]]; - }, - - 'rgb-hsl': function(r, g, b) { - var max = Math.max(r, g, b), - min = Math.min(r, g, b), - delta = max - min, - achromatic = delta === 0, - h = achromatic ? 0 - : ( max == r ? (g - b) / delta + (g < b ? 6 : 0) - : max == g ? (b - r) / delta + 2 - : (r - g) / delta + 4) * 60, - l = (max + min) / 2, - s = achromatic ? 0 : l < 0.5 - ? delta / (max + min) - : delta / (2 - max - min); - return [h, s, l]; - }, - - 'hsl-rgb': function(h, s, l) { - h = (((h / 360) % 1) + 1) % 1; - if (s === 0) - return [l, l, l]; - var t3s = [ h + 1 / 3, h, h - 1 / 3 ], - t2 = l < 0.5 ? l * (1 + s) : l + s - l * s, - t1 = 2 * l - t2, - c = []; - for (var i = 0; i < 3; i++) { - var t3 = t3s[i]; - if (t3 < 0) t3 += 1; - if (t3 > 1) t3 -= 1; - c[i] = 6 * t3 < 1 - ? t1 + (t2 - t1) * 6 * t3 - : 2 * t3 < 1 - ? t2 - : 3 * t3 < 2 - ? t1 + (t2 - t1) * ((2 / 3) - t3) * 6 - : t1; - } - return c; - }, - - 'rgb-gray': function(r, g, b) { - return [r * 0.2989 + g * 0.587 + b * 0.114]; - }, - - 'gray-rgb': function(g) { - return [g, g, g]; - }, - - 'gray-hsb': function(g) { - return [0, 0, g]; - }, - - 'gray-hsl': function(g) { - return [0, 0, g]; - }, - - 'gradient-rgb': function() { - return []; - }, - - 'rgb-gradient': function() { - return []; - } - - }; - - return Base.each(types, function(properties, type) { - componentParsers[type] = []; - Base.each(properties, function(name, index) { - var part = Base.capitalize(name), - hasOverlap = /^(hue|saturation)$/.test(name), - parser = componentParsers[type][index] = name === 'gradient' - ? function(value) { - var current = this._components[0]; - value = Gradient.read(Array.isArray(value) ? value - : arguments, 0, { readNull: true }); - if (current !== value) { - if (current) - current._removeOwner(this); - if (value) - value._addOwner(this); - } - return value; - } - : type === 'gradient' - ? function() { - return Point.read(arguments, 0, { - readNull: name === 'highlight', - clone: true - }); - } - : function(value) { - return value == null || isNaN(value) ? 0 : value; - }; - - this['get' + part] = function() { - return this._type === type - || hasOverlap && /^hs[bl]$/.test(this._type) - ? this._components[index] - : this._convert(type)[index]; - }; - - this['set' + part] = function(value) { - if (this._type !== type - && !(hasOverlap && /^hs[bl]$/.test(this._type))) { - this._components = this._convert(type); - this._properties = types[type]; - this._type = type; - } - this._components[index] = parser.call(this, value); - this._changed(); - }; - }, this); - }, { - _class: 'Color', - _readIndex: true, - - initialize: function Color(arg) { - var slice = Array.prototype.slice, - args = arguments, - read = 0, - type, - components, - alpha, - values; - if (Array.isArray(arg)) { - args = arg; - arg = args[0]; - } - var argType = arg != null && typeof arg; - if (argType === 'string' && arg in types) { - type = arg; - arg = args[1]; - if (Array.isArray(arg)) { - components = arg; - alpha = args[2]; - } else { - if (this.__read) - read = 1; - args = slice.call(args, 1); - argType = typeof arg; - } - } - if (!components) { - values = argType === 'number' - ? args - : argType === 'object' && arg.length != null - ? arg - : null; - if (values) { - if (!type) - type = values.length >= 3 - ? 'rgb' - : 'gray'; - var length = types[type].length; - alpha = values[length]; - if (this.__read) - read += values === arguments - ? length + (alpha != null ? 1 : 0) - : 1; - if (values.length > length) - values = slice.call(values, 0, length); - } else if (argType === 'string') { - type = 'rgb'; - components = fromCSS(arg); - if (components.length === 4) { - alpha = components[3]; - components.length--; - } - } else if (argType === 'object') { - if (arg.constructor === Color) { - type = arg._type; - components = arg._components.slice(); - alpha = arg._alpha; - if (type === 'gradient') { - for (var i = 1, l = components.length; i < l; i++) { - var point = components[i]; - if (point) - components[i] = point.clone(); - } - } - } else if (arg.constructor === Gradient) { - type = 'gradient'; - values = args; - } else { - type = 'hue' in arg - ? 'lightness' in arg - ? 'hsl' - : 'hsb' - : 'gradient' in arg || 'stops' in arg - || 'radial' in arg - ? 'gradient' - : 'gray' in arg - ? 'gray' - : 'rgb'; - var properties = types[type], - parsers = componentParsers[type]; - this._components = components = []; - for (var i = 0, l = properties.length; i < l; i++) { - var value = arg[properties[i]]; - if (value == null && i === 0 && type === 'gradient' - && 'stops' in arg) { - value = { - stops: arg.stops, - radial: arg.radial - }; - } - value = parsers[i].call(this, value); - if (value != null) - components[i] = value; - } - alpha = arg.alpha; - } - } - if (this.__read && type) - read = 1; - } - this._type = type || 'rgb'; - this._id = UID.get(Color); - if (!components) { - this._components = components = []; - var parsers = componentParsers[this._type]; - for (var i = 0, l = parsers.length; i < l; i++) { - var value = parsers[i].call(this, values && values[i]); - if (value != null) - components[i] = value; - } - } - this._components = components; - this._properties = types[this._type]; - this._alpha = alpha; - if (this.__read) - this.__read = read; - }, - - _serialize: function(options, dictionary) { - var components = this.getComponents(); - return Base.serialize( - /^(gray|rgb)$/.test(this._type) - ? components - : [this._type].concat(components), - options, true, dictionary); - }, - - _changed: function() { - this._canvasStyle = null; - if (this._owner) - this._owner._changed(65); - }, - - _convert: function(type) { - var converter; - return this._type === type - ? this._components.slice() - : (converter = converters[this._type + '-' + type]) - ? converter.apply(this, this._components) - : converters['rgb-' + type].apply(this, - converters[this._type + '-rgb'].apply(this, - this._components)); - }, - - convert: function(type) { - return new Color(type, this._convert(type), this._alpha); - }, - - getType: function() { - return this._type; - }, - - setType: function(type) { - this._components = this._convert(type); - this._properties = types[type]; - this._type = type; - }, - - getComponents: function() { - var components = this._components.slice(); - if (this._alpha != null) - components.push(this._alpha); - return components; - }, - - getAlpha: function() { - return this._alpha != null ? this._alpha : 1; - }, - - setAlpha: function(alpha) { - this._alpha = alpha == null ? null : Math.min(Math.max(alpha, 0), 1); - this._changed(); - }, - - hasAlpha: function() { - return this._alpha != null; - }, - - equals: function(color) { - var col = Base.isPlainValue(color, true) - ? Color.read(arguments) - : color; - return col === this || col && this._class === col._class - && this._type === col._type - && this._alpha === col._alpha - && Base.equals(this._components, col._components) - || false; - }, - - toString: function() { - var properties = this._properties, - parts = [], - isGradient = this._type === 'gradient', - f = Formatter.instance; - for (var i = 0, l = properties.length; i < l; i++) { - var value = this._components[i]; - if (value != null) - parts.push(properties[i] + ': ' - + (isGradient ? value : f.number(value))); - } - if (this._alpha != null) - parts.push('alpha: ' + f.number(this._alpha)); - return '{ ' + parts.join(', ') + ' }'; - }, - - toCSS: function(hex) { - var components = this._convert('rgb'), - alpha = hex || this._alpha == null ? 1 : this._alpha; - function convert(val) { - return Math.round((val < 0 ? 0 : val > 1 ? 1 : val) * 255); - } - components = [ - convert(components[0]), - convert(components[1]), - convert(components[2]) - ]; - if (alpha < 1) - components.push(alpha < 0 ? 0 : alpha); - return hex - ? '#' + ((1 << 24) + (components[0] << 16) - + (components[1] << 8) - + components[2]).toString(16).slice(1) - : (components.length == 4 ? 'rgba(' : 'rgb(') - + components.join(',') + ')'; - }, - - toCanvasStyle: function(ctx) { - if (this._canvasStyle) - return this._canvasStyle; - if (this._type !== 'gradient') - return this._canvasStyle = this.toCSS(); - var components = this._components, - gradient = components[0], - stops = gradient._stops, - origin = components[1], - destination = components[2], - canvasGradient; - if (gradient._radial) { - var radius = destination.getDistance(origin), - highlight = components[3]; - if (highlight) { - var vector = highlight.subtract(origin); - if (vector.getLength() > radius) - highlight = origin.add(vector.normalize(radius - 0.1)); - } - var start = highlight || origin; - canvasGradient = ctx.createRadialGradient(start.x, start.y, - 0, origin.x, origin.y, radius); - } else { - canvasGradient = ctx.createLinearGradient(origin.x, origin.y, - destination.x, destination.y); - } - for (var i = 0, l = stops.length; i < l; i++) { - var stop = stops[i]; - canvasGradient.addColorStop(stop._rampPoint, - stop._color.toCanvasStyle()); - } - return this._canvasStyle = canvasGradient; - }, - - transform: function(matrix) { - if (this._type === 'gradient') { - var components = this._components; - for (var i = 1, l = components.length; i < l; i++) { - var point = components[i]; - matrix._transformPoint(point, point, true); - } - this._changed(); - } - }, - - statics: { - _types: types, - - random: function() { - var random = Math.random; - return new Color(random(), random(), random()); - } - } - }); -}, -new function() { - var operators = { - add: function(a, b) { - return a + b; - }, - - subtract: function(a, b) { - return a - b; - }, - - multiply: function(a, b) { - return a * b; - }, - - divide: function(a, b) { - return a / b; - } - }; - - return Base.each(operators, function(operator, name) { - this[name] = function(color) { - color = Color.read(arguments); - var type = this._type, - components1 = this._components, - components2 = color._convert(type); - for (var i = 0, l = components1.length; i < l; i++) - components2[i] = operator(components1[i], components2[i]); - return new Color(type, components2, - this._alpha != null - ? operator(this._alpha, color.getAlpha()) - : null); - }; - }, { - }); -}); - -var Gradient = Base.extend({ - _class: 'Gradient', - - initialize: function Gradient(stops, radial) { - this._id = UID.get(); - if (stops && this._set(stops)) - stops = radial = null; - if (!this._stops) - this.setStops(stops || ['white', 'black']); - if (this._radial == null) - this.setRadial(typeof radial === 'string' && radial === 'radial' - || radial || false); - }, - - _serialize: function(options, dictionary) { - return dictionary.add(this, function() { - return Base.serialize([this._stops, this._radial], - options, true, dictionary); - }); - }, - - _changed: function() { - for (var i = 0, l = this._owners && this._owners.length; i < l; i++) - this._owners[i]._changed(); - }, - - _addOwner: function(color) { - if (!this._owners) - this._owners = []; - this._owners.push(color); - }, - - _removeOwner: function(color) { - var index = this._owners ? this._owners.indexOf(color) : -1; - if (index != -1) { - this._owners.splice(index, 1); - if (this._owners.length === 0) - this._owners = undefined; - } - }, - - clone: function() { - var stops = []; - for (var i = 0, l = this._stops.length; i < l; i++) - stops[i] = this._stops[i].clone(); - return new Gradient(stops, this._radial); - }, - - getStops: function() { - return this._stops; - }, - - setStops: function(stops) { - if (this.stops) { - for (var i = 0, l = this._stops.length; i < l; i++) - this._stops[i]._owner = undefined; - } - if (stops.length < 2) - throw new Error( - 'Gradient stop list needs to contain at least two stops.'); - this._stops = GradientStop.readAll(stops, 0, { clone: true }); - for (var i = 0, l = this._stops.length; i < l; i++) { - var stop = this._stops[i]; - stop._owner = this; - if (stop._defaultRamp) - stop.setRampPoint(i / (l - 1)); - } - this._changed(); - }, - - getRadial: function() { - return this._radial; - }, - - setRadial: function(radial) { - this._radial = radial; - this._changed(); - }, - - equals: function(gradient) { - if (gradient === this) - return true; - if (gradient && this._class === gradient._class - && this._stops.length === gradient._stops.length) { - for (var i = 0, l = this._stops.length; i < l; i++) { - if (!this._stops[i].equals(gradient._stops[i])) - return false; - } - return true; - } - return false; - } -}); - -var GradientStop = Base.extend({ - _class: 'GradientStop', - - initialize: function GradientStop(arg0, arg1) { - if (arg0) { - var color, rampPoint; - if (arg1 === undefined && Array.isArray(arg0)) { - color = arg0[0]; - rampPoint = arg0[1]; - } else if (arg0.color) { - color = arg0.color; - rampPoint = arg0.rampPoint; - } else { - color = arg0; - rampPoint = arg1; - } - this.setColor(color); - this.setRampPoint(rampPoint); - } - }, - - clone: function() { - return new GradientStop(this._color.clone(), this._rampPoint); - }, - - _serialize: function(options, dictionary) { - return Base.serialize([this._color, this._rampPoint], options, true, - dictionary); - }, - - _changed: function() { - if (this._owner) - this._owner._changed(65); - }, - - getRampPoint: function() { - return this._rampPoint; - }, - - setRampPoint: function(rampPoint) { - this._defaultRamp = rampPoint == null; - this._rampPoint = rampPoint || 0; - this._changed(); - }, - - getColor: function() { - return this._color; - }, - - setColor: function(color) { - this._color = Color.read(arguments); - if (this._color === color) - this._color = color.clone(); - this._color._owner = this; - this._changed(); - }, - - equals: function(stop) { - return stop === this || stop && this._class === stop._class - && this._color.equals(stop._color) - && this._rampPoint == stop._rampPoint - || false; - } -}); - -var Style = Base.extend(new function() { - var defaults = { - fillColor: undefined, - strokeColor: undefined, - strokeWidth: 1, - strokeCap: 'butt', - strokeJoin: 'miter', - strokeScaling: true, - miterLimit: 10, - dashOffset: 0, - dashArray: [], - windingRule: 'nonzero', - shadowColor: undefined, - shadowBlur: 0, - shadowOffset: new Point(), - selectedColor: undefined, - fontFamily: 'sans-serif', - fontWeight: 'normal', - fontSize: 12, - font: 'sans-serif', - leading: null, - justification: 'left' - }; - - var flags = { - strokeWidth: 97, - strokeCap: 97, - strokeJoin: 97, - strokeScaling: 105, - miterLimit: 97, - fontFamily: 9, - fontWeight: 9, - fontSize: 9, - font: 9, - leading: 9, - justification: 9 - }; - - var item = { beans: true }, - fields = { - _defaults: defaults, - _textDefaults: new Base(defaults, { - fillColor: new Color() - }), - beans: true - }; - - Base.each(defaults, function(value, key) { - var isColor = /Color$/.test(key), - isPoint = key === 'shadowOffset', - part = Base.capitalize(key), - flag = flags[key], - set = 'set' + part, - get = 'get' + part; - - fields[set] = function(value) { - var owner = this._owner, - children = owner && owner._children; - if (children && children.length > 0 - && !(owner instanceof CompoundPath)) { - for (var i = 0, l = children.length; i < l; i++) - children[i]._style[set](value); - } else { - var old = this._values[key]; - if (old !== value) { - if (isColor) { - if (old) - old._owner = undefined; - if (value && value.constructor === Color) { - if (value._owner) - value = value.clone(); - value._owner = owner; - } - } - this._values[key] = value; - if (owner) - owner._changed(flag || 65); - } - } - }; - - fields[get] = function(_dontMerge) { - var owner = this._owner, - children = owner && owner._children, - value; - if (!children || children.length === 0 || _dontMerge - || owner instanceof CompoundPath) { - var value = this._values[key]; - if (value === undefined) { - value = this._defaults[key]; - if (value && value.clone) - value = value.clone(); - } else { - var ctor = isColor ? Color : isPoint ? Point : null; - if (ctor && !(value && value.constructor === ctor)) { - this._values[key] = value = ctor.read([value], 0, - { readNull: true, clone: true }); - if (value && isColor) - value._owner = owner; - } - } - return value; - } - for (var i = 0, l = children.length; i < l; i++) { - var childValue = children[i]._style[get](); - if (i === 0) { - value = childValue; - } else if (!Base.equals(value, childValue)) { - return undefined; - } - } - return value; - }; - - item[get] = function(_dontMerge) { - return this._style[get](_dontMerge); - }; - - item[set] = function(value) { - this._style[set](value); - }; - }); - - Item.inject(item); - return fields; -}, { - _class: 'Style', - - initialize: function Style(style, _owner, _project) { - this._values = {}; - this._owner = _owner; - this._project = _owner && _owner._project || _project || paper.project; - if (_owner instanceof TextItem) - this._defaults = this._textDefaults; - if (style) - this.set(style); - }, - - set: function(style) { - var isStyle = style instanceof Style, - values = isStyle ? style._values : style; - if (values) { - for (var key in values) { - if (key in this._defaults) { - var value = values[key]; - this[key] = value && isStyle && value.clone - ? value.clone() : value; - } - } - } - }, - - equals: function(style) { - return style === this || style && this._class === style._class - && Base.equals(this._values, style._values) - || false; - }, - - hasFill: function() { - return !!this.getFillColor(); - }, - - hasStroke: function() { - return !!this.getStrokeColor() && this.getStrokeWidth() > 0; - }, - - hasShadow: function() { - return !!this.getShadowColor() && this.getShadowBlur() > 0; - }, - - getView: function() { - return this._project.getView(); - }, - - getFontStyle: function() { - var fontSize = this.getFontSize(); - return this.getFontWeight() - + ' ' + fontSize + (/[a-z]/i.test(fontSize + '') ? ' ' : 'px ') - + this.getFontFamily(); - }, - - getFont: '#getFontFamily', - setFont: '#setFontFamily', - - getLeading: function getLeading() { - var leading = getLeading.base.call(this), - fontSize = this.getFontSize(); - if (/pt|em|%|px/.test(fontSize)) - fontSize = this.getView().getPixelSize(fontSize); - return leading != null ? leading : fontSize * 1.2; - } - -}); - -var DomElement = new function() { - function handlePrefix(el, name, set, value) { - var prefixes = ['', 'webkit', 'moz', 'Moz', 'ms', 'o'], - suffix = name[0].toUpperCase() + name.substring(1); - for (var i = 0; i < 6; i++) { - var prefix = prefixes[i], - key = prefix ? prefix + suffix : name; - if (key in el) { - if (set) { - el[key] = value; - } else { - return el[key]; - } - break; - } - } - } - - return { - getStyles: function(el) { - var doc = el && el.nodeType !== 9 ? el.ownerDocument : el, - view = doc && doc.defaultView; - return view && view.getComputedStyle(el, ''); - }, - - getBounds: function(el, viewport) { - var doc = el.ownerDocument, - body = doc.body, - html = doc.documentElement, - rect; - try { - rect = el.getBoundingClientRect(); - } catch (e) { - rect = { left: 0, top: 0, width: 0, height: 0 }; - } - var x = rect.left - (html.clientLeft || body.clientLeft || 0), - y = rect.top - (html.clientTop || body.clientTop || 0); - if (!viewport) { - var view = doc.defaultView; - x += view.pageXOffset || html.scrollLeft || body.scrollLeft; - y += view.pageYOffset || html.scrollTop || body.scrollTop; - } - return new Rectangle(x, y, rect.width, rect.height); - }, - - getViewportBounds: function(el) { - var doc = el.ownerDocument, - view = doc.defaultView, - html = doc.documentElement; - return new Rectangle(0, 0, - view.innerWidth || html.clientWidth, - view.innerHeight || html.clientHeight - ); - }, - - getOffset: function(el, viewport) { - return DomElement.getBounds(el, viewport).getPoint(); - }, - - getSize: function(el) { - return DomElement.getBounds(el, true).getSize(); - }, - - isInvisible: function(el) { - return DomElement.getSize(el).equals(new Size(0, 0)); - }, - - isInView: function(el) { - return !DomElement.isInvisible(el) - && DomElement.getViewportBounds(el).intersects( - DomElement.getBounds(el, true)); - }, - - getPrefixed: function(el, name) { - return handlePrefix(el, name); - }, - - setPrefixed: function(el, name, value) { - if (typeof name === 'object') { - for (var key in name) - handlePrefix(el, key, true, name[key]); - } else { - handlePrefix(el, name, true, value); - } - } - }; -}; - -var DomEvent = { - add: function(el, events) { - for (var type in events) { - var func = events[type], - parts = type.split(/[\s,]+/g); - for (var i = 0, l = parts.length; i < l; i++) - el.addEventListener(parts[i], func, false); - } - }, - - remove: function(el, events) { - for (var type in events) { - var func = events[type], - parts = type.split(/[\s,]+/g); - for (var i = 0, l = parts.length; i < l; i++) - el.removeEventListener(parts[i], func, false); - } - }, - - getPoint: function(event) { - var pos = event.targetTouches - ? event.targetTouches.length - ? event.targetTouches[0] - : event.changedTouches[0] - : event; - return new Point( - pos.pageX || pos.clientX + document.documentElement.scrollLeft, - pos.pageY || pos.clientY + document.documentElement.scrollTop - ); - }, - - getTarget: function(event) { - return event.target || event.srcElement; - }, - - getRelatedTarget: function(event) { - return event.relatedTarget || event.toElement; - }, - - getOffset: function(event, target) { - return DomEvent.getPoint(event).subtract(DomElement.getOffset( - target || DomEvent.getTarget(event))); - }, - - stop: function(event) { - event.stopPropagation(); - event.preventDefault(); - } -}; - -DomEvent.requestAnimationFrame = new function() { - var nativeRequest = DomElement.getPrefixed(window, 'requestAnimationFrame'), - requested = false, - callbacks = [], - focused = true, - timer; - - DomEvent.add(window, { - focus: function() { - focused = true; - }, - blur: function() { - focused = false; - } - }); - - function handleCallbacks() { - for (var i = callbacks.length - 1; i >= 0; i--) { - var entry = callbacks[i], - func = entry[0], - el = entry[1]; - if (!el || (PaperScope.getAttribute(el, 'keepalive') == 'true' - || focused) && DomElement.isInView(el)) { - callbacks.splice(i, 1); - func(); - } - } - if (nativeRequest) { - if (callbacks.length) { - nativeRequest(handleCallbacks); - } else { - requested = false; - } - } - } - - return function(callback, element) { - callbacks.push([callback, element]); - if (nativeRequest) { - if (!requested) { - nativeRequest(handleCallbacks); - requested = true; - } - } else if (!timer) { - timer = setInterval(handleCallbacks, 1000 / 60); - } - }; -}; - -var View = Base.extend(Emitter, { - _class: 'View', - - initialize: function View(project, element) { - this._project = project; - this._scope = project._scope; - this._element = element; - var size; - if (!this._pixelRatio) - this._pixelRatio = window.devicePixelRatio || 1; - this._id = element.getAttribute('id'); - if (this._id == null) - element.setAttribute('id', this._id = 'view-' + View._id++); - DomEvent.add(element, this._viewEvents); - var none = 'none'; - DomElement.setPrefixed(element.style, { - userSelect: none, - touchAction: none, - touchCallout: none, - contentZooming: none, - userDrag: none, - tapHighlightColor: 'rgba(0,0,0,0)' - }); - - function getSize(name) { - return element[name] || parseInt(element.getAttribute(name), 10); - }; - - function getCanvasSize() { - var size = DomElement.getSize(element); - return size.isNaN() || size.isZero() - ? new Size(getSize('width'), getSize('height')) - : size; - }; - - if (PaperScope.hasAttribute(element, 'resize')) { - var that = this; - DomEvent.add(window, this._windowEvents = { - resize: function() { - that.setViewSize(getCanvasSize()); - } - }); - } - this._setViewSize(size = getCanvasSize()); - if (PaperScope.hasAttribute(element, 'stats') - && typeof Stats !== 'undefined') { - this._stats = new Stats(); - var stats = this._stats.domElement, - style = stats.style, - offset = DomElement.getOffset(element); - style.position = 'absolute'; - style.left = offset.x + 'px'; - style.top = offset.y + 'px'; - document.body.appendChild(stats); - } - View._views.push(this); - View._viewsById[this._id] = this; - this._viewSize = size; - (this._matrix = new Matrix())._owner = this; - this._zoom = 1; - if (!View._focused) - View._focused = this; - this._frameItems = {}; - this._frameItemCount = 0; - }, - - remove: function() { - if (!this._project) - return false; - if (View._focused === this) - View._focused = null; - View._views.splice(View._views.indexOf(this), 1); - delete View._viewsById[this._id]; - if (this._project._view === this) - this._project._view = null; - DomEvent.remove(this._element, this._viewEvents); - DomEvent.remove(window, this._windowEvents); - this._element = this._project = null; - this.off('frame'); - this._animate = false; - this._frameItems = {}; - return true; - }, - - _events: Base.each(['onResize', 'onMouseDown', 'onMouseUp', 'onMouseMove'], - function(name) { - this[name] = { - install: function(type) { - this._installEvent(type); - }, - - uninstall: function(type) { - this._uninstallEvent(type); - } - }; - }, { - onFrame: { - install: function() { - this.play(); - }, - - uninstall: function() { - this.pause(); - } - } - } - ), - - _animate: false, - _time: 0, - _count: 0, - - _requestFrame: function() { - var that = this; - DomEvent.requestAnimationFrame(function() { - that._requested = false; - if (!that._animate) - return; - that._requestFrame(); - that._handleFrame(); - }, this._element); - this._requested = true; - }, - - _handleFrame: function() { - paper = this._scope; - var now = Date.now() / 1000, - delta = this._before ? now - this._before : 0; - this._before = now; - this._handlingFrame = true; - this.emit('frame', new Base({ - delta: delta, - time: this._time += delta, - count: this._count++ - })); - if (this._stats) - this._stats.update(); - this._handlingFrame = false; - this.update(); - }, - - _animateItem: function(item, animate) { - var items = this._frameItems; - if (animate) { - items[item._id] = { - item: item, - time: 0, - count: 0 - }; - if (++this._frameItemCount === 1) - this.on('frame', this._handleFrameItems); - } else { - delete items[item._id]; - if (--this._frameItemCount === 0) { - this.off('frame', this._handleFrameItems); - } - } - }, - - _handleFrameItems: function(event) { - for (var i in this._frameItems) { - var entry = this._frameItems[i]; - entry.item.emit('frame', new Base(event, { - time: entry.time += event.delta, - count: entry.count++ - })); - } - }, - - _update: function() { - this._project._needsUpdate = true; - if (this._handlingFrame) - return; - if (this._animate) { - this._handleFrame(); - } else { - this.update(); - } - }, - - _changed: function(flags) { - if (flags & 1) - this._project._needsUpdate = true; - }, - - _transform: function(matrix) { - this._matrix.concatenate(matrix); - this._bounds = null; - this._update(); - }, - - getElement: function() { - return this._element; - }, - - getPixelRatio: function() { - return this._pixelRatio; - }, - - getResolution: function() { - return this._pixelRatio * 72; - }, - - getViewSize: function() { - var size = this._viewSize; - return new LinkedSize(size.width, size.height, this, 'setViewSize'); - }, - - setViewSize: function() { - var size = Size.read(arguments), - delta = size.subtract(this._viewSize); - if (delta.isZero()) - return; - this._viewSize.set(size.width, size.height); - this._setViewSize(size); - this._bounds = null; - this.emit('resize', { - size: size, - delta: delta - }); - this._update(); - }, - - _setViewSize: function(size) { - var element = this._element; - element.width = size.width; - element.height = size.height; - }, - - getBounds: function() { - if (!this._bounds) - this._bounds = this._matrix.inverted()._transformBounds( - new Rectangle(new Point(), this._viewSize)); - return this._bounds; - }, - - getSize: function() { - return this.getBounds().getSize(); - }, - - getCenter: function() { - return this.getBounds().getCenter(); - }, - - setCenter: function() { - var center = Point.read(arguments); - this.scrollBy(center.subtract(this.getCenter())); - }, - - getZoom: function() { - return this._zoom; - }, - - setZoom: function(zoom) { - this._transform(new Matrix().scale(zoom / this._zoom, - this.getCenter())); - this._zoom = zoom; - }, - - isVisible: function() { - return DomElement.isInView(this._element); - }, - - scrollBy: function() { - this._transform(new Matrix().translate(Point.read(arguments).negate())); - }, - - play: function() { - this._animate = true; - if (!this._requested) - this._requestFrame(); - }, - - pause: function() { - this._animate = false; - }, - - draw: function() { - this.update(); - }, - - projectToView: function() { - return this._matrix._transformPoint(Point.read(arguments)); - }, - - viewToProject: function() { - return this._matrix._inverseTransform(Point.read(arguments)); - } - -}, { - statics: { - _views: [], - _viewsById: {}, - _id: 0, - - create: function(project, element) { - if (typeof element === 'string') - element = document.getElementById(element); - return new CanvasView(project, element); - } - } -}, -new function() { - var tool, - prevFocus, - tempFocus, - dragging = false; - - function getView(event) { - var target = DomEvent.getTarget(event); - return target.getAttribute && View._viewsById[target.getAttribute('id')]; - } - - function viewToProject(view, event) { - return view.viewToProject(DomEvent.getOffset(event, view._element)); - } - - function updateFocus() { - if (!View._focused || !View._focused.isVisible()) { - for (var i = 0, l = View._views.length; i < l; i++) { - var view = View._views[i]; - if (view && view.isVisible()) { - View._focused = tempFocus = view; - break; - } - } - } - } - - function handleMouseMove(view, point, event) { - view._handleEvent('mousemove', point, event); - var tool = view._scope.tool; - if (tool) { - tool._handleEvent(dragging && tool.responds('mousedrag') - ? 'mousedrag' : 'mousemove', point, event); - } - view.update(); - return tool; - } - - var navigator = window.navigator, - mousedown, mousemove, mouseup; - if (navigator.pointerEnabled || navigator.msPointerEnabled) { - mousedown = 'pointerdown MSPointerDown'; - mousemove = 'pointermove MSPointerMove'; - mouseup = 'pointerup pointercancel MSPointerUp MSPointerCancel'; - } else { - mousedown = 'touchstart'; - mousemove = 'touchmove'; - mouseup = 'touchend touchcancel'; - if (!('ontouchstart' in window && navigator.userAgent.match( - /mobile|tablet|ip(ad|hone|od)|android|silk/i))) { - mousedown += ' mousedown'; - mousemove += ' mousemove'; - mouseup += ' mouseup'; - } - } - - var viewEvents = { - 'selectstart dragstart': function(event) { - if (dragging) - event.preventDefault(); - } - }; - - var docEvents = { - mouseout: function(event) { - var view = View._focused, - target = DomEvent.getRelatedTarget(event); - if (view && (!target || target.nodeName === 'HTML')) - handleMouseMove(view, viewToProject(view, event), event); - }, - - scroll: updateFocus - }; - - viewEvents[mousedown] = function(event) { - var view = View._focused = getView(event), - point = viewToProject(view, event); - dragging = true; - view._handleEvent('mousedown', point, event); - if (tool = view._scope.tool) - tool._handleEvent('mousedown', point, event); - view.update(); - }; - - docEvents[mousemove] = function(event) { - var view = View._focused; - if (!dragging) { - var target = getView(event); - if (target) { - if (view !== target) - handleMouseMove(view, viewToProject(view, event), event); - prevFocus = view; - view = View._focused = tempFocus = target; - } else if (tempFocus && tempFocus === view) { - view = View._focused = prevFocus; - updateFocus(); - } - } - if (view) { - var point = viewToProject(view, event); - if (dragging || view.getBounds().contains(point)) - tool = handleMouseMove(view, point, event); - } - }; - - docEvents[mouseup] = function(event) { - var view = View._focused; - if (!view || !dragging) - return; - var point = viewToProject(view, event); - dragging = false; - view._handleEvent('mouseup', point, event); - if (tool) - tool._handleEvent('mouseup', point, event); - view.update(); - }; - - DomEvent.add(document, docEvents); - - DomEvent.add(window, { - load: updateFocus - }); - - var mouseFlags = { - mousedown: { - mousedown: 1, - mousedrag: 1, - click: 1, - doubleclick: 1 - }, - mouseup: { - mouseup: 1, - mousedrag: 1, - click: 1, - doubleclick: 1 - }, - mousemove: { - mousedrag: 1, - mousemove: 1, - mouseenter: 1, - mouseleave: 1 - } - }; - - return { - _viewEvents: viewEvents, - - _handleEvent: function() {}, - - _installEvent: function(type) { - var counters = this._eventCounters; - if (counters) { - for (var key in mouseFlags) { - counters[key] = (counters[key] || 0) - + (mouseFlags[key][type] || 0); - } - } - }, - - _uninstallEvent: function(type) { - var counters = this._eventCounters; - if (counters) { - for (var key in mouseFlags) - counters[key] -= mouseFlags[key][type] || 0; - } - }, - - statics: { - updateFocus: updateFocus - } - }; -}); - -var CanvasView = View.extend({ - _class: 'CanvasView', - - initialize: function CanvasView(project, canvas) { - if (!(canvas instanceof HTMLCanvasElement)) { - var size = Size.read(arguments, 1); - if (size.isZero()) - throw new Error( - 'Cannot create CanvasView with the provided argument: ' - + [].slice.call(arguments, 1)); - canvas = CanvasProvider.getCanvas(size); - } - this._context = canvas.getContext('2d'); - this._eventCounters = {}; - this._pixelRatio = 1; - if (!/^off|false$/.test(PaperScope.getAttribute(canvas, 'hidpi'))) { - var deviceRatio = window.devicePixelRatio || 1, - backingStoreRatio = DomElement.getPrefixed(this._context, - 'backingStorePixelRatio') || 1; - this._pixelRatio = deviceRatio / backingStoreRatio; - } - View.call(this, project, canvas); - }, - - _setViewSize: function(size) { - var element = this._element, - pixelRatio = this._pixelRatio, - width = size.width, - height = size.height; - element.width = width * pixelRatio; - element.height = height * pixelRatio; - if (pixelRatio !== 1) { - if (!PaperScope.hasAttribute(element, 'resize')) { - var style = element.style; - style.width = width + 'px'; - style.height = height + 'px'; - } - this._context.scale(pixelRatio, pixelRatio); - } - }, - - getPixelSize: function(size) { - var browser = paper.browser, - pixels; - if (browser && browser.firefox) { - var parent = this._element.parentNode, - temp = document.createElement('div'); - temp.style.fontSize = size; - parent.appendChild(temp); - pixels = parseFloat(DomElement.getStyles(temp).fontSize); - parent.removeChild(temp); - } else { - var ctx = this._context, - prevFont = ctx.font; - ctx.font = size + ' serif'; - pixels = parseFloat(ctx.font); - ctx.font = prevFont; - } - return pixels; - }, - - getTextWidth: function(font, lines) { - var ctx = this._context, - prevFont = ctx.font, - width = 0; - ctx.font = font; - for (var i = 0, l = lines.length; i < l; i++) - width = Math.max(width, ctx.measureText(lines[i]).width); - ctx.font = prevFont; - return width; - }, - - update: function(force) { - var project = this._project; - if (!project || !force && !project._needsUpdate) - return false; - var ctx = this._context, - size = this._viewSize; - ctx.clearRect(0, 0, size.width + 1, size.height + 1); - project.draw(ctx, this._matrix, this._pixelRatio); - project._needsUpdate = false; - return true; - } -}, -new function() { - var downPoint, - lastPoint, - overPoint, - downItem, - lastItem, - overItem, - dragItem, - dblClick, - clickTime; - - function callEvent(view, type, event, point, target, lastPoint) { - var item = target, - mouseEvent; - - function call(obj) { - if (obj.responds(type)) { - if (!mouseEvent) { - mouseEvent = new MouseEvent(type, event, point, target, - lastPoint ? point.subtract(lastPoint) : null); - } - if (obj.emit(type, mouseEvent) && mouseEvent.isStopped) { - event.preventDefault(); - return true; - } - } - } - - while (item) { - if (call(item)) - return true; - item = item.getParent(); - } - if (call(view)) - return true; - return false; - } - - return { - _handleEvent: function(type, point, event) { - if (!this._eventCounters[type]) - return; - var project = this._project, - hit = project.hitTest(point, { - tolerance: 0, - fill: true, - stroke: true - }), - item = hit && hit.item, - stopped = false; - switch (type) { - case 'mousedown': - stopped = callEvent(this, type, event, point, item); - dblClick = lastItem == item && (Date.now() - clickTime < 300); - downItem = lastItem = item; - downPoint = lastPoint = overPoint = point; - dragItem = !stopped && item; - while (dragItem && !dragItem.responds('mousedrag')) - dragItem = dragItem._parent; - break; - case 'mouseup': - stopped = callEvent(this, type, event, point, item, downPoint); - if (dragItem) { - if (lastPoint && !lastPoint.equals(point)) - callEvent(this, 'mousedrag', event, point, dragItem, - lastPoint); - if (item !== dragItem) { - overPoint = point; - callEvent(this, 'mousemove', event, point, item, - overPoint); - } - } - if (!stopped && item && item === downItem) { - clickTime = Date.now(); - callEvent(this, dblClick && downItem.responds('doubleclick') - ? 'doubleclick' : 'click', event, downPoint, item); - dblClick = false; - } - downItem = dragItem = null; - break; - case 'mousemove': - if (dragItem) - stopped = callEvent(this, 'mousedrag', event, point, - dragItem, lastPoint); - if (!stopped) { - if (item !== overItem) - overPoint = point; - stopped = callEvent(this, type, event, point, item, - overPoint); - } - lastPoint = overPoint = point; - if (item !== overItem) { - callEvent(this, 'mouseleave', event, point, overItem); - overItem = item; - callEvent(this, 'mouseenter', event, point, item); - } - break; - } - return stopped; - } - }; -}); - -var Event = Base.extend({ - _class: 'Event', - - initialize: function Event(event) { - this.event = event; - }, - - isPrevented: false, - isStopped: false, - - preventDefault: function() { - this.isPrevented = true; - this.event.preventDefault(); - }, - - stopPropagation: function() { - this.isStopped = true; - this.event.stopPropagation(); - }, - - stop: function() { - this.stopPropagation(); - this.preventDefault(); - }, - - getModifiers: function() { - return Key.modifiers; - } -}); - -var KeyEvent = Event.extend({ - _class: 'KeyEvent', - - initialize: function KeyEvent(down, key, character, event) { - Event.call(this, event); - this.type = down ? 'keydown' : 'keyup'; - this.key = key; - this.character = character; - }, - - toString: function() { - return "{ type: '" + this.type - + "', key: '" + this.key - + "', character: '" + this.character - + "', modifiers: " + this.getModifiers() - + " }"; - } -}); - -var Key = new function() { - - var specialKeys = { - 8: 'backspace', - 9: 'tab', - 13: 'enter', - 16: 'shift', - 17: 'control', - 18: 'option', - 19: 'pause', - 20: 'caps-lock', - 27: 'escape', - 32: 'space', - 35: 'end', - 36: 'home', - 37: 'left', - 38: 'up', - 39: 'right', - 40: 'down', - 46: 'delete', - 91: 'command', - 93: 'command', - 224: 'command' - }, - - specialChars = { - 9: true, - 13: true, - 32: true - }, - - modifiers = new Base({ - shift: false, - control: false, - option: false, - command: false, - capsLock: false, - space: false - }), - - charCodeMap = {}, - keyMap = {}, - commandFixMap, - downCode; - - function handleKey(down, keyCode, charCode, event) { - var character = charCode ? String.fromCharCode(charCode) : '', - specialKey = specialKeys[keyCode], - key = specialKey || character.toLowerCase(), - type = down ? 'keydown' : 'keyup', - view = View._focused, - scope = view && view.isVisible() && view._scope, - tool = scope && scope.tool, - name; - keyMap[key] = down; - if (down) { - charCodeMap[keyCode] = charCode; - } else { - delete charCodeMap[keyCode]; - } - if (specialKey && (name = Base.camelize(specialKey)) in modifiers) { - modifiers[name] = down; - var browser = paper.browser; - if (name === 'command' && browser && browser.mac) { - if (down) { - commandFixMap = {}; - } else { - for (var code in commandFixMap) { - if (code in charCodeMap) - handleKey(false, code, commandFixMap[code], event); - } - commandFixMap = null; - } - } - } else if (down && commandFixMap) { - commandFixMap[keyCode] = charCode; - } - if (tool && tool.responds(type)) { - paper = scope; - tool.emit(type, new KeyEvent(down, key, character, event)); - if (view) - view.update(); - } - } - - DomEvent.add(document, { - keydown: function(event) { - var code = event.which || event.keyCode; - if (code in specialKeys || modifiers.command) { - handleKey(true, code, - code in specialChars || modifiers.command ? code : 0, - event); - } else { - downCode = code; - } - }, - - keypress: function(event) { - if (downCode != null) { - handleKey(true, downCode, event.which || event.keyCode, event); - downCode = null; - } - }, - - keyup: function(event) { - var code = event.which || event.keyCode; - if (code in charCodeMap) - handleKey(false, code, charCodeMap[code], event); - } - }); - - DomEvent.add(window, { - blur: function(event) { - for (var code in charCodeMap) - handleKey(false, code, charCodeMap[code], event); - } - }); - - return { - modifiers: modifiers, - - isDown: function(key) { - return !!keyMap[key]; - } - }; -}; - -var MouseEvent = Event.extend({ - _class: 'MouseEvent', - - initialize: function MouseEvent(type, event, point, target, delta) { - Event.call(this, event); - this.type = type; - this.point = point; - this.target = target; - this.delta = delta; - }, - - toString: function() { - return "{ type: '" + this.type - + "', point: " + this.point - + ', target: ' + this.target - + (this.delta ? ', delta: ' + this.delta : '') - + ', modifiers: ' + this.getModifiers() - + ' }'; - } -}); - -var ToolEvent = Event.extend({ - _class: 'ToolEvent', - _item: null, - - initialize: function ToolEvent(tool, type, event) { - this.tool = tool; - this.type = type; - this.event = event; - }, - - _choosePoint: function(point, toolPoint) { - return point ? point : toolPoint ? toolPoint.clone() : null; - }, - - getPoint: function() { - return this._choosePoint(this._point, this.tool._point); - }, - - setPoint: function(point) { - this._point = point; - }, - - getLastPoint: function() { - return this._choosePoint(this._lastPoint, this.tool._lastPoint); - }, - - setLastPoint: function(lastPoint) { - this._lastPoint = lastPoint; - }, - - getDownPoint: function() { - return this._choosePoint(this._downPoint, this.tool._downPoint); - }, - - setDownPoint: function(downPoint) { - this._downPoint = downPoint; - }, - - getMiddlePoint: function() { - if (!this._middlePoint && this.tool._lastPoint) { - return this.tool._point.add(this.tool._lastPoint).divide(2); - } - return this._middlePoint; - }, - - setMiddlePoint: function(middlePoint) { - this._middlePoint = middlePoint; - }, - - getDelta: function() { - return !this._delta && this.tool._lastPoint - ? this.tool._point.subtract(this.tool._lastPoint) - : this._delta; - }, - - setDelta: function(delta) { - this._delta = delta; - }, - - getCount: function() { - return /^mouse(down|up)$/.test(this.type) - ? this.tool._downCount - : this.tool._count; - }, - - setCount: function(count) { - this.tool[/^mouse(down|up)$/.test(this.type) ? 'downCount' : 'count'] - = count; - }, - - getItem: function() { - if (!this._item) { - var result = this.tool._scope.project.hitTest(this.getPoint()); - if (result) { - var item = result.item, - parent = item._parent; - while (/^(Group|CompoundPath)$/.test(parent._class)) { - item = parent; - parent = parent._parent; - } - this._item = item; - } - } - return this._item; - }, - - setItem: function(item) { - this._item = item; - }, - - toString: function() { - return '{ type: ' + this.type - + ', point: ' + this.getPoint() - + ', count: ' + this.getCount() - + ', modifiers: ' + this.getModifiers() - + ' }'; - } -}); - -var Tool = PaperScopeItem.extend({ - _class: 'Tool', - _list: 'tools', - _reference: 'tool', - _events: [ 'onActivate', 'onDeactivate', 'onEditOptions', - 'onMouseDown', 'onMouseUp', 'onMouseDrag', 'onMouseMove', - 'onKeyDown', 'onKeyUp' ], - - initialize: function Tool(props) { - PaperScopeItem.call(this); - this._firstMove = true; - this._count = 0; - this._downCount = 0; - this._set(props); - }, - - getMinDistance: function() { - return this._minDistance; - }, - - setMinDistance: function(minDistance) { - this._minDistance = minDistance; - if (minDistance != null && this._maxDistance != null - && minDistance > this._maxDistance) { - this._maxDistance = minDistance; - } - }, - - getMaxDistance: function() { - return this._maxDistance; - }, - - setMaxDistance: function(maxDistance) { - this._maxDistance = maxDistance; - if (this._minDistance != null && maxDistance != null - && maxDistance < this._minDistance) { - this._minDistance = maxDistance; - } - }, - - getFixedDistance: function() { - return this._minDistance == this._maxDistance - ? this._minDistance : null; - }, - - setFixedDistance: function(distance) { - this._minDistance = this._maxDistance = distance; - }, - - _updateEvent: function(type, point, minDistance, maxDistance, start, - needsChange, matchMaxDistance) { - if (!start) { - if (minDistance != null || maxDistance != null) { - var minDist = minDistance != null ? minDistance : 0, - vector = point.subtract(this._point), - distance = vector.getLength(); - if (distance < minDist) - return false; - if (maxDistance != null && maxDistance != 0) { - if (distance > maxDistance) { - point = this._point.add(vector.normalize(maxDistance)); - } else if (matchMaxDistance) { - return false; - } - } - } - if (needsChange && point.equals(this._point)) - return false; - } - this._lastPoint = start && type == 'mousemove' ? point : this._point; - this._point = point; - switch (type) { - case 'mousedown': - this._lastPoint = this._downPoint; - this._downPoint = this._point; - this._downCount++; - break; - case 'mouseup': - this._lastPoint = this._downPoint; - break; - } - this._count = start ? 0 : this._count + 1; - return true; - }, - - _fireEvent: function(type, event) { - var sets = paper.project._removeSets; - if (sets) { - if (type === 'mouseup') - sets.mousedrag = null; - var set = sets[type]; - if (set) { - for (var id in set) { - var item = set[id]; - for (var key in sets) { - var other = sets[key]; - if (other && other != set) - delete other[item._id]; - } - item.remove(); - } - sets[type] = null; - } - } - return this.responds(type) - && this.emit(type, new ToolEvent(this, type, event)); - }, - - _handleEvent: function(type, point, event) { - paper = this._scope; - var called = false; - switch (type) { - case 'mousedown': - this._updateEvent(type, point, null, null, true, false, false); - called = this._fireEvent(type, event); - break; - case 'mousedrag': - var needsChange = false, - matchMaxDistance = false; - while (this._updateEvent(type, point, this.minDistance, - this.maxDistance, false, needsChange, matchMaxDistance)) { - called = this._fireEvent(type, event) || called; - needsChange = true; - matchMaxDistance = true; - } - break; - case 'mouseup': - if (!point.equals(this._point) - && this._updateEvent('mousedrag', point, this.minDistance, - this.maxDistance, false, false, false)) { - called = this._fireEvent('mousedrag', event); - } - this._updateEvent(type, point, null, this.maxDistance, false, - false, false); - called = this._fireEvent(type, event) || called; - this._updateEvent(type, point, null, null, true, false, false); - this._firstMove = true; - break; - case 'mousemove': - while (this._updateEvent(type, point, this.minDistance, - this.maxDistance, this._firstMove, true, false)) { - called = this._fireEvent(type, event) || called; - this._firstMove = false; - } - break; - } - if (called) - event.preventDefault(); - return called; - } - -}); - -var Http = { - request: function(method, url, callback, async) { - async = (async === undefined) ? true : async; - var xhr = new (window.ActiveXObject || XMLHttpRequest)( - 'Microsoft.XMLHTTP'); - xhr.open(method.toUpperCase(), url, async); - if ('overrideMimeType' in xhr) - xhr.overrideMimeType('text/plain'); - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var status = xhr.status; - if (status === 0 || status === 200) { - callback.call(xhr, xhr.responseText); - } else { - throw new Error('Could not load ' + url + ' (Error ' - + status + ')'); - } - } - }; - return xhr.send(null); - } -}; - -var CanvasProvider = { - canvases: [], - - getCanvas: function(width, height) { - var canvas, - clear = true; - if (typeof width === 'object') { - height = width.height; - width = width.width; - } - if (this.canvases.length) { - canvas = this.canvases.pop(); - } else { - canvas = document.createElement('canvas'); - } - var ctx = canvas.getContext('2d'); - if (canvas.width === width && canvas.height === height) { - if (clear) - ctx.clearRect(0, 0, width + 1, height + 1); - } else { - canvas.width = width; - canvas.height = height; - } - ctx.save(); - return canvas; - }, - - getContext: function(width, height) { - return this.getCanvas(width, height).getContext('2d'); - }, - - release: function(obj) { - var canvas = obj.canvas ? obj.canvas : obj; - canvas.getContext('2d').restore(); - this.canvases.push(canvas); - } -}; - -var BlendMode = new function() { - var min = Math.min, - max = Math.max, - abs = Math.abs, - sr, sg, sb, sa, - br, bg, bb, ba, - dr, dg, db; - - function getLum(r, g, b) { - return 0.2989 * r + 0.587 * g + 0.114 * b; - } - - function setLum(r, g, b, l) { - var d = l - getLum(r, g, b); - dr = r + d; - dg = g + d; - db = b + d; - var l = getLum(dr, dg, db), - mn = min(dr, dg, db), - mx = max(dr, dg, db); - if (mn < 0) { - var lmn = l - mn; - dr = l + (dr - l) * l / lmn; - dg = l + (dg - l) * l / lmn; - db = l + (db - l) * l / lmn; - } - if (mx > 255) { - var ln = 255 - l, - mxl = mx - l; - dr = l + (dr - l) * ln / mxl; - dg = l + (dg - l) * ln / mxl; - db = l + (db - l) * ln / mxl; - } - } - - function getSat(r, g, b) { - return max(r, g, b) - min(r, g, b); - } - - function setSat(r, g, b, s) { - var col = [r, g, b], - mx = max(r, g, b), - mn = min(r, g, b), - md; - mn = mn === r ? 0 : mn === g ? 1 : 2; - mx = mx === r ? 0 : mx === g ? 1 : 2; - md = min(mn, mx) === 0 ? max(mn, mx) === 1 ? 2 : 1 : 0; - if (col[mx] > col[mn]) { - col[md] = (col[md] - col[mn]) * s / (col[mx] - col[mn]); - col[mx] = s; - } else { - col[md] = col[mx] = 0; - } - col[mn] = 0; - dr = col[0]; - dg = col[1]; - db = col[2]; - } - - var modes = { - multiply: function() { - dr = br * sr / 255; - dg = bg * sg / 255; - db = bb * sb / 255; - }, - - screen: function() { - dr = br + sr - (br * sr / 255); - dg = bg + sg - (bg * sg / 255); - db = bb + sb - (bb * sb / 255); - }, - - overlay: function() { - dr = br < 128 ? 2 * br * sr / 255 : 255 - 2 * (255 - br) * (255 - sr) / 255; - dg = bg < 128 ? 2 * bg * sg / 255 : 255 - 2 * (255 - bg) * (255 - sg) / 255; - db = bb < 128 ? 2 * bb * sb / 255 : 255 - 2 * (255 - bb) * (255 - sb) / 255; - }, - - 'soft-light': function() { - var t = sr * br / 255; - dr = t + br * (255 - (255 - br) * (255 - sr) / 255 - t) / 255; - t = sg * bg / 255; - dg = t + bg * (255 - (255 - bg) * (255 - sg) / 255 - t) / 255; - t = sb * bb / 255; - db = t + bb * (255 - (255 - bb) * (255 - sb) / 255 - t) / 255; - }, - - 'hard-light': function() { - dr = sr < 128 ? 2 * sr * br / 255 : 255 - 2 * (255 - sr) * (255 - br) / 255; - dg = sg < 128 ? 2 * sg * bg / 255 : 255 - 2 * (255 - sg) * (255 - bg) / 255; - db = sb < 128 ? 2 * sb * bb / 255 : 255 - 2 * (255 - sb) * (255 - bb) / 255; - }, - - 'color-dodge': function() { - dr = br === 0 ? 0 : sr === 255 ? 255 : min(255, 255 * br / (255 - sr)); - dg = bg === 0 ? 0 : sg === 255 ? 255 : min(255, 255 * bg / (255 - sg)); - db = bb === 0 ? 0 : sb === 255 ? 255 : min(255, 255 * bb / (255 - sb)); - }, - - 'color-burn': function() { - dr = br === 255 ? 255 : sr === 0 ? 0 : max(0, 255 - (255 - br) * 255 / sr); - dg = bg === 255 ? 255 : sg === 0 ? 0 : max(0, 255 - (255 - bg) * 255 / sg); - db = bb === 255 ? 255 : sb === 0 ? 0 : max(0, 255 - (255 - bb) * 255 / sb); - }, - - darken: function() { - dr = br < sr ? br : sr; - dg = bg < sg ? bg : sg; - db = bb < sb ? bb : sb; - }, - - lighten: function() { - dr = br > sr ? br : sr; - dg = bg > sg ? bg : sg; - db = bb > sb ? bb : sb; - }, - - difference: function() { - dr = br - sr; - if (dr < 0) - dr = -dr; - dg = bg - sg; - if (dg < 0) - dg = -dg; - db = bb - sb; - if (db < 0) - db = -db; - }, - - exclusion: function() { - dr = br + sr * (255 - br - br) / 255; - dg = bg + sg * (255 - bg - bg) / 255; - db = bb + sb * (255 - bb - bb) / 255; - }, - - hue: function() { - setSat(sr, sg, sb, getSat(br, bg, bb)); - setLum(dr, dg, db, getLum(br, bg, bb)); - }, - - saturation: function() { - setSat(br, bg, bb, getSat(sr, sg, sb)); - setLum(dr, dg, db, getLum(br, bg, bb)); - }, - - luminosity: function() { - setLum(br, bg, bb, getLum(sr, sg, sb)); - }, - - color: function() { - setLum(sr, sg, sb, getLum(br, bg, bb)); - }, - - add: function() { - dr = min(br + sr, 255); - dg = min(bg + sg, 255); - db = min(bb + sb, 255); - }, - - subtract: function() { - dr = max(br - sr, 0); - dg = max(bg - sg, 0); - db = max(bb - sb, 0); - }, - - average: function() { - dr = (br + sr) / 2; - dg = (bg + sg) / 2; - db = (bb + sb) / 2; - }, - - negation: function() { - dr = 255 - abs(255 - sr - br); - dg = 255 - abs(255 - sg - bg); - db = 255 - abs(255 - sb - bb); - } - }; - - var nativeModes = this.nativeModes = Base.each([ - 'source-over', 'source-in', 'source-out', 'source-atop', - 'destination-over', 'destination-in', 'destination-out', - 'destination-atop', 'lighter', 'darker', 'copy', 'xor' - ], function(mode) { - this[mode] = true; - }, {}); - - var ctx = CanvasProvider.getContext(1, 1); - Base.each(modes, function(func, mode) { - var darken = mode === 'darken', - ok = false; - ctx.save(); - try { - ctx.fillStyle = darken ? '#300' : '#a00'; - ctx.fillRect(0, 0, 1, 1); - ctx.globalCompositeOperation = mode; - if (ctx.globalCompositeOperation === mode) { - ctx.fillStyle = darken ? '#a00' : '#300'; - ctx.fillRect(0, 0, 1, 1); - ok = ctx.getImageData(0, 0, 1, 1).data[0] !== darken ? 170 : 51; - } - } catch (e) {} - ctx.restore(); - nativeModes[mode] = ok; - }); - CanvasProvider.release(ctx); - - this.process = function(mode, srcContext, dstContext, alpha, offset) { - var srcCanvas = srcContext.canvas, - normal = mode === 'normal'; - if (normal || nativeModes[mode]) { - dstContext.save(); - dstContext.setTransform(1, 0, 0, 1, 0, 0); - dstContext.globalAlpha = alpha; - if (!normal) - dstContext.globalCompositeOperation = mode; - dstContext.drawImage(srcCanvas, offset.x, offset.y); - dstContext.restore(); - } else { - var process = modes[mode]; - if (!process) - return; - var dstData = dstContext.getImageData(offset.x, offset.y, - srcCanvas.width, srcCanvas.height), - dst = dstData.data, - src = srcContext.getImageData(0, 0, - srcCanvas.width, srcCanvas.height).data; - for (var i = 0, l = dst.length; i < l; i += 4) { - sr = src[i]; - br = dst[i]; - sg = src[i + 1]; - bg = dst[i + 1]; - sb = src[i + 2]; - bb = dst[i + 2]; - sa = src[i + 3]; - ba = dst[i + 3]; - process(); - var a1 = sa * alpha / 255, - a2 = 1 - a1; - dst[i] = a1 * dr + a2 * br; - dst[i + 1] = a1 * dg + a2 * bg; - dst[i + 2] = a1 * db + a2 * bb; - dst[i + 3] = sa * alpha + a2 * ba; - } - dstContext.putImageData(dstData, offset.x, offset.y); - } - }; -}; - -var SVGStyles = Base.each({ - fillColor: ['fill', 'color'], - strokeColor: ['stroke', 'color'], - strokeWidth: ['stroke-width', 'number'], - strokeCap: ['stroke-linecap', 'string'], - strokeJoin: ['stroke-linejoin', 'string'], - strokeScaling: ['vector-effect', 'lookup', { - true: 'none', - false: 'non-scaling-stroke' - }, function(item, value) { - return !value - && (item instanceof PathItem - || item instanceof Shape - || item instanceof TextItem); - }], - miterLimit: ['stroke-miterlimit', 'number'], - dashArray: ['stroke-dasharray', 'array'], - dashOffset: ['stroke-dashoffset', 'number'], - fontFamily: ['font-family', 'string'], - fontWeight: ['font-weight', 'string'], - fontSize: ['font-size', 'number'], - justification: ['text-anchor', 'lookup', { - left: 'start', - center: 'middle', - right: 'end' - }], - opacity: ['opacity', 'number'], - blendMode: ['mix-blend-mode', 'string'] -}, function(entry, key) { - var part = Base.capitalize(key), - lookup = entry[2]; - this[key] = { - type: entry[1], - property: key, - attribute: entry[0], - toSVG: lookup, - fromSVG: lookup && Base.each(lookup, function(value, name) { - this[value] = name; - }, {}), - exportFilter: entry[3], - get: 'get' + part, - set: 'set' + part - }; -}, {}); - -var SVGNamespaces = { - href: 'http://www.w3.org/1999/xlink', - xlink: 'http://www.w3.org/2000/xmlns' -}; - -new function() { - var formatter; - - function setAttributes(node, attrs) { - for (var key in attrs) { - var val = attrs[key], - namespace = SVGNamespaces[key]; - if (typeof val === 'number') - val = formatter.number(val); - if (namespace) { - node.setAttributeNS(namespace, key, val); - } else { - node.setAttribute(key, val); - } - } - return node; - } - - function createElement(tag, attrs) { - return setAttributes( - document.createElementNS('http://www.w3.org/2000/svg', tag), attrs); - } - - function getTransform(matrix, coordinates, center) { - var attrs = new Base(), - trans = matrix.getTranslation(); - if (coordinates) { - matrix = matrix.shiftless(); - var point = matrix._inverseTransform(trans); - attrs[center ? 'cx' : 'x'] = point.x; - attrs[center ? 'cy' : 'y'] = point.y; - trans = null; - } - if (!matrix.isIdentity()) { - var decomposed = matrix.decompose(); - if (decomposed && !decomposed.shearing) { - var parts = [], - angle = decomposed.rotation, - scale = decomposed.scaling; - if (trans && !trans.isZero()) - parts.push('translate(' + formatter.point(trans) + ')'); - if (!Numerical.isZero(scale.x - 1) - || !Numerical.isZero(scale.y - 1)) - parts.push('scale(' + formatter.point(scale) +')'); - if (angle) - parts.push('rotate(' + formatter.number(angle) + ')'); - attrs.transform = parts.join(' '); - } else { - attrs.transform = 'matrix(' + matrix.getValues().join(',') + ')'; - } - } - return attrs; - } - - function exportGroup(item, options) { - var attrs = getTransform(item._matrix), - children = item._children; - var node = createElement('g', attrs); - for (var i = 0, l = children.length; i < l; i++) { - var child = children[i]; - var childNode = exportSVG(child, options); - if (childNode) { - if (child.isClipMask()) { - var clip = createElement('clipPath'); - clip.appendChild(childNode); - setDefinition(child, clip, 'clip'); - setAttributes(node, { - 'clip-path': 'url(#' + clip.id + ')' - }); - } else { - node.appendChild(childNode); - } - } - } - return node; - } - - function exportRaster(item, options) { - var attrs = getTransform(item._matrix, true), - size = item.getSize(), - image = item.getImage(); - attrs.x -= size.width / 2; - attrs.y -= size.height / 2; - attrs.width = size.width; - attrs.height = size.height; - attrs.href = options.embedImages === false && image && image.src - || item.toDataURL(); - return createElement('image', attrs); - } - - function exportPath(item, options) { - var matchShapes = options.matchShapes; - if (matchShapes) { - var shape = item.toShape(false); - if (shape) - return exportShape(shape, options); - } - var segments = item._segments, - type, - attrs = getTransform(item._matrix); - if (segments.length === 0) - return null; - if (matchShapes && !item.hasHandles()) { - if (segments.length >= 3) { - type = item._closed ? 'polygon' : 'polyline'; - var parts = []; - for(var i = 0, l = segments.length; i < l; i++) - parts.push(formatter.point(segments[i]._point)); - attrs.points = parts.join(' '); - } else { - type = 'line'; - var first = segments[0]._point, - last = segments[segments.length - 1]._point; - attrs.set({ - x1: first.x, - y1: first.y, - x2: last.x, - y2: last.y - }); - } - } else { - type = 'path'; - attrs.d = item.getPathData(null, options.precision); - } - return createElement(type, attrs); - } - - function exportShape(item) { - var type = item._type, - radius = item._radius, - attrs = getTransform(item._matrix, true, type !== 'rectangle'); - if (type === 'rectangle') { - type = 'rect'; - var size = item._size, - width = size.width, - height = size.height; - attrs.x -= width / 2; - attrs.y -= height / 2; - attrs.width = width; - attrs.height = height; - if (radius.isZero()) - radius = null; - } - if (radius) { - if (type === 'circle') { - attrs.r = radius; - } else { - attrs.rx = radius.width; - attrs.ry = radius.height; - } - } - return createElement(type, attrs); - } - - function exportCompoundPath(item, options) { - var attrs = getTransform(item._matrix); - var data = item.getPathData(null, options.precision); - if (data) - attrs.d = data; - return createElement('path', attrs); - } - - function exportPlacedSymbol(item, options) { - var attrs = getTransform(item._matrix, true), - symbol = item.getSymbol(), - symbolNode = getDefinition(symbol, 'symbol'), - definition = symbol.getDefinition(), - bounds = definition.getBounds(); - if (!symbolNode) { - symbolNode = createElement('symbol', { - viewBox: formatter.rectangle(bounds) - }); - symbolNode.appendChild(exportSVG(definition, options)); - setDefinition(symbol, symbolNode, 'symbol'); - } - attrs.href = '#' + symbolNode.id; - attrs.x += bounds.x; - attrs.y += bounds.y; - attrs.width = formatter.number(bounds.width); - attrs.height = formatter.number(bounds.height); - attrs.overflow = 'visible'; - return createElement('use', attrs); - } - - function exportGradient(color) { - var gradientNode = getDefinition(color, 'color'); - if (!gradientNode) { - var gradient = color.getGradient(), - radial = gradient._radial, - origin = color.getOrigin().transform(), - destination = color.getDestination().transform(), - attrs; - if (radial) { - attrs = { - cx: origin.x, - cy: origin.y, - r: origin.getDistance(destination) - }; - var highlight = color.getHighlight(); - if (highlight) { - highlight = highlight.transform(); - attrs.fx = highlight.x; - attrs.fy = highlight.y; - } - } else { - attrs = { - x1: origin.x, - y1: origin.y, - x2: destination.x, - y2: destination.y - }; - } - attrs.gradientUnits = 'userSpaceOnUse'; - gradientNode = createElement( - (radial ? 'radial' : 'linear') + 'Gradient', attrs); - var stops = gradient._stops; - for (var i = 0, l = stops.length; i < l; i++) { - var stop = stops[i], - stopColor = stop._color, - alpha = stopColor.getAlpha(); - attrs = { - offset: stop._rampPoint, - 'stop-color': stopColor.toCSS(true) - }; - if (alpha < 1) - attrs['stop-opacity'] = alpha; - gradientNode.appendChild(createElement('stop', attrs)); - } - setDefinition(color, gradientNode, 'color'); - } - return 'url(#' + gradientNode.id + ')'; - } - - function exportText(item) { - var node = createElement('text', getTransform(item._matrix, true)); - node.textContent = item._content; - return node; - } - - var exporters = { - Group: exportGroup, - Layer: exportGroup, - Raster: exportRaster, - Path: exportPath, - Shape: exportShape, - CompoundPath: exportCompoundPath, - PlacedSymbol: exportPlacedSymbol, - PointText: exportText - }; - - function applyStyle(item, node, isRoot) { - var attrs = {}, - parent = !isRoot && item.getParent(); - - if (item._name != null) - attrs.id = item._name; - - Base.each(SVGStyles, function(entry) { - var get = entry.get, - type = entry.type, - value = item[get](); - if (entry.exportFilter - ? entry.exportFilter(item, value) - : !parent || !Base.equals(parent[get](), value)) { - if (type === 'color' && value != null) { - var alpha = value.getAlpha(); - if (alpha < 1) - attrs[entry.attribute + '-opacity'] = alpha; - } - attrs[entry.attribute] = value == null - ? 'none' - : type === 'number' - ? formatter.number(value) - : type === 'color' - ? value.gradient - ? exportGradient(value, item) - : value.toCSS(true) - : type === 'array' - ? value.join(',') - : type === 'lookup' - ? entry.toSVG[value] - : value; - } - }); - - if (attrs.opacity === 1) - delete attrs.opacity; - - if (!item._visible) - attrs.visibility = 'hidden'; - - return setAttributes(node, attrs); - } - - var definitions; - function getDefinition(item, type) { - if (!definitions) - definitions = { ids: {}, svgs: {} }; - return item && definitions.svgs[type + '-' + item._id]; - } - - function setDefinition(item, node, type) { - if (!definitions) - getDefinition(); - var id = definitions.ids[type] = (definitions.ids[type] || 0) + 1; - node.id = type + '-' + id; - definitions.svgs[type + '-' + item._id] = node; - } - - function exportDefinitions(node, options) { - var svg = node, - defs = null; - if (definitions) { - svg = node.nodeName.toLowerCase() === 'svg' && node; - for (var i in definitions.svgs) { - if (!defs) { - if (!svg) { - svg = createElement('svg'); - svg.appendChild(node); - } - defs = svg.insertBefore(createElement('defs'), - svg.firstChild); - } - defs.appendChild(definitions.svgs[i]); - } - definitions = null; - } - return options.asString - ? new XMLSerializer().serializeToString(svg) - : svg; - } - - function exportSVG(item, options, isRoot) { - var exporter = exporters[item._class], - node = exporter && exporter(item, options); - if (node) { - var onExport = options.onExport; - if (onExport) - node = onExport(item, node, options) || node; - var data = JSON.stringify(item._data); - if (data && data !== '{}' && data !== 'null') - node.setAttribute('data-paper-data', data); - } - return node && applyStyle(item, node, isRoot); - } - - function setOptions(options) { - if (!options) - options = {}; - formatter = new Formatter(options.precision); - return options; - } - - Item.inject({ - exportSVG: function(options) { - options = setOptions(options); - return exportDefinitions(exportSVG(this, options, true), options); - } - }); - - Project.inject({ - exportSVG: function(options) { - options = setOptions(options); - var layers = this.layers, - view = this.getView(), - size = view.getViewSize(), - node = createElement('svg', { - x: 0, - y: 0, - width: size.width, - height: size.height, - version: '1.1', - xmlns: 'http://www.w3.org/2000/svg', - 'xmlns:xlink': 'http://www.w3.org/1999/xlink' - }), - parent = node, - matrix = view._matrix; - if (!matrix.isIdentity()) - parent = node.appendChild( - createElement('g', getTransform(matrix))); - for (var i = 0, l = layers.length; i < l; i++) - parent.appendChild(exportSVG(layers[i], options, true)); - return exportDefinitions(node, options); - } - }); -}; - -new function() { - - function getValue(node, name, isString, allowNull) { - var namespace = SVGNamespaces[name], - value = namespace - ? node.getAttributeNS(namespace, name) - : node.getAttribute(name); - if (value === 'null') - value = null; - return value == null - ? allowNull - ? null - : isString - ? '' - : 0 - : isString - ? value - : parseFloat(value); - } - - function getPoint(node, x, y, allowNull) { - x = getValue(node, x, false, allowNull); - y = getValue(node, y, false, allowNull); - return allowNull && (x == null || y == null) ? null - : new Point(x, y); - } - - function getSize(node, w, h, allowNull) { - w = getValue(node, w, false, allowNull); - h = getValue(node, h, false, allowNull); - return allowNull && (w == null || h == null) ? null - : new Size(w, h); - } - - function convertValue(value, type, lookup) { - return value === 'none' - ? null - : type === 'number' - ? parseFloat(value) - : type === 'array' - ? value ? value.split(/[\s,]+/g).map(parseFloat) : [] - : type === 'color' - ? getDefinition(value) || value - : type === 'lookup' - ? lookup[value] - : value; - } - - function importGroup(node, type, options, isRoot) { - var nodes = node.childNodes, - isClip = type === 'clippath', - item = new Group(), - project = item._project, - currentStyle = project._currentStyle, - children = []; - if (!isClip) { - item = applyAttributes(item, node, isRoot); - project._currentStyle = item._style.clone(); - } - if (isRoot) { - var defs = node.querySelectorAll('defs'); - for (var i = 0, l = defs.length; i < l; i++) { - importSVG(defs[i], options, false); - } - } - for (var i = 0, l = nodes.length; i < l; i++) { - var childNode = nodes[i], - child; - if (childNode.nodeType === 1 - && childNode.nodeName.toLowerCase() !== 'defs' - && (child = importSVG(childNode, options, false)) - && !(child instanceof Symbol)) - children.push(child); - } - item.addChildren(children); - if (isClip) - item = applyAttributes(item.reduce(), node, isRoot); - project._currentStyle = currentStyle; - if (isClip || type === 'defs') { - item.remove(); - item = null; - } - return item; - } - - function importPoly(node, type) { - var coords = node.getAttribute('points').match( - /[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g), - points = []; - for (var i = 0, l = coords.length; i < l; i += 2) - points.push(new Point( - parseFloat(coords[i]), - parseFloat(coords[i + 1]))); - var path = new Path(points); - if (type === 'polygon') - path.closePath(); - return path; - } - - function importPath(node) { - var data = node.getAttribute('d'), - param = { pathData: data }; - return (data.match(/m/gi) || []).length > 1 || /z\S+/i.test(data) - ? new CompoundPath(param) - : new Path(param); - } - - function importGradient(node, type) { - var id = (getValue(node, 'href', true) || '').substring(1), - isRadial = type === 'radialgradient', - gradient; - if (id) { - gradient = definitions[id].getGradient(); - } else { - var nodes = node.childNodes, - stops = []; - for (var i = 0, l = nodes.length; i < l; i++) { - var child = nodes[i]; - if (child.nodeType === 1) - stops.push(applyAttributes(new GradientStop(), child)); - } - gradient = new Gradient(stops, isRadial); - } - var origin, destination, highlight; - if (isRadial) { - origin = getPoint(node, 'cx', 'cy'); - destination = origin.add(getValue(node, 'r'), 0); - highlight = getPoint(node, 'fx', 'fy', true); - } else { - origin = getPoint(node, 'x1', 'y1'); - destination = getPoint(node, 'x2', 'y2'); - } - applyAttributes( - new Color(gradient, origin, destination, highlight), node); - return null; - } - - var importers = { - '#document': function (node, type, options, isRoot) { - var nodes = node.childNodes; - for (var i = 0, l = nodes.length; i < l; i++) { - var child = nodes[i]; - if (child.nodeType === 1) { - var next = child.nextSibling; - document.body.appendChild(child); - var item = importSVG(child, options, isRoot); - if (next) { - node.insertBefore(child, next); - } else { - node.appendChild(child); - } - return item; - } - } - }, - g: importGroup, - svg: importGroup, - clippath: importGroup, - polygon: importPoly, - polyline: importPoly, - path: importPath, - lineargradient: importGradient, - radialgradient: importGradient, - - image: function (node) { - var raster = new Raster(getValue(node, 'href', true)); - raster.on('load', function() { - var size = getSize(node, 'width', 'height'); - this.setSize(size); - var center = this._matrix._transformPoint( - getPoint(node, 'x', 'y').add(size.divide(2))); - this.translate(center); - }); - return raster; - }, - - symbol: function(node, type, options, isRoot) { - return new Symbol(importGroup(node, type, options, isRoot), true); - }, - - defs: importGroup, - - use: function(node) { - var id = (getValue(node, 'href', true) || '').substring(1), - definition = definitions[id], - point = getPoint(node, 'x', 'y'); - return definition - ? definition instanceof Symbol - ? definition.place(point) - : definition.clone().translate(point) - : null; - }, - - circle: function(node) { - return new Shape.Circle(getPoint(node, 'cx', 'cy'), - getValue(node, 'r')); - }, - - ellipse: function(node) { - return new Shape.Ellipse({ - center: getPoint(node, 'cx', 'cy'), - radius: getSize(node, 'rx', 'ry') - }); - }, - - rect: function(node) { - var point = getPoint(node, 'x', 'y'), - size = getSize(node, 'width', 'height'), - radius = getSize(node, 'rx', 'ry'); - return new Shape.Rectangle(new Rectangle(point, size), radius); - }, - - line: function(node) { - return new Path.Line(getPoint(node, 'x1', 'y1'), - getPoint(node, 'x2', 'y2')); - }, - - text: function(node) { - var text = new PointText(getPoint(node, 'x', 'y') - .add(getPoint(node, 'dx', 'dy'))); - text.setContent(node.textContent.trim() || ''); - return text; - } - }; - - function applyTransform(item, value, name, node) { - var transforms = (node.getAttribute(name) || '').split(/\)\s*/g), - matrix = new Matrix(); - for (var i = 0, l = transforms.length; i < l; i++) { - var transform = transforms[i]; - if (!transform) - break; - var parts = transform.split(/\(\s*/), - command = parts[0], - v = parts[1].split(/[\s,]+/g); - for (var j = 0, m = v.length; j < m; j++) - v[j] = parseFloat(v[j]); - switch (command) { - case 'matrix': - matrix.concatenate( - new Matrix(v[0], v[1], v[2], v[3], v[4], v[5])); - break; - case 'rotate': - matrix.rotate(v[0], v[1], v[2]); - break; - case 'translate': - matrix.translate(v[0], v[1]); - break; - case 'scale': - matrix.scale(v); - break; - case 'skewX': - matrix.skew(v[0], 0); - break; - case 'skewY': - matrix.skew(0, v[0]); - break; - } - } - item.transform(matrix); - } - - function applyOpacity(item, value, name) { - var color = item[name === 'fill-opacity' ? 'getFillColor' - : 'getStrokeColor'](); - if (color) - color.setAlpha(parseFloat(value)); - } - - var attributes = Base.set(Base.each(SVGStyles, function(entry) { - this[entry.attribute] = function(item, value) { - item[entry.set](convertValue(value, entry.type, entry.fromSVG)); - if (entry.type === 'color' && item instanceof Shape) { - var color = item[entry.get](); - if (color) - color.transform(new Matrix().translate( - item.getPosition(true).negate())); - } - }; - }, {}), { - id: function(item, value) { - definitions[value] = item; - if (item.setName) - item.setName(value); - }, - - 'clip-path': function(item, value) { - var clip = getDefinition(value); - if (clip) { - clip = clip.clone(); - clip.setClipMask(true); - if (item instanceof Group) { - item.insertChild(0, clip); - } else { - return new Group(clip, item); - } - } - }, - - gradientTransform: applyTransform, - transform: applyTransform, - - 'fill-opacity': applyOpacity, - 'stroke-opacity': applyOpacity, - - visibility: function(item, value) { - item.setVisible(value === 'visible'); - }, - - display: function(item, value) { - item.setVisible(value !== null); - }, - - 'stop-color': function(item, value) { - if (item.setColor) - item.setColor(value); - }, - - 'stop-opacity': function(item, value) { - if (item._color) - item._color.setAlpha(parseFloat(value)); - }, - - offset: function(item, value) { - var percentage = value.match(/(.*)%$/); - item.setRampPoint(percentage - ? percentage[1] / 100 - : parseFloat(value)); - }, - - viewBox: function(item, value, name, node, styles) { - var rect = new Rectangle(convertValue(value, 'array')), - size = getSize(node, 'width', 'height', true); - if (item instanceof Group) { - var scale = size ? rect.getSize().divide(size) : 1, - matrix = new Matrix().translate(rect.getPoint()).scale(scale); - item.transform(matrix.inverted()); - } else if (item instanceof Symbol) { - if (size) - rect.setSize(size); - var clip = getAttribute(node, 'overflow', styles) != 'visible', - group = item._definition; - if (clip && !rect.contains(group.getBounds())) { - clip = new Shape.Rectangle(rect).transform(group._matrix); - clip.setClipMask(true); - group.addChild(clip); - } - } - } - }); - - function getAttribute(node, name, styles) { - var attr = node.attributes[name], - value = attr && attr.value; - if (!value) { - var style = Base.camelize(name); - value = node.style[style]; - if (!value && styles.node[style] !== styles.parent[style]) - value = styles.node[style]; - } - return !value - ? undefined - : value === 'none' - ? null - : value; - } - - function applyAttributes(item, node, isRoot) { - var styles = { - node: DomElement.getStyles(node) || {}, - parent: !isRoot && DomElement.getStyles(node.parentNode) || {} - }; - Base.each(attributes, function(apply, name) { - var value = getAttribute(node, name, styles); - if (value !== undefined) - item = Base.pick(apply(item, value, name, node, styles), item); - }); - return item; - } - - var definitions = {}; - function getDefinition(value) { - var match = value && value.match(/\((?:#|)([^)']+)/); - return match && definitions[match[1]]; - } - - function importSVG(source, options, isRoot) { - if (!source) - return null; - if (!options) { - options = {}; - } else if (typeof options === 'function') { - options = { onLoad: options }; - } - - var node = source, - scope = paper; - - function onLoadCallback(svg) { - paper = scope; - var item = importSVG(svg, options, isRoot), - onLoad = options.onLoad, - view = scope.project && scope.getView(); - if (onLoad) - onLoad.call(this, item); - view.update(); - } - - if (isRoot) { - if (typeof source === 'string' && !/^.*</.test(source)) { - node = document.getElementById(source); - if (node) { - source = null; - } else { - return Http.request('get', source, onLoadCallback); - } - } else if (typeof File !== 'undefined' && source instanceof File) { - var reader = new FileReader(); - reader.onload = function() { - onLoadCallback(reader.result); - }; - return reader.readAsText(source); - } - } - - if (typeof source === 'string') - node = new DOMParser().parseFromString(source, 'image/svg+xml'); - if (!node.nodeName) - throw new Error('Unsupported SVG source: ' + source); - var type = node.nodeName.toLowerCase(), - importer = importers[type], - item, - data = node.getAttribute && node.getAttribute('data-paper-data'), - settings = scope.settings, - applyMatrix = settings.applyMatrix; - settings.applyMatrix = false; - item = importer && importer(node, type, options, isRoot) || null; - settings.applyMatrix = applyMatrix; - if (item) { - if (type !== '#document' && !(item instanceof Group)) - item = applyAttributes(item, node, isRoot); - var onImport = options.onImport; - if (onImport) - item = onImport(node, item, options) || item; - if (options.expandShapes && item instanceof Shape) { - item.remove(); - item = item.toPath(); - } - if (data) - item._data = JSON.parse(data); - } - if (isRoot) { - definitions = {}; - if (item && Base.pick(options.applyMatrix, applyMatrix)) - item.matrix.apply(true, true); - } - return item; - } - - Item.inject({ - importSVG: function(node, options) { - return this.addChild(importSVG(node, options, true)); - } - }); - - Project.inject({ - importSVG: function(node, options) { - this.activate(); - return importSVG(node, options, true); - } - }); -}; - -paper = new (PaperScope.inject(Base.exports, { - enumerable: true, - Base: Base, - Numerical: Numerical, - Key: Key -}))(); - -if (true) { - !(__WEBPACK_AMD_DEFINE_FACTORY__ = (paper), - __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? - (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : - __WEBPACK_AMD_DEFINE_FACTORY__), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); -} else if (typeof module === 'object' && module) { - module.exports = paper; -} - -return paper; -}; - - -/***/ }), -/* 110 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var interpolate = __webpack_require__(108); - -var BSplineGraphic = React.createClass({ - displayName: "BSplineGraphic", - componentWillMount: function componentWillMount() { - var _this = this; - - // lots of instance binding, because we want instance binding, not proto/class binding. - this.cvs = undefined; - this.ctx = undefined; - this.key = undefined; - this.keyCode = undefined; - this.mouseX = undefined; - this.mouseY = undefined; - this.isMouseDown = undefined; - this.width = 0; - this.height = 0; - this.activeDistance = 9; - this.points = []; - this.knots = []; - this.weights = []; - this.nodes = []; - this.cp = undefined; - this.dx = undefined; - this.dy = undefined; - // and sketch value binding. - var sketch = this.props.sketch; - Object.keys(sketch).forEach(function (fn) { - _this[fn] = sketch[fn]; - // rebind "this" if we're dealing with a function - if (typeof _this[fn] === "function") { - _this[fn] = _this[fn].bind(_this); - } - }); - }, - - - render: function render() { - return React.createElement("canvas", { className: "bspline-graphic", ref: "sketch" }); - }, - - keydownlisten: function keydownlisten(e) { - this.setKeyboardValues(e);this.keyDown(); - }, - keyuplisten: function keyuplisten(e) { - this.setKeyboardValues(e);this.keyUp(); - }, - keypresslisten: function keypresslisten(e) { - this.setKeyboardValues(e);this.keyPressed(); - }, - mousedownlisten: function mousedownlisten(e) { - this.setMouseValues(e);this.mouseDown(); - }, - mouseuplisten: function mouseuplisten(e) { - this.setMouseValues(e);this.mouseUp(); - }, - mousemovelisten: function mousemovelisten(e) { - this.setMouseValues(e);this.mouseMove();if (this.isMouseDown && this.mouseDrag) { - this.mouseDrag(); - } - }, - wheellissten: function wheellissten(e) { - e.preventDefault();this.scrolled(e.deltaY < 0 ? 1 : -1); - }, - componentDidMount: function componentDidMount() { - var cvs = this.cvs = this.refs.sketch; - // Keyboard event handling - cvs.addEventListener("keydown", this.keydownlisten); - cvs.addEventListener("keyup", this.keyuplisten); - cvs.addEventListener("keypress", this.keypresslisten); - // Mouse event handling - cvs.addEventListener("mousedown", this.mousedownlisten); - cvs.addEventListener("mouseup", this.mouseuplisten); - cvs.addEventListener("mousemove", this.mousemovelisten); - // Scroll event handling - if (this.props.scrolling) { - cvs.addEventListener("wheel", this.wheellissten); - } - // Boom let's go - this.setup(); - }, - componentWillUnmount: function componentWillUnmount() { - var cvs = this.cvs = this.refs.sketch; - cvs.removeEventListener("keydown", this.keydownlisten); - cvs.removeEventListener("keyup", this.keyuplisten); - cvs.removeEventListener("keypress", this.keypresslisten); - cvs.removeEventListener("mousedown", this.mousedownlisten); - cvs.removeEventListener("mouseup", this.mouseuplisten); - cvs.removeEventListener("mousemove", this.mousemovelisten); - if (this.props.scrolling) { - cvs.removeEventListener("wheel", this.wheellissten); - } - }, - - - // base API - - drawCurve: function drawCurve(points) { - points = points || this.points; - var ctx = this.ctx; - var weights = this.weights.length > 0 ? this.weights : false; - ctx.beginPath(); - var p = interpolate(0, this.degree, points, this.knots, weights); - ctx.moveTo(p[0], p[1]); - for (var t = 0.01; t < 1; t += 0.01) { - p = interpolate(t, this.degree, points, this.knots, weights); - ctx.lineTo(p[0], p[1]); - } - p = interpolate(1, this.degree, points, this.knots, weights); - ctx.lineTo(p[0], p[1]); - ctx.stroke(); - ctx.closePath(); - }, - drawKnots: function drawKnots(points) { - var _this2 = this; - - var knots = this.knots; - var weights = this.weights.length > 0 ? this.weights : false; - knots.forEach(function (knot, i) { - if (i < _this2.degree) return; - if (i > knots.length - 1 - _this2.degree) return; - var p = interpolate(knot, _this2.degree, points, knots, weights, false, true); - _this2.circle(p[0], p[1], 3); - }); - }, - - - // FIXME: TODO: these do not seem correct using uniform knots - drawNodes: function drawNodes(points) { - var _this3 = this; - - var i = 0, - p; - this.stroke(150); - this.nodes.forEach(function (node, i) { - try { - p = interpolate(node, _this3.degree, points, _this3.knots, false, false, true); - _this3.line(p[0], p[1], points[i][0], points[i++][1]); - } catch (e) { - console.error(e); - } - }); - }, - - - // FIXME: this doesn't work with a degree change - formKnots: function formKnots(points, open) { - open = open === true ? true : false; - if (!open) return this.formUniformKnots(points); - - var l = points.length, - knots = [], - m = l - this.degree, - i; - - // form the open-uniform knot vector - for (i = 1; i < l - this.degree; i++) { - knots.push(i + this.degree); - } - // add [degree] zeroes at the front - for (i = 0; i <= this.degree; i++) { - knots = [this.degree].concat(knots); - } - // add [degree] max-values to the back - for (i = 0; i <= this.degree; i++) { - knots.push(m + this.degree); - } - - return knots; - }, - formUniformKnots: function formUniformKnots(points) { - var knots = []; - for (var i = this.points.length + this.degree; i >= 0; i--) { - knots.push(i); - } - return knots.reverse(); - }, - formNodes: function formNodes(knots, points) { - var domain = [this.degree, knots.length - 1 - this.degree]; - var nodes = [], - node, - k, - offset; - for (k = 0; k < this.points.length; k++) { - node = 0; - for (offset = 1; offset <= this.degree; offset++) { - node += knots[k + offset]; - } - node /= this.degree; - if (node < knots[domain[0]]) continue; - if (node > knots[domain[1]]) continue; - nodes.push(node); - } - return nodes; - }, - formWeights: function formWeights(points) { - var weights = []; - points.forEach(function (p) { - return weights.push(1); - }); - return weights; - }, - setDegree: function setDegree(d) { - this.degree += d; - this.knots = this.formKnots(this.points); - this.nodes = this.formNodes(this.knots, this.points); - }, - near: function near(p, x, y) { - var dx = p.x - x, - dy = p.y - y, - d = Math.sqrt(dx * dx + dy * dy); - return d < this.activeDistance; - }, - getCurrentPoint: function getCurrentPoint(x, y) { - for (var i = 0; i < this.points.length; i++) { - if (this.near(this.points[i], x, y)) { - return this.points[i]; - } - } - }, - - - // Interaction stuffs - - keyDown: function keyDown() { - if (this.key === 'ArrowUp') { - this.setDegree(1); - } - if (this.key === 'ArrowDown') { - if (this.degree > 1) { - this.setDegree(-1); - } - } - this.redraw(); - }, - keyUp: function keyUp() { - // ... do nothing? - }, - keyPressed: function keyPressed() { - // ... do nothing? - }, - mouseDown: function mouseDown() { - this.isMouseDown = true; - this.cp = this.getCurrentPoint(this.mouseX, this.mouseY); - if (!this.cp) { - this.points.push({ x: this.mouseX, y: this.mouseY }); - this.knots = this.formKnots(this.points); - this.nodes = this.formNodes(this.knots, this.points); - } - this.redraw(); - }, - mouseUp: function mouseUp() { - this.isMouseDown = false; - this.cp = false; - this.redraw(); - }, - mouseDrag: function mouseDrag() { - if (this.cp) { - this.cp.x = this.mouseX; - this.cp.y = this.mouseY; - this.redraw(); - } - }, - mouseMove: function mouseMove() { - // ... do nothing? - }, - scrolled: function scrolled(direction) { - this.cp = this.getCurrentPoint(this.mouseX, this.mouseY); - if (!this.cp) return; - // base case - var pos = this.points.indexOf(this.cp); - if (this.weights.length > pos) { - this.weights[pos] += direction * 0.1; - if (this.weights[pos] < 0) { - this.weights[pos] = 0; - } - } - // possible multiplicity due to "closed" curves - pos = this.points.indexOf(this.cp, pos + 1); - if (pos !== -1 && this.weights.length > pos) { - this.weights[pos] += direction * 0.1; - if (this.weights[pos] < 0) { - this.weights[pos] = 0; - } - } - this.redraw(); - }, - - - // keyboard events - setKeyboardValues: function setKeyboardValues(e) { - if (!e.ctrlKey && !e.metaKey && !e.altKey) { - e.preventDefault(); - } - this.key = e.key; - this.keyCode = e.code; - }, - - - // mouse events - setMouseValues: function setMouseValues(e) { - var brect = this.cvs.getBoundingClientRect(); - this.mouseX = e.clientX - brect.left; - this.mouseY = e.clientY - brect.top; - }, - - - // API stuffs - - size: function size(w, h) { - this.width = w | 0; - this.height = (h || w) | 0; - this.cvs.width = this.width; - this.cvs.height = this.height; - this.ctx = this.cvs.getContext("2d"); - }, - redraw: function redraw() { - this.draw(); - }, - clear: function clear() { - this.ctx.clearRect(0, 0, this.width, this.height); - }, - grid: function grid(spacing) { - spacing = ((spacing || 10) | 0) + 0.5; - this.stroke(200, 200, 220); - for (var x = spacing; x < this.width - 1; x += spacing) { - this.line(x, 0, x, this.height); - } - for (var y = spacing; y < this.height - 1; y += spacing) { - this.line(0, y, this.width, y); - } - }, - circle: function circle(x, y, r) { - var hr = r / 2; - var ctx = this.ctx; - ctx.beginPath(); - ctx.moveTo(x, y); - ctx.arc(x, y, r, 0, Math.PI * 2); - ctx.stroke(); - ctx.closePath(); - }, - line: function line(a, b, c, d) { - var ctx = this.ctx; - ctx.beginPath(); - ctx.moveTo(a, b); - ctx.lineTo(c, d); - ctx.stroke(); - ctx.closePath(); - }, - stroke: function stroke(r, g, b, a) { - if (typeof r === "string") { - return this.ctx.strokeStyle = r; - } - if (g === undefined) { - g = r;b = r; - } - if (a === undefined) { - a = 1; - } - this.ctx.strokeStyle = this.rgba(r, g, b, a); - }, - noStroke: function noStroke() { - this.ctx.strokeStyle = "none"; - }, - fill: function fill(r, g, b, a) { - if (typeof r === "string") { - return this.ctx.fillStyle = r; - } - if (g === undefined) { - g = r;b = r; - } - if (a === undefined) { - a = 1; - } - this.ctx.fillStyle = this.rgba(r, g, b, a); - }, - noFill: function noFill() { - this.ctx.fillStyle = "none"; - }, - rgba: function rgba(r, g, b, a) { - return "rgba(" + r + "," + g + "," + b + "," + a + ")"; - }, - beginPath: function beginPath() { - this.ctx.beginPath();this.bp = true; - }, - vertex: function vertex(x, y) { - if (!this.bp) { - return this.ctx.lineTo(x, y); - } - this.ctx.moveTo(x, y); - this.bp = false; - }, - endPath: function endPath() { - this.ctx.stroke(); - this.ctx.closePath(); - } -}); - -module.exports = BSplineGraphic; - -/***/ }), -/* 111 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var Footer = React.createClass({ - displayName: "Footer", - - - render: function render() { - return React.createElement( - "footer", - { className: "copyright" }, - "This article is © 2011-2016 to me, Mike \"Pomax\" Kamermans, but the text, code, and images are ", - React.createElement( - "a", - { href: "https://github.com/Pomax/bezierinfo/blob/gh-pages/LICENSE.md" }, - "almost no rights reserved" - ), - ". Go do something cool with it!" - ); - } - -}); - -module.exports = Footer; - -/***/ }), -/* 112 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); -var Page = __webpack_require__(117); - -var sectionList = __webpack_require__(41), - sectionMap = function sectionMap(mapping) { - return Object.keys(sectionList).map(mapping); -}, - allSections = sectionMap(function (name, entry) { - var Type = sectionList[name]; - return React.createElement(Type, { key: name, name: name, number: entry }); -}); - -var FullArticle = React.createClass({ - displayName: "FullArticle", - - render: function render() { - return React.createElement( - Page, - null, - allSections - ); - } -}); - -module.exports = FullArticle; - -/***/ }), -/* 113 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var baseClass = { - render: function render() { - return React.createElement( - "figure", - { className: this.props.inline ? "inline" : false }, - React.createElement("canvas", { ref: "canvas", - tabIndex: "0", - style: { - width: this.panelCount * this.defaultWidth + "px", - height: this.defaultHeight + "px" - }, - onMouseDown: this.mouseDown, - onMouseMove: this.mouseMove, - onMouseUp: this.mouseUp, - onClick: this.onClick, - onKeyUp: this.onKeyUp, - onKeyDown: this.onKeyDown, - onKeyPress: this.onKeyPress - }), - React.createElement( - "figcaption", - null, - this.props.title, - " ", - this.props.children - ) - ); - }, - - componentDidMount: function componentDidMount() { - var cvs = this.refs.canvas; - var dpr = this.getPixelRatio(); - cvs.width = this.defaultWidth * dpr; - cvs.height = this.defaultHeight * dpr; - this.cvs = cvs; - var ctx = cvs.getContext("2d"); - this.ctx = ctx; - this.ctx.scale(dpr, dpr); - - if (this.props.paperjs) { - var Paper = this.Paper = __webpack_require__(109); - Paper.setup(cvs); - } - - if (this.props.setup) { - this.props.setup(this); - } - - if (this.props.draw) { - this.props.draw(this, this.curve); - } - - if (this.props.autoplay) { - this.play(); - } - } -}; - -// For some reason we can copy from gfx into base but -// not the other way around, while preserving context. -var gfxObject = __webpack_require__(121); -Object.keys(gfxObject).forEach(function (fname) { - baseClass[fname] = gfxObject[fname]; -}); - -module.exports = React.createClass(baseClass); - -/***/ }), -/* 114 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var Header = React.createClass({ - displayName: 'Header', - - render: function render() { - return React.createElement( - 'header', - null, - React.createElement( - 'h1', - null, - 'A Primer on Bézier Curves' - ), - React.createElement( - 'h2', - null, - 'A free, online book for when you really need to know how to do Bézier things.' - ) - ); - } -}); - -module.exports = Header; - -/***/ }), -/* 115 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var KnotController = React.createClass({ - displayName: 'KnotController', - getInitialState: function getInitialState() { - return { - owner: false, - knots: [] - }; - }, - bindKnots: function bindKnots(owner, knots) { - this.setState({ owner: owner, knots: knots }); - }, - render: function render() { - var _this = this; - - var type = 'range'; - var min = 0; - var max = this.state.knots.length; - var step = 1; - return React.createElement( - 'section', - { className: 'knot-controls' }, - React.createElement( - 'h2', - null, - 'knot values' - ), - this.state.knots.map(function (value, position) { - var props = { - type: type, min: min, max: max, step: step, - value: value, - onChange: function onChange(e) { - var k = _this.state.knots; - k[position] = e.target.value; - _this.setState({ knots: k }, function () { - _this.state.owner.redraw(); - }); - } - }; - return React.createElement( - 'div', - { key: 'knot' + position }, - min, - React.createElement('input', props), - max, - ' (= ', - value, - ')' - ); - }) - ); - } -}); - -module.exports = KnotController; - -/***/ }), -/* 116 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); -var ReactRouter = __webpack_require__(102); -var Link = ReactRouter.Link; - -var sections = __webpack_require__(41); -var sectionPages = Object.keys(sections); - -var SectionHeader = __webpack_require__(69); - -var Navigation = React.createClass({ - displayName: 'Navigation', - - generateNavItem: function generateNavItem(name, entry) { - var Type = sections[name]; - var title = Type.getDefaultProps().title; - var locale = SectionHeader.locale; - if (typeof window !== "undefined" && window.location.toString().indexOf(locale) === -1) { - locale = ''; - } - var fragmentid = (locale ? './' + locale + '/' : '.') + '#' + name; - var link = React.createElement( - 'a', - { href: fragmentid }, - title - ); - if (this.props.fullNav) { - link = React.createElement( - Link, - { to: name }, - title - ); - } - var last = sectionPages.length - 1; - if (entry === last) entry = null; - return React.createElement( - 'li', - { key: name, 'data-number': entry }, - link - ); - }, - - generateNav: function generateNav() { - if (this.props.compact) return null; - - return React.createElement( - 'div', - { ref: 'navigation' }, - React.createElement( - 'navigation', - { className: this.props.compact ? "compact" : null }, - React.createElement( - 'ul', - { className: 'navigation' }, - sectionPages.map(this.generateNavItem) - ) - ) - ); - }, - - render: function render() { - return this.generateNav(); - } -}); - -module.exports = Navigation; - -/***/ }), -/* 117 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var Ribbon = __webpack_require__(119); -var Header = __webpack_require__(114); -var Relatives = __webpack_require__(118); -var LocaleSwitcher = __webpack_require__(123).LocaleSwitcher; -var Navigation = __webpack_require__(116); -var Footer = __webpack_require__(111); - -var Page = React.createClass({ - displayName: "Page", - - renderCompactContent: function renderCompactContent(nav) { - return React.createElement( - "div", - null, - React.createElement(Relatives, { prev: this.props.prev, next: this.props.next, position: "before" }), - this.props.children, - React.createElement(Relatives, { prev: this.props.prev, next: this.props.next, position: "after" }) - ); - }, - - renderCompactRoot: function renderCompactRoot(nav) { - return React.createElement( - "div", - null, - this.props.children, - nav - ); - }, - - renderPageContent: function renderPageContent(nav) { - return React.createElement( - "div", - null, - React.createElement(LocaleSwitcher, null), - nav, - this.props.children - ); - }, - - render: function render() { - var content; - var compact = this.props.compact; - var isRoot = this.props.name === '/'; - var nav = React.createElement(Navigation, { compact: compact && !isRoot }); - - if (compact) { - if (isRoot) { - content = this.renderCompactRoot(nav); - } else { - content = this.renderCompactContent(nav); - } - } else { - content = this.renderPageContent(nav); - } - - return React.createElement( - "div", - null, - React.createElement(Ribbon, null), - React.createElement(Header, null), - content, - React.createElement(Footer, null) - ); - } -}); - -module.exports = Page; - -/***/ }), -/* 118 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); -var ReactRouter = __webpack_require__(102); -var Link = ReactRouter.Link; - -var sections = __webpack_require__(41); -var pageIDs = Object.keys(sections); - -var Relatives = React.createClass({ - displayName: 'Relatives', - getInitialState: function getInitialState() { - var prev = this.props.prev; - if (prev > -1) { - prev = { - to: pageIDs[prev], - title: sections[pageIDs[prev]].getDefaultProps().title - }; - } else { - prev = false; - } - - var next = this.props.next; - if (next < pageIDs.length) { - next = { - to: pageIDs[next], - title: sections[pageIDs[next]].getDefaultProps().title - }; - } else { - next = false; - } - - return { - prev: prev, - next: next - }; - }, - - - render: function render() { - if (!this.props.prev && !this.props.next) return null; - return React.createElement( - 'table', - { className: "relatives " + this.props.position }, - React.createElement( - 'tbody', - null, - React.createElement( - 'tr', - null, - React.createElement( - 'td', - null, - !this.state.prev ? null : React.createElement( - Link, - { className: 'prev', to: this.state.prev.to }, - this.props.prev + ". " + this.state.prev.title - ) - ), - React.createElement( - 'td', - { className: 'toc' }, - React.createElement( - Link, - { to: '/' }, - 'ToC' - ) - ), - React.createElement( - 'td', - null, - !this.state.next ? null : React.createElement( - Link, - { className: 'next', to: this.state.next.to }, - this.props.next + ". " + this.state.next.title - ) - ) - ) - ) - ); - } -}); - -module.exports = Relatives; - -/***/ }), -/* 119 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var Ribbon = React.createClass({ - displayName: "Ribbon", - - getInitialState: function getInitialState() { - return { - href: "http://github.com/pomax/BezierInfo-2" - }; - }, - - render: function render() { - return React.createElement( - "div", - { className: "ribbon" }, - React.createElement("img", { src: "images/ribbon.png", alt: "This page on GitHub", style: { border: "none" }, useMap: "#githubmap", width: "200px", height: "149px" }), - React.createElement( - "map", - { name: "githubmap" }, - React.createElement("area", { shape: "poly", coords: "30,0, 200,0, 200,114", href: this.state.href, alt: "This page on GitHub" }) - ) - ); - } -}); - -module.exports = Ribbon; - -/***/ }), -/* 120 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var WeightController = React.createClass({ - displayName: 'WeightController', - getInitialState: function getInitialState() { - return { - owner: false, - weights: [], - closed: false - }; - }, - bindWeights: function bindWeights(owner, weights, closed) { - this.setState({ owner: owner, weights: weights, closed: closed }); - }, - render: function render() { - var _this = this; - - var type = 'range'; - var min = 0; - var max = this.state.weights.length; - var step = 1; - - var overlap = this.state.closed; - var baselength = this.state.weights.length; - if (overlap !== false) { - baselength -= overlap; - } - - return React.createElement( - 'section', - { className: 'knot-controls' }, - React.createElement( - 'h2', - null, - 'weight values' - ), - this.state.weights.map(function (value, position) { - if (overlap && position >= baselength) { - return null; - } - var props = { - type: type, min: min, max: max, step: step, - value: value, - onChange: function onChange(e) { - var k = _this.state.weights; - k[position] = e.target.value; - if (overlap && position < overlap) { - k[position + baselength] = e.target.value; - } - _this.setState({ weights: k }, function () { - _this.state.owner.redraw(); - }); - } - }; - return React.createElement( - 'div', - { key: 'knot' + position }, - min, - React.createElement('input', props), - max, - ' (= ', - value, - ')' - ); - }) - ); - } -}); - -module.exports = WeightController; - -/***/ }), -/* 121 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var hasWindow = typeof window !== "undefined"; -var chroma = /*hasWindow ? window.chroma : */__webpack_require__(210); -var Bezier = /*hasWindow ? window.Bezier : */__webpack_require__(208); - -// event coordinate fix -var fix = function fix(e) { - e = e || window.event; - var target = e.target || e.srcElement, - rect = target.getBoundingClientRect(); - e.offsetX = e.clientX - rect.left; - e.offsetY = e.clientY - rect.top; -}; - -var API = { - Paper: false, - - defaultWidth: 275, - defaultHeight: 275, - panelCount: 1, - - Bezier: Bezier, - utils: Bezier.getUtils(), - curve: false, - mx: 0, - my: 0, - cx: 0, - cy: 0, - mp: false, - offset: { x: 0, y: 0 }, - lpts: [], - colorSeed: 0, - playing: false, - frame: 0, - playinterval: 33, - - animate: function animate() { - if (this.playing) { - this.frame++; - // requestAnimationFrame is spectacularly too fast - setTimeout(this.animate, this.playinterval); - this.props.draw(this, this.curve); - } - }, - - getFrame: function getFrame() { - return this.frame; - }, - getPlayInterval: function getPlayInterval() { - return this.playinterval; - }, - play: function play() { - this.playing = true;this.animate(); - }, - pause: function pause() { - this.playing = false; - }, - redraw: function redraw() { - if (this.props.draw) { - this.props.draw(this, this.curve); - } - }, - - mouseDown: function mouseDown(evt) { - var _this = this; - - fix(evt); - this.mx = evt.offsetX; - this.my = evt.offsetY; - - this.movingPoint = false; - this.dragging = false; - this.down = true; - - this.lpts.forEach(function (p, idx) { - if (Math.abs(_this.mx - p.x) < 10 && Math.abs(_this.my - p.y) < 10) { - _this.movingPoint = true; - _this.mp = p; - _this.mp_idx = idx; - _this.cx = p.x; - _this.cy = p.y; - } - }); - - if (this.props.onMouseDown) { - this.props.onMouseDown(evt, this); - } - - if ('setCapture' in evt.target) { - evt.target.setCapture(); - } - }, - - mouseMove: function mouseMove(evt) { - fix(evt); - - if (!this.props.static) { - - if (this.down) { - this.dragging = true; - } - - var found = false; - this.lpts.forEach(function (p) { - var mx = evt.offsetX; - var my = evt.offsetY; - if (Math.abs(mx - p.x) < 10 && Math.abs(my - p.y) < 10) { - found = found || true; - } - }); - this.cvs.style.cursor = found ? "pointer" : "default"; - - this.hover = { - x: evt.offsetX, - y: evt.offsetY - }; - - if (this.movingPoint) { - this.ox = evt.offsetX - this.mx; - this.oy = evt.offsetY - this.my; - this.mp.x = Math.max(0, Math.min(this.defaultWidth, this.cx + this.ox)); - this.mp.y = Math.max(0, Math.min(this.defaultHeight, this.cy + this.oy)); - if (this.curve.forEach) { - for (var i = 0, c, _pts; i < this.curve.length; i++) { - c = this.curve[i]; - _pts = c.points; - if (_pts.indexOf(this.mp) > -1) { - c.update(); - break; - } - } - } else if (this.curve && this.curve.update) { - this.curve.update(); - } - } - } - - if (this.props.onMouseMove) { - this.props.onMouseMove(evt, this); - } - - if (this.dragging && this.props.onMouseDrag) { - this.props.onMouseDrag(evt, this); - } - - if (!this.props.static && !this.playing && this.props.draw) { - this.props.draw(this, this.curve); - } - }, - - mouseUp: function mouseUp(evt) { - this.down = false; - if (!this.movingPoint) { - if (this.props.onMouseUp) { - this.props.onMouseUp(evt, this); - } - return; - } - this.movingPoint = false; - this.mp = false; - if (this.props.onMouseUp) { - this.props.onMouseUp(evt, this); - } - }, - - onClick: function onClick(evt) { - fix(evt); - this.mx = evt.offsetX; - this.my = evt.offsetY; - if (!this.dragging && this.props.onClick) { - this.props.onClick(evt, this); - } - }, - - onKeyUp: function onKeyUp(evt) { - if (this.props.onKeyUp) { - this.props.onKeyUp(evt, this); - if (!this.playing && this.props.draw) { - this.props.draw(this, this.curve); - } - } - }, - - onKeyDown: function onKeyDown(evt) { - if (this.props.onKeyDown) { - this.props.onKeyDown(evt, this); - if (!this.playing && this.props.draw) { - this.props.draw(this, this.curve); - } - } - }, - - onKeyPress: function onKeyPress(evt) { - if (this.props.onKeyPress) { - this.props.onKeyPress(evt, this); - if (!this.playing && this.props.draw) { - this.props.draw(this, this.curve); - } - } - }, - - /** - * API for curve drawing. - */ - - reset: function reset() { - this.refs.canvas.width = this.refs.canvas.width; - this.ctx.strokeStyle = "black"; - this.ctx.lineWidth = 1; - this.ctx.fillStyle = "none"; - var dpr = this.getPixelRatio(); - this.ctx.scale(dpr, dpr); - this.offset = { x: 0, y: 0 }; - this.colorSeed = 0; - }, - - setSize: function setSize(w, h) { - this.defaultWidth = w; - this.defaultHeight = h; - - var cvs = this.refs.canvas; - cvs.style.width = this.panelCount * w + "px"; - cvs.style.height = h + "px"; - - var dpr = this.getPixelRatio(); - cvs.width = this.panelCount * w * dpr; - cvs.height = h * dpr; - this.ctx.scale(dpr, dpr); - }, - - setCurves: function setCurves(c) { - this.setCurve(c); - }, - - setCurve: function setCurve(c) { - var pts = []; - c = c instanceof Array ? c : Array.prototype.slice.call(arguments); - c.forEach(function (nc) { - pts = pts.concat(nc.points); - }); - this.curve = c.length === 1 ? c[0] : c; - this.lpts = pts; - }, - - getPanelWidth: function getPanelWidth() { - return this.defaultWidth; - }, - - getPanelHeight: function getPanelHeight() { - return this.defaultHeight; - }, - - getDefaultQuadratic: function getDefaultQuadratic() { - return new this.Bezier(70, 250, 20, 110, 250, 60); - }, - - getDefaultCubic: function getDefaultCubic() { - return new this.Bezier(120, 160, 35, 200, 220, 260, 220, 40); - }, - - getPixelRatio: function getPixelRatio() { - return window.devicePixelRatio || 1; - }, - - toImage: function toImage() { - var dataURL = this.refs.canvas.toDataURL(); - var img = new Image(); - img.src = dataURL; - img.devicePixelRatio = this.getPixelRatio(); - return img; - }, - - setPanelCount: function setPanelCount(c) { - this.panelCount = c; - var cvs = this.refs.canvas; - cvs.width = c * this.defaultWidth * this.getPixelRatio(); - cvs.style.width = c * this.defaultWidth + "px"; - }, - - setOffset: function setOffset(f) { - this.offset = f; - }, - - setColor: function setColor(c) { - this.ctx.strokeStyle = c; - }, - - getColor: function getColor() { - return this.ctx.strokeStyle || "black"; - }, - - setWeight: function setWeight(c) { - this.ctx.lineWidth = c; - }, - - noColor: function noColor(c) { - this.ctx.strokeStyle = "transparent"; - }, - - setRandomColor: function setRandomColor(a) { - a = typeof a === "undefined" ? 1 : a; - var h = this.colorSeed % 360, - s = 1.0, - l = 0.34; - this.colorSeed += 87; - this.ctx.strokeStyle = chroma.hsl(h, s, l).alpha(a).css(); - }, - - setRandomFill: function setRandomFill(a) { - a = typeof a === "undefined" ? 1 : a; - var h = this.colorSeed % 360, - s = 1.0, - l = 0.34; - this.colorSeed += 87; - this.ctx.fillStyle = chroma.hsl(h, s, l).alpha(a).css(); - }, - - setFill: function setFill(c) { - this.ctx.fillStyle = c; - }, - - getFill: function getFill() { - return this.ctx.fillStyle || "transparent"; - }, - - noFill: function noFill() { - this.ctx.fillStyle = "transparent"; - }, - - drawSkeleton: function drawSkeleton(curve, offset, nocoords) { - offset = offset || { x: 0, y: 0 }; - var pts = curve.points; - if (pts.length > 2) { - this.ctx.strokeStyle = "lightgrey"; - this.drawLine(pts[0], pts[1], offset); - var last = pts.length - 2; - for (var i = 1; i < last; i++) { - this.drawLine(pts[i], pts[i + 1], offset); - } - this.drawLine(pts[last], pts[last + 1], offset); - } - this.ctx.strokeStyle = "black"; - this.drawPoints(pts, offset); - if (!nocoords) { - this.drawCoordinates(curve, offset); - } - }, - - drawGrid: function drawGrid(xcount, ycount, offset) { - var w = this.defaultWidth, - h = this.defaultHeight, - xstep = w / xcount, - ox = xstep / 2, - ystep = h / ycount, - oy = ystep / 2, - x, - xv, - y, - yv, - p1, - p2; - for (x = 0; x < xcount; x++) { - xv = ox + x * xstep; - p1 = { x: xv, y: 0 }; - p2 = { x: xv, y: h }; - this.drawLine(p1, p2, offset); - } - for (y = 0; y < ycount; y++) { - yv = oy + y * ystep; - p1 = { x: 0, y: yv }; - p2 = { x: w, y: yv }; - this.drawLine(p1, p2, offset); - } - }, - - drawHull: function drawHull(curve, t, offset) { - var hull = curve instanceof Array ? curve : curve.hull(t); - if (hull.length === 6) { - this.drawLine(hull[0], hull[1], offset); - this.drawLine(hull[1], hull[2], offset); - this.drawLine(hull[3], hull[4], offset); - } else { - this.drawLine(hull[0], hull[1], offset); - this.drawLine(hull[1], hull[2], offset); - this.drawLine(hull[2], hull[3], offset); - this.drawLine(hull[4], hull[5], offset); - this.drawLine(hull[5], hull[6], offset); - this.drawLine(hull[7], hull[8], offset); - } - return hull; - }, - - drawCoordinates: function drawCoordinates(curve, offset) { - var _this2 = this; - - offset = offset || { x: 0, y: 0 }; - var pts = curve.points; - this.setFill("black"); - pts.forEach(function (p) { - _this2.text("(" + p.x + "," + p.y + ")", { x: p.x + offset.x + 5, y: p.y + offset.y + 10 }); - }); - }, - - drawFunction: function drawFunction(generator, offset) { - var start = generator.start || 0, - p0 = generator(start), - end = generator.end || 1, - plast = generator(end), - step = generator.step || 0.01, - scale = generator.scale || 1, - p, - t; - for (t = step; t < end; t += step) { - p = generator(t, scale); - this.drawLine(p0, p, offset); - p0 = p; - } - this.drawLine(p, plast, offset); - }, - - drawCurve: function drawCurve(curve, offset) { - var _this3 = this; - - offset = offset || { x: 0, y: 0 }; - var p = curve.points; - - if (p.length <= 3 || 5 <= p.length) { - var points = curve.getLUT(100); - var p0 = points[0]; - points.forEach(function (p1, i) { - if (!i) return; - _this3.drawLine(p0, p1, offset); - p0 = p1; - }); - return; - } - - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - this.ctx.beginPath(); - this.ctx.moveTo(p[0].x + ox, p[0].y + oy); - if (p.length === 3) { - this.ctx.quadraticCurveTo(p[1].x + ox, p[1].y + oy, p[2].x + ox, p[2].y + oy); - } else if (p.length === 4) { - this.ctx.bezierCurveTo(p[1].x + ox, p[1].y + oy, p[2].x + ox, p[2].y + oy, p[3].x + ox, p[3].y + oy); - } - this.ctx.stroke(); - this.ctx.closePath(); - }, - - drawLine: function drawLine(p1, p2, offset) { - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - this.ctx.beginPath(); - this.ctx.moveTo(p1.x + ox, p1.y + oy); - this.ctx.lineTo(p2.x + ox, p2.y + oy); - this.ctx.stroke(); - }, - - drawPoint: function drawPoint(p, offset) { - this.drawCircle(p, 1, offset); - }, - - drawPoints: function drawPoints(points, offset) { - offset = offset || { x: 0, y: 0 }; - points.forEach(function (p) { - this.drawCircle(p, offset.x !== 0 || offset.y !== 0 ? 1.5 : 3, offset); - }.bind(this)); - }, - - drawArc: function drawArc(p, offset) { - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - this.ctx.beginPath(); - this.ctx.moveTo(p.x + ox, p.y + oy); - this.ctx.arc(p.x + ox, p.y + oy, p.r, p.s, p.e); - this.ctx.lineTo(p.x + ox, p.y + oy); - this.ctx.fill(); - this.ctx.stroke(); - }, - - drawCircle: function drawCircle(p, r, offset) { - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - this.ctx.beginPath(); - this.ctx.arc(p.x + ox, p.y + oy, r, 0, 2 * Math.PI); - this.ctx.stroke(); - }, - - drawbbox: function drawbbox(bbox, offset) { - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - this.ctx.beginPath(); - this.ctx.moveTo(bbox.x.min + ox, bbox.y.min + oy); - this.ctx.lineTo(bbox.x.min + ox, bbox.y.max + oy); - this.ctx.lineTo(bbox.x.max + ox, bbox.y.max + oy); - this.ctx.lineTo(bbox.x.max + ox, bbox.y.min + oy); - this.ctx.closePath(); - this.ctx.stroke(); - }, - - drawRect: function drawRect(p1, p2, offset) { - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - var x = p1.x + ox, - y = p1.y + oy, - w = p2.x - p1.x, - h = p2.y - p1.y; - this.ctx.beginPath(); - this.ctx.moveTo(x, y); - this.ctx.lineTo(x + w, y); - this.ctx.lineTo(x + w, y + h); - this.ctx.lineTo(x, y + h); - this.ctx.closePath(); - this.ctx.fill(); - this.ctx.stroke(); - }, - - drawPath: function drawPath(path, offset) { - var _this4 = this; - - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - this.ctx.beginPath(); - path.forEach(function (p, idx) { - if (idx === 0) { - return _this4.ctx.moveTo(p.x + ox, p.y + oy); - } - _this4.ctx.lineTo(p.x + ox, p.y + oy); - }); - if (closed) this.ctx.closePath(); - this.ctx.fill(); - this.ctx.stroke(); - }, - - drawShape: function drawShape(shape, offset) { - offset = offset || { x: 0, y: 0 }; - var ox = offset.x + this.offset.x; - var oy = offset.y + this.offset.y; - var order = shape.forward.points.length - 1; - this.ctx.beginPath(); - this.ctx.moveTo(ox + shape.startcap.points[0].x, oy + shape.startcap.points[0].y); - this.ctx.lineTo(ox + shape.startcap.points[3].x, oy + shape.startcap.points[3].y); - if (order === 3) { - this.ctx.bezierCurveTo(ox + shape.forward.points[1].x, oy + shape.forward.points[1].y, ox + shape.forward.points[2].x, oy + shape.forward.points[2].y, ox + shape.forward.points[3].x, oy + shape.forward.points[3].y); - } else { - this.ctx.quadraticCurveTo(ox + shape.forward.points[1].x, oy + shape.forward.points[1].y, ox + shape.forward.points[2].x, oy + shape.forward.points[2].y); - } - this.ctx.lineTo(ox + shape.endcap.points[3].x, oy + shape.endcap.points[3].y); - if (order === 3) { - this.ctx.bezierCurveTo(ox + shape.back.points[1].x, oy + shape.back.points[1].y, ox + shape.back.points[2].x, oy + shape.back.points[2].y, ox + shape.back.points[3].x, oy + shape.back.points[3].y); - } else { - this.ctx.quadraticCurveTo(ox + shape.back.points[1].x, oy + shape.back.points[1].y, ox + shape.back.points[2].x, oy + shape.back.points[2].y); - } - this.ctx.closePath(); - this.ctx.fill(); - this.ctx.stroke(); - }, - - text: function text(_text, coord, offset) { - offset = offset || { x: 0, y: 0 }; - if (this.offset) { - offset.x += this.offset.x; - offset.y += this.offset.y; - } - this.ctx.fillText(_text, coord.x + offset.x, coord.y + offset.y); - }, - - image: function image(_image, offset) { - var _this5 = this; - - offset = offset || { x: 0, y: 0 }; - if (this.offset) { - offset.x += this.offset.x; - offset.y += this.offset.y; - } - var dpr = _image.devicePixelRatio || 1; - if (_image.loaded) { - this.ctx.drawImage(_image, offset.x, offset.y, _image.width / dpr, _image.height / dpr); - } else { - _image.onload = function () { - _image.loaded = true; - _this5.ctx.drawImage(_image, offset.x, offset.y, _image.width / dpr, _image.height / dpr); - }; - } - }, - - drawAxes: function drawAxes(pad, xlabel, xs, xe, ylabel, ys, ye, offset) { - offset = offset || { x: 0, y: 0 }; - var dim = this.getPanelWidth(); - - this.drawLine({ x: pad, y: pad }, { x: dim - pad, y: pad }, offset); - this.drawLine({ x: pad, y: pad }, { x: pad, y: dim - pad }, offset); - - this.setFill("black"); - - this.text(xlabel + " →", { x: offset.x + dim / 2, y: offset.y + 15 }); - this.text(xs, { x: offset.x + pad, y: offset.y + 15 }); - this.text(xe, { x: offset.x + dim - pad, y: offset.y + 15 }); - - this.text(ylabel, { x: offset.x + 5, y: offset.y + dim / 2 - pad }); - this.text("↓", { x: offset.x + 5, y: offset.y + dim / 2 }); - this.text(ys, { x: offset.x + 4, y: offset.y + pad + 5 }); - this.text(ye, { x: offset.x + 2, y: offset.y + dim - pad + 10 }); - } -}; - -if (hasWindow) { - window["Bezier Graphics API"] = API; -} -if (true) { - module.exports = API; -} - -/***/ }), -/* 122 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var React = __webpack_require__(5); - -var Locale = __webpack_require__(68); -var locale = new Locale(); -var page = "locale-switcher"; - -module.exports = function (props) { - return React.createElement( - "div", - { className: "locale-switcher" }, - locale.getContent(page, this) - ); -}; - -/***/ }), -/* 123 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - "LocaleSwitcher": __webpack_require__(122) -}; - -/***/ }), -/* 124 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - onClick: function onClick(evt, api) { - api.t = api.curve.on({ x: evt.offsetX, y: evt.offsetY }, 7); - if (api.t < 0.05 || api.t > 0.95) api.t = false; - api.redraw(); - }, - - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - curve.points[0].y -= 10; - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - curve.points[2].y -= 20; - api.setCurve(curve); - api.lut = curve.getLUT(100); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var h = api.getPanelHeight(); - - api.setColor("black"); - if (api.t) { - api.drawCircle(api.curve.get(api.t), 3); - api.setColor("lightgrey"); - var hull = api.drawHull(curve, api.t); - var utils = api.utils; - - var A, B, C; - - if (hull.length === 6) { - A = curve.points[1]; - B = hull[5]; - C = utils.lli4(A, B, curve.points[0], curve.points[2]); - api.setColor("lightgrey"); - api.drawLine(curve.points[0], curve.points[2]); - } else if (hull.length === 10) { - A = hull[5]; - B = hull[9]; - C = utils.lli4(A, B, curve.points[0], curve.points[3]); - api.setColor("lightgrey"); - api.drawLine(curve.points[0], curve.points[3]); - } - - api.setColor("#00FF00"); - api.drawLine(A, B); - api.setColor("red"); - api.drawLine(B, C); - api.setColor("black"); - api.drawCircle(C, 3); - - api.setFill("black"); - api.text("A", { x: 10 + A.x, y: A.y }); - api.text("B (t = " + api.utils.round(api.t, 2) + ")", { x: 10 + B.x, y: B.y }); - api.text("C", { x: 10 + C.x, y: C.y }); - - var d1 = utils.dist(A, B); - var d2 = utils.dist(B, C); - var ratio = d1 / d2; - - api.text("d1 (A-B): " + utils.round(d1, 2) + ", d2 (B-C): " + utils.round(d2, 2) + ", ratio (d1/d2): " + utils.round(ratio, 4), { x: 10, y: h - 7 }); - } - }, - - setCT: function setCT(evt, api) { - api.t = evt.offsetX / api.getPanelWidth(); - }, - - drawCTgraph: function drawCTgraph(api) { - api.reset(); - api.setColor("black"); - var w = api.getPanelWidth(); - var pad = 20; - var fwh = w - 2 * pad; - api.drawAxes(pad, "t", 0, 1, "u", 0, 1); - api.setColor("blue"); - var uPoint = function uPoint(t) { - var value = api.u(t), - res = { x: pad + t * fwh, y: pad + value * fwh }; - return res; - }; - api.drawFunction(uPoint); - if (api.t) { - var v = api.u(api.t), - v1 = api.utils.round(v, 3), - v2 = api.utils.round(1 - v, 3), - up = uPoint(api.t); - api.drawLine({ x: up.x, y: pad }, up); - api.drawLine({ x: pad, y: up.y }, up); - api.drawCircle(up, 3); - api.setFill("blue"); - api.text(" t = " + api.utils.round(api.t, 3), { x: up.x + 10, y: up.y - 7 }); - api.text("u(t) = " + api.utils.round(v, 3), { x: up.x + 10, y: up.y + 7 }); - api.setFill("black"); - api.text("C = " + v1 + " * start + " + v2 + " * end", { x: w / 2 - pad, y: pad + fwh }); - } - }, - - drawQCT: function drawQCT(api) { - api.u = api.u || function (t) { - var top = (t - 1) * (t - 1), - bottom = 2 * t * t - 2 * t + 1; - return top / bottom; - }; - this.drawCTgraph(api); - }, - - drawCCT: function drawCCT(api) { - api.u = api.u || function (t) { - var top = (1 - t) * (1 - t) * (1 - t), - bottom = t * t * t + top; - return top / bottom; - }; - this.drawCTgraph(api); - } -}; - -/***/ }), -/* 125 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(124); -var generateBase = __webpack_require__(1); -module.exports = generateBase("abc", handler); - -/***/ }), -/* 126 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - align: function align(points, line) { - var tx = line.p1.x, - ty = line.p1.y, - a = -Math.atan2(line.p2.y - ty, line.p2.x - tx), - cos = Math.cos, - sin = Math.sin, - d = function d(v) { - return { - x: (v.x - tx) * cos(a) - (v.y - ty) * sin(a), - y: (v.x - tx) * sin(a) + (v.y - ty) * cos(a) - }; - }; - return points.map(d); - }, - - draw: function draw(api, curve) { - api.setPanelCount(2); - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var pts = curve.points; - var line = { p1: pts[0], p2: pts[pts.length - 1] }; - var apts = this.align(pts, line); - var aligned = new api.Bezier(apts); - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - - var offset = { x: w, y: 0 }; - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - offset.x += w / 4; - offset.y += h / 2; - api.setColor("grey"); - api.drawLine({ x: 0, y: -h / 2 }, { x: 0, y: h / 2 }, offset); - api.drawLine({ x: -w / 4, y: 0 }, { x: w, y: 0 }, offset); - api.setFill("grey"); - - api.setColor("black"); - api.drawSkeleton(aligned, offset); - api.drawCurve(aligned, offset); - } -}; - -/***/ }), -/* 127 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(126); -var generateBase = __webpack_require__(1); -module.exports = generateBase("aligning", handler); - -/***/ }), -/* 128 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var atan2 = Math.atan2, - PI = Math.PI, - TAU = 2 * PI, - cos = Math.cos, - sin = Math.sin; - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "error", - values: { - "38": 0.1, // up arrow - "40": -0.1 // down arrow - }, - controller: function controller(api) { - if (api.error < 0.1) { - api.error = 0.1; - } - } - } - }, - - setupCircle: function setupCircle(api) { - var curve = new api.Bezier(70, 70, 140, 40, 240, 130); - api.setCurve(curve); - }, - - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - api.error = 0.5; - }, - - getCCenter: function getCCenter(api, p1, p2, p3) { - // deltas - var dx1 = p2.x - p1.x, - dy1 = p2.y - p1.y, - dx2 = p3.x - p2.x, - dy2 = p3.y - p2.y; - - // perpendiculars (quarter circle turned) - var dx1p = dx1 * cos(PI / 2) - dy1 * sin(PI / 2), - dy1p = dx1 * sin(PI / 2) + dy1 * cos(PI / 2), - dx2p = dx2 * cos(PI / 2) - dy2 * sin(PI / 2), - dy2p = dx2 * sin(PI / 2) + dy2 * cos(PI / 2); - - // chord midpoints - var mx1 = (p1.x + p2.x) / 2, - my1 = (p1.y + p2.y) / 2, - mx2 = (p2.x + p3.x) / 2, - my2 = (p2.y + p3.y) / 2; - - // midpoint offsets - var mx1n = mx1 + dx1p, - my1n = my1 + dy1p, - mx2n = mx2 + dx2p, - my2n = my2 + dy2p; - - // intersection of these lines: - var i = api.utils.lli8(mx1, my1, mx1n, my1n, mx2, my2, mx2n, my2n); - var r = api.utils.dist(i, p1); - - // arc start/end values, over mid point - var s = atan2(p1.y - i.y, p1.x - i.x), - m = atan2(p2.y - i.y, p2.x - i.x), - e = atan2(p3.y - i.y, p3.x - i.x); - - // determine arc direction (cw/ccw correction) - var __; - if (s < e) { - // if s<m<e, arc(s, e) - // if m<s<e, arc(e, s + TAU) - // if s<e<m, arc(e, s + TAU) - if (s > m || m > e) { - s += TAU; - } - if (s > e) { - __ = e;e = s;s = __; - } - } else { - // if e<m<s, arc(e, s) - // if m<e<s, arc(s, e + TAU) - // if e<s<m, arc(s, e + TAU) - if (e < m && m < s) { - __ = e;e = s;s = __; - } else { - e += TAU; - } - } - - // assign and done. - i.s = s; - i.e = e; - i.r = r; - return i; - }, - - drawCircle: function drawCircle(api, curve) { - api.reset(); - var pts = curve.points; - - // get center - var C = this.getCCenter(api, pts[0], pts[1], pts[2]); - // outer circle - api.setColor("grey"); - api.drawCircle(C, api.utils.dist(C, pts[0])); - - // controllable points - api.setColor("black"); - pts.forEach(function (p) { - return api.drawCircle(p, 3); - }); - - // chords and perpendicular lines - var m; - - api.setColor("blue"); - api.drawLine(pts[0], pts[1]); - m = { x: (pts[0].x + pts[1].x) / 2, y: (pts[0].y + pts[1].y) / 2 }; - api.drawLine(m, { x: C.x + (C.x - m.x), y: C.y + (C.y - m.y) }); - - api.setColor("red"); - api.drawLine(pts[1], pts[2]); - m = { x: (pts[1].x + pts[2].x) / 2, y: (pts[1].y + pts[2].y) / 2 }; - api.drawLine(m, { x: C.x + (C.x - m.x), y: C.y + (C.y - m.y) }); - - api.setColor("green"); - api.drawLine(pts[2], pts[0]); - m = { x: (pts[2].x + pts[0].x) / 2, y: (pts[2].y + pts[0].y) / 2 }; - api.drawLine(m, { x: C.x + (C.x - m.x), y: C.y + (C.y - m.y) }); - - // center - api.setColor("black"); - api.drawPoint(C); - api.setFill("black"); - api.text("Intersection point", C, { x: -25, y: 10 }); - }, - - drawSingleArc: function drawSingleArc(api, curve) { - api.reset(); - var arcs = curve.arcs(api.error); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var a = arcs[0]; - api.setColor("red"); - api.setFill("rgba(255,0,0,0.2)"); - api.debug = true; - api.drawArc(a); - - api.setFill("black"); - api.text("Arc approximation with total error " + api.utils.round(api.error, 1), { x: 10, y: 15 }); - }, - - drawArcs: function drawArcs(api, curve) { - api.reset(); - var arcs = curve.arcs(api.error); - api.drawSkeleton(curve); - api.drawCurve(curve); - arcs.forEach(function (a) { - api.setRandomColor(0.3); - api.setFill(api.getColor()); - api.drawArc(a); - }); - - api.setFill("black"); - api.text("Arc approximation with total error " + api.utils.round(api.error, 1) + " per arc segment", { x: 10, y: 15 }); - } -}; - -/***/ }), -/* 129 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(128); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("arcapproximation", handler)); - -/***/ }), -/* 130 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var sin = Math.sin; -var tau = Math.PI * 2; - -module.exports = { - setup: function setup(api) { - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - var generator; - if (!this.generator) { - generator = function generator(v, scale) { - scale = scale || 1; - return { - x: v * w / tau, - y: scale * sin(v) - }; - }; - generator.start = 0; - generator.end = tau; - generator.step = 0.1; - generator.scale = h / 3; - this.generator = generator; - } - }, - - drawSine: function drawSine(api, dheight) { - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - var generator = this.generator; - generator.dheight = dheight; - - api.setColor("black"); - api.drawLine({ x: 0, y: h / 2 }, { x: w, y: h / 2 }); - api.drawFunction(generator, { x: 0, y: h / 2 }); - }, - - drawSlices: function drawSlices(api, steps) { - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - var f = w / tau; - var area = 0; - var c = steps <= 25 ? 1 : 0; - api.reset(); - api.setColor("transparent"); - api.setFill("rgba(150,150,255, 0.4)"); - for (var step = tau / steps, i = step / 2, v, p1, p2; i < tau + step / 2; i += step) { - v = this.generator(i); - p1 = { x: v.x - f * step / 2 + c, y: 0 }; - p2 = { x: v.x + f * step / 2 - c, y: v.y * this.generator.scale }; - - if (!c) { - api.setFill("rgba(150,150,255," + (0.4 + 0.3 * Math.random()) + ")"); - } - api.drawRect(p1, p2, { x: 0, y: h / 2 }); - area += step * Math.abs(v.y * this.generator.scale); - } - api.setFill("black"); - var trueArea = (100 * 4 * h / 3 | 0) / 100; - var currArea = (100 * area | 0) / 100; - api.text("Approximating with " + steps + " strips (true area: " + trueArea + "): " + currArea, { x: 10, y: h - 15 }); - }, - - drawCoarseIntegral: function drawCoarseIntegral(api) { - api.reset(); - this.drawSlices(api, 10); - this.drawSine(api); - }, - - drawFineIntegral: function drawFineIntegral(api) { - api.reset(); - this.drawSlices(api, 24); - this.drawSine(api); - }, - - drawSuperFineIntegral: function drawSuperFineIntegral(api) { - api.reset(); - this.drawSlices(api, 99); - this.drawSine(api); - }, - - setupCurve: function setupCurve(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - drawCurve: function drawCurve(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - var len = curve.length(); - api.setFill("black"); - api.text("Curve length: " + len + " pixels", { x: 10, y: 15 }); - } -}; - -/***/ }), -/* 131 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(130); -var generateBase = __webpack_require__(1); -module.exports = generateBase("arclength", handler); - -/***/ }), -/* 132 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "steps", - values: { - "38": 1, // up arrow - "40": -1 // down arrow - }, - controller: function controller(api) { - if (api.steps < 1) { - api.steps = 1; - } - } - } - }, - - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - api.steps = 10; - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - api.steps = 16; - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - - var pts = curve.getLUT(api.steps); - - var step = 1 / api.steps; - var p0 = curve.points[0], - pc; - for (var t = step; t < 1.0 + step; t += step) { - pc = curve.get(Math.min(t, 1)); - api.setColor("red"); - api.drawLine(p0, pc); - p0 = pc; - } - - var len = curve.length(); - var alen = 0; - for (var i = 0, p1, dx, dy; i < pts.length - 1; i++) { - p0 = pts[i]; - p1 = pts[i + 1]; - dx = p1.x - p0.x; - dy = p1.y - p0.y; - alen += Math.sqrt(dx * dx + dy * dy); - } - alen = (100 * alen | 0) / 100; - len = (100 * len | 0) / 100; - - api.text("Approximate length, " + api.steps + " steps: " + alen + " (true: " + len + ")", { x: 10, y: 15 }); - } -}; - -/***/ }), -/* 133 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(132); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("arclengthapprox", handler)); - -/***/ }), -/* 134 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.reset(); - api.setColor("#00FF00"); - api.drawbbox(curve.bbox()); - api.setColor("black"); - api.drawSkeleton(curve); - api.drawCurve(curve); - api.setColor("red"); - curve.extrema().values.forEach(function (t) { - api.drawCircle(curve.get(t), 3); - }); - } -}; - -/***/ }), -/* 135 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(134); -var generateBase = __webpack_require__(1); -module.exports = generateBase("boundingbox", handler); - -/***/ }), -/* 136 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - degree: 3, - activeDistance: 9, - - setup: function setup() { - this.size(600, 300); - this.draw(); - }, - draw: function draw() { - var _this = this; - - this.clear(); - this.grid(25); - var p = this.points[0]; - this.points.forEach(function (n) { - _this.stroke(200); - _this.line(n.x, n.y, p.x, p.y); - p = n; - _this.stroke(0); - _this.circle(p.x, p.y, 4); - }); - this.drawSplineData(); - }, - drawSplineData: function drawSplineData() { - if (this.points.length <= this.degree) return; - var mapped = this.points.map(function (p) { - return [p.x, p.y]; - }); - this.drawCurve(mapped); - this.drawKnots(mapped); - } -}; - -/***/ }), -/* 137 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - degree: 3, - activeDistance: 9, - - setup: function setup() { - this.size(400, 400); - - var TAU = Math.PI * 2; - for (var i = 0; i < TAU; i += TAU / 9) { - this.points.push({ - x: this.width / 2 + 100 * Math.cos(i), - y: this.height / 2 + 100 * Math.sin(i) - }); - } - - this.knots = this.formKnots(this.points); - var m = Math.round(this.points.length / 2) | 0; - this.knots[m + 0] = this.knots[m]; - this.knots[m + 1] = this.knots[m]; - this.knots[m + 2] = this.knots[m]; - for (var _i = m + 3; _i < this.knots.length; _i++) { - this.knots[_i] = this.knots[_i - 1] + 1; - } - - if (this.props.controller) { - this.props.controller(this, this.knots); - } - - this.draw(); - }, - draw: function draw() { - var _this = this; - - this.clear(); - this.grid(25); - var p = this.points[0]; - this.points.forEach(function (n) { - _this.stroke(200); - _this.line(n.x, n.y, p.x, p.y); - p = n; - _this.stroke(0); - _this.circle(p.x, p.y, 4); - }); - this.drawSplineData(); - }, - drawSplineData: function drawSplineData() { - if (this.points.length <= this.degree) return; - var mapped = this.points.map(function (p) { - return [p.x, p.y]; - }); - this.drawCurve(mapped); - this.drawKnots(mapped); - } -}; - -/***/ }), -/* 138 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - basicSketch: __webpack_require__(136), - interpolationGraph: __webpack_require__(140), - uniformBSpline: __webpack_require__(143), - centerCutBSpline: __webpack_require__(137), - openUniformBSpline: __webpack_require__(141), - rationalUniformBSpline: __webpack_require__(142), - - bindKnots: function bindKnots(owner, knots, ref) { - this.refs[ref].bindKnots(owner, knots); - }, - - bindWeights: function bindWeights(owner, weights, closed, ref) { - this.refs[ref].bindWeights(owner, weights, closed); - } -}; - -/***/ }), -/* 139 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(138); -var generateBase = __webpack_require__(1); -module.exports = generateBase("bsplines", handler); - -/***/ }), -/* 140 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var colors = ['#C00', '#CC0', '#0C0', '#0CC', '#00C', '#C0C', '#600', '#660', '#060', '#066', '#006', '#606']; - -module.exports = { - degree: 3, - activeDistance: 9, - cache: { N: [] }, - - setup: function setup() { - this.size(600, 300); - this.points = [{ x: 0, y: 0 }, { x: 100, y: -100 }, { x: 200, y: 100 }, { x: 300, y: -100 }, { x: 400, y: 100 }, { x: 500, y: 0 }]; - this.knots = this.formKnots(this.points); - if (this.props.controller) { - this.props.controller(this, this.knots); - } - this.draw(); - }, - draw: function draw() { - this.clear(); - var pad = 25; - this.grid(pad); - this.stroke(0); - this.line(pad, 0, pad, this.height); - var y = this.height - pad; - this.line(0, y, this.width, y); - - var k = this.degree; - var n = this.points.length || 4; - - for (var i = 0; i < n + 1 + k; i++) { - this.drawN(i, k, pad, (this.width - pad) / (2 * (n + 2)), this.height - 2 * pad); - } - }, - drawN: function drawN(i, k, pad, w, h) { - this.stroke(colors[i]); - var knots = this.knots; - this.beginPath(); - for (var start = i - 1, t = start, step = 0.1, end = i + k + 1; t < end; t += step) { - var x = pad + i * w + t * w; - var y = this.height - pad - this.N(i, k, t) * h; - this.vertex(x, y); - } - this.endPath(); - }, - N: function N(i, k, t) { - var t_i = this.knots[i]; - var t_i1 = this.knots[i + 1]; - var t_ik1 = this.knots[i + k - 1]; - var t_ik = this.knots[i + k]; - - if (k === 1) { - return t_i <= t && t <= t_i1 ? 1 : 0; - } - - var n1 = t - t_i; - var d1 = t_ik1 - t_i; - var a1 = d1 === 0 ? 0 : n1 / d1; - - var n2 = t_ik - t; - var d2 = t_ik - t_i1; - var a2 = d2 === 0 ? 0 : n2 / d2; - - var N1 = 0; - if (a1 !== 0) { - var n1v = this.ensureN(i, k - 1, t); - N1 = n1v === undefined ? this.N(i, k - 1, t) : n1v; - } - - var N2 = 0; - if (a2 !== 0) { - var n2v = this.ensureN(i + 1, k - 1, t); - N2 = n2v === undefined ? this.N(i + 1, k - 1, t) : n2v; - } - - this.cacheN(i, k, t, a1 * N1 + a2 * N2); - return this.cache.N[i][k][t]; - }, - ensureN: function ensureN(i, k, t) { - if (!this.cache.N) { - this.cache.N = []; - } - var N = this.cache.N; - if (!N[i]) { - N[i] = []; - } - if (!N[i][k]) { - N[i][k] = []; - } - return N[i][k][t]; - }, - cacheN: function cacheN(i, k, t, value) { - this.ensureN(i, k, t); - this.cache.N[i][k][t] = value; - } -}; - -/***/ }), -/* 141 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - degree: 3, - activeDistance: 9, - - setup: function setup() { - this.size(400, 400); - - var TAU = Math.PI * 2; - for (var i = 0; i < TAU; i += TAU / 10) { - this.points.push({ - x: this.width / 2 + 100 * Math.cos(i), - y: this.height / 2 + 100 * Math.sin(i) - }); - } - - this.knots = this.formKnots(this.points, true); - - if (this.props.controller) { - this.props.controller(this, this.knots); - } - - this.draw(); - }, - draw: function draw() { - var _this = this; - - this.clear(); - this.grid(25); - var p = this.points[0]; - this.points.forEach(function (n) { - _this.stroke(200); - _this.line(n.x, n.y, p.x, p.y); - p = n; - _this.stroke(0); - _this.circle(p.x, p.y, 4); - }); - this.drawSplineData(); - }, - drawSplineData: function drawSplineData() { - if (this.points.length <= this.degree) return; - var mapped = this.points.map(function (p) { - return [p.x, p.y]; - }); - this.drawCurve(mapped); - this.drawKnots(mapped); - } -}; - -/***/ }), -/* 142 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - degree: 3, - activeDistance: 9, - weights: [], - - setup: function setup() { - this.size(400, 400); - - var TAU = Math.PI * 2; - var r = this.width / 3; - for (var i = 0; i < 6; i++) { - this.points.push({ - x: this.width / 2 + r * Math.cos(i / 6 * TAU), - y: this.height / 2 + r * Math.sin(i / 6 * TAU) - }); - } - this.points = this.points.concat(this.points.slice(0, 3)); - this.closed = this.degree; - - this.knots = this.formKnots(this.points); - this.weights = this.formWeights(this.points); - - if (this.props.controller) { - this.props.controller(this, this.knots, this.weights, this.closed); - } - - this.draw(); - }, - draw: function draw() { - var _this = this; - - this.clear(); - this.grid(25); - var p = this.points[0]; - this.points.forEach(function (n) { - _this.stroke(200); - _this.line(n.x, n.y, p.x, p.y); - p = n; - _this.stroke(0); - _this.circle(p.x, p.y, 4); - }); - this.drawSplineData(); - }, - drawSplineData: function drawSplineData() { - if (this.points.length <= this.degree) return; - var mapped = this.points.map(function (p) { - return [p.x, p.y]; - }); - this.drawCurve(mapped); - this.drawKnots(mapped); - } -}; - -/***/ }), -/* 143 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - degree: 3, - activeDistance: 9, - - setup: function setup() { - this.size(400, 400); - - var TAU = Math.PI * 2; - for (var i = 0; i < TAU; i += TAU / 10) { - this.points.push({ - x: this.width / 2 + 100 * Math.cos(i), - y: this.height / 2 + 100 * Math.sin(i) - }); - } - - this.knots = this.formKnots(this.points); - if (this.props.controller) { - this.props.controller(this, this.knots); - } - this.draw(); - }, - draw: function draw() { - var _this = this; - - this.clear(); - this.grid(25); - var p = this.points[0]; - this.points.forEach(function (n) { - _this.stroke(200); - _this.line(n.x, n.y, p.x, p.y); - p = n; - _this.stroke(0); - _this.circle(p.x, p.y, 4); - }); - this.drawSplineData(); - }, - drawSplineData: function drawSplineData() { - if (this.points.length <= this.degree) return; - var mapped = this.points.map(function (p) { - return [p.x, p.y]; - }); - this.drawCurve(mapped); - this.drawKnots(mapped); - } -}; - -/***/ }), -/* 144 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setup: function setup(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - api.reset(); - api._map_loaded = false; - }, - - draw: function draw(api, curve) { - var w = 400, - h = w, - unit = this.unit, - center = { x: w / 2, y: h / 2 }; - - api.setSize(w, h); - api.setPanelCount(2); - api.reset(); - - api.drawSkeleton(curve); - api.drawCurve(curve); - - api.offset.x += 400; - - if (api._map_loaded) { - api.image(api._map_image); - } else { - setTimeout(function () { - this.drawBase(api, curve); - this.draw(api, curve); - }.bind(this), 100); - } - - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }); - - var npts = [{ x: 0, y: 0 }, { x: 0, y: unit }, { x: unit, y: unit }, this.forwardTransform(curve.points, unit)]; - - var canonical = new api.Bezier(npts); - api.setColor("blue"); - api.drawCurve(canonical, center); - api.drawCircle(npts[3], 3, center); - }, - - forwardTransform: function forwardTransform(pts, s) { - s = s || 1; - var p1 = pts[0], - p2 = pts[1], - p3 = pts[2], - p4 = pts[3]; - - var xn = -p1.x + p4.x - (-p1.x + p2.x) * (-p1.y + p4.y) / (-p1.y + p2.y); - var xd = -p1.x + p3.x - (-p1.x + p2.x) * (-p1.y + p3.y) / (-p1.y + p2.y); - var np4x = s * xn / xd; - - var yt1 = s * (-p1.y + p4.y) / (-p1.y + p2.y); - var yt2 = s - s * (-p1.y + p3.y) / (-p1.y + p2.y); - var yp = yt2 * xn / xd; - var np4y = yt1 + yp; - - return { x: np4x, y: np4y }; - }, - - drawBase: function drawBase(api, curve) { - api.reset(); - - var w = 400, - h = w, - unit = this.unit = w / 5, - center = { x: w / 2, y: h / 2 }; - - api.setSize(w, h); - - // axes + gridlines - api.setColor("lightgrey"); - for (var x = 0; x < w; x += unit / 2) { - api.drawLine({ x: x, y: 0 }, { x: x, y: h }); - } - for (var y = 0; y < h; y += unit / 2) { - api.drawLine({ x: 0, y: y }, { x: w, y: y }); - } - api.setColor("black"); - api.drawLine({ x: w / 2, y: 0 }, { x: w / 2, y: h }); - api.drawLine({ x: 0, y: h / 2 }, { x: w, y: h / 2 }); - - // Inflection border: - api.setColor("green"); - api.drawLine({ x: -w / 2, y: unit }, { x: w / 2, y: unit }, center); - - // the three stable points - api.setColor("black"); - api.setFill("black"); - api.drawCircle({ x: 0, y: 0 }, 4, center); - api.text("(0,0)", { x: 5 + center.x, y: 15 + center.y }); - api.drawCircle({ x: 0, y: unit }, 4, center); - api.text("(0,1)", { x: 5 + center.x, y: unit + 15 + center.y }); - api.drawCircle({ x: unit, y: unit }, 4, center); - api.text("(1,1)", { x: unit + 5 + center.x, y: unit + 15 + center.y }); - - // cusp parabola: - api.setWeight(1.5); - api.setColor("#FF0000"); - api.setFill(api.getColor()); - var pts = []; - var px = 1, - py = 1; - for (x = -10; x <= 1; x += 0.01) { - y = (-x * x + 2 * x + 3) / 4; - if (x > -10) { - pts.push({ x: unit * px, y: unit * py }); - api.drawLine({ x: unit * px, y: unit * py }, { x: unit * x, y: unit * y }, center); - } - px = x; - py = y; - } - pts.push({ x: unit * px, y: unit * py }); - api.text("Curve form has cusp →", { x: w / 2 - unit * 2, y: h / 2 + unit / 2.5 }); - - // loop/arch transition boundary, elliptical section - api.setColor("#FF00FF"); - api.setFill(api.getColor()); - var sqrt = Math.sqrt; - for (x = 1; x >= 0; x -= 0.005) { - pts.push({ x: unit * px, y: unit * py }); - y = 0.5 * (sqrt(3) * sqrt(4 * x - x * x) - x); - api.drawLine({ x: unit * px, y: unit * py }, { x: unit * x, y: unit * y }, center); - px = x; - py = y; - } - pts.push({ x: unit * px, y: unit * py }); - api.text("← Curve forms a loop at t = 1", { x: w / 2 + unit / 4, y: h / 2 + unit / 1.5 }); - - // loop/arch transition boundary, parabolic section - api.setColor("#3300FF"); - api.setFill(api.getColor()); - for (x = 0; x > -w; x -= 0.01) { - pts.push({ x: unit * px, y: unit * py }); - y = (-x * x + 3 * x) / 3; - api.drawLine({ x: unit * px, y: unit * py }, { x: unit * x, y: unit * y }, center); - px = x; - py = y; - } - pts.push({ x: unit * px, y: unit * py }); - api.text("← Curve forms a loop at t = 0", { x: w / 2 - unit + 10, y: h / 2 - unit * 1.25 }); - - // shape fill - api.setColor("transparent"); - api.setFill("rgba(255,120,100,0.2)"); - api.drawPath(pts, center); - pts = [{ x: -w / 2, y: unit }, { x: w / 2, y: unit }, { x: w / 2, y: h }, { x: -w / 2, y: h }]; - api.setFill("rgba(0,200,0,0.2)"); - api.drawPath(pts, center); - - // further labels - api.setColor("black"); - api.setFill(api.getColor()); - api.text("← Curve form has one inflection →", { x: w / 2 - unit, y: h / 2 + unit * 1.75 }); - api.text("← Plain curve ↕", { x: w / 2 + unit / 2, y: h / 6 }); - api.text("↕ Double inflection", { x: 10, y: h / 2 - 10 }); - - api._map_image = api.toImage(); - api._map_loaded = true; - } -}; - -/***/ }), -/* 145 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(144); -var generateBase = __webpack_require__(1); -module.exports = generateBase("canonical", handler); - -/***/ }), -/* 146 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var generateBase = __webpack_require__(1); -module.exports = generateBase("catmullconv"); - -/***/ }), -/* 147 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "distance", - values: { - "38": 1, // up arrow - "40": -1 // down arrow - } - } - }, - - setup: function setup(api) { - api.setPanelCount(3); - api.lpts = [{ x: 56, y: 153 }, { x: 144, y: 83 }, { x: 188, y: 185 }]; - api.distance = 0; - }, - - convert: function convert(p1, p2, p3, p4) { - var t = 0.5; - return [p2, { - x: p2.x + (p3.x - p1.x) / (6 * t), - y: p2.y + (p3.y - p1.y) / (6 * t) - }, { - x: p3.x - (p4.x - p2.x) / (6 * t), - y: p3.y - (p4.y - p2.y) / (6 * t) - }, p3]; - }, - - draw: function draw(api) { - api.reset(); - api.setColor("lightblue"); - api.drawGrid(10, 10); - - var pts = api.lpts; - api.setColor("black"); - api.setFill("black"); - pts.forEach(function (p, pos) { - api.drawCircle(p, 3); - api.text("point " + (pos + 1), p, { x: 10, y: 7 }); - }); - - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - var offset = { x: w, y: 0 }; - api.setColor("lightblue"); - api.drawGrid(10, 10, offset); - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - - pts.forEach(function (p, pos) { - api.drawCircle(p, 3, offset); - }); - var p1 = pts[0], - p2 = pts[1], - p3 = pts[2]; - var dx = p3.x - p1.x, - dy = p3.y - p1.y, - m = Math.sqrt(dx * dx + dy * dy); - dx /= m; - dy /= m; - api.drawLine(p1, p3, offset); - - var p0 = { - x: p1.x + (p3.x - p2.x) - api.distance * dx, - y: p1.y + (p3.y - p2.y) - api.distance * dy - }; - var p4 = { - x: p1.x + (p3.x - p2.x) + api.distance * dx, - y: p1.y + (p3.y - p2.y) + api.distance * dy - }; - var center = api.utils.lli4(p1, p3, p2, { - x: (p0.x + p4.x) / 2, - y: (p0.y + p4.y) / 2 - }); - api.setColor("blue"); - api.drawCircle(center, 3, offset); - api.drawLine(pts[1], center, offset); - api.setColor("#666"); - api.drawLine(center, p0, offset); - api.drawLine(center, p4, offset); - - api.setFill("blue"); - api.text("p0", p0, { x: -20 + offset.x, y: offset.y + 2 }); - api.text("p4", p4, { x: +10 + offset.x, y: offset.y + 2 }); - - // virtual point p0 - api.setColor("red"); - api.drawCircle(p0, 3, offset); - api.drawLine(p2, p0, offset); - api.drawLine(p1, { - x: p1.x + (p2.x - p0.x) / 5, - y: p1.y + (p2.y - p0.y) / 5 - }, offset); - - // virtual point p4 - api.setColor("#00FF00"); - api.drawCircle(p4, 3, offset); - api.drawLine(p2, p4, offset); - api.drawLine(p3, { - x: p3.x + (p4.x - p2.x) / 5, - y: p3.y + (p4.y - p2.y) / 5 - }, offset); - - // Catmull-Rom curve for p0-p1-p2-p3-p4 - var c1 = new api.Bezier(this.convert(p0, p1, p2, p3)), - c2 = new api.Bezier(this.convert(p1, p2, p3, p4)); - api.setColor("lightgrey"); - api.drawCurve(c1, offset); - api.drawCurve(c2, offset); - - offset.x += w; - api.setColor("lightblue"); - api.drawGrid(10, 10, offset); - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - - api.drawCurve(c1, offset); - api.drawCurve(c2, offset); - api.drawPoints(c1.points, offset); - api.drawPoints(c2.points, offset); - api.setColor("lightgrey"); - api.drawLine(c1.points[0], c1.points[1], offset); - api.drawLine(c1.points[2], c2.points[1], offset); - api.drawLine(c2.points[2], c2.points[3], offset); - } -}; - -/***/ }), -/* 148 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(147); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("catmullmoulding", handler)); - -/***/ }), -/* 149 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var sin = Math.sin, - cos = Math.cos; - -module.exports = { - setup: function setup(api) { - api.w = api.getPanelWidth(); - api.h = api.getPanelHeight(); - api.pad = 20; - api.r = api.w / 2 - api.pad; - api.mousePt = false; - api.angle = 0; - var spt = { x: api.w - api.pad, y: api.h / 2 }; - api.setCurve(new api.Bezier(spt, spt, spt)); - }, - - draw: function draw(api, curve) { - api.reset(); - api.setColor("lightgrey"); - api.drawGrid(1, 1); - api.setColor("red"); - api.drawCircle({ x: api.w / 2, y: api.h / 2 }, api.r); - api.setColor("transparent"); - api.setFill("rgba(100,255,100,0.4)"); - var p = { - x: api.w / 2, - y: api.h / 2, - r: api.r, - s: api.angle < 0 ? api.angle : 0, - e: api.angle < 0 ? 0 : api.angle - }; - api.drawArc(p); - api.setColor("black"); - api.drawSkeleton(curve); - api.drawCurve(curve); - }, - - onMouseMove: function onMouseMove(evt, api) { - var x = evt.offsetX - api.w / 2, - y = evt.offsetY - api.h / 2; - var angle = Math.atan2(y, x); - var pts = api.curve.points; - // new control - var r = api.r, - b = (cos(angle) - 1) / sin(angle); - pts[1] = { - x: api.w / 2 + r * (cos(angle) - b * sin(angle)), - y: api.w / 2 + r * (sin(angle) + b * cos(angle)) - }; - // new endpoint - pts[2] = { - x: api.w / 2 + api.r * cos(angle), - y: api.w / 2 + api.r * sin(angle) - }; - api.setCurve(new api.Bezier(pts)); - api.angle = angle; - } -}; - -/***/ }), -/* 150 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(149); -var generateBase = __webpack_require__(1); -module.exports = generateBase("circles", handler); - -/***/ }), -/* 151 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var sin = Math.sin, - cos = Math.cos, - tan = Math.tan; - -module.exports = { - setup: function setup(api) { - api.setSize(400, 400); - api.w = api.getPanelWidth(); - api.h = api.getPanelHeight(); - api.pad = 80; - api.r = api.w / 2 - api.pad; - api.mousePt = false; - api.angle = 0; - var spt = { x: api.w - api.pad, y: api.h / 2 }; - api.setCurve(new api.Bezier(spt, spt, spt, spt)); - }, - - guessCurve: function guessCurve(S, B, E) { - var C = { - x: (S.x + E.x) / 2, - y: (S.y + E.y) / 2 - }, - A = { - x: B.x + (B.x - C.x) / 3, // cubic ratio at t=0.5 is 1/3 - y: B.y + (B.y - C.y) / 3 - }, - bx = (E.x - S.x) / 4, - by = (E.y - S.y) / 4, - e1 = { - x: B.x - bx, - y: B.y - by - }, - e2 = { - x: B.x + bx, - y: B.y + by - }, - v1 = { - x: A.x + (e1.x - A.x) * 2, - y: A.y + (e1.y - A.y) * 2 - }, - v2 = { - x: A.x + (e2.x - A.x) * 2, - y: A.y + (e2.y - A.y) * 2 - }, - nc1 = { - x: S.x + (v1.x - S.x) * 2, - y: S.y + (v1.y - S.y) * 2 - }, - nc2 = { - x: E.x + (v2.x - E.x) * 2, - y: E.y + (v2.y - E.y) * 2 - }; - return [nc1, nc2]; - }, - - draw: function draw(api, curve) { - api.reset(); - - api.setColor("lightgrey"); - api.drawGrid(1, 1); - api.setColor("rgba(255,0,0,0.4)"); - api.drawCircle({ x: api.w / 2, y: api.h / 2 }, api.r); - api.setColor("transparent"); - api.setFill("rgba(100,255,100,0.4)"); - var p = { - x: api.w / 2, - y: api.h / 2, - r: api.r, - s: api.angle < 0 ? api.angle : 0, - e: api.angle < 0 ? 0 : api.angle - }; - api.drawArc(p); - - // guessed curve - var B = { - x: api.w / 2 + api.r * cos(api.angle / 2), - y: api.w / 2 + api.r * sin(api.angle / 2) - }; - var S = curve.points[0], - E = curve.points[3], - nc = this.guessCurve(S, B, E); - var guess = new api.Bezier([S, nc[0], nc[1], E]); - api.setColor("rgb(140,140,255)"); - api.drawLine(guess.points[0], guess.points[1]); - api.drawLine(guess.points[1], guess.points[2]); - api.drawLine(guess.points[2], guess.points[3]); - api.setColor("blue"); - api.drawCurve(guess); - api.drawCircle(guess.points[1], 3); - api.drawCircle(guess.points[2], 3); - - // real curve - api.drawSkeleton(curve); - api.setColor("black"); - api.drawLine(curve.points[1], curve.points[2]); - api.drawCurve(curve); - }, - - onMouseMove: function onMouseMove(evt, api) { - var x = evt.offsetX - api.w / 2, - y = evt.offsetY - api.h / 2; - if (x > api.w / 2) return; - - var angle = Math.atan2(y, x); - if (angle < 0) { - angle = 2 * Math.PI + angle; - } - var pts = api.curve.points; - // new control 1 - var r = api.r, - f = 4 * tan(angle / 4) / 3; - pts[1] = { - x: api.w / 2 + r, - y: api.w / 2 + r * f - }; - // new control 2 - pts[2] = { - x: api.w / 2 + api.r * (cos(angle) + f * sin(angle)), - y: api.w / 2 + api.r * (sin(angle) - f * cos(angle)) - }; - // new endpoint - pts[3] = { - x: api.w / 2 + api.r * cos(angle), - y: api.w / 2 + api.r * sin(angle) - }; - api.setCurve(new api.Bezier(pts)); - api.angle = angle; - }, - - drawCircle: function drawCircle(api) { - api.setSize(325, 325); - api.reset(); - - var w = api.getPanelWidth(), - h = api.getPanelHeight(), - pad = 60, - r = w / 2 - pad, - k = 0.55228, - offset = { x: -pad / 2, y: -pad / 4 }; - - var curve = new api.Bezier([{ x: w / 2 + r, y: h / 2 }, { x: w / 2 + r, y: h / 2 + k * r }, { x: w / 2 + k * r, y: h / 2 + r }, { x: w / 2, y: h / 2 + r }]); - - api.setColor("lightgrey"); - api.drawLine({ x: 0, y: h / 2 }, { x: w + pad, y: h / 2 }, offset); - api.drawLine({ x: w / 2, y: 0 }, { x: w / 2, y: h + pad }, offset); - - var pts = curve.points; - - api.setColor("red"); - api.drawPoint(pts[0], offset); - api.drawPoint(pts[1], offset); - api.drawPoint(pts[2], offset); - api.drawPoint(pts[3], offset); - api.drawCurve(curve, offset); - api.setColor("rgb(255,160,160)"); - api.drawLine(pts[0], pts[1], offset); - api.drawLine(pts[1], pts[2], offset); - api.drawLine(pts[2], pts[3], offset); - - api.setFill("red"); - api.text(pts[0].x - w / 2 + "," + (pts[0].y - h / 2), { x: pts[0].x + 7, y: pts[0].y + 3 }, offset); - api.text(pts[1].x - w / 2 + "," + (pts[1].y - h / 2), { x: pts[1].x + 7, y: pts[1].y + 3 }, offset); - api.text(pts[2].x - w / 2 + "," + (pts[2].y - h / 2), { x: pts[2].x + 7, y: pts[2].y + 7 }, offset); - api.text(pts[3].x - w / 2 + "," + (pts[3].y - h / 2), { x: pts[3].x, y: pts[3].y + 13 }, offset); - - pts.forEach(function (p) { - p.x = -(p.x - w); - }); - api.setColor("blue"); - api.drawCurve(curve, offset); - api.drawLine(pts[2], pts[3], offset); - api.drawPoint(pts[2], offset); - api.setFill("blue"); - api.text("reflected", { x: pts[2].x - pad / 2, y: pts[2].y + 13 }, offset); - api.setColor("rgb(200,200,255)"); - api.drawLine(pts[1], pts[0], offset); - api.drawPoint(pts[1], offset); - - pts.forEach(function (p) { - p.y = -(p.y - h); - }); - api.setColor("green"); - api.drawCurve(curve, offset); - - pts.forEach(function (p) { - p.x = -(p.x - w); - }); - api.setColor("purple"); - api.drawCurve(curve, offset); - api.drawLine(pts[1], pts[0], offset); - api.drawPoint(pts[1], offset); - api.setFill("purple"); - api.text("reflected", { x: pts[1].x + 10, y: pts[1].y + 3 }, offset); - api.setColor("rgb(200,200,255)"); - api.drawLine(pts[2], pts[3], offset); - api.drawPoint(pts[2], offset); - - api.setColor("black"); - api.setFill("black"); - api.drawLine({ x: w / 2, y: h / 2 }, { x: w / 2 + r - 2, y: h / 2 }, offset); - api.drawLine({ x: w / 2, y: h / 2 }, { x: w / 2, y: h / 2 + r - 2 }, offset); - api.text("r = " + r, { x: w / 2 + r / 3, y: h / 2 + 10 }, offset); - } -}; - -/***/ }), -/* 152 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(151); -var generateBase = __webpack_require__(1); -module.exports = generateBase("circles_cubic", handler); - -/***/ }), -/* 153 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - componentDidMount: function componentDidMount() { - if (typeof document !== "undefined") { - var script = document.createElement("script"); - script.src = "lib/site/disqus.js"; - script.async = true; - document.head.appendChild(script); - } - } -}; - -/***/ }), -/* 154 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(153); -var generateBase = __webpack_require__(1); -module.exports = generateBase("comments", handler); - -/***/ }), -/* 155 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - curve.points[2].x = 210; - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.setPanelCount(3); - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var tf = curve.order, - pad = 20, - pts = curve.points, - w = api.getPanelWidth(), - wp = w - 2 * pad, - h = api.getPanelHeight(), - offset = { x: w, y: 0 }; - - var x_pts = JSON.parse(JSON.stringify(pts)).map(function (p, t) { - return { x: wp * t / tf, y: p.x }; - }); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - api.drawAxes(pad, "t", 0, 1, "x", 0, w, offset); - offset.x += pad; - api.drawCurve(new api.Bezier(x_pts), offset); - - offset.x += w - pad; - var y_pts = JSON.parse(JSON.stringify(pts)).map(function (p, t) { - return { x: wp * t / tf, y: p.y }; - }); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - api.drawAxes(pad, "t", 0, 1, "y", 0, w, offset); - offset.x += pad; - api.drawCurve(new api.Bezier(y_pts), offset); - } -}; - -/***/ }), -/* 156 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(155); -var generateBase = __webpack_require__(1); -module.exports = generateBase("components", handler); - -/***/ }), -/* 157 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - drawCubic: function drawCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - drawCurve: function drawCurve(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - }, - - drawFunction: function drawFunction(api, label, where, generator) { - api.setRandomColor(); - api.drawFunction(generator); - api.setFill(api.getColor()); - if (label) api.text(label, where); - }, - - drawLerpBox: function drawLerpBox(api, dim, pad, p) { - api.noColor(); - api.setFill("rgba(0,0,100,0.2)"); - var p1 = { x: p.x - 5, y: pad }, - p2 = { x: p.x + 5, y: dim }; - api.drawRect(p1, p2); - api.setColor("black"); - }, - - drawLerpPoint: function drawLerpPoint(api, tf, pad, fwh, p) { - p.y = pad + tf * fwh; - api.drawCircle(p, 3); - api.setFill("black"); - api.text((tf * 10000 | 0) / 100 + "%", { x: p.x + 10, y: p.y + 4 }); - api.noFill(); - }, - - drawQuadraticLerp: function drawQuadraticLerp(api) { - api.reset(); - - var dim = api.getPanelWidth(), - pad = 20, - fwh = dim - pad * 2; - - api.drawAxes(pad, "t", 0, 1, "S", "0%", "100%"); - - var p = api.hover; - if (p && p.x >= pad && p.x <= dim - pad) { - this.drawLerpBox(api, dim, pad, p); - var t = (p.x - pad) / fwh; - this.drawLerpPoint(api, (1 - t) * (1 - t), pad, fwh, p); - this.drawLerpPoint(api, 2 * (1 - t) * t, pad, fwh, p); - this.drawLerpPoint(api, t * t, pad, fwh, p); - } - - this.drawFunction(api, "first term", { x: pad * 2, y: fwh }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * (1 - t) * (1 - t) - }; - }); - this.drawFunction(api, "second term", { x: dim / 2 - 1.5 * pad, y: dim / 2 + pad }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * 2 * (1 - t) * t - }; - }); - this.drawFunction(api, "third term", { x: fwh - pad * 2.5, y: fwh }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * t * t - }; - }); - }, - - drawCubicLerp: function drawCubicLerp(api) { - api.reset(); - - var dim = api.getPanelWidth(), - pad = 20, - fwh = dim - pad * 2; - - api.drawAxes(pad, "t", 0, 1, "S", "0%", "100%"); - - var p = api.hover; - if (p && p.x >= pad && p.x <= dim - pad) { - this.drawLerpBox(api, dim, pad, p); - var t = (p.x - pad) / fwh; - this.drawLerpPoint(api, (1 - t) * (1 - t) * (1 - t), pad, fwh, p); - this.drawLerpPoint(api, 3 * (1 - t) * (1 - t) * t, pad, fwh, p); - this.drawLerpPoint(api, 3 * (1 - t) * t * t, pad, fwh, p); - this.drawLerpPoint(api, t * t * t, pad, fwh, p); - } - - this.drawFunction(api, "first term", { x: pad * 2, y: fwh }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * (1 - t) * (1 - t) * (1 - t) - }; - }); - this.drawFunction(api, "second term", { x: dim / 2 - 4 * pad, y: dim / 2 }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * 3 * (1 - t) * (1 - t) * t - }; - }); - this.drawFunction(api, "third term", { x: dim / 2 + 2 * pad, y: dim / 2 }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * 3 * (1 - t) * t * t - }; - }); - this.drawFunction(api, "fourth term", { x: fwh - pad * 2.5, y: fwh }, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * t * t * t - }; - }); - }, - - draw15thLerp: function draw15thLerp(api) { - api.reset(); - - var dim = api.getPanelWidth(), - pad = 20, - fwh = dim - pad * 2; - - api.drawAxes(pad, "t", 0, 1, "S", "0%", "100%"); - - var factors = [1, 15, 105, 455, 1365, 3003, 5005, 6435, 6435, 5005, 3003, 1365, 455, 105, 15, 1]; - - var p = api.hover, - n; - if (p && p.x >= pad && p.x <= dim - pad) { - this.drawLerpBox(api, dim, pad, p); - for (n = 0; n <= 15; n++) { - var t = (p.x - pad) / fwh, - tf = factors[n] * Math.pow(1 - t, 15 - n) * Math.pow(t, n); - this.drawLerpPoint(api, tf, pad, fwh, p); - } - } - - for (n = 0; n <= 15; n++) { - var label = false, - position = false; - if (n === 0) { - label = "first term"; - position = { x: pad + 5, y: fwh }; - } - if (n === 15) { - label = "last term"; - position = { x: dim - 3.5 * pad, y: fwh }; - } - this.drawFunction(api, label, position, function (t) { - return { - x: pad + t * fwh, - y: pad + fwh * factors[n] * Math.pow(1 - t, 15 - n) * Math.pow(t, n) - }; - }); - } - } -}; - -/***/ }), -/* 158 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(157); -var generateBase = __webpack_require__(1); -module.exports = generateBase("control", handler); - -/***/ }), -/* 159 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var abs = Math.abs; - -module.exports = { - setup: function setup(api) { - this.api = api; - api.setPanelCount(3); - var curve1 = new api.Bezier(10, 100, 90, 30, 40, 140, 220, 220); - var curve2 = new api.Bezier(5, 150, 180, 20, 80, 250, 210, 190); - api.setCurve(curve1, curve2); - this.pairReset(); - }, - - pairReset: function pairReset() { - this.prevstep = 0; - this.step = 0; - }, - - draw: function draw(api, curves) { - var _this = this; - - api.reset(); - var offset = { x: 0, y: 0 }; - curves.forEach(function (curve) { - api.drawSkeleton(curve); - api.drawCurve(curve); - }); - - // next panel: iterations - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - offset.x += w; - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - - if (this.step === 0) { - this.pairs = [{ c1: curves[0], c2: curves[1] }]; - } - - if (this.step !== this.prevstep) { - var pairs = this.pairs; - this.pairs = []; - this.finals = []; - pairs.forEach(function (p) { - - if (p.c1.length() < 0.6 && p.c2.length() < 0.6) { - return _this.finals.push(p); - } - - var s1 = p.c1.split(0.5); - api.setColor("black"); - api.drawCurve(p.c1, offset); - api.setColor("red"); - api.drawbbox(s1.left.bbox(), offset); - api.drawbbox(s1.right.bbox(), offset); - - var s2 = p.c2.split(0.5); - api.setColor("black"); - api.drawCurve(p.c2, offset); - api.setColor("blue"); - api.drawbbox(s2.left.bbox(), offset); - api.drawbbox(s2.right.bbox(), offset); - - if (s1.left.overlaps(s2.left)) { - _this.pairs.push({ c1: s1.left, c2: s2.left }); - } - if (s1.left.overlaps(s2.right)) { - _this.pairs.push({ c1: s1.left, c2: s2.right }); - } - if (s1.right.overlaps(s2.left)) { - _this.pairs.push({ c1: s1.right, c2: s2.left }); - } - if (s1.right.overlaps(s2.right)) { - _this.pairs.push({ c1: s1.right, c2: s2.right }); - } - }); - this.prevstep = this.step; - } else { - this.pairs.forEach(function (p) { - api.setColor("black"); - api.drawCurve(p.c1, offset); - api.drawCurve(p.c2, offset); - api.setColor("red"); - api.drawbbox(p.c1.bbox(), offset); - api.setColor("blue"); - api.drawbbox(p.c2.bbox(), offset); - }); - } - - if (this.pairs.length === 0) { - this.pairReset(); - this.draw(api, curves); - } - - // next panel: results - offset.x += w; - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - - // get intersections as coordinates - var results = curves[0].intersects(curves[1]).map(function (s) { - var tvals = s.split('/').map(function (v) { - return parseFloat(v); - }); - return { t1: tvals[0], t2: tvals[1] }; - }); - - // filter out likely duplicates - var curr = results[0], - _, - i, - same = function same(a, b) { - return abs(a.t1 - b.t1) < 0.01 && abs(a.t2 - b.t2) < 0.01; - }; - for (i = 1; i < results.length; i++) { - _ = results[i]; - if (same(curr, _)) { - results.splice(i--, 1); - } else { - curr = _; - } - } - - api.setColor("lightblue"); - api.drawCurve(curves[0], offset); - api.drawCurve(curves[1], offset); - - api.setColor("blue"); - results.forEach(function (tvals) { - api.drawCircle(curves[0].get(tvals.t1), 3, offset); - }); - }, - - stepUp: function stepUp() { - this.step++; - this.api.redraw(); - } -}; - -/***/ }), -/* 160 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(159); -var generateBase = __webpack_require__(1); -module.exports = generateBase("curveintersection", handler); - -/***/ }), -/* 161 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setup: function setup(api) { - var points = [{ x: 90, y: 110 }, { x: 25, y: 40 }, { x: 230, y: 40 }, { x: 150, y: 240 }]; - api.setCurve(new api.Bezier(points)); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - if (api.hover) { - api.setColor("rgb(200,100,100)"); - var dim = api.getPanelWidth(); - var t = api.hover.x / dim; - var hull = api.drawHull(curve, t); - - for (var i = 4; i <= 8; i++) { - api.drawCircle(hull[i], 3); - } - - var p = curve.get(t); - api.drawCircle(p, 5); - api.setFill("black"); - api.drawCircle(p, 3); - var perc = t * 100 | 0; - t = perc / 100; - api.text("Sequential interpolation for " + perc + "% (t=" + t + ")", { x: 10, y: 15 }); - } - } -}; - -/***/ }), -/* 162 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(161); -var generateBase = __webpack_require__(1); -module.exports = generateBase("decasteljau", handler); - -/***/ }), -/* 163 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var generateBase = __webpack_require__(1); -module.exports = generateBase("derivatives"); - -/***/ }), -/* 164 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "step", - values: { - "38": 0.1, // up arrow - "40": -0.1 // down arrow - }, - controller: function controller(api) { - if (api.step < 0.1) { - api.step = 0.1; - } - } - } - }, - - setup: function setup(api) { - api.step = 5; - }, - - draw: function draw(api, curve) { - var dim = api.getPanelWidth(), - w = dim, - h = dim, - w2 = w / 2, - h2 = h / 2, - w4 = w2 / 2, - h4 = h2 / 2; - - api.reset(); - api.setColor("black"); - api.drawLine({ x: 0, y: h2 }, { x: w, y: h2 }); - api.drawLine({ x: w2, y: 0 }, { x: w2, y: h }); - - var offset = { x: w2, y: h2 }; - for (var t = 0, p; t <= api.step; t += 0.1) { - p = { - x: w4 * Math.cos(t), - y: h4 * Math.sin(t) - }; - api.drawPoint(p, offset); - var modulo = t % 1; - if (modulo < 0.05 || modulo > 0.95) { - api.text("t = " + Math.round(t), { - x: offset.x + 1.25 * w4 * Math.cos(t) - 10, - y: offset.y + 1.25 * h4 * Math.sin(t) + 5 - }); - api.drawCircle(p, 2, offset); - } - } - } -}; - -/***/ }), -/* 165 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(164); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("explanation", handler)); - -/***/ }), -/* 166 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = new api.Bezier(70, 155, 20, 110, 100, 75); - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = new api.Bezier(60, 105, 75, 30, 215, 115, 140, 160); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - api.setColor("lightgrey"); - - var t, - step = 0.05, - min = -10; - var pt = curve.get(min - step), - pn; - for (t = min; t <= step; t += step) { - pn = curve.get(t); - api.drawLine(pt, pn); - pt = pn; - } - - pt = curve.get(1); - var max = 10; - for (t = 1 + step; t <= max; t += step) { - pn = curve.get(t); - api.drawLine(pt, pn); - pt = pn; - } - } -}; - -/***/ }), -/* 167 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(166); -var generateBase = __webpack_require__(1); -module.exports = generateBase("extended", handler); - -/***/ }), -/* 168 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - curve.points[2].x = 210; - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.setPanelCount(3); - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var tf = curve.order + 1, - pad = 20, - pts = curve.points, - w = api.getPanelWidth(), - h = api.getPanelHeight(), - offset = { x: w, y: 0 }; - - var x_pts = JSON.parse(JSON.stringify(pts)).map(function (p, t) { - return { x: w * t / tf, y: p.x }; - }); - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - api.drawAxes(pad, "t", 0, 1, "x", 0, w, offset); - offset.x += pad; - var xcurve = new api.Bezier(x_pts); - api.drawCurve(xcurve, offset); - api.setColor("red"); - xcurve.extrema().y.forEach(function (t) { - var p = xcurve.get(t); - api.drawCircle(p, 3, offset); - }); - - offset.x += w - pad; - var y_pts = JSON.parse(JSON.stringify(pts)).map(function (p, t) { - return { x: w * t / tf, y: p.y }; - }); - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - api.drawAxes(pad, "t", 0, 1, "y", 0, w, offset); - offset.x += pad; - var ycurve = new api.Bezier(y_pts); - api.drawCurve(ycurve, offset); - api.setColor("red"); - ycurve.extrema().y.forEach(function (t) { - var p = ycurve.get(t); - api.drawCircle(p, 3, offset); - }); - } -}; - -/***/ }), -/* 169 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(168); -var generateBase = __webpack_require__(1); -module.exports = generateBase("extremities", handler); - -/***/ }), -/* 170 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "steps", - values: { - "38": 1, // up arrow - "40": -1 // down arrow - }, - controller: function controller(api) { - if (api.steps < 1) { - api.steps = 1; - } - } - } - }, - - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - api.steps = 3; - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - api.steps = 5; - }, - - drawFlattened: function drawFlattened(api, curve) { - api.reset(); - api.setColor("#DDD"); - api.drawSkeleton(curve); - api.setColor("#DDD"); - api.drawCurve(curve); - var step = 1 / api.steps; - var p0 = curve.points[0], - pc; - for (var t = step; t < 1.0 + step; t += step) { - pc = curve.get(Math.min(t, 1)); - api.setColor("red"); - api.drawLine(p0, pc); - p0 = pc; - } - api.setFill("black"); - api.text("Curve approximation using " + api.steps + " segments", { x: 10, y: 15 }); - }, - - values: { - "38": 1, // up arrow - "40": -1 // down arrow - }, - - onKeyDown: function onKeyDown(e, api) { - var v = this.values[e.keyCode]; - if (v) { - e.preventDefault(); - api.steps += v; - if (api.steps < 1) { - api.steps = 1; - } - } - } -}; - -/***/ }), -/* 171 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(170); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("flattening", handler)); - -/***/ }), -/* 172 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "distance", - values: { - "38": 1, // up arrow - "40": -1 // down arrow - } - } - }, - - setup: function setup(api, curve) { - api.setCurve(curve); - api.distance = 20; - }, - - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - this.setup(api, curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - this.setup(api, curve); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - api.setColor("blue"); - var outline = curve.outline(0, 0, api.distance, api.distance); - outline.curves.forEach(function (c) { - return api.drawCurve(c); - }); - } -}; - -/***/ }), -/* 173 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(172); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("graduatedoffset", handler)); - -/***/ }), -/* 174 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupCubic: function setupCubic(api) { - var curve = new api.Bezier(135, 25, 25, 135, 215, 75, 215, 240); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - api.setColor("red"); - curve.inflections().forEach(function (t) { - api.drawCircle(curve.get(t), 5); - }); - } -}; - -/***/ }), -/* 175 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(174); -var generateBase = __webpack_require__(1); -module.exports = generateBase("inflections", handler); - -/***/ }), -/* 176 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var min = Math.min, - max = Math.max; - -module.exports = { - setupLines: function setupLines(api) { - var curve1 = new api.Bezier([50, 50, 150, 110]); - var curve2 = new api.Bezier([50, 250, 170, 170]); - api.setCurve(curve1, curve2); - }, - - drawLineIntersection: function drawLineIntersection(api, curves) { - api.reset(); - - var lli = api.utils.lli4; - var p = lli(curves[0].points[0], curves[0].points[1], curves[1].points[0], curves[1].points[1]); - - var mark = 0; - curves.forEach(function (curve) { - api.drawSkeleton(curve); - api.setColor("black"); - if (p) { - var pts = curve.points, - mx = min(pts[0].x, pts[1].x), - my = min(pts[0].y, pts[1].y), - Mx = max(pts[0].x, pts[1].x), - My = max(pts[0].y, pts[1].y); - if (mx <= p.x && my <= p.y && Mx >= p.x && My >= p.y) { - api.setColor("#00FF00"); - mark++; - } - } - api.drawCurve(curve); - }); - - if (p) { - api.setColor(mark < 2 ? "red" : "#00FF00"); - api.drawCircle(p, 3); - } - }, - - setupQuadratic: function setupQuadratic(api) { - var curve1 = api.getDefaultQuadratic(); - var curve2 = new api.Bezier([15, 250, 220, 20]); - api.setCurve(curve1, curve2); - }, - - setupCubic: function setupCubic(api) { - var curve1 = new api.Bezier([100, 240, 30, 60, 210, 230, 160, 30]); - var curve2 = new api.Bezier([25, 260, 230, 20]); - api.setCurve(curve1, curve2); - }, - - draw: function draw(api, curves) { - api.reset(); - curves.forEach(function (curve) { - api.drawSkeleton(curve); - api.drawCurve(curve); - }); - - var utils = api.utils; - var line = { p1: curves[1].points[0], p2: curves[1].points[1] }; - var acpts = utils.align(curves[0].points, line); - var nB = new api.Bezier(acpts); - var roots = utils.roots(nB.points); - roots.forEach(function (t) { - var p = curves[0].get(t); - api.drawCircle(p, 3); - api.text("t = " + t, { x: p.x + 5, y: p.y + 10 }); - }); - } -}; - -/***/ }), -/* 177 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(176); -var generateBase = __webpack_require__(1); -module.exports = generateBase("intersections", handler); - -/***/ }), -/* 178 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - drawQuadratic: function drawQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - }, - - drawCubic: function drawCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - drawCurve: function drawCurve(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - } -}; - -/***/ }), -/* 179 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(178); -var generateBase = __webpack_require__(1); -module.exports = generateBase("introduction", handler); - -/***/ }), -/* 180 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var generateBase = __webpack_require__(1); -module.exports = generateBase("matrix"); - -/***/ }), -/* 181 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var generateBase = __webpack_require__(1); -module.exports = generateBase("matrixsplit"); - -/***/ }), -/* 182 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var abs = Math.abs; - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - api.setPanelCount(3); - var curve = api.getDefaultQuadratic(); - curve.points[2].x -= 30; - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - api.setPanelCount(3); - var curve = new api.Bezier([100, 230, 30, 160, 200, 50, 210, 160]); - curve.points[2].y -= 20; - api.setCurve(curve); - api.lut = curve.getLUT(100); - }, - - saveCurve: function saveCurve(evt, api) { - if (!api.t) return; - api.setCurve(api.newcurve); - api.t = false; - api.redraw(); - }, - - findTValue: function findTValue(evt, api) { - var t = api.curve.on({ x: evt.offsetX, y: evt.offsetY }, 7); - if (t < 0.05 || t > 0.95) return false; - return t; - }, - - markQB: function markQB(evt, api) { - api.t = this.findTValue(evt, api); - if (api.t) { - var t = api.t, - t2 = 2 * t, - top = t2 * t - t2, - bottom = top + 1, - ratio = abs(top / bottom), - curve = api.curve, - A = api.A = curve.points[1], - B = api.B = curve.get(t); - api.C = api.utils.lli4(A, B, curve.points[0], curve.points[2]); - api.ratio = ratio; - } - }, - - markCB: function markCB(evt, api) { - api.t = this.findTValue(evt, api); - if (api.t) { - var t = api.t, - mt = 1 - t, - t3 = t * t * t, - mt3 = mt * mt * mt, - bottom = t3 + mt3, - top = bottom - 1, - ratio = abs(top / bottom), - curve = api.curve, - hull = curve.hull(t), - A = api.A = hull[5], - B = api.B = curve.get(t); - api.db = curve.derivative(t); - api.C = api.utils.lli4(A, B, curve.points[0], curve.points[3]); - api.ratio = ratio; - } - }, - - drag: function drag(evt, api) { - if (!api.t) return; - - var newB = api.newB = { - x: evt.offsetX, - y: evt.offsetY - }; - - // now that we know A, B, C and the AB:BC ratio, we can compute the new A' based on the desired B' - api.newA = { - x: newB.x - (api.C.x - newB.x) / api.ratio, - y: newB.y - (api.C.y - newB.y) / api.ratio - }; - }, - - dragQB: function dragQB(evt, api) { - if (!api.t) return; - this.drag(evt, api); - api.update = [api.newA]; - }, - - dragCB: function dragCB(evt, api) { - if (!api.t) return; - this.drag(evt, api); - - // preserve struts for B when repositioning - var curve = api.curve, - hull = curve.hull(api.t), - B = api.B, - Bl = hull[7], - Br = hull[8], - dbl = { x: Bl.x - B.x, y: Bl.y - B.y }, - dbr = { x: Br.x - B.x, y: Br.y - B.y }, - pts = curve.points, - - // find new point on s--c1 - p1 = { x: api.newB.x + dbl.x, y: api.newB.y + dbl.y }, - sc1 = { - x: api.newA.x - (api.newA.x - p1.x) / (1 - api.t), - y: api.newA.y - (api.newA.y - p1.y) / (1 - api.t) - }, - - // find new point on c2--e - p2 = { x: api.newB.x + dbr.x, y: api.newB.y + dbr.y }, - sc2 = { - x: api.newA.x + (p2.x - api.newA.x) / api.t, - y: api.newA.y + (p2.y - api.newA.y) / api.t - }, - - // construct new c1` based on the fact that s--sc1 is s--c1 * t - nc1 = { - x: pts[0].x + (sc1.x - pts[0].x) / api.t, - y: pts[0].y + (sc1.y - pts[0].y) / api.t - }, - - // construct new c2` based on the fact that e--sc2 is e--c2 * (1-t) - nc2 = { - x: pts[3].x - (pts[3].x - sc2.x) / (1 - api.t), - y: pts[3].y - (pts[3].y - sc2.y) / (1 - api.t) - }; - - api.p1 = p1; - api.p2 = p2; - api.sc1 = sc1; - api.sc2 = sc2; - api.nc1 = nc1; - api.nc2 = nc2; - - api.update = [nc1, nc2]; - }, - - drawMould: function drawMould(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var w = api.getPanelWidth(), - h = api.getPanelHeight(), - offset = { x: w, y: 0 }, - round = api.utils.round; - - api.setColor("black"); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - api.drawLine({ x: w, y: 0 }, { x: w, y: h }, offset); - - if (api.t) { - api.drawCircle(curve.get(api.t), 3); - api.npts = [curve.points[0]].concat(api.update).concat([curve.points.slice(-1)[0]]); - api.newcurve = new api.Bezier(api.npts); - - api.setColor("lightgrey"); - api.drawCurve(api.newcurve); - var newhull = api.drawHull(api.newcurve, api.t, offset); - api.drawLine(api.npts[0], api.npts.slice(-1)[0], offset); - api.drawLine(api.newA, api.newB, offset); - - api.setColor("grey"); - api.drawCircle(api.newA, 3, offset); - api.setColor("blue"); - api.drawCircle(api.B, 3, offset); - api.drawCircle(api.C, 3, offset); - api.drawCircle(api.newB, 3, offset); - api.drawLine(api.B, api.C, offset); - api.drawLine(api.newB, api.C, offset); - - api.setFill("black"); - api.text("A'", api.newA, { x: offset.x + 7, y: offset.y + 1 }); - api.text("start", curve.get(0), { x: offset.x + 7, y: offset.y + 1 }); - api.text("end", curve.get(1), { x: offset.x + 7, y: offset.y + 1 }); - api.setFill("blue"); - api.text("B'", api.newB, { x: offset.x + 7, y: offset.y + 1 }); - api.text("B, at t = " + round(api.t, 2), api.B, { x: offset.x + 7, y: offset.y + 1 }); - api.text("C", api.C, { x: offset.x + 7, y: offset.y + 1 }); - - if (curve.order === 3) { - var hull = curve.hull(api.t); - api.drawLine(hull[7], hull[8], offset); - api.drawLine(newhull[7], newhull[8], offset); - api.drawCircle(newhull[7], 3, offset); - api.drawCircle(newhull[8], 3, offset); - api.text("e1", newhull[7], { x: offset.x + 7, y: offset.y + 1 }); - api.text("e2", newhull[8], { x: offset.x + 7, y: offset.y + 1 }); - } - - offset.x += w; - - api.setColor("lightgrey"); - api.drawSkeleton(api.newcurve, offset); - api.setColor("black"); - api.drawCurve(api.newcurve, offset); - } else { - offset.x += w; - api.drawCurve(curve, offset); - } - } -}; - -/***/ }), -/* 183 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(182); -var generateBase = __webpack_require__(1); -module.exports = generateBase("moulding", handler); - -/***/ }), -/* 184 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "distance", - values: { - "38": 1, // up arrow - "40": -1 // down arrow - } - } - }, - - setup: function setup(api, curve) { - api.setCurve(curve); - api.distance = 20; - }, - - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - this.setup(api, curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - this.setup(api, curve); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - - var reduced = curve.reduce(); - reduced.forEach(function (c) { - api.setRandomColor(); - api.drawCurve(c); - api.drawCircle(c.points[0], 1); - }); - var last = reduced.slice(-1)[0]; - api.drawPoint(last.points[3] || last.points[2]); - - api.setColor("red"); - var offset = curve.offset(api.distance); - offset.forEach(function (c) { - api.drawPoint(c.points[0]); - api.drawCurve(c); - }); - last = offset.slice(-1)[0]; - api.drawPoint(last.points[3] || last.points[2]); - - api.setColor("blue"); - offset = curve.offset(-api.distance); - offset.forEach(function (c) { - api.drawPoint(c.points[0]); - api.drawCurve(c); - }); - last = offset.slice(-1)[0]; - api.drawPoint(last.points[3] || last.points[2]); - } -}; - -/***/ }), -/* 185 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(184); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("offsetting", handler)); - -/***/ }), -/* 186 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var abs = Math.abs; - -module.exports = { - setup: function setup(api) { - api.lpts = [{ x: 56, y: 153 }, { x: 144, y: 83 }, { x: 188, y: 185 }]; - }, - - onClick: function onClick(evt, api) { - if (api.lpts.length == 3) { - api.lpts = []; - } - api.lpts.push({ - x: evt.offsetX, - y: evt.offsetY - }); - api.redraw(); - }, - - getQRatio: function getQRatio(t) { - var t2 = 2 * t, - top = t2 * t - t2, - bottom = top + 1; - return abs(top / bottom); - }, - - getCRatio: function getCRatio(t) { - var mt = 1 - t, - t3 = t * t * t, - mt3 = mt * mt * mt, - bottom = t3 + mt3, - top = bottom - 1; - return abs(top / bottom); - }, - - drawQuadratic: function drawQuadratic(api, curve) { - var labels = ["start", "t=0.5", "end"]; - - api.reset(); - - api.setColor("lightblue"); - api.drawGrid(10, 10); - - api.setFill("black"); - api.setColor("black"); - api.lpts.forEach(function (p, i) { - api.drawCircle(p, 3); - api.text(labels[i], p, { x: 5, y: 2 }); - }); - - if (api.lpts.length === 3) { - var S = api.lpts[0], - E = api.lpts[2], - B = api.lpts[1], - C = { - x: (S.x + E.x) / 2, - y: (S.y + E.y) / 2 - }; - api.setColor("blue"); - api.drawLine(S, E); - api.drawLine(B, C); - api.drawCircle(C, 3); - var ratio = this.getQRatio(0.5), - A = { - x: B.x + (B.x - C.x) / ratio, - y: B.y + (B.y - C.y) / ratio - }; - curve = new api.Bezier([S, A, E]); - api.setColor("lightgrey"); - api.drawLine(A, B); - api.drawLine(A, S); - api.drawLine(A, E); - api.setColor("black"); - api.drawCircle(A, 1); - api.drawCurve(curve); - } - }, - - drawCubic: function drawCubic(api, curve) { - var labels = ["start", "t=0.5", "end"]; - - api.reset(); - - api.setFill("black"); - api.setColor("black"); - api.lpts.forEach(function (p, i) { - api.drawCircle(p, 3); - api.text(labels[i], p, { x: 5, y: 2 }); - }); - - api.setColor("lightblue"); - api.drawGrid(10, 10); - - if (api.lpts.length === 3) { - var S = api.lpts[0], - E = api.lpts[2], - B = api.lpts[1], - C = { - x: (S.x + E.x) / 2, - y: (S.y + E.y) / 2 - }; - - api.setColor("blue"); - api.drawLine(S, E); - api.drawLine(B, C); - api.drawCircle(C, 1); - - var ratio = this.getCRatio(0.5), - A = { - x: B.x + (B.x - C.x) / ratio, - y: B.y + (B.y - C.y) / ratio - }, - selen = api.utils.dist(S, E), - bclen_min = selen / 8, - bclen = api.utils.dist(B, C), - aesthetics = 4, - be12dist = bclen_min + bclen / aesthetics, - bx = be12dist * (E.x - S.x) / selen, - by = be12dist * (E.y - S.y) / selen, - e1 = { - x: B.x - bx, - y: B.y - by - }, - e2 = { - x: B.x + bx, - y: B.y + by - }, - v1 = { - x: A.x + (e1.x - A.x) * 2, - y: A.y + (e1.y - A.y) * 2 - }, - v2 = { - x: A.x + (e2.x - A.x) * 2, - y: A.y + (e2.y - A.y) * 2 - }, - nc1 = { - x: S.x + (v1.x - S.x) * 2, - y: S.y + (v1.y - S.y) * 2 - }, - nc2 = { - x: E.x + (v2.x - E.x) * 2, - y: E.y + (v2.y - E.y) * 2 - }; - - curve = new api.Bezier([S, nc1, nc2, E]); - api.drawLine(e1, e2); - api.setColor("lightgrey"); - api.drawLine(A, C); - api.drawLine(A, v1); - api.drawLine(A, v2); - api.drawLine(S, nc1); - api.drawLine(E, nc2); - api.drawLine(nc1, nc2); - api.setColor("black"); - api.drawCircle(A, 1); - api.drawCircle(nc1, 1); - api.drawCircle(nc2, 1); - api.drawCurve(curve); - } - } -}; - -/***/ }), -/* 187 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(186); -var generateBase = __webpack_require__(1); -module.exports = generateBase("pointcurves", handler); - -/***/ }), -/* 188 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - - var i, - t, - p, - tg, - n, - m, - nd = 20; - for (i = 0; i <= 10; i++) { - t = i / 10.0; - p = curve.get(t); - tg = curve.derivative(t); - m = Math.sqrt(tg.x * tg.x + tg.y * tg.y); - tg = { x: tg.x / m, y: tg.y / m }; - n = curve.normal(t); - api.setColor("blue"); - api.drawLine(p, { x: p.x + tg.x * nd, y: p.y + tg.y * nd }); - api.setColor("red"); - api.drawLine(p, { x: p.x + n.x * nd, y: p.y + n.y * nd }); - api.setColor("black"); - api.drawCircle(p, 3); - } - } -}; - -/***/ }), -/* 189 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(188); -var generateBase = __webpack_require__(1); -module.exports = generateBase("pointvectors", handler); - -/***/ }), -/* 190 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var atan2 = Math.atan2, - sqrt = Math.sqrt, - sin = Math.sin, - cos = Math.cos; - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var w = api.getPanelWidth(), - h = api.getPanelHeight(), - cx = w / 2, - cy = h / 2, - pad = 40, - pts = [ - // first curve: - { x: cx, y: pad }, { x: w - pad, y: pad }, { x: w - pad, y: cy }, - // subsequent curve - { x: w - pad, y: h - pad }, { x: cx, y: h - pad }, - // subsequent curve - { x: pad, y: h - pad }, { x: pad, y: cy }, - // final curve control point - { x: pad, y: pad }]; - api.lpts = pts; - }, - - setupCubic: function setupCubic(api) { - var w = api.getPanelWidth(), - h = api.getPanelHeight(), - cx = w / 2, - cy = h / 2, - pad = 40, - r = (w - 2 * pad) / 2, - k = 0.55228, - kr = k * r, - pts = [ - // first curve: - { x: cx, y: pad }, { x: cx + kr, y: pad }, { x: w - pad, y: cy - kr }, { x: w - pad, y: cy }, - // subsequent curve - { x: w - pad, y: cy + kr }, { x: cx + kr, y: h - pad }, { x: cx, y: h - pad }, - // subsequent curve - { x: cx - kr, y: h - pad }, { x: pad, y: cy + kr }, { x: pad, y: cy }, - // final curve control point - { x: pad, y: cy - kr }, { x: cx - kr, y: pad }]; - api.lpts = pts; - }, - - movePointsQuadraticLD: function movePointsQuadraticLD(api, i) { - // ...we need to move _everything_ - var anchor, fixed, toMove; - for (var p = 1; p < 4; p++) { - anchor = i + (2 * p - 2) + api.lpts.length; - anchor = api.lpts[anchor % api.lpts.length]; - fixed = i + (2 * p - 1); - fixed = api.lpts[fixed % api.lpts.length]; - toMove = i + 2 * p; - toMove = api.lpts[toMove % api.lpts.length]; - - toMove.x = fixed.x + (fixed.x - anchor.x); - toMove.y = fixed.y + (fixed.y - anchor.y); - } - // then, the furthest point cannot be computed properly! - toMove = i + 6; - toMove = api.lpts[toMove % api.lpts.length]; - api.problem = toMove; - }, - - movePointsCubicLD: function movePointsCubicLD(api, i) { - var toMove, fixed; - if (i % 3 === 1) { - fixed = i - 1; - fixed += fixed < 0 ? api.lpts.length : 0; - toMove = i - 2; - toMove += toMove < 0 ? api.lpts.length : 0; - } else { - fixed = (i + 1) % api.lpts.length; - toMove = (i + 2) % api.lpts.length; - } - fixed = api.lpts[fixed]; - toMove = api.lpts[toMove]; - toMove.x = fixed.x + (fixed.x - api.mp.x); - toMove.y = fixed.y + (fixed.y - api.mp.y); - }, - - linkDerivatives: function linkDerivatives(evt, api) { - if (api.mp) { - var quad = api.lpts.length === 8; - var i = api.mp_idx; - if (quad) { - if (i % 2 !== 0) { - this.movePointsQuadraticLD(api, i); - } - } else { - if (i % 3 !== 0) { - this.movePointsCubicLD(api, i); - } - } - } - }, - - movePointsQuadraticDirOnly: function movePointsQuadraticDirOnly(api, i) { - // ...we need to move _everything_ ...again - var anchor, fixed, toMove; - - // move left and right - [-1, 1].forEach(function (v) { - anchor = api.mp; - fixed = i + v + api.lpts.length; - fixed = api.lpts[fixed % api.lpts.length]; - toMove = i + 2 * v + api.lpts.length; - toMove = api.lpts[toMove % api.lpts.length]; - var a = atan2(fixed.y - anchor.y, fixed.x - anchor.x), - dx = toMove.x - fixed.x, - dy = toMove.y - fixed.y, - d = sqrt(dx * dx + dy * dy); - toMove.x = fixed.x + d * cos(a); - toMove.y = fixed.y + d * sin(a); - }); - - // then, the furthest point cannot be computed properly! - toMove = i + 4; - toMove = api.lpts[toMove % api.lpts.length]; - api.problem = toMove; - }, - - movePointsCubicDirOnly: function movePointsCubicDirOnly(api, i) { - var toMove, fixed; - if (i % 3 === 1) { - fixed = i - 1; - fixed += fixed < 0 ? api.lpts.length : 0; - toMove = i - 2; - toMove += toMove < 0 ? api.lpts.length : 0; - } else { - fixed = (i + 1) % api.lpts.length; - toMove = (i + 2) % api.lpts.length; - } - fixed = api.lpts[fixed]; - toMove = api.lpts[toMove]; - var a = atan2(fixed.y - api.mp.y, fixed.x - api.mp.x), - dx = toMove.x - fixed.x, - dy = toMove.y - fixed.y, - d = sqrt(dx * dx + dy * dy); - toMove.x = fixed.x + d * cos(a); - toMove.y = fixed.y + d * sin(a); - }, - - linkDirection: function linkDirection(evt, api) { - if (api.mp) { - var quad = api.lpts.length === 8; - var i = api.mp_idx; - if (quad) { - if (i % 2 !== 0) { - this.movePointsQuadraticDirOnly(api, i); - } - } else { - if (i % 3 !== 0) { - this.movePointsCubicDirOnly(api, i); - } - } - } - }, - - bufferPoints: function bufferPoints(evt, api) { - api.bpts = JSON.parse(JSON.stringify(api.lpts)); - }, - - moveQuadraticPoint: function moveQuadraticPoint(api, i) { - this.moveCubicPoint(api, i); - - // then move the other control points - [-1, 1].forEach(function (v) { - var anchor = i - v + api.lpts.length; - anchor = api.lpts[anchor % api.lpts.length]; - var fixed = i - 2 * v + api.lpts.length; - fixed = api.lpts[fixed % api.lpts.length]; - var toMove = i - 3 * v + api.lpts.length; - toMove = api.lpts[toMove % api.lpts.length]; - var a = atan2(fixed.y - anchor.y, fixed.x - anchor.x), - dx = toMove.x - fixed.x, - dy = toMove.y - fixed.y, - d = sqrt(dx * dx + dy * dy); - toMove.x = fixed.x + d * cos(a); - toMove.y = fixed.y + d * sin(a); - }); - - // then signal a problem - var toMove = i + 4; - toMove = api.lpts[toMove % api.lpts.length]; - api.problem = toMove; - }, - - moveCubicPoint: function moveCubicPoint(api, i) { - var op = api.bpts[i], - np = api.lpts[i], - dx = np.x - op.x, - dy = np.y - op.y, - len = api.lpts.length, - l = i - 1 + len, - r = i + 1, - - // original left and right - ol = api.bpts[l % len], - or = api.bpts[r % len], - - // current left and right - nl = api.lpts[l % len], - nr = api.lpts[r % len]; - // update current left - nl.x = ol.x + dx; - nl.y = ol.y + dy; - // update current right - nr.x = or.x + dx; - nr.y = or.y + dy; - return { x: dx, y: dy }; - }, - - modelCurve: function modelCurve(evt, api) { - if (api.mp) { - var quad = api.lpts.length === 8; - var i = api.mp_idx; - if (quad) { - if (i % 2 !== 0) { - this.movePointsQuadraticDirOnly(api, i); - } else { - this.moveQuadraticPoint(api, i); - } - } else { - if (i % 3 !== 0) { - this.movePointsCubicDirOnly(api, i); - } else { - this.moveCubicPoint(api, i); - } - } - } - }, - - draw: function draw(api, curves) { - api.reset(); - var pts = api.lpts; - var quad = pts.length === 8; - - var c1 = quad ? new api.Bezier(pts[0], pts[1], pts[2]) : new api.Bezier(pts[0], pts[1], pts[2], pts[3]); - api.drawSkeleton(c1, false, true); - api.drawCurve(c1); - - var c2 = quad ? new api.Bezier(pts[2], pts[3], pts[4]) : new api.Bezier(pts[3], pts[4], pts[5], pts[6]); - api.drawSkeleton(c2, false, true); - api.drawCurve(c2); - - var c3 = quad ? new api.Bezier(pts[4], pts[5], pts[6]) : new api.Bezier(pts[6], pts[7], pts[8], pts[9]); - api.drawSkeleton(c3, false, true); - api.drawCurve(c3); - - var c4 = quad ? new api.Bezier(pts[6], pts[7], pts[0]) : new api.Bezier(pts[9], pts[10], pts[11], pts[0]); - api.drawSkeleton(c4, false, true); - api.drawCurve(c4); - - if (api.problem) { - api.setColor("red"); - api.drawCircle(api.problem, 5); - } - } -}; - -/***/ }), -/* 191 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(190); -var generateBase = __webpack_require__(1); -module.exports = generateBase("polybezier", handler); - -/***/ }), -/* 192 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var generateBase = __webpack_require__(1); -module.exports = generateBase("preface"); - -/***/ }), -/* 193 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setup: function setup(api) { - api.setSize(320, 320); - var curve = new api.Bezier([{ x: 248, y: 188 }, { x: 218, y: 294 }, { x: 45, y: 290 }, { x: 12, y: 236 }, { x: 14, y: 82 }, { x: 186, y: 177 }, { x: 221, y: 90 }, { x: 18, y: 156 }, { x: 34, y: 57 }, { x: 198, y: 18 }]); - api.setCurve(curve); - api._lut = curve.getLUT(); - }, - - findClosest: function findClosest(LUT, p, dist) { - var i, - end = LUT.length, - d, - dd = dist(LUT[0], p), - f = 0; - for (i = 1; i < end; i++) { - d = dist(LUT[i], p); - if (d < dd) { - f = i;dd = d; - } - } - return f / (end - 1); - }, - - draw: function draw(api, curve) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - if (api.mousePt) { - api.setColor("red"); - api.setFill("red"); - api.drawCircle(api.mousePt, 3); - // naive t value - var t = this.findClosest(api._lut, api.mousePt, api.utils.dist); - // no real point in refining for illustration purposes - var p = curve.get(t); - api.drawLine(p, api.mousePt); - api.drawCircle(p, 3); - api.text("t = " + api.utils.round(t, 2), p, { x: 10, y: 3 }); - } - }, - - onMouseMove: function onMouseMove(evt, api) { - api.mousePt = { x: evt.offsetX, y: evt.offsetY }; - api._lut = api.curve.getLUT(); - } -}; - -/***/ }), -/* 194 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(193); -var generateBase = __webpack_require__(1); -module.exports = generateBase("projections", handler); - -/***/ }), -/* 195 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var Reordering = { - statics: { - // Improve this based on http://www.sirver.net/blog/2011/08/23/degree-reduction-of-bezier-curves/ - lower: function lower(curve) { - var pts = curve.points, - q = [], - n = pts.length; - pts.forEach(function (p, k) { - if (!k) { - return q[k] = p; - } - var f1 = k / n, - f2 = 1 - f1; - q[k] = { - x: f1 * p.x + f2 * pts[k - 1].x, - y: f1 * p.y + f2 * pts[k - 1].y - }; - }); - q.splice(n - 1, 1); - q[n - 2] = pts[n - 1]; - curve.points = q; - return curve; - }, - - keyHandlingOptions: { - values: { - "38": function _(api) { - api.setCurve(api.curve.raise()); - }, - "40": function _(api) { - api.setCurve(Reordering.lower(api.curve)); - } - } - } - }, - - getInitialState: function getInitialState() { - return { - order: 0 - }; - }, - - setup: function setup(api) { - var points = []; - var w = api.getPanelWidth(), - h = api.getPanelHeight(); - for (var i = 0; i < 10; i++) { - points.push({ - x: w / 2 + Math.random() * 20 + Math.cos(Math.PI * 2 * i / 10) * (w / 2 - 40), - y: h / 2 + Math.random() * 20 + Math.sin(Math.PI * 2 * i / 10) * (h / 2 - 40) - }); - } - var curve = new api.Bezier(points); - api.setCurve(curve); - }, - - draw: function draw(api, curve) { - api.reset(); - var pts = curve.points; - - this.setState({ - order: pts.length - }); - - var p0 = pts[0]; - - // we can't "just draw" this curve, since it'll be an arbitrary order, - // And the canvas only does 2nd and 3rd - we use de Casteljau's algorithm: - for (var t = 0; t <= 1; t += 0.01) { - var q = JSON.parse(JSON.stringify(pts)); - while (q.length > 1) { - for (var i = 0; i < q.length - 1; i++) { - q[i] = { - x: q[i].x + (q[i + 1].x - q[i].x) * t, - y: q[i].y + (q[i + 1].y - q[i].y) * t - }; - } - q.splice(q.length - 1, 1); - } - api.drawLine(p0, q[0]); - p0 = q[0]; - } - - p0 = pts[0]; - api.setColor("black"); - api.drawCircle(p0, 3); - pts.forEach(function (p) { - if (p === p0) return; - api.setColor("#DDD"); - api.drawLine(p0, p); - api.setColor("black"); - api.drawCircle(p, 3); - p0 = p; - }); - }, - - getOrder: function getOrder() { - var order = this.state.order; - if (order % 10 === 1 && order !== 11) { - order += "st"; - } else if (order % 10 === 2 && order !== 12) { - order += "nd"; - } else if (order % 10 === 3 && order !== 13) { - order += "rd"; - } else { - order += "th"; - } - return order; - } -}; - -module.exports = Reordering; - -/***/ }), -/* 196 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(195); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("reordering", handler)); - -/***/ }), -/* 197 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var modes; - -module.exports = { - getInitialState: function getInitialState() { - modes = this.modes = ["unite", "intersect", "exclude", "subtract"]; - return { - mode: modes[0] - }; - }, - - setMode: function setMode(mode) { - this.setState({ mode: mode }); - }, - - formPath: function formPath(api, mx, my, w, h) { - mx = mx || 0; - my = my || 0; - var unit = 30; - var unit2 = unit / 2; - w = w || 8 * unit; - h = h || 4 * unit; - var w2 = w / 2; - var h2 = h / 2; - var ow3 = w2 / 3; - var oh3 = h2 / 3; - - var Paper = api.Paper; - var Path = Paper.Path; - var Point = Paper.Point; - var path = new Path(); - - path.moveTo(new Point(mx - w2 + unit * 2, my - h2)); - path.cubicCurveTo(new Point(mx - w2 + unit2, my - h2 + unit2), new Point(mx - w2 + unit2, my + h2 - unit2), new Point(mx - w2 + unit * 2, my + h2)); - path.cubicCurveTo(new Point(mx - ow3, my + oh3), new Point(mx + ow3, my + oh3), new Point(mx + w2 - unit * 2, my + h2)); - path.cubicCurveTo(new Point(mx + w2 - unit2, my + h2 - unit2), new Point(mx + w2 - unit2, my - h2 + unit2), new Point(mx + w2 - unit * 2, my - h2)); - path.cubicCurveTo(new Point(mx + ow3, my - oh3), new Point(mx - ow3, my - oh3), new Point(mx - w2 + unit * 2, my - h2)); - path.closePath(true); - path.strokeColor = "rgb(100,100,255)"; - return path; - }, - - setup: function setup(api) { - var dim = api.getPanelWidth(); - var pad = 40; - var cx = dim / 2; - var cy = dim / 2; - api.c1 = this.formPath(api, cx, cy); - cx += pad; - cy += pad; - api.c2 = this.formPath(api, cx, cy); - this.state.mode = modes[0]; - }, - - onMouseMove: function onMouseMove(evt, api) { - var cx = evt.offsetX; - var cy = evt.offsetY; - api.c2.position = { x: cx, y: cy }; - }, - - draw: function draw(api) { - if (api.c3) { - api.c3.remove(); - } - var c1 = api.c1, - c2 = api.c2, - fn = c1[this.state.mode].bind(c1), - c3 = api.c3 = fn(c2); - - c3.strokeColor = "red"; - c3.fillColor = "rgba(255,100,100,0.4)"; - api.Paper.view.draw(); - } -}; - -/***/ }), -/* 198 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(197); -var generateBase = __webpack_require__(1); -module.exports = generateBase("shapes", handler); - -/***/ }), -/* 199 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - api.forward = true; - }, - - drawSplit: function drawSplit(api, curve) { - api.setPanelCount(2); - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var offset = { x: 0, y: 0 }; - var t = 0.5; - var pt = curve.get(0.5); - var split = curve.split(t); - api.drawCurve(split.left); - api.drawCurve(split.right); - api.setColor("red"); - api.drawCircle(pt, 3); - - api.setColor("black"); - offset.x = api.getPanelWidth(); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: api.getPanelHeight() }, offset); - - api.setColor("lightgrey"); - api.drawCurve(curve, offset); - api.drawCircle(pt, 4); - - offset.x -= 20; - offset.y -= 20; - api.drawSkeleton(split.left, offset, true); - api.drawCurve(split.left, offset); - - offset.x += 40; - offset.y += 40; - api.drawSkeleton(split.right, offset, true); - api.drawCurve(split.right, offset); - }, - - drawAnimated: function drawAnimated(api, curve) { - api.setPanelCount(3); - api.reset(); - - var frame = api.getFrame(); - var interval = 5 * api.getPlayInterval(); - var t = frame % interval / interval; - var forward = frame % (2 * interval) < interval; - if (forward) { - t = t % 1; - } else { - t = 1 - t % 1; - } - var offset = { x: 0, y: 0 }; - - api.setColor("lightblue"); - api.drawHull(curve, t); - api.drawSkeleton(curve); - api.drawCurve(curve); - var pt = curve.get(t); - api.drawCircle(pt, 4); - - api.setColor("black"); - offset.x += api.getPanelWidth(); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: api.getPanelHeight() }, offset); - - var split = curve.split(t); - - api.setColor("lightgrey"); - api.drawCurve(curve, offset); - api.drawHull(curve, t, offset); - api.setColor("black"); - api.drawCurve(split.left, offset); - api.drawPoints(split.left.points, offset); - api.setFill("black"); - api.text("Left side of curve split at t = " + (100 * t | 0) / 100, { x: 10 + offset.x, y: 15 + offset.y }); - - offset.x += api.getPanelWidth(); - api.drawLine({ x: 0, y: 0 }, { x: 0, y: api.getPanelHeight() }, offset); - - api.setColor("lightgrey"); - api.drawCurve(curve, offset); - api.drawHull(curve, t, offset); - api.setColor("black"); - api.drawCurve(split.right, offset); - api.drawPoints(split.right.points, offset); - api.setFill("black"); - api.text("Right side of curve split at t = " + (100 * t | 0) / 100, { x: 10 + offset.x, y: 15 + offset.y }); - }, - - togglePlay: function togglePlay(evt, api) { - if (api.playing) { - api.pause(); - } else { - api.play(); - } - } -}; - -/***/ }), -/* 200 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(199); -var generateBase = __webpack_require__(1); -module.exports = generateBase("splitting", handler); - -/***/ }), -/* 201 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setupQuadratic: function setupQuadratic(api) { - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - }, - - setupCubic: function setupCubic(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - }, - - align: function align(points, line) { - var tx = line.p1.x, - ty = line.p1.y, - a = -Math.atan2(line.p2.y - ty, line.p2.x - tx), - cos = Math.cos, - sin = Math.sin, - d = function d(v) { - return { - x: (v.x - tx) * cos(a) - (v.y - ty) * sin(a), - y: (v.x - tx) * sin(a) + (v.y - ty) * cos(a), - a: a - }; - }; - return points.map(d); - }, - - // FIXME: I'm not satisfied with needing to turn a bbox[] into a point[], - // this needs a bezier.js solution, really, with a call curve.tightbbox() - transpose: function transpose(points, angle, offset) { - var tx = offset.x, - ty = offset.y, - cos = Math.cos, - sin = Math.sin, - v = [points.x.min, points.y.min, points.x.max, points.y.max]; - return [{ x: v[0], y: v[1] }, { x: v[2], y: v[1] }, { x: v[2], y: v[3] }, { x: v[0], y: v[3] }].map(function (p) { - var x = p.x, - y = p.y; - return { - x: x * cos(angle) - y * sin(angle) + tx, - y: x * sin(angle) + y * cos(angle) + ty - }; - }); - }, - - draw: function draw(api, curve) { - api.reset(); - - var pts = curve.points; - var line = { p1: pts[0], p2: pts[pts.length - 1] }; - var apts = this.align(pts, line); - var angle = -apts[0].a; - var aligned = new api.Bezier(apts); - var bbox = aligned.bbox(); - var tpts = this.transpose(bbox, angle, pts[0]); - - api.setColor("#00FF00"); - api.drawLine(tpts[0], tpts[1]); - api.drawLine(tpts[1], tpts[2]); - api.drawLine(tpts[2], tpts[3]); - api.drawLine(tpts[3], tpts[0]); - - api.setColor("black"); - api.drawSkeleton(curve); - api.drawCurve(curve); - } -}; - -/***/ }), -/* 202 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(201); -var generateBase = __webpack_require__(1); -module.exports = generateBase("tightbounds", handler); - -/***/ }), -/* 203 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - statics: { - keyHandlingOptions: { - propName: "steps", - values: { - "38": 1, // up arrow - "40": -1 // down arrow - }, - controller: function controller(api) { - if (api.steps < 1) { - api.steps = 1; - } - } - } - }, - - setup: function setup(api) { - var curve = api.getDefaultCubic(); - api.setCurve(curve); - api.steps = 8; - }, - - generate: function generate(api, curve, offset, pad, fwh) { - offset.x += pad; - offset.y += pad; - var len = curve.length(); - var pts = [{ x: 0, y: 0, d: 0 }]; - for (var v = 1, t, d; v <= 100; v++) { - t = v / 100; - d = curve.split(t).left.length(); - pts.push({ - x: api.utils.map(t, 0, 1, 0, fwh), - y: api.utils.map(d, 0, len, 0, fwh), - d: d, - t: t - }); - } - return pts; - }, - - draw: function draw(api, curve, offset) { - api.reset(); - api.drawSkeleton(curve); - api.drawCurve(curve); - - var len = curve.length(); - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - var pad = 20; - var fwh = w - 2 * pad; - - offset.x += w; - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - api.drawAxes(pad, "t", 0, 1, "d", 0, len, offset); - - return this.generate(api, curve, offset, pad, fwh); - }, - - plotOnly: function plotOnly(api, curve) { - api.setPanelCount(2); - var offset = { x: 0, y: 0 }; - var pts = this.draw(api, curve, offset); - for (var i = 0; i < pts.length - 1; i++) { - api.drawLine(pts[i], pts[i + 1], offset); - } - }, - - drawColoured: function drawColoured(api, curve) { - api.setPanelCount(3); - var w = api.getPanelWidth(); - var h = api.getPanelHeight(); - var pad = 20; - var fwh = w - 2 * pad; - - var offset = { x: 0, y: 0 }; - var len = curve.length(); - var pts = this.draw(api, curve, offset); - var s = api.steps, - i, - p, - ts = []; - for (i = 0; i <= s; i++) { - var target = i * len / s; - // find the t nearest our target distance - for (p = 0; p < pts.length; p++) { - if (pts[p].d > target) { - p--; - break; - } - } - if (p < 0) p = 0; - if (p === pts.length) p = pts.length - 1; - ts.push(pts[p]); - } - - for (i = 0; i < pts.length - 1; i++) { - api.drawLine(pts[i], pts[i + 1], offset); - } - - ts.forEach(function (p) { - var pt = { x: api.utils.map(p.t, 0, 1, 0, fwh), y: 0 }; - var pd = { x: 0, y: api.utils.map(p.d, 0, len, 0, fwh) }; - api.setColor("black"); - api.drawCircle(pt, 3, offset); - api.drawCircle(pd, 3, offset); - api.setColor("lightgrey"); - api.drawLine(pt, { x: pt.x, y: pd.y }, offset); - api.drawLine(pd, { x: pt.x, y: pd.y }, offset); - }); - - offset = { x: 2 * w, y: 0 }; - api.drawLine({ x: 0, y: 0 }, { x: 0, y: h }, offset); - - var idx = 0, - colors = ["rgb(240,0,200)", "rgb(0,40,200)"]; - api.setColor(colors[idx]); - var p0 = curve.get(pts[0].t), - p1; - api.drawCircle(curve.get(0), 4, offset); - - for (i = 1, p1; i < pts.length; i++) { - p1 = curve.get(pts[i].t); - api.drawLine(p0, p1, offset); - if (ts.indexOf(pts[i]) !== -1) { - api.setColor(colors[++idx % colors.length]); - api.drawCircle(p1, 4, offset); - } - p0 = p1; - } - } -}; - -/***/ }), -/* 204 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(203); -var generateBase = __webpack_require__(1); -var keyHandling = __webpack_require__(16); -module.exports = keyHandling(generateBase("tracing", handler)); - -/***/ }), -/* 205 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - setup: function setup(api) { - api.setPanelCount(3); - var curve = api.getDefaultQuadratic(); - api.setCurve(curve); - api.step = 25; - }, - - draw: function draw(api, curve) { - var dim = api.getPanelWidth(), - pts = curve.points, - p1 = pts[0], - p2 = pts[1], - p3 = pts[2], - p1e, - p2e, - m, - t, - i, - offset = { x: 0, y: 0 }, - d, - v, - tvp; - - api.reset(); - - api.setColor("black"); - api.setFill("black"); - api.drawSkeleton(curve, offset); - api.text("First linear interpolation at " + api.step + "% steps", { x: 5, y: 15 }, offset); - - offset.x += dim; - api.drawLine({ x: 0, y: 0 }, { x: 0, y: this.dim }, offset); - api.drawSkeleton(curve, offset); - api.text("Second interpolation at " + api.step + "% steps", { x: 5, y: 15 }, offset); - - offset.x += dim; - api.drawLine({ x: 0, y: 0 }, { x: 0, y: this.dim }, offset); - api.drawSkeleton(curve, offset); - api.text("Curve points generated this way", { x: 5, y: 15 }, offset); - - api.setColor("lightgrey"); - for (t = 1, d = 20, v, tvp; t < d; t++) { - v = t / d; - tvp = curve.get(v); - api.drawCircle(tvp, 2, offset); - } - - for (i = 3 * api.step; i > 0; i -= api.step) { - t = i / 100; - if (t > 1) continue; - api.setRandomColor(); - - p1e = { - x: p1.x + t * (p2.x - p1.x), - y: p1.y + t * (p2.y - p1.y) - }; - - p2e = { - x: p2.x + t * (p3.x - p2.x), - y: p2.y + t * (p3.y - p2.y) - }; - - m = { - x: p1e.x + t * (p2e.x - p1e.x), - y: p1e.y + t * (p2e.y - p1e.y) - }; - - offset = { x: 0, y: 0 }; - api.drawCircle(p1e, 3, offset); - api.drawCircle(p2e, 3, offset); - api.setWeight(0.5); - api.drawLine(p1e, p2e, offset); - api.setWeight(1.5); - api.drawLine(p1, p1e, offset); - api.drawLine(p2, p2e, offset); - api.setWeight(1); - - offset.x += dim; - api.drawCircle(p1e, 3, offset); - api.drawCircle(p2e, 3, offset); - api.setWeight(0.5); - api.drawLine(p1e, p2e, offset); - api.setWeight(1.5); - api.drawLine(p1e, m, offset); - api.setWeight(1); - api.drawCircle(m, 3, offset); - - offset.x += dim; - api.drawCircle(m, 3, offset); - - api.text(i + "%, or t = " + api.utils.round(t, 2), { x: m.x + 10 + offset.x, y: m.y + 10 + offset.y }); - } - }, - - values: { - "38": 1, // up arrow - "40": -1 // down arrow - }, - - onKeyDown: function onKeyDown(e, api) { - var v = this.values[e.keyCode]; - if (v) { - e.preventDefault(); - api.step += v; - if (api.step < 1) { - api.step = 1; - } - } - } -}; - -/***/ }), -/* 206 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var handler = __webpack_require__(205); -var generateBase = __webpack_require__(1); -module.exports = generateBase("whatis", handler); - -/***/ }), -/* 207 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -var React=__webpack_require__(5);var Graphic=__webpack_require__(113);var SectionHeader=__webpack_require__(69);var BSplineGraphic=__webpack_require__(110);var KnotController=__webpack_require__(115);var WeightController=__webpack_require__(120);SectionHeader.locale="en-GB";module.exports={"locale":"en-GB","preface":{"locale":"en-GB","title":"Preface","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"preface",title:"Preface"}),React.createElement("p",null,"In order to draw things in 2D, we usually rely on lines, which typically get classified into two categories: straight lines, and curves. The first of these are as easy to draw as they are easy to make a computer draw. Give a computer the first and last point in the line, and BAM! straight line. No questions asked."),React.createElement("p",null,"Curves, however, are a much bigger problem. While we can draw curves with ridiculous ease freehand, computers are a bit handicapped in that they can't draw curves unless there is a mathematical function that describes how it should be drawn. In fact, they even need this for straight lines, but the function is ridiculously easy, so we tend to ignore that as far as computers are concerned, all lines are \"functions\", regardless of whether they're straight or curves. However, that does mean that we need to come up with fast-to-compute functions that lead to nice looking curves on a computer. There's a number of these, and in this article we'll focus on a particular function that has received quite a bit of attention, and is used in pretty much anything that can draw curves: \"Bézier\" curves"),React.createElement("p",null,"They're named after ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Pierre_B%C3%A9zier"},"Pierre Bézier"),", who is principally responsible for getting them known to the world as a curve well-suited for design work (working for Renault and publishing his investigations in 1962), although he was not the first, or only one, to \"invent\" these type of curves. One might be tempted to say that the mathematician ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Paul_de_Casteljau"},"Paul de Casteljau")," was first, investigating the nature of these curves in 1959 while working at Citroën, coming up with a really elegant way of figuring out how to draw them. However, de Casteljau did not publish his work, making the question \"who was first\" hard to answer in any absolute sense. Or is it? Bézier curves are, at their core, \"Bernstein polynomials\", a family of mathematical functions investigated by ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Sergei_Natanovich_Bernstein"},"Sergei Natanovich Bernstein"),", with publications on them at least as far back as 1912. Anyway, that's mostly trivia, what you are more likely to care about is that these curves are handy: you can link up multiple Bézier curves so that the combination looks like a single curve. If you've ever drawn Photoshop \"paths\" or worked with vector drawing programs like Flash, Illustrator or nkscape, those curves you've been drawing are Bézier curves."),React.createElement("p",null,"So, what if you need to program them yourself? What are the pitfalls? How do you draw them? What are the bounding boxes, how do you determine intersections, how can you extrude a curve, in short: how do you do everything that you might want when you do with these curves? That's what this page is for. Prepare to be mathed!"),React.createElement("p",null,"—Pomax (or in the tweetworld, ",React.createElement("a",{href:"https://twitter.com/TheRealPomax"},"@TheRealPomax"),")"),React.createElement("div",{className:"note"},React.createElement("h2",{id:"note-virtually-all-b-zier-graphics-are-interactive-"},"Note: virtually all Bézier graphics are interactive."),React.createElement("p",null,"This page uses interactive examples, relying heavily on ",React.createElement("a",{href:"http://pomax.github.io/bezierjs"},"Bezier.js"),", as well as \"real\" maths (in LaTeX form) which is typeset using the most excellent ",React.createElement("a",{href:"http://MathJax.org"},"MathJax")," library. The page is generated offline as a React application, using Webpack, which has made adding \"view source\" options considerably more challenging. I'm still trying to figure out how to add them back in, but it didn't feel like it should hold up deploying this update compared to the previous years' version."),React.createElement("h2",{id:"this-book-is-open-source-"},"This book is open source."),React.createElement("p",null,"This book is an open source software project, and lives on two github repositorites. The first is ",React.createElement("a",{href:"https://github.com/pomax/bezierinfo"},"https://github.com/pomax/bezierinfo")," and is the purely-for-presentation version you are viewing right now. The other repository is ",React.createElement("a",{href:"https://github.com/pomax/BezierInfo-2"},"https://github.com/pomax/BezierInfo-2"),", which is the development version, housing all the html, javascript, and css. You can fork either of these, and pretty much do with them as you please, except for passing it off as your own work wholesale, of course =)"),React.createElement("h2",{id:"how-complicated-is-the-maths-going-to-be-"},"How complicated is the maths going to be?"),React.createElement("p",null,"Most of the mathematics in this Primer are early high school maths. If you understand basic arithmetic, and you know how to read English, you should be able to get by just fine. There will at times be ",React.createElement("em",null,"far")," more complicated maths, but if you don't feel like digesting them, you can safely skip over them by either skipping over the \"detail boxes\" in section or by just jumping to the end of a section with maths that looks too involving. The end of sections typically simply list the conclusions so you can just work with those values directly."),React.createElement("h2",{id:"questions-comments-"},"Questions, comments:"),React.createElement("p",null,"If you have suggestions for new sections, hit up the ",React.createElement("a",{href:"https://github.com/pomax/BezierInfo-2/issues"},"Github issue tracker")," (also reachable from the repo linked to in the upper right). If you have questions about the material, there's currently no comment section while I'm doing the rewrite, but you can use the issue tracker for that as well. Once the rewrite is done, I'll add a general comment section back in, and maybe a more topical \"select this section of text and hit the 'question' button to ask a question about it\" system. We'll see."),React.createElement("h2",{id:"buy-me-a-coffee-"},"Buy me a coffee?"),React.createElement("p",null,"If you enjoyed this book, or you simply found it useful for something you were trying to get done, and you were wondering how to let me know you appreciated this book, you can always ",React.createElement("a",{href:"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QPRDLNGDANJSW"},"buy me a coffee"),", however-much a coffee is where you live. This work has grown over the years, from a small primer to a 70ish print-page-equivalent reader on the subject of Bézier curves, and a lot of coffee went into the making of it. I don't regret a minute I spent on writing it, but I can always do with some more coffee to keep on writing!")));}},"introduction":{"locale":"en-GB","title":"A lightning introduction","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"introduction",title:"A lightning introduction",number:"1"}),React.createElement("p",null,"Let's start with the good stuff: when we're talking about Bézier curves, we're talking about the things that you can see in the following graphics. They run from some start point to some end point, with their curvature influenced by one or more \"intermediate\" control points. Now, because all the graphics on this page are interactive, go manipulate those curves a bit: click-drag the points, and see how their shape changes based on what you do."),React.createElement("div",{className:"figure"},React.createElement(Graphic,{inline:true,title:"Quadratic Bézier curves",setup:handler.drawQuadratic,draw:handler.drawCurve}),React.createElement(Graphic,{inline:true,title:"Cubic Bézier curves",setup:handler.drawCubic,draw:handler.drawCurve})),React.createElement("p",null,"These curves are used a lot in computer aided design and computer aided manufacturing (CAD/CAM) applications, as well as in graphic design programs like Adobe Illustrator and Photoshop, Inkscape, the Gimp, etc. and in graphic technologies like scalable vector graphics (SVG) and OpenType fonts (ttf/otf). A lot of things use Bézier curves, so if you want to learn more about them... prepare to get your learn on!"));}},"whatis":{"locale":"en-GB","title":"So what makes a Bézier Curve?","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"whatis",title:"So what makes a Bézier Curve?",number:"2"}),React.createElement("p",null,"Playing with the points for curves may have given you a feel for how Bézier curves behave, but what ",React.createElement("em",null,"are")," Bézier curves, really? There are two ways to explain what a Bézier curve is, and they turn out to be the entirely equivalent, but one of them uses complicated maths, and the other uses really simple maths. So... let's start with the simple explanation:"),React.createElement("p",null,"Bezier curves are the result of ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Linear_interpolation"},"linear interpolations"),". That sounds complicated but you've been doing linear interpolation since you were very young: any time you had to point at something between two other things, you've been applying linear interpolation. It's simply \"picking a point between two points\"."),React.createElement("p",null,"If we know the distance between those two points, and we want a new point that is, say, 20% the distance away from the first point (and thus 80% the distance away from the second point) then we can compute that really easily:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/8090904d6448ed0c8e6151aecf62f361d51ead96.svg",width:"526.4rem",height:"107.8rem"}),React.createElement("p",null,"So let's look at that in action: the following graphic is interactive in that you can use your up and down arrow keys to increase or decrease the interpolation ratio, to see what happens. We start with three points, which gives us two lines. Linear interpolation over those lines gives use two points, between which we can again perform linear interpolation, yielding a single point. And that point —and all points we can form in this way for all ratios taken together— form our Bézier curve:"),React.createElement(Graphic,{title:"Linear Interpolation leading to Bézier curves",setup:handler.setup,draw:handler.draw,onKeyDown:handler.onKeyDown}),React.createElement("p",null,"And that brings us to the complicated maths: calculus."),React.createElement("p",null,"While it doesn't look like that's what we've just done, we actually just drew a quadratic curve, in steps, rather than in a single go. One of the fascinating parts about Bézier curves is that they can both be described in terms of polynomial functions, as well as in terms of very simple interpolations of interpolations of [...]. That, in turn, means we can look at what these curves can do based on both \"real maths\" (by examining the functions, their derivatives, and all that stuff), as well as by looking at the \"mechanical\" composition (which tells us that a curve will never extend beyond the points we used to construct it, for instance)"),React.createElement("p",null,"So let's start looking at Bézier curves a bit more in depth. Their mathematical expressions, the properties we can derive from those, and the various things we can do to, and with, Bézier curves."));}},"explanation":{"locale":"en-GB","title":"The mathematics of Bézier curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"explanation",title:"The mathematics of Bézier curves",number:"3"}),React.createElement("p",null,"Bézier curves are a form of \"parametric\" function. Mathematically speaking, parametric functions are cheats: a \"function\" is actually a well defined term representing a mapping from any number of inputs to a ",React.createElement("strong",null,"single")," output. Numbers go in, a single number comes out. Change the numbers that go in, and the number that comes out is still a single number. Parametric functions cheat. They basically say \"alright, well, we want multiple values coming out, so we'll just use more than one function\". An illustration: Let's say we have a function that maps some value, let's call it ",React.createElement("i",null,"x"),", to some other value, using some kind of number manipulation:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/785e792c343b71d4e674ac94d8800940b30917ac.svg",width:"100.8rem",height:"18.2rem"}),React.createElement("p",null,"The notation ",React.createElement("i",null,"f(x)")," is the standard way to show that it's a function (by convention called ",React.createElement("i",null,"f")," if we're only listing one) and its output changes based on one variable (in this case, ",React.createElement("i",null,"x"),"). Change ",React.createElement("i",null,"x"),", and the output for ",React.createElement("i",null,"f(x)")," changes."),React.createElement("p",null,"So far so good. Now, let's look at parametric functions, and how they cheat. Let's take the following two functions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0dfe7562b43441e72201ff4cdd2e8b6e2e3ecb2d.svg",width:"98rem",height:"37.8rem"}),React.createElement("p",null,"There's nothing really remarkable about them, they're just a sine and cosine function, but you'll notice the inputs have different names. If we change the value for ",React.createElement("i",null,"a"),", we're not going to change the output value for ",React.createElement("i",null,"f(b)"),", since ",React.createElement("i",null,"a")," isn't used in that function. Parametric functions cheat by changing that. In a parametric function all the different functions share a variable, like this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ed6f533530199d1e99b3319ba137c1327b0459c0.svg",width:"105rem",height:"42rem"}),React.createElement("p",null,"Multiple functions, but only one variable. If we change the value for ",React.createElement("i",null,"t"),", we change the outcome of both ",React.createElement("i",null,"f",React.createElement("sub",null,"a"),"(t)")," and ",React.createElement("i",null,"f",React.createElement("sub",null,"b"),"(t)"),". You might wonder how that's useful, and the answer is actually pretty simple: if we change the labels ",React.createElement("i",null,"f",React.createElement("sub",null,"a"),"(t)")," and ",React.createElement("i",null,"f",React.createElement("sub",null,"b"),"(t)")," with what we usually mean with them for parametric curves, things might be a lot more obvious:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ea632ea75d6a2aeb6fe69c07feb6e76f81884746.svg",width:"81.19999999999999rem",height:"42rem"}),React.createElement("p",null,"There we go. ",React.createElement("i",null,"x"),"/",React.createElement("i",null,"y")," coordinates, linked through some mystery value ",React.createElement("i",null,"t"),"."),React.createElement("p",null,"So, parametric curves don't define a ",React.createElement("i",null,"y")," coordinate in terms of an ",React.createElement("i",null,"x")," coordinate, like normal functions do, but they instead link the values to a \"control\" variable. If we vary the value of ",React.createElement("i",null,"t"),", then with every change we get ",React.createElement("strong",null,"two")," values, which we can use as (",React.createElement("i",null,"x"),",",React.createElement("i",null,"y"),") coordinates in a graph. The above set of functions, for instance, generates points on a circle: We can range ",React.createElement("i",null,"t")," from negative to positive infinity, and the resulting (",React.createElement("i",null,"x"),",",React.createElement("i",null,"y"),") coordinates will always lie on a circle with radius 1 around the origin (0,0). If we plot it for ",React.createElement("i",null,"t")," from 0 to 5, we get this (use your up and down arrow keys to change the plot end value):"),React.createElement(Graphic,{preset:"empty",title:"A (partial) circle: x=sin(t), y=cos(t)","static":true,setup:handler.setup,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"Bézier curves are (one in many classes of) parametric functions, and are characterised by using the same base function for all its dimensions. Unlike the above example, where the ",React.createElement("i",null,"x")," and ",React.createElement("i",null,"y")," values use different functions (one uses a sine, the other a cosine), Bézier curves use the \"binomial polynomial\" for both ",React.createElement("i",null,"x")," and ",React.createElement("i",null,"y"),". So what are binomial polynomials?"),React.createElement("p",null,"You may remember polynomials from high school, where they're those sums that look like:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3e8b26cf8833db7089d65e9c6b3953a3140bb19f.svg",width:"224rem",height:"21rem"}),React.createElement("p",null,"If they have a highest order term ",React.createElement("i",null,"x³")," they're called \"cubic\" polynomials, if it's ",React.createElement("i",null,"x²")," it's a \"square\" polynomial, if it's just ",React.createElement("i",null,"x")," it's a line (and if there aren't even any terms with ",React.createElement("i",null,"x")," it's not a polynomial!)"),React.createElement("p",null,"Bézier curves are polynomials of ",React.createElement("i",null,"t"),", rather than ",React.createElement("i",null,"x"),", with the value for ",React.createElement("i",null,"t")," fixed being between 0 and 1, with coefficients ",React.createElement("i",null,"a"),", ",React.createElement("i",null,"b")," etc. taking the \"binomial\" form, which sounds fancy but is actually a pretty simple description for mixing values:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/565d935cab46bc995f53190102dadfdd1afc08f6.svg",width:"385rem",height:"68.6rem"}),React.createElement("p",null,"I know what you're thinking: that doesn't look too simple, but if we remove ",React.createElement("i",null,"t")," and add in \"times one\", things suddenly look pretty easy. Check out these binomial terms:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/8c618738924e53a313a31fa407b3d91155525ee1.svg",width:"219.79999999999998rem",height:"91rem"}),React.createElement("p",null,"Notice that 2 is the same as 1+1, and 3 is 2+1 and 1+2, and 6 is 3+3... As you can see, each time we go up a dimension, we simply start and end with 1, and everything in between is just \"the two numbers above it, added together\". Now ",React.createElement("i",null,"that's")," easy to remember."),React.createElement("p",null,"There's an equally simple way to figure out how the polynomial terms work: if we rename ",React.createElement("i",null,"(1-t)")," to ",React.createElement("i",null,"a")," and ",React.createElement("i",null,"t")," to ",React.createElement("i",null,"b"),", and remove the weights for a moment, we get this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c8740a3a9a63b592e1480883a54024ebdaffaf05.svg",width:"316.4rem",height:"62.99999999999999rem"}),React.createElement("p",null,"It's basically just a sum of \"every combination of ",React.createElement("i",null,"a")," and ",React.createElement("i",null,"b"),"\", progressively replacing ",React.createElement("i",null,"a"),"'s with ",React.createElement("i",null,"b"),"'s after every + sign. So that's actually pretty simple too. So now you know binomial polynomials, and just for completeness I'm going to show you the generic function for this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/444a01611e5709f702c36f6ca17aa2761c0877a9.svg",width:"315rem",height:"57.4rem"}),React.createElement("p",null,"And that's the full description for Bézier curves. Σ in this function indicates that this is a series of additions (using the variable listed below the Σ, starting at ...=<value> and ending at the value listed on top of the Σ)."),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"how-to-implement-the-basis-function"},"How to implement the basis function"),React.createElement("p",null,"We could naively implement the basis function as a mathematical construct, using the function as our guide, like this:"),React.createElement("pre",null,"function Bezier(n,t):\n sum = 0\n for(k=0; k<n; k++):\n sum += n!/(k!*(n-k)!) * (1-t)^(n-k) * t^(k)\n return sum\n"),React.createElement("p",null,"I say we could, because we're not going to: the factorial function is ",React.createElement("em",null,"incredibly")," expensive. And, as we can see from the above explanation, we can actually create Pascal's triangle quite easily without it: just start at [1], then [1,1], then [1,2,1], then [1,3,3,1], and so on, with each next row fitting 1 more number than the previous row, starting and ending with \"1\", with all the numbers in between being the sum of the previous row's elements on either side \"above\" the one we're computing."),React.createElement("p",null,"We can generate this as a list of lists lightning fast, and then never have to compute the binomial terms because we have a lookup table:"),React.createElement("pre",null,"lut = [ [1], // n=0\n [1,1], // n=1\n [1,2,1], // n=2\n [1,3,3,1], // n=3\n [1,4,6,4,1], // n=4\n [1,5,10,10,5,1], // n=5\n [1,6,15,20,15,6,1]] // n=6\n\nbinomial(n,k):\n while(n >= lut.length):\n s = lut.length\n nextRow = new array(size=s+1)\n nextRow[0] = 1\n for(i=1, prev=s-1; i<prev; i++):\n nextRow[i] = lut[prev][i-1] + lut[prev][i]\n nextRow[s] = 1\n lut.add(nextRow)\n return lut[n][k]\n"),React.createElement("p",null,"So what's going on here? First, we declare a lookup table with a size that's reasonably large enough to accommodate most lookups. Then, we declare a function to get us the values we need, and we make sure that if an n/k pair is requested that isn't in the LUT yet, we expand it first. Our basis function now looks like this:"),React.createElement("pre",null,"function Bezier(n,t):\n sum = 0\n for(k=0; k<=n; k++):\n sum += binomial(n,k) * (1-t)^(n-k) * t^(k)\n return sum\n"),React.createElement("p",null,"Perfect. Of course, we can optimize further. For most computer graphics purposes, we don't need arbitrary curves. We need quadratic and cubic curves (this primer actually does do arbitrary curves, so you'll find code similar to shown here), which means we can drastically simplify the code:"),React.createElement("pre",null,"function Bezier(2,t):\n t2 = t * t\n mt = 1-t\n mt2 = mt * mt\n return mt2 + 2*mt*t + t2\n\nfunction Bezier(3,t):\n t2 = t * t\n t3 = t2 * t\n mt = 1-t\n mt2 = mt * mt\n mt3 = mt2 * mt\n return mt3 + 3*mt2*t + 3*mt*t2 + t3\n"),React.createElement("p",null,"And now we know how to program the basis function. Exellent.")),React.createElement("p",null,"So, now we know what the base function(s) look(s) like, time to add in the magic that makes Bézier curves so special: control points."));}},"control":{"locale":"en-GB","title":"Controlling Bézier curvatures","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"control",title:"Controlling Bézier curvatures",number:"4"}),React.createElement("p",null,"Bézier curves are (like all \"splines\") interpolation functions, meaning they take a set of points, and generate values somewhere \"between\" those points. (One of the consequences of this is that you'll never be able to generate a point that lies outside the outline for the control points, commonly called the \"hull\" for the curve. Useful information!). In fact, we can visualize how each point contributes to the value generated by the function, so we can see which points are important, where, in the curve."),React.createElement("p",null,"The following graphs show the interpolation functions for quadratic and cubic curves, with \"S\" being the strength of a point's contribution to the total sum of the Bézier function. Click or click-drag to see the interpolation percentages for each curve-defining point at a specific ",React.createElement("i",null,"t")," value."),React.createElement("div",{className:"figure"},React.createElement(Graphic,{inline:true,preset:"simple",title:"Quadratic interpolations",draw:handler.drawQuadraticLerp}),React.createElement(Graphic,{inline:true,preset:"simple",title:"Cubic interpolations",draw:handler.drawCubicLerp}),React.createElement(Graphic,{inline:true,preset:"simple",title:"15th order interpolations",draw:handler.draw15thLerp})),React.createElement("p",null,"Also shown is the interpolation function for a 15",React.createElement("sup",null,"th")," order Bézier function. As you can see, the start and end point contribute considerably more to the curve's shape than any other point in the control point set."),React.createElement("p",null,"If we want to change the curve, we need to change the weights of each point, effectively changing the interpolations. The way to do this is about as straight forward as possible: just multiply each point with a value that changes its strength. These values are conventionally called \"Weights\", and we can add them to our original Bézier function:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/cc82da74955e71db3f5f0ab77dcc4664c0387bec.svg",width:"369.59999999999997rem",height:"57.4rem"}),React.createElement("p",null,"That looks complicated, but as it so happens, the \"weights\" are actually just the coordinate values we want our curve to have: for an ",React.createElement("i",null,"n",React.createElement("sup",null,"th"))," order curve, w",React.createElement("sub",null,"0")," is our start coordinate, w",React.createElement("sub",null,"n")," is our last coordinate, and everything in between is a controlling coordinate. Say we want a cubic curve that starts at (120,160), is controlled by (35,200) and (220,260) and ends at (220,40), we use this Bézier curve:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/853858526831a7ef3eb170efe49de397bb4913a1.svg",width:"496.99999999999994rem",height:"42rem"}),React.createElement("p",null,"Which gives us the curve we saw at the top of the article:"),React.createElement(Graphic,{preset:"simple",title:"Our cubic Bézier curve",setup:handler.drawCubic,draw:handler.drawCurve}),React.createElement("p",null,"What else can we do with Bézier curves? Quite a lot, actually. The rest of this article covers a multitude of possible operations and algorithms that we can apply, and the tasks they achieve."),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"how-to-implement-the-weighted-basis-function"},"How to implement the weighted basis function"),React.createElement("p",null,"Given that we already know how to implement basis function, adding in the control points is remarkably easy:"),React.createElement("pre",null,"function Bezier(n,t,w[]):\n sum = 0\n for(k=0; k<n; k++):\n sum += w[k] * binomial(n,k) * (1-t)^(n-k) * t^(k)\n return sum\n"),React.createElement("p",null,"And for the extremely optimized versions:"),React.createElement("pre",null,"function Bezier(2,t,w[]):\n t2 = t * t\n mt = 1-t\n mt2 = mt * mt\n return w[0]*mt2 + w[1]*2*mt*t + w[2]*t2\n\nfunction Bezier(3,t,w[]):\n t2 = t * t\n t3 = t2 * t\n mt = 1-t\n mt2 = mt * mt\n mt3 = mt2 * mt\n return w[0]*mt3 + 3*w[1]*mt2*t + 3*w[2]*mt*t2 + w[3]*t3\n"),React.createElement("p",null,"And now we know how to program the weighted basis function.")));}},"extended":{"locale":"en-GB","title":"The Bézier interval [0,1]","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"extended",title:"The Bézier interval [0,1]",number:"5"}),React.createElement("p",null,"Now that we know the mathematics behind Bézier curves, there's one curious thing that you may have noticed: they always run from ",React.createElement("code",null,"t=0")," to ",React.createElement("code",null,"t=1"),". Why that particular interval?"),React.createElement("p",null,"It all has to do with how we run from \"the start\" of our curve to \"the end\" of our curve. If we have a value that is a mixture of two other values, then the general formula for this is:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7f5ebb8489a8d04beb28f47c8aac2632b78ae764.svg",width:"225.39999999999998rem",height:"16.799999999999997rem"}),React.createElement("p",null,"The obvious start and end values here need to be ",React.createElement("code",null,"a=1, b=0"),", so that the mixed value is 100% value 1, and 0% value 2, and ",React.createElement("code",null,"a=0, b=1"),", so that the mixed value is 0% value 1 and 100% value 2. Additionally, we don't want \"a\" and \"b\" to be independent: if they are, then we could just pick whatever values we like, and end up with a mixed value that is, for example, 100% value 1 ",React.createElement("strong",null,"and")," 100% value 2. In principle that's fine, but for Bézier curves we always want mixed values ",React.createElement("em",null,"between")," the start and end point, so we need to make sure we can never set \"a\" and \"b\" to some values that lead to a mix value that sums to more than 100%. And that's easy:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d326c8f323ccd2da00d998b533ac26a1c04fcfba.svg",width:"225.39999999999998rem",height:"16.799999999999997rem"}),React.createElement("p",null,"With this we can guarantee that we never sum above 100%. By restricting ",React.createElement("code",null,"a")," to values in the interval [0,1], we will always be somewhere between our two values (inclusively), and we will always sum to a 100% mix."),React.createElement("p",null,"But... what if we use this form, used in the assumption that we will only ever use values between 0 and 1, and instead use values outside of that interval? Do things go horribly wrong? Well... not really, but we get to \"see more\"."),React.createElement("p",null,"In the case of Bézier curves, extending the interval simply makes our curve \"keep going\". Bézier curves are simply segments on some polynomial curve, so if we pick a wider interval we simply get to see more of the curve. So what do they look like?"),React.createElement("p",null,"The following two graphics show you Bézier curves rendered \"the usual way\", as well as the curves they \"lie on\" if we were to extend the ",React.createElement("code",null,"t")," values much further. As you can see, there's a lot more \"shape\" hidden in the rest of the curve, and we can model those parts by moving the curve points around."),React.createElement(Graphic,{preset:"simple",title:"Quadratic infinite interval Bézier curve",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"simple",title:"Cubic infinite interval Bézier curve",setup:handler.setupCubic,draw:handler.draw}),React.createElement("p",null,"In fact, there are curves used in graphics design and computer modelling that do the opposite of Bézier curves, where rather than fixing the interval, and giving you free coordinates, they fix the coordinates, but give you freedom over the interval. A great example of this is the ",React.createElement("a",{href:"http://levien.com/phd/phd.html"},"\"Spiro\" curve"),", which is a curve based on part of a ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Euler_spiral"},"Cornu Spiral, also known as Euler's Spiral"),". It's a very aesthetically pleasing curve and you'll find it in quite a few graphics packages like ",React.createElement("a",{href:"https://fontforge.github.io"},"FontForge")," and ",React.createElement("a",{href:"https://inkscape.org"},"Inkscape"),", having even been used in font design (such as for the Inconsolata font)."));}},"matrix":{"locale":"en-GB","title":"Bézier curvatures as matrix operations","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"matrix",title:"Bézier curvatures as matrix operations",number:"6"}),React.createElement("p",null,"We can also represent Bézier as matrix operations, by expressing the Bézier formula as a polynomial basis function and a coefficients matrix, and the actual coordinates as matrix. Let's look at what this means for the cubic curve:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d961171d6d1dfc22bb1756901e79102147914360.svg",width:"491.4rem",height:"21rem"}),React.createElement("p",null,"Disregarding our actual coordinates for a moment, we have:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/f925c339011e6c38e47b9c3a571e02fca80eb5c3.svg",width:"371rem",height:"19.599999999999998rem"}),React.createElement("p",null,"We can write this as a sum of four expressions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/30d76165668bf15f62986503bea100f39c5b9fec.svg",width:"147rem",height:"78.39999999999999rem"}),React.createElement("p",null,"And we can expand these expressions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7ca5abe1124ba1e51b7f12e0469cb4b1407593b8.svg",width:"417.2rem",height:"78.39999999999999rem"}),React.createElement("p",null,"Furthermore, we can make all the 1 and 0 factors explicit:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/bccbb94942e3ff79579e4719106f4701c157727e.svg",width:"228.2rem",height:"78.39999999999999rem"}),React.createElement("p",null,"And ",React.createElement("em",null,"that"),", we can view as a series of four matrix operations:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d5f85d80fbbc62e1e8d58621b76f3d0224876b62.svg",width:"637rem",height:"75.6rem"}),React.createElement("p",null,"If we compact this into a single matrix operation, we get:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7140be48f45b2e7190fa8dffef5c05c47c038ab0.svg",width:"237.99999999999997rem",height:"75.6rem"}),React.createElement("p",null,"This kind of polynomial basis representation is generally written with the bases in increasing order, which means we need to flip our ",React.createElement("code",null,"t")," matrix horizontally, and our big \"mixing\" matrix upside down:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/4e1849950a5c13f5135aa3412e0ee634cdc67301.svg",width:"237.99999999999997rem",height:"75.6rem"}),React.createElement("p",null,"And then finally, we can add in our original coordinates as a single third matrix:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5910e25a46d9e86ab34513017f1274628a40e5a7.svg",width:"338.79999999999995rem",height:"77rem"}),React.createElement("p",null,"We can perform the same trick for the quadratic curve, in which case we end up with:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e56e78e406d625c2a5ec584216f79a5fee00d8ea.svg",width:"275.79999999999995rem",height:"57.4rem"}),React.createElement("p",null,"If we plug in a ",React.createElement("code",null,"t")," value, and then multiply the matrices, we will get exactly the same values as when we evaluate the original polynomial function, or as when we evaluate the curve using progessive linear interpolation."),React.createElement("p",null,React.createElement("strong",null,"So: why would we bother with matrices?")," Matrix representations allow us to discover things about functions that would otherwise be hard to tell. It turns out that the curves form ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Triangular_matrix"},"triangular matrices"),", and they have a determinant equal to the product of the actual coordinates we use for our curve. It's also invertible, which means there's ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Invertible_matrix#The_invertible_matrix_theorem"},"a ton of properties")," that are all satisfied. Of course, the main question is: \"Why is this useful to us, now?\", and the answer to that is that it's not immediately useful, but you'll be seeing some instances where certain curve properties can be either computed via function manipulation, or via clever use of matrices, and sometimes the matrix approach can be (drastically) faster."),React.createElement("p",null,"So for now, just remember that we can represent curves this way, and let's move on."));}},"decasteljau":{"locale":"en-GB","title":"de Casteljau's algorithm","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"decasteljau",title:"de Casteljau's algorithm",number:"7"}),React.createElement("p",null,"If we want to draw Bézier curves we can run through all values of ",React.createElement("code",null,"t")," from 0 to 1 and then compute the weighted basis function, getting the ",React.createElement("code",null,"x/y")," values we need to plot, but the more complex the curve gets, the more expensive this becomes. Instead, we can use \"de Casteljau's algorithm\" to draw curves, which is a geometric approach to drawing curves, and really easy to implement. So easy, in fact, you can do it by hand with a pencil and ruler."),React.createElement("p",null,"Rather than using our calculus function to find ",React.createElement("code",null,"x/y")," values for ",React.createElement("code",null,"t"),", let's do this instead:"),React.createElement("ul",null,React.createElement("li",null,"treat ",React.createElement("code",null,"t")," as a ratio (which it is). t=0 is 0% along a line, t=1 is 100% along a line."),React.createElement("li",null,"Take all lines between the curve's defining points. For an order ",React.createElement("code",null,"n")," curve, that's ",React.createElement("code",null,"n")," lines."),React.createElement("li",null,"Place markers along each of these line, at distance ",React.createElement("code",null,"t"),". So if ",React.createElement("code",null,"t")," is 0.2, place the mark at 20% from the start, 80% from the end."),React.createElement("li",null,"Now form lines between ",React.createElement("code",null,"those")," points. This gives ",React.createElement("code",null,"n-1")," lines."),React.createElement("li",null,"Place markers along each of these line at distance ",React.createElement("code",null,"t"),"."),React.createElement("li",null,"Form lines between ",React.createElement("code",null,"those")," points. This'll be ",React.createElement("code",null,"n-2")," lines."),React.createElement("li",null,"place markers, form lines, place markers, etc."),React.createElement("li",null,"repeat this until you have only one line left. The point ",React.createElement("code",null,"t")," on that line coincides with the original curve point at ",React.createElement("code",null,"t"),".")),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"how-to-implement-de-casteljau-s-algorithm"},"How to implement de Casteljau's algorithm"),React.createElement("p",null,"Let's just use the algorithm we just specified, and implement that:"),React.createElement("pre",null,"function drawCurve(points[], t):\n if(points.length==1):\n draw(points[0])\n else:\n newpoints=array(points.size-1)\n for(i=0; i<newpoints.length; i++):\n newpoints[i] = (1-t) * points[i] + t * points[i+1]\n drawCurve(newpoints, t)\n"),React.createElement("p",null,"And done, that's the algorithm implemented. Except usually you don't get the luxury of overloading the \"+\" operator, so let's also give the code for when you need to work with ",React.createElement("code",null,"x")," and ",React.createElement("code",null,"y")," values:"),React.createElement("pre",null,"function drawCurve(points[], t):\n if(points.length==1):\n draw(points[0])\n else:\n newpoints=array(points.size-1)\n for(i=0; i<newpoints.length; i++):\n x = (1-t) * points[i].x + t * points[i+1].x\n y = (1-t) * points[i].y + t * points[i+1].y\n newpoints[i] = new point(x,y)\n drawCurve(newpoints, t)\n"),React.createElement("p",null,"So what does this do? This draws a point, if the passed list of points is only 1 point long. Otherwise it will create a new list of points that sit at the ",React.createElement("i",null,"t")," ratios (i.e. the \"markers\" outlined in the above algorithm), and then call the draw function for this new list.")),React.createElement("p",null,"To see this in action, mouse-over the following sketch. Moving the mouse changes which curve point is explicitly evaluated using de Casteljau's algorithm, moving the cursor left-to-right (or, of course, right-to-left), shows you how a curve is generated using this approach."),React.createElement(Graphic,{preset:"simple",title:"Traversing a curve using de Casteljau's algorithm",setup:handler.setup,draw:handler.draw}));}},"flattening":{"locale":"en-GB","title":"Simplified drawing","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"flattening",title:"Simplified drawing",number:"8"}),React.createElement("p",null,"We can also simplify the drawing process by \"sampling\" the curve at certain points, and then joining those points up with straight lines, a process known as \"flattening\", as we are reducing a curve to a simple sequence of straight, \"flat\" lines."),React.createElement("p",null,"We can do this is by saying \"we want X segments\", and then sampling the curve at intervals that are spaced such that we end up with the number of segments we wanted. The advantage of this method is that it's fast: instead of evaluating 100 or even 1000 curve coordinates, we can sample a much lower number and still end up with a curve that sort-of-kind-of looks good enough. The disadvantage of course is that we lose the precision of working with \"the real curve\", so we usually can't use the flattened for for doing true intersection detection, or curvature alignment."),React.createElement(Graphic,{preset:"twopanel",title:"Flattening a quadratic curve",setup:handler.setupQuadratic,draw:handler.drawFlattened,onKeyDown:handler.onKeyDown}),React.createElement(Graphic,{preset:"twopanel",title:"Flattening a cubic curve",setup:handler.setupCubic,draw:handler.drawFlattened,onKeyDown:handler.onKeyDown}),React.createElement("p",null,"Try clicking on the sketch and using your up and down arrow keys to lower the number of segments for both the quadratic and cubic curve. You'll notice that for certain curvatures, a low number of segments works quite well, but for more complex curvatures (try this for the cubic curve), a higher number is required to capture the curvature changes properly."),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"how-to-implement-curve-flattening"},"How to implement curve flattening"),React.createElement("p",null,"Let's just use the algorithm we just specified, and implement that:"),React.createElement("pre",null,"function flattenCurve(curve, segmentCount):\n step = 1/segmentCount;\n coordinates = [curve.getXValue(0), curve.getYValue(0)]\n for(i=1; i <= segmentCount; i++):\n t = i*step;\n coordinates.push[curve.getXValue(t), curve.getYValue(t)]\n return coordinates;\n"),React.createElement("p",null,"And done, that's the algorithm implemented. That just leaves drawing the resulting \"curve\" as a sequence of lines:"),React.createElement("pre",null,"function drawFlattenedCurve(curve, segmentCount):\n coordinates = flattenCurve(curve, segmentCount)\n coord = coordinates[0], _coords;\n for(i=1; i < coordinates.length; i++):\n _coords = coordinates[i]\n line(coords, _coords)\n coords = _coords\n"),React.createElement("p",null,"We start with the first coordinate as reference point, and then just draw lines between each point and its next point.")));}},"splitting":{"locale":"en-GB","title":"Splitting curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"splitting",title:"Splitting curves",number:"9"}),React.createElement("p",null,"With de Casteljau's algorithm we also find all the points we need to split up a Bézier curve into two, smaller curves, which taken together form the original curve. When we construct de Casteljau's skeleton for some value ",React.createElement("code",null,"t"),", the procedure gives us all the points we need to split a curve at that ",React.createElement("code",null,"t")," value: one curve is defined by all the inside skeleton points found prior to our on-curve point, with the other curve being defined by all the inside skeleton points after our on-curve point."),React.createElement(Graphic,{title:"Splitting a curve",setup:handler.setupCubic,draw:handler.drawSplit}),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"implementing-curve-splitting"},"implementing curve splitting"),React.createElement("p",null,"We can implement curve splitting by bolting some extra logging onto the de Casteljau function:"),React.createElement("pre",null,"left=[]\nright=[]\nfunction drawCurve(points[], t):\n if(points.length==1):\n left.add(points[0])\n right.add(points[0])\n draw(points[0])\n else:\n newpoints=array(points.size-1)\n for(i=0; i<newpoints.length; i++):\n if(i==0):\n left.add(points[i])\n if(i==newpoints.length-1):\n right.add(points[i+1])\n newpoints[i] = (1-t) * points[i] + t * points[i+1]\n drawCurve(newpoints, t)\n"),React.createElement("p",null,"After running this function for some value ",React.createElement("code",null,"t"),", the ",React.createElement("code",null,"left")," and ",React.createElement("code",null,"right")," arrays will contain all the coordinates for two new curves - one to the \"left\" of our ",React.createElement("code",null,"t")," value, the other on the \"right\", of the same order as the original curve, and overlayed exactly on the original curve.")),React.createElement("p",null,"This is best illustrated with an animated graphic (click to play/pause):"),React.createElement(Graphic,{preset:"threepanel",title:"Bézier curve splitting",setup:handler.setupCubic,draw:handler.drawAnimated,onClick:handler.togglePlay}));}},"matrixsplit":{"locale":"en-GB","title":"Splitting curves using matrices","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"matrixsplit",title:"Splitting curves using matrices",number:"10"}),React.createElement("p",null,"Another way to split curves is to exploit the matrix representation of a Bézier curve. In ",React.createElement("a",{href:"#matrix"},"the section on matrices")," we saw that we can represent curves as matrix multiplications. Specifically, we saw these two forms for the quadratic, and cubic curves, respectively (using the reversed Bézier coefficients vector for legibility):"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e56e78e406d625c2a5ec584216f79a5fee00d8ea.svg",width:"275.79999999999995rem",height:"57.4rem"}),React.createElement("p",null,"and"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/01ea4f74c4785a19bedf18034b51510c5ce2ad8f.svg",width:"338.79999999999995rem",height:"77rem"}),React.createElement("p",null,"Let's say we want to split the curve at some point ",React.createElement("code",null,"t = z"),", forming two new (obviously smaller) Bézier curves. To find the coordinates for these two Bézier curves, we can use the matrix representation and some linear algebra. First, we split out the the actual \"point on the curve\" information as a new matrix multiplication:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d6fa091a86782480968c232ef86513c578030004.svg",width:"680.4rem",height:"57.4rem"}),React.createElement("p",null,"and"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d487e1e0181420995be49b25bc6595c9d0360435.svg",width:"845.5999999999999rem",height:"78.39999999999999rem"}),React.createElement("p",null,"If we could compact these matrices back to a form ",React.createElement("strong",null,"[t values] · [bezier matrix] · [column matrix]"),", with the first two staying the same, then that column matrix on the right would be the coordinates of a new Bézier curve that describes the first segment, from ",React.createElement("code",null,"t = 0")," to ",React.createElement("code",null,"t = z"),". As it turns out, we can do this quite easily, by exploiting some simple rules of linear algebra (and if you don't care about the derivations, just skip to the end of the box for the results!)."),React.createElement("div",{className:"note"},React.createElement("h2",{id:"deriving-new-hull-coordinates"},"Deriving new hull coordinates"),React.createElement("p",null,"Deriving the two segments upon splitting a curve takes a few steps, and the higher the curve order, the more work it is, so let's look at the quadratic curve first:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d4b8355c3f1f80aacfc2766423a30151c5180a02.svg",width:"365.4rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/fe5f623585a9bbb836f54164aecaadd3fc4ec953.svg",width:"259rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1eb9833685c9189c64d9cbdfdbb24a94e70e493f.svg",width:"259rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/55f9d31b32a3e8855f2d28c3253201c8963eefd1.svg",width:"257.59999999999997rem",height:"57.4rem"}),React.createElement("p",null,"We do this, because [",React.createElement("em",null,"M · M",React.createElement("sup",null,"-1")),"] is the identity matrix (a bit like multiplying something by x/x in calculus. It doesn't do anything to the function, but it does allow you to rewrite it to something that may be easier to work with, or can be broken up differently). Adding that as matrix multiplication has no effect on the total formula, but it does allow us to change the matrix sequence [",React.createElement("em",null,"something · M"),"] to a sequence [",React.createElement("em",null,"M · something"),"], and that makes a world of difference: if we know what [",React.createElement("em",null,"M",React.createElement("sup",null,"-1")," · Z · M"),"] is, we can apply that to our coordinates, and be left with a proper matrix representation of a quadratic Bézier curve (which is [",React.createElement("em",null,"T · M · P"),"]), with a new set of coordinates that represent the curve from ",React.createElement("em",null,"t = 0")," to ",React.createElement("em",null,"t = z"),". So let's get computing:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1dbabc115128a85389cbbcc75fbced48e5a2ca25.svg",width:"658rem",height:"58.8rem"}),React.createElement("p",null,"Excellent! Now we can form our new quadratic curve:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/2972cd74dab6560ea68189c2e53f247287cbefae.svg",width:"438.2rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/39b64e07c41ef6d734064f017036f6391321e924.svg",width:"502.59999999999997rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d615960f862664749c54858520c364efeb4a4c5a.svg",width:"516.6rem",height:"57.4rem"}),React.createElement("p",null,React.createElement("strong",null,React.createElement("em",null,"Brilliant")),": if we want a subcurve from ",React.createElement("code",null,"t = 0")," to ",React.createElement("code",null,"t = z"),", we can keep the first coordinate the same (which makes sense), our control point becomes a z-ratio mixture of the original control point and the start point, and the new end point is a mixture that looks oddly similar to a bernstein polynomial of degree two, except it uses (z-1) rather than (1-z)... These new coordinates are actually really easy to compute directly!"),React.createElement("p",null,"Of course, that's only one of the two curves. Getting the section from ",React.createElement("code",null,"t = z")," to ",React.createElement("code",null,"t = 1")," requires doing this again. We first observe what what we just did is actually evaluate the general interval [0,",React.createElement("code",null,"z"),"], which we wrote down simplified becuase of that zero, but we actually evaluated this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/a51e64df3cb31acf32d0ad5814c8c6cff41ae611.svg",width:"400.4rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b50cdfed6656e681d5885a14a3af3e67efa4ccb.svg",width:"329rem",height:"57.4rem"}),React.createElement("p",null,"If we want the interval [",React.createElement("em",null,"z"),",1], we will be evaluating this instead:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/eca8cfda9b7a3f0819ec38acc53f95af67bb26bb.svg",width:"484.4rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e8c983a3efd47356c971fe46add4d0cdf103cced.svg",width:"432.59999999999997rem",height:"60.199999999999996rem"}),React.createElement("p",null,"We're going to do the same trick, to turn ",React.createElement("code",null,"[something · M]")," into ",React.createElement("code",null,"[M · something]"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/a28b6dcc1335de19a065b6a04d8bb45d86122bb7.svg",width:"765.8rem",height:"60.199999999999996rem"}),React.createElement("p",null,"So, our final second curve looks like:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5851c9191acb59456e3706a8f6f1a0f85e691eda.svg",width:"442.4rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0333e63f50b3d43067dc299280f70e9eb98711bb.svg",width:"496.99999999999994rem",height:"60.199999999999996rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/00a133860115d7a4db4ddf62781b5ae2bffef088.svg",width:"516.6rem",height:"60.199999999999996rem"}),React.createElement("p",null,React.createElement("strong",null,React.createElement("em",null,"Nice")),": we see the same as before; can keep the last coordinate the same (which makes sense), our control point becomes a z-ratio mixture of the original control point and the end point, and the new start point is a mixture that looks oddly similar to a bernstein polynomial of degree two, except it uses (z-1) rather than (1-z). These new coordinates are ",React.createElement("em",null,"also")," really easy to compute directly!")),React.createElement("p",null,"So, using linear algebra rather than de Casteljau's algorithm, we have determined that for any quadratic curve split at some value ",React.createElement("code",null,"t = z"),", we get two subcurves that are described as Bézier curves with simple-to-derive coordinates."),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5769f44aea3344c32c497a3a77d236f524222b95.svg",width:"604.8rem",height:"57.4rem"}),React.createElement("p",null,"and"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1fdde935dc357642358bdf5e632d6539c9d4debd.svg",width:"599.1999999999999rem",height:"60.199999999999996rem"}),React.createElement("p",null,"We can do the same for cubic curves. However, I'll spare you the actual derivation (don't let that stop you from writing that out yourself, though) and simply show you the resulting new coordinate sets:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/44db09290062827525a9b23cbaf91e65063d86d7.svg",width:"883.4rem",height:"78.39999999999999rem"}),React.createElement("p",null,"and"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d6b1abe72bac1b55d184f2c4254769404371d06f.svg",width:"886.1999999999999rem",height:"81.19999999999999rem"}),React.createElement("p",null,"So, looking at our matrices, did we really need to compute the second segment matrix? No, we didn't. Actually having one segment's matrix means we implicitly have the other: push the values of each row in the matrix ",React.createElement("strong",null,React.createElement("em",null,"Q"))," to the right, with zeroes getting pushed off the right edge and appearing back on the left, and then flip the matrix vertically. Presto, you just \"calculated\" ",React.createElement("strong",null,React.createElement("em",null,"Q'")),"."),React.createElement("p",null,"Implementing curve splitting this way requires less recursion, and is just straight arithmetic with cached values, so can be cheaper on systems were recursion is expensive. If you're doing computation with devices that are good at matrix multiplication, chopping up a Bézier curve with this method will be a lot faster than applying de Casteljau."));}},"reordering":{"locale":"en-GB","title":"Lowering and elevating curve order","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"reordering",title:"Lowering and elevating curve order",number:"11"}),React.createElement("p",null,"One interesting property of Bézier curves is that an ",React.createElement("em",null,"n",React.createElement("sup",null,"th"))," order curve can always be perfectly represented by an ",React.createElement("em",null,"(n+1)",React.createElement("sup",null,"th"))," order curve, by giving the higher order curve specific control points."),React.createElement("p",null,"If we have a curve with three points, then we can create a four point curve that exactly reproduce the original curve as long as we give it the same start and end points, and for its two control points we pick \"1/3",React.createElement("sup",null,"rd")," start + 2/3",React.createElement("sup",null,"rd")," control\" and \"2/3",React.createElement("sup",null,"rd")," control + 1/3",React.createElement("sup",null,"rd")," end\", and now we have exactly the same curve as before, except represented as a cubic curve, rather than a quadratic curve."),React.createElement("p",null,"The general rule for raising an ",React.createElement("em",null,"n",React.createElement("sup",null,"th"))," order curve to an ",React.createElement("em",null,"(n+1)",React.createElement("sup",null,"th"))," order curve is as follows (observing that the start and end weights are the same as the start and end weights for the old curve):"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c69c811b7fa790fbc7d082f29855b6f66243b454.svg",width:"803.5999999999999rem",height:"64.39999999999999rem"}),React.createElement("p",null,"However, this rule also has as direct consequence that you ",React.createElement("strong",null,"cannot")," generally safely lower a curve from ",React.createElement("em",null,"n",React.createElement("sup",null,"th"))," order to ",React.createElement("em",null,"(n-1)",React.createElement("sup",null,"th"))," order, because the control points cannot be \"pulled apart\" cleanly. We can try to, but the resulting curve will not be identical to the original, and may in fact look completely different."),React.createElement("p",null,"We can apply this to a (semi) random curve, as is done in the following graphic. Select the sketch and press your up and down arrow keys to elevate or lower the curve order."),React.createElement(Graphic,{preset:"simple",title:"A "+handler.getOrder()+" order Bézier curve",setup:handler.setup,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"There is a good, if mathematical, explanation on the matrices necessary for optimal reduction over on ",React.createElement("a",{href:"http://www.sirver.net/blog/2011/08/23/degree-reduction-of-bezier-curves"},"Sirver's Castle"),", which given time will find its way in a more direct description into this article."));}},"derivatives":{"locale":"en-GB","title":"Derivatives","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"derivatives",title:"Derivatives",number:"12"}),React.createElement("p",null,"There's a number of useful things that you can do with Bézier curves based on their derivative, and one of the more amusing observations about Bézier curves is that their derivatives are, in fact, also Bézier curves. In fact, the derivation of a Bézier curve is relatively straight forward, although we do need a bit of math. First, let's look at the derivative rule for Bézier curves, which is:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/17c8e825e1d2ae198cd7c33427870a3cf8ff31a1.svg",width:"350rem",height:"46.199999999999996rem"}),React.createElement("p",null,"which we can also write (observing that ",React.createElement("i",null,"b")," in this formula is the same as our ",React.createElement("i",null,"w")," weights, and that ",React.createElement("i",null,"n")," times a summation is the same as a summation where each term is multiplied by ",React.createElement("i",null,"n"),") as:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/a3a62e074a592e2c6497046261452ef89d1893d3.svg",width:"359.79999999999995rem",height:"46.199999999999996rem"}),React.createElement("p",null,"Or, in plain text: the derivative of an n",React.createElement("sup",null,"th")," degree Bézier curve is an (n-1)",React.createElement("sup",null,"th")," degree Bézier curve, with one fewer term, and new weights w'",React.createElement("sub",null,"0"),"...w'",React.createElement("sub",null,"n-1")," derived from the original weights as n(w",React.createElement("sub",null,"i+1")," - w",React.createElement("sub",null,"i"),"), so for a 3rd degree curve, with four weights, the derivative has three new weights w'",React.createElement("sub",null,"0")," = 3(w",React.createElement("sub",null,"1"),"-w",React.createElement("sub",null,"0"),"), w'",React.createElement("sub",null,"1")," = 3(w",React.createElement("sub",null,"2"),"-w",React.createElement("sub",null,"1"),") and w'",React.createElement("sub",null,"2")," = 3(w",React.createElement("sub",null,"3"),"-w",React.createElement("sub",null,"2"),")."),React.createElement("div",{className:"note"},React.createElement("h3",{id:"-slow-down-why-is-that-true-"},"\"Slow down, why is that true?\""),React.createElement("p",null,"Sometimes just being told \"this is the derivative\" is nice, but you might want to see why this is indeed the case. As such, let's have a look at the proof for this derivative. First off, the weights are independent of the full Bézier function, so the derivative involves only the derivative of the polynomial basis function. So, let's find that:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1f8148ecaac6af494a8bb96d2f96f7a96f85d9e0.svg",width:"219.79999999999998rem",height:"37.8rem"}),React.createElement("p",null,"Applying the ",React.createElement("a",{href:"http://en.wikipedia.org/wiki/Product_rule"},"product")," and ",React.createElement("a",{href:"http://en.wikipedia.org/wiki/Chain_rule"},"chain")," rules gives us:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5dbfaadcef0cb26159cedb26c9c7c54ac008064d.svg",width:"432.59999999999997rem",height:"29.4rem"}),React.createElement("p",null,"Which is hard to work with, so let's expand that properly:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ebfac729364de2cfd10ba3b8b4a6a6c44e7b4578.svg",width:"361.2rem",height:"28rem"}),React.createElement("p",null,"Now, the trick is to turn this expression into something that has binomial coefficients again, so we want to end up with things that look like \"x! over y!(x-y)!\". If we can do that in a way that involves terms of ",React.createElement("i",null,"n-1")," and ",React.createElement("i",null,"k-1"),", we'll be on the right track."),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b2a6fe8fe85ddf02a05f618b9ab12d65cc60cb3c.svg",width:"574rem",height:"79.8rem"}),React.createElement("p",null,"And that's the first part done: the two components inside the parentheses are actually regular, lower order Bezier expressions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/222b5aafd8b8fca6dcfc04ca7ac4248f652752fd.svg",width:"560rem",height:"50.4rem"}),React.createElement("p",null,"Now to apply this to our weighted Bezier curves. We'll write out the plain curve formula that we saw earlier, and then work our way through to its derivative:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e2f7ff20e5f540af4cb96cae56a241f3ea3f52f0.svg",width:"553rem",height:"117.6rem"}),React.createElement("p",null,"If we expand this (with some color to show how terms line up), and reorder the terms by increasing values for ",React.createElement("i",null,"k")," we see the following:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/2505458c9422a6a1dcc59ad2f5b134c1daf0c860.svg",width:"315rem",height:"114.8rem"}),React.createElement("p",null,"Two of these terms fall way: the first term falls away because there is no -1",React.createElement("sup",null,"st")," term in a summation. As such, it always contributes \"nothing\", so we can safely completely ignore it for the purpose of finding the derivative function. The other term is the very last term in this expansion: one involving ",React.createElement("i",null,"B",React.createElement("sub",null,"n-1,n")),". This term would have a binomial coefficient of [",React.createElement("i",null,"i")," choose ",React.createElement("i",null,"i+1"),"], which is a non-existent binomial coefficient. Again, this term would contribute \"nothing\", so we can ignore it, too. This means we're left with:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/f058419c1a80d98e6f74ceaf385a1c4e1fc3c645.svg",width:"309.4rem",height:"74.19999999999999rem"}),React.createElement("p",null,"And that's just a summation of lower order curves:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/08a399ed22fbf888982020848612ab348e4cbfc3.svg",width:"751.8rem",height:"37.8rem"}),React.createElement("p",null,"We can rewrite this as a normal summation, and we're done:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b66421144e6848bbbe434a23b3a7b311ce9ff770.svg",width:"572.5999999999999rem",height:"53.199999999999996rem"})),React.createElement("p",null,"Let's rewrite that in a form similar to our original formula, so we can see the difference. We will first list our original formula for Bézier curves, and then the derivative:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/cc82da74955e71db3f5f0ab77dcc4664c0387bec.svg",width:"369.59999999999997rem",height:"57.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/6c95e389e593152cd24eb52e891db7c7b37c4e97.svg",width:"560rem",height:"61.599999999999994rem"}),React.createElement("p",null,"What are the differences? In terms of the actual Bézier curve, virtually nothing! We lowered the order (rather than ",React.createElement("i",null,"n"),", it's now ",React.createElement("i",null,"n-1"),"), but it's still the same Bézier function. The only real difference is in how the weights change when we derive the curve's function. If we have four points A, B, C, and D, then the derivative will have three points, the second derivative two, and the third derivative one:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/34e8aadefa9d0ee443efe27a1fc76210eedb373c.svg",width:"548.8rem",height:"77rem"}),React.createElement("p",null,"We can keep performing this trick for as long as we have more than one weight. Once we have one weight left, the next step will see ",React.createElement("i",null,"k = 0"),", and the result of our \"Bézier function\" summation is zero, because we're not adding anything at all. As such, a quadratic curve has no second derivative, a cubic curve has no third derivative, and generalized: an ",React.createElement("i",null,"n",React.createElement("sup",null,"th"))," order curve has ",React.createElement("i",null,"n-1")," (meaningful) derivatives, with any further derivative being zero."));}},"pointvectors":{"locale":"en-GB","title":"Tangents and normals","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"pointvectors",title:"Tangents and normals",number:"13"}),React.createElement("p",null,"If you want to move objects along a curve, or \"away from\" a curve, the two vectors you're most interested in are the tangent vector and normal vector for curve points. These are actually really easy to find. For moving, and orienting, along a curve we use the tangent, which indicates the direction travel at specific points, and is literally just the first derivative of our curve:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/2271ae26977a681a1695d14ea8255564e716916e.svg",width:"148.39999999999998rem",height:"42rem"}),React.createElement("p",null,"This gives us the directional vector we want. We can normalize it to give us uniform directional vectors (having a length of 1.0) at each point, and then do whatever it is we want to do based on those directions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3cb2c4f5806142e83c66e1312520d0783d15201c.svg",width:"263.2rem",height:"26.599999999999998rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/72826b8f5053c299dbb2082678191e3564bb50a6.svg",width:"303.79999999999995rem",height:"60.199999999999996rem"}),React.createElement("p",null,"The tangent is very useful for moving along a line, but what if we want to move away from the curve instead, perpendicular to the curve at some point ",React.createElement("i",null,"t"),"? In that case we want the \"normal\" vector. This vector runs at a right angle to the direction of the curve, and is typically of length 1.0, so all we have to do is rotate the normalized directional vector and we're done:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/6cb29c325e059e236343bdd448c149ecc6d8795f.svg",width:"355.59999999999997rem",height:"62.99999999999999rem"}),React.createElement("div",{className:"note"},React.createElement("p",null,"Rotating coordinates is actually very easy, if you know the rule for it. You might find it explained as \"applying a ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Rotation_matrix"},"rotation matrix"),", which is what we'll look at here, too. Essentially, the idea is to take the circles over which we can rotate, and simply \"sliding the coordinates\" over these circles by the desired angle. If we want a quarter circle turn, we take the coordinate, slide it along the cirle by a quarter turn, and done."),React.createElement("p",null,"To turn any point ",React.createElement("i",null,"(x,y)")," into a rotated point ",React.createElement("i",null,"(x',y')")," (over 0,0) by some angle φ, we apply this nicely easy computation:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d3932ac925ad9f238029d888dc5432f6678f6491.svg",width:"191.79999999999998rem",height:"39.199999999999996rem"}),React.createElement("p",null,"Which is the \"long\" version of the following matrix transformation:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7297632eb150a8f5f37178612f71e5d0f2c367b1.svg",width:"221.2rem",height:"42rem"}),React.createElement("p",null,"And that's all we need to rotate any coordinate. Note that for quarter, half and three quarter turns these functions become even easier, since ",React.createElement("em",null,"sin")," and ",React.createElement("em",null,"cos")," for these angles are, respectively: 0 and 1, -1 and 0, and 0 and -1."),React.createElement("p",null,"But ",React.createElement("strong",null,React.createElement("em",null,"why"))," does this work? Why this matrix multiplication? ",React.createElement("a",{href:"http://en.wikipedia.org/wiki/Rotation_matrix#Decomposition_into_shears"},"Wikipedia")," (Technically, Thomas Herter and Klaus Lott) tells us that a rotation matrix can be treated as a sequence of three (elementary) shear operations. When we combine this into a single matrix operation (because all matrix multiplications can be collapsed), we get the matrix that you see above. ",React.createElement("a",{href:"http://datagenetics.com/blog/august32013/index.html"},"DataGenetics")," have an excellent article about this very thing: it's really quite cool, and I strongly recommend taking a quick break from this primer to read that article.")),React.createElement("p",null,"The following two graphics show the tangent and normal along a quadratic and cubic curve, with the direction vector coloured blue, and the normal vector coloured red (the markers are spaced out evenly as ",React.createElement("em",null,"t"),"-intervals, not spaced equidistant)."),React.createElement("div",{className:"figure"},React.createElement(Graphic,{preset:"simple",title:"Quadratic Bézier tangents and normals",inline:true,setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"simple",title:"Cubic Bézier tangents and normals",inline:true,setup:handler.setupCubic,draw:handler.draw})));}},"components":{"locale":"en-GB","title":"Component functions","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"components",title:"Component functions",number:"14"}),React.createElement("p",null,"One of the first things people run into when they start using Bézier curves in their own programs is \"I know how to draw the curve, but how do I determine the bounding box?\". It's actually reasonably straight forward to do so, but it requires having some knowledge on exploiting math to get the values we need. For bounding boxes, we aren't actually interested in the curve itself, but only in its \"extremities\": the minimum and maximum values the curve has for its x- and y-axis values. If you remember your calculus (provided you ever took calculus, otherwise it's going to be hard to remember) we can determine function extremities using the first derivative of that function, but this poses a problem, since our function is parametric: every axis has its own function."),React.createElement("p",null,"The solution: compute the derivative for each axis separately, and then fit them back together in the same way we do for the original."),React.createElement("p",null,"Let's look at how a parametric Bézier curve \"splits up\" into two normal functions, one for the x-axis and one for the y-axis. Note the left-most figure is again an interactive curve, without labeled axes (you get coordinates in the graph instead). The center and right-most figures are the component functions for computing the x-axis value, given a value for ",React.createElement("i",null,"t")," (between 0 and 1 inclusive), and the y-axis value, respectively."),React.createElement("p",null,"If you move points in a curve sideways, you should only see the middle graph change; likely, moving points vertically should only show a change in the right graph."),React.createElement(Graphic,{preset:"simple",title:"Quadratic Bézier curve components",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"simple",title:"Cubic Bézier curve components",setup:handler.setupCubic,draw:handler.draw}));}},"extremities":{"locale":"en-GB","title":"Finding extremities: root finding","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"extremities",title:"Finding extremities: root finding",number:"15"}),React.createElement("p",null,"Now that we understand (well, superficially anyway) the component functions, we can find the extremities of our Bézier curve by finding maxima and minima on the component functions, by solving the equations B'(t) = 0 and B''(t) = 0. Although, in the case of quadratic curves there is no B''(t), so we only need to compute B'(t) = 0. So, how do we compute the first and second derivatives? Fairly easily, actually, until our derivatives are 4th order or higher... then things get really hard. But let's start simple:"),React.createElement("h3",{id:"quadratic-curves-linear-derivatives-"},"Quadratic curves: linear derivatives."),React.createElement("p",null,"Finding the solution for \"where is this line 0\" should be trivial:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/baa66be2d93813bf9ef4aef1dbfac3db772e30e2.svg",width:"138.6rem",height:"109.19999999999999rem"}),React.createElement("p",null,"Done. And quadratic curves have no meaningful second derivative, so we're ",React.createElement("em",null,"really")," done."),React.createElement("h3",{id:"cubic-curves-the-quadratic-formula-"},"Cubic curves: the quadratic formula."),React.createElement("p",null,"The derivative of a cubic curve is a quadratic curve, and finding the roots for a quadratic Bézier curve means we can apply the ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Quadratic_formula"},"Quadratic formula"),". If you've seen it before, you'll remember it, and if you haven't, it looks like this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d5882cc83b002196c8e701ad273ced103e2b4484.svg",width:"431.2rem",height:"42rem"}),React.createElement("p",null,"So, if we can express a Bézier component function as a plain polynomial, we're done: we just plug in the values into the quadratic formula, check if that square root is negative or not (if it is, there are no roots) and then just compute the two values that come out (because of that plus/minus sign we get two). Any value between 0 and 1 is a root that matters for Bézier curves, anything below or above that is irrelevant (because Bézier curves are only defined over the interval [0,1]). So, how do we convert?"),React.createElement("p",null,"First we turn our cubic Bézier function into a quadratic one, by following the rule mentioned at the end of the ",React.createElement("a",{href:"#derivatives"},"derivatives section"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d38fc2ce8c5af65b94b56897b8ae8d304c84a4b7.svg",width:"561.4rem",height:"37.8rem"}),React.createElement("p",null,"And then, using these ",React.createElement("em",null,"v")," values, we can find out what our ",React.createElement("em",null,"a"),", ",React.createElement("em",null,"b"),", and ",React.createElement("em",null,"c")," should be:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/292b2b9178aca5486da7e1a596e66091ba2ed282.svg",width:"330.4rem",height:"124.6rem"}),React.createElement("p",null,"This gives us thee coefficients ",React.createElement("em",null,"a"),", ",React.createElement("em",null,"b"),", and ",React.createElement("em",null,"c")," that are expressed in terms of ",React.createElement("em",null,"v")," values, where the ",React.createElement("em",null,"v")," values are just convenient expressions of our original ",React.createElement("em",null,"p")," values, so we can do some trivial substitution to get:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/2de779b7b9c6aa130b9aeadbb8c46878b94920a1.svg",width:"323.4rem",height:"65.8rem"}),React.createElement("p",null,"Easy peasy. We can now almost trivially find the roots by plugging those values into the quadratic formula. We also note that the second derivative of a cubic curve means computing the first derivative of a quadratic curve, and we just saw how to do that in the section above."),React.createElement("h3",{id:"quartic-curves-cardano-s-algorithm-"},"Quartic curves: Cardano's algorithm."),React.createElement("p",null,"Quartic—fourth degree—curves have a cubic function as derivative. Now, cubic functions are a bit of a problem because they're really hard to solve. But, way back in the 16",React.createElement("sup",null,"th")," century, ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Gerolamo_Cardano"},"Gerolamo Cardano")," figured out that even if the general cubic function is really hard to solve, it can be rewritten to a form for which finding the roots is \"easy\", and then the only hard part is figuring out how to go from that form to the generic form. So:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/a16a0da87e138b1307973397275c296eb475b1b1.svg",width:"478.79999999999995rem",height:"21rem"}),React.createElement("p",null,"This is easier because for the \"easier formula\" we can use ",React.createElement("a",{href:"http://www.wolframalpha.com/input/?i=t^3+%2B+pt+%2B+q"},"regular calculus")," to find the roots (as a cubic function, however, it can have up to three roots, but two of those can be complex. For the purpose of Bézier curve extremities, we can completely ignore those complex roots, since our ",React.createElement("em",null,"t")," is a plain real number from 0 to 1)."),React.createElement("p",null,"So, the trick is to figure out how to turn the first formula into the second formula, and to then work out the maths that gives us the roots. This is explained in detail over at ",React.createElement("a",{href:"http://www.trans4mind.com/personal_development/mathematics/polynomials/cubicAlgebra.htm"},"Ken J. Ward's page")," for solving the cubic equation, so instead of showing the maths, I'm simply going to show the programming code for solving the cubic equation, with the complex roots getting totally ignored."),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"implementing-cardano-s-algorithm-for-finding-all-real-roots"},"Implementing Cardano's algorithm for finding all real roots"),React.createElement("p",null,"The \"real roots\" part is fairly important, because while you cannot take a square, cube, etc. root of a negative number in the \"real\" number space (denoted with ℝ), this is perfectly fine in the ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Complex_number"},"\"complex\" number")," space (denoted with ℂ). And, as it so happens, Cardano is also attributed as the first mathematician in history to have made use of complex numbers in his calculations. For this very algorithm!"),React.createElement("pre",null,"// A helper function to filter for values in the [0,1] interval:\nfunction accept(t) {\n return 0<=t && t <=1;\n}\n\n// A real-cuberoots-only function:\nfunction crt(v) {\n if(v<0) return -Math.pow(-v,1/3);\n return Math.pow(v,1/3);\n}\n\n// Now then: given cubic coordinates {pa, pb, pc, pd} find all roots.\nfunction getCubicRoots(pa, pb, pc, pd) {\n var d = (-pa + 3*pb - 3*pc + pd),\n a = (3*pa - 6*pb + 3*pc) / d,\n b = (-3*pa + 3*pb) / d,\n c = pa / d;\n\n var p = (3*b - a*a)/3,\n p3 = p/3,\n q = (2*a*a*a - 9*a*b + 27*c)/27,\n q2 = q/2,\n discriminant = q2*q2 + p3*p3*p3;\n\n // and some variables we're going to use later on:\n var u1,v1,root1,root2,root3;\n\n // three possible real roots:\n if (discriminant < 0) {\n var mp3 = -p/3,\n mp33 = mp3*mp3*mp3,\n r = sqrt( mp33 ),\n t = -q / (2*r),\n cosphi = t<-1 ? -1 : t>1 ? 1 : t,\n phi = acos(cosphi),\n crtr = cuberoot(r),\n t1 = 2*crtr;\n root1 = t1 * cos(phi/3) - a/3;\n root2 = t1 * cos((phi+2*pi)/3) - a/3;\n root3 = t1 * cos((phi+4*pi)/3) - a/3;\n return [root1, root2, root3].filter(accept);\n }\n\n // three real roots, but two of them are equal:\n if(discriminant === 0) {\n u1 = q2 < 0 ? cuberoot(-q2) : -cuberoot(q2);\n root1 = 2*u1 - a/3;\n root2 = -u1 - a/3;\n return [root1, root2].filter(accept);\n }\n\n // one real root, two complex roots\n var sd = sqrt(discriminant);\n u1 = cuberoot(sd - q2);\n v1 = cuberoot(sd + q2);\n root1 = u1 - v1 - a/3;\n return [root1].filter(accept);\n}\n")),React.createElement("p",null,"And that's it. The maths is complicated, but the code is pretty much just \"follow the maths, while caching as many values as we can to reduce recomputing things as much as possible\" and now we have a way to find all roots for a cubic function and can just move on with using that to find extremities of our curves."),React.createElement("h3",{id:"quintic-and-higher-order-curves-finding-numerical-solutions"},"Quintic and higher order curves: finding numerical solutions"),React.createElement("p",null,"The problem with this is that as the order of the curve goes up, we can't actually solve those equations the normal way. We can't take the function, and then work out what the solutions are. Not to mention that even solving a third order derivative (for a fourth order curve) is already a royal pain in the backside. We need a better solution. We need numerical approaches."),React.createElement("p",null,"That's a fancy word for saying \"rather than solve the function, treat the problem as a sequence of identical operations, the performing of which gets us closer and closer to the real answer\". As it turns out, there is a really nice numerical root finding algorithm, called the ",React.createElement("a",{href:"http://en.wikipedia.org/wiki/Newton-Raphson"},"Newton-Raphson")," root finding method (yes, after ",React.createElement("em",null,React.createElement("a",{href:"https://en.wikipedia.org/wiki/Isaac_Newton"},"that"))," Newton), which we can make use of."),React.createElement("p",null,"The Newton-Raphson approach consists of picking a value ",React.createElement("em",null,"t")," (any will do), and getting the corresponding value at that ",React.createElement("em",null,"t")," value. For normal functions, we can treat that value as a height. If the height is zero, we're done, we have found a root. If it's not, we take the tangent of the curve at that point, and extend it until it passes the x-axis, which will be at some new point ",React.createElement("em",null,"t"),". We then repeat the procedure with this new value, and we keep doing this until we find our root."),React.createElement("p",null,"Mathematically, this means that for some ",React.createElement("em",null,"t"),", at step ",React.createElement("em",null,"n=1"),", we perform the following calculation until ",React.createElement("em",null,"f",React.createElement("sub",null,"y")),"(",React.createElement("em",null,"t"),") is zero, so that the next ",React.createElement("em",null,"t")," is the same as the one we already have:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b563256be7016370365935944308cf878cdbc29c.svg",width:"130.2rem",height:"47.599999999999994rem"}),React.createElement("p",null,"(The wikipedia article has a decent animation for this process, so I'm not adding a sketch for that here unless there are requests for it)"),React.createElement("p",null,"Now, this works well only if we can pick good starting points, and our curve is continuously differentiable and doesn't have oscillations. Glossing over the exact meaning of those terms, the curves we're dealing with conform to those constraints, so as long as we pick good starting points, this will work. So the question is: which starting points do we pick?"),React.createElement("p",null,"As it turns out, Newton-Raphson is so blindingly fast, so we could get away with just not picking: we simply run the algorithm from ",React.createElement("em",null,"t=0")," to ",React.createElement("em",null,"t=1")," at small steps (say, 1/200",React.createElement("sup",null,"th"),") and the result will be all the roots we want. Of course, this may pose problems for high order Bézier curves: 200 steps for a 200",React.createElement("sup",null,"th")," order Bézier curve is going to go wrong, but that's okay: there is no reason, ever, to use Bézier curves of crazy high orders. You might use a fifth order curve to get the \"nicest still remotely workable\" approximation of a full circle with a single Bézier curve, that's pretty much as high as you'll ever need to go."),React.createElement("h3",{id:"in-conclusion-"},"In conclusion:"),React.createElement("p",null,"So now that we know how to do root finding, we can determine the first and second derivative roots for our Bézier curves, and show those roots overlaid on the previous graphics:"),React.createElement(Graphic,{preset:"simple",title:"Quadratic Bézier curve extremities",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"simple",title:"Cubic Bézier curve extremities",setup:handler.setupCubic,draw:handler.draw}));}},"boundingbox":{"locale":"en-GB","title":"Bounding boxes","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"boundingbox",title:"Bounding boxes",number:"16"}),React.createElement("p",null,"If we have the extremities, and the start/end points, a simple for loop that tests for min/max values for x and y means we have the four values we need to box in our curve:"),React.createElement("p",null,React.createElement("em",null,"Computing the bounding box for a Bézier curve"),":"),React.createElement("ol",null,React.createElement("li",null,"Find all ",React.createElement("em",null,"t")," value(s) for the curve derivative's x- and y-roots."),React.createElement("li",null,"Discard any ",React.createElement("em",null,"t")," value that's lower than 0 or higher than 1, because Bézier curves only use the interval [0,1]."),React.createElement("li",null,"Determine the lowest and highest value when plugging the values ",React.createElement("em",null,"t=0"),", ",React.createElement("em",null,"t=1")," and each of the found roots into the original functions: the lowest value is the lower bound, and the highest value is the upper bound for the bounding box we want to construct.")),React.createElement("p",null,"Applying this approach to our previous root finding, we get the following bounding boxes (with all curve extremity points shown on the curve):"),React.createElement(Graphic,{preset:"simple",title:"Quadratic Bézier bounding box",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"simple",title:"Cubic Bézier bounding box",setup:handler.setupCubic,draw:handler.draw}),React.createElement("p",null,"We can construct even nicer boxes by aligning them along our curve, rather than along the x- and y-axis, but in order to do so we first need to look at how aligning works."));}},"aligning":{"locale":"en-GB","title":"Aligning curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"aligning",title:"Aligning curves",number:"17"}),React.createElement("p",null,"While there are an incredible number of curves we can define by varying the x- and y-coordinates for the control points, not all curves are actually distinct. For instance, if we define a curve, and then rotate it 90 degrees, it's still the same curve, and we'll find its extremities in the same spots, just at different draw coordinates. As such, one way to make sure we're working with a \"unique\" curve is to \"axis-align\" it."),React.createElement("p",null,"Aligning also simplifies a curve's functions. We can translate (move) the curve so that the first point lies on (0,0), which turns our ",React.createElement("em",null,"n")," term polynomial functions into ",React.createElement("em",null,"n-1")," term functions. The order stays the same, but we have less terms. Then, we can rotate the curves so that the last point always lies on the x-axis, too, making its coordinate (...,0). This further simplifies the function for the y-component to an ",React.createElement("em",null,"n-2")," term function. For instance, if we have a cubic curve such as this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d253dc7ff011a8ae46f3351975f1d4beedd7a794.svg",width:"499.79999999999995rem",height:"42rem"}),React.createElement("p",null,"Then translating it so that the first coordinate lies on (0,0), moving all ",React.createElement("em",null,"x")," coordinates by -120, and all ",React.createElement("em",null,"y")," coordinates by -160, gives us:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b3ec747086a146c1b2c682afea6b1eae016c9a7a.svg",width:"482.99999999999994rem",height:"42rem"}),React.createElement("p",null,"If we then rotate the curve so that its end point lies on the x-axis, the coordinates (integer-rounded for illustrative purposes here) become:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/fd82fad845da25b074dff33bbc4aa563d5f367a7.svg",width:"474.59999999999997rem",height:"42rem"}),React.createElement("p",null,"If we drop all the zero-terms, this gives us:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b4d6e220358b2d00f0cf516f433fbe5ecb58f25d.svg",width:"386.4rem",height:"42rem"}),React.createElement("p",null,"We can see that our original curve definition has been simplified considerably. The following graphics illustrate the result of aligning our example curves to the x-axis, with the cubic case using the coordinates that were just used in the example formulae:"),React.createElement(Graphic,{preset:"twopanel",title:"Aligning a quadratic curve",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"twopanel",title:"Aligning a cubic curve",setup:handler.setupCubic,draw:handler.draw}));}},"tightbounds":{"locale":"en-GB","title":"Tight boxes","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"tightbounds",title:"Tight boxes",number:"18"}),React.createElement("p",null,"With our knowledge of bounding boxes, and curve alignment, We can now form the \"tight\" bounding box for curves. We first align our curve, recording the translation we performed, \"T\", and the rotation angle we used, \"R\". We then determine the aligned curve's normal bounding box. Once we have that, we can map that bounding box back to our original curve by rotating it by -R, and then translating it by -T. We now have nice tight bounding boxes for our curves:"),React.createElement(Graphic,{preset:"twopanel",title:"Aligning a quadratic curve",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"twopanel",title:"Aligning a cubic curve",setup:handler.setupCubic,draw:handler.draw}),React.createElement("p",null,"These are, strictly speaking, not necessarily the tightest possible bounding boxes. It is possible to compute the optimal bounding box by determining which spanning lines we need to effect a minimal box area, but because of the parametric nature of Bézier curves this is actually a rather costly operation, and the gain in bounding precision is often not worth it. If there is high demand for it, I'll add a section on how to precisely compute the best fit bounding box, but the maths is fairly gruelling and just not really worth spending time on."));}},"inflections":{"locale":"en-GB","title":"Curve inflections","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"inflections",title:"Curve inflections",number:"19"}),React.createElement("p",null,"Now that we know how to align a curve, there's one more thing we can calculate: inflection points. Imagine we have a variable size circle that we can slide up against our curve. We place it against the curve and adjust its radius so that where it touches the curve, the curvatures of the curve and the circle are the same, and then we start to slide the circle along the curve - for quadratic curves, we can always do this without the circle behaving oddly: we might have to change the radius of the circle as we slide it along, but it'll always sit against the same side of the curve."),React.createElement("p",null,"But what happens with cubic curves? Imagine we have an S curve and we place our circle at the start of the curve, and start sliding it along. For a while we can simply adjust the radius and things will be fine, but once we get to the midpoint of that S, something odd happens: the circle \"flips\" from one side of the curve to the other side, in order for the curvatures to keep matching. This is called an inflection, and we can find out where those happen relatively easily."),React.createElement("p",null,"What we need to do is solve a simple equation:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b039194e01b6081628efaf4aa169a4c50fa4aae4.svg",width:"61.599999999999994rem",height:"16.799999999999997rem"}),React.createElement("p",null,"What we're saying here is that given the curvature function ",React.createElement("em",null,"C(t)"),", we want to know for which values of ",React.createElement("em",null,"t")," this function is zero, meaning there is no \"curvature\", which will be exactly at the point between our circle being on one side of the curve, and our circle being on the other side of the curve. So what does ",React.createElement("em",null,"C(t)")," look like? Actually something that seems not too hard:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/297d1e13000b19d351e5884a40909652a2ee83e2.svg",width:"404.59999999999997rem",height:"22.4rem"}),React.createElement("p",null,"So the function ",React.createElement("em",null,"C(t)")," is wholly defined by the first and second derivative functions for the parametric dimensions of our curve. And as already shown, derivatives of Bézier curves are just simpler Bézier curves, with very easy to compute new coefficients, so this should be pretty easy."),React.createElement("p",null,"However as we've seen in the section on aligning, aligning lets us simplify things ",React.createElement("em",null,"a lot"),", by completely removing the contributions of the first coordinate from most mathematical evaluations, and removing the last ",React.createElement("em",null,"y")," coordinate as well by virtue of the last point lying on the x-axis. So, while we can evaluate ",React.createElement("em",null,"C(t) = 0")," for our curve, it'll be much easier to first axis-align the curve and ",React.createElement("em",null,"then")," evalutating the curvature function."),React.createElement("div",{className:"note"},React.createElement("h3",{id:"let-s-derive-the-full-formula-anyway"},"Let's derive the full formula anyway"),React.createElement("p",null,"Of course, before we do our aligned check, let's see what happens if we compute the curvature function without axis-aligning. We start with the first and second derivatives, given our basis functions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e522d174844a5a31f585cc04cab944a3c4593781.svg",width:"631.4rem",height:"74.19999999999999rem"}),React.createElement("p",null,"And of course the same functions for ",React.createElement("em",null,"y"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/57d857282b8c91da5caf94dcfbe85145dbd760a8.svg",width:"418.59999999999997rem",height:"72.8rem"}),React.createElement("p",null,"Asking a computer to now compose the ",React.createElement("em",null,"C(t)")," function for us (and to expand it to a readable form of simple terms) gives us this rather overly complicated set of arithmetic expressions:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e69d797dc67f0bd2d826fcf8c48c22ff5decf23.svg",width:"579.5999999999999rem",height:"102.19999999999999rem"}),React.createElement("p",null,"That is... unwieldy. So, we note that there are a lot of terms that involve multiplications involving x1, y1, and y4, which would all disappear if we axis-align our curve, which is why aligning is a great idea.")),React.createElement("p",null,"Aligning our curve so that three of the eight coefficients become zero, we end up with the following simple term function for ",React.createElement("em",null,"C(t)"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/f61c01094f0de8ca4c7f26a229f0206d54b13930.svg",width:"589.4rem",height:"22.4rem"}),React.createElement("p",null,"That's a lot easier to work with: we see a fair number of terms that we can compute and then cache, giving us the following simplification:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c1e427616a8a2502abf3cf46415971d0df9a273c.svg",width:"534.8rem",height:"77rem"}),React.createElement("p",null,"This is a plain quadratic curve, and we know how to solve ",React.createElement("em",null,"C(t) = 0"),"; we use the quadratic formula:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/368099657b735b0d17becbbe7be915e88e8c04c5.svg",width:"456.4rem",height:"57.4rem"}),React.createElement("p",null,"We can easily compute this value ",React.createElement("em",null,"if")," the descriminator isn't a negative number (because we only want real roots, not complex roots), and ",React.createElement("em",null,"if")," ",React.createElement("em",null,"x")," is not zero, because divisions by zero are rather useless."),React.createElement("p",null,"Taking that into account, we compute ",React.createElement("em",null,"t"),", we disregard any ",React.createElement("em",null,"t")," value that isn't in the Bézier interval [0,1], and we now know at which ",React.createElement("em",null,"t")," value(s) our curve will inflect."),React.createElement(Graphic,{title:"Finding cubic Bézier curve inflections",setup:handler.setupCubic,draw:handler.draw}));}},"canonical":{"locale":"en-GB","title":"Canonical form (for cubic curves)","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"canonical",title:"Canonical form (for cubic curves)",number:"20"}),React.createElement("p",null,"While quadratic curves are relatively simple curves to analyze, the same cannot be said of the cubic curve. As a curvature controlled by more than one control points, it exhibits all kinds of features like loops, cusps, odd colinear features, and up to two inflection points because the curvature can change direction up to three times. Now, knowing what kind of curve we're dealing with means that some algorithms can be run more efficiently than if we have to implement them as generic solvers, so is there a way to determine the curve type without lots of work?"),React.createElement("p",null,"As it so happens, the answer is yes and the solution we're going to look at was presented by Maureen C. Stone from Xerox PARC and Tony D. deRose from the University of Washington in their joint paper ",React.createElement("a",{href:"http://graphics.pixar.com/people/derose/publications/CubicClassification/paper.pdf"},"\"A Geometric Characterization of Parametric Cubic curves\""),". It was published in 1989, and defines curves as having a \"canonical\" form (i.e. a form that all curves can be reduced to) from which we can immediately tell which features a curve will have. So how does it work?"),React.createElement("p",null,"The first observation that makes things work is that if we have a cubic curve with four points, we can apply a linear transformation to these points such that three of the points end up on (0,0), (0,1) and (1,1), with the last point then being \"somewhere\". After applying that transformation, the location of that last point can then tell us what kind of curve we're dealing with. Specifically, we see the following breakdown:"),React.createElement(Graphic,{"static":true,preset:"simple",title:"The canonical curve map",setup:handler.setup,draw:handler.drawBase}),React.createElement("p",null,"This is a fairly funky image, so let's see how it breaks down. We see the three fixed points at (0,0), (0,1) and (1,1), and then the fourth point is somewhere. Depending on where it is, our curve will have certain features. Namely, if the fourth point is..."),React.createElement("ol",null,React.createElement("li",null,"anywhere on and in the red zone, the curve will be self-intersecting, yielding either a cusp or a loop. Anywhere inside the the red zone, this will be a loop. We won't know ",React.createElement("i",null,"where")," that loop is (in terms of ",React.createElement("i",null,"t")," values), but we are guaranteed that there is one."),React.createElement("li",null,"on the left (red) edge, the curve will have a cusp. We again don't know ",React.createElement("em",null,"where"),", just that it has one. This edge is described by the function:")),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ae5a63e86bb367e6266a394962387344d0a92b10.svg",width:"189rem",height:"39.199999999999996rem"}),React.createElement("ol",null,React.createElement("li",null,"on the lower right (pink) edge, the curve will have a loop at t=1, so we know the end coordinate of the curve also lies ",React.createElement("em",null,"on")," the curve. This edge is described by the function:")),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d389fcde05a773be99f84db5fc9ed7ef043bf406.svg",width:"242.2rem",height:"40.599999999999994rem"}),React.createElement("ol",null,React.createElement("li",null,"on the top (blue) edge, the curve will have a loop at t=0, so we know the start coordinate of the curve also lies ",React.createElement("em",null,"on")," the curve. This edge is described by the function:")),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d97181a9d0ada19862a0ff2cebb08bdee00868d7.svg",width:"161rem",height:"39.199999999999996rem"}),React.createElement("ol",null,React.createElement("li",null,"inside the green zone, the curve will have a single inflection, switching concave/convex once."),React.createElement("li",null,"between the red and green zones, the curve has two inflections, meaning its curvature switches between concave/convex form twice."),React.createElement("li",null,"anywhere on the right of the red zone, the curve will have no inflections. It'll just be a well-behaved arch.")),React.createElement("p",null,"Of course, this map is fairly small, but the regions extend to infinity, with well defined boundaries."),React.createElement("div",{className:"note"},React.createElement("h3",{id:"wait-where-do-those-lines-come-from-"},"Wait, where do those lines come from?"),React.createElement("p",null,"Without repeating the paper mentioned at the top of this section, the loop-boundaries come from rewriting the curve into canonical form, and then solving the formulae for which constraints must hold for which possible curve properties. In the paper these functions yield formulae for where you will find cusp points, or loops where we know t=0 or t=1, but those functions are derived for the full cubic expression, meaning they apply to t=-∞ to t=∞... For Bézier curves we only care about the \"clipped interval\" t=0 to t=1, so some of the properties that apply when you look at the curve over an infinite interval simply don't apply to the Bézier curve interval."),React.createElement("p",null,"The right bound for the loop region, indicating where the curve switches from \"having inflections\" to \"having a loop\", for the general cubic curve, is actually mirrored over x=1, but for Bézier curves this right half doesn't apply, so we don't need to pay attention to it. Similarly, the boundaries for t=0 and t=1 loops are also nice clean curves but get \"cut off\" when we only look at what the general curve does over the interval t=0 to t=1."),React.createElement("p",null,"For the full details, head over to the paper and read through sections 3 and 4. If you still remember your high school precalculus, you can probably follow along with this paper, although you might have to read it a few times before all the bits \"click\".")),React.createElement("p",null,"So now the question becomes: how do we manipulate our curve so that it fits this canonical form, with three fixed points, and one \"free\" point? Enter linear algerba. Don't worry, I'll be doing all the math for you, as well as show you what the effect is on our curves, but basically we're going to be using linear algebra, rather than calculus, because \"it's way easier\". Sometimes a calculus approach is very hard to work with, when the equivalent geometrical solution is super obvious."),React.createElement("p",null,"The approach is going to start with a curve that doesn't have all-colinear points (so we need to make sure the points don't all fall on a straight line), and then applying four graphics operations that you will probably have heard of: translation (moving all points by some fixed x- and y-distance), scaling (multiplying all points by some x and y scale factor), and shearing (an operation that turns rectangles into parallelograms)."),React.createElement("p",null,"Step 1: we translate any curve by -p1.x and -p1.y, so that the curve starts at (0,0). We're going to make use of an interesting trick here, by pretending our 2D coordinates are 3D, with the ",React.createElement("i",null,"z")," coordinate simply always being 1. This is an old trick in graphics to overcome the limitations of 2D transformations: without it, we can only turn (x,y) coordinates into new coordinates of the form (ax + by, cx + dy), which means we can't do translation, since that requires we end up with some kind of (x + a, y + b). If we add a bogus ",React.createElement("i",null,"z")," coordinate that is always 1, then we can suddenly add arbitrary values. For example:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/00ca2970fccea8f0883af6db4fbc3a60efd2539d.svg",width:"495.59999999999997rem",height:"57.4rem"}),React.createElement("p",null,"Sweet! ",React.createElement("i",null,"z")," stays 1, so we can effectively ignore it entirely, but we added some plain values to our x and y coordinates. So, if we want to subtract p1.x and p1.y, we use:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1a48a27661f19f066ddd591fb4fc0d553b34c944.svg",width:"477.4rem",height:"60.199999999999996rem"}),React.createElement("p",null,"Running all our coordinates through this transformation gives a new set of coordinates, let's call those ",React.createElement("b",null,"U"),", where the first coordinate lies on (0,0), and the rest is still somewhat free. Our next job is to make sure point 2 ends up lying on the ",React.createElement("i",null,"x=0")," line, so what we want is a transformation matrix that, when we run it, subtracts ",React.createElement("i",null,"x")," from whatever ",React.createElement("i",null,"x")," we currently have. This is called ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Shear_matrix"},"shearing"),", and the typical x-shear matrix and its transformation looks like this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/8e98c870c9d5b60bccf196d29e290f9de6657ce7.svg",width:"204.39999999999998rem",height:"56rem"}),React.createElement("p",null,"So we want some shearing value that, when multiplied by ",React.createElement("i",null,"y"),", yields ",React.createElement("i",null,"-x"),", so our x coordinate becomes zero. That value is simpy ",React.createElement("i",null,"-x/y"),", because ",React.createElement("i",null,"-x/y * y = -x"),". Done:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/585fa88864a98008c15225bdbeb0eb26a4653dab.svg",width:"140rem",height:"70rem"}),React.createElement("p",null,"Now, running this on all our points generates a new set of coordinates, let's call those V, which now have point 1 on (0,0) and point 2 on (0, some-value), and we wanted it at (0,1), so we need to ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Scaling_%28geometry%29"},"do some scaling")," to make sure it ends up at (0,1). Additionally, we want point 3 to end up on (1,1), so we can also scale x to make sure its x-coordinate will be 1 after we run the transform. That means we'll be x-scaling by 1/point3",React.createElement("sub",null,"x"),", and y-scaling by point2",React.createElement("sub",null,"y"),". This is really easy:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/bf9c60b59e6247de3fece63638a8333bdcd068a4.svg",width:"144.2rem",height:"74.19999999999999rem"}),React.createElement("p",null,"Then, finally, this generates a new set of coordinates, let's call those W, of which point 1 lies on (0,0), point 2 lies on (0,1), and point three lies on (1, ...) so all that's left is to make sure point 3 ends up at (1,1) - but we can't scale! Point 2 is already in the right place, and y-scaling would move it out of (0,1) again, so our only option is to y-shear point three, just like how we x-sheared point 2 earlier. In this case, we do the same trick, but with ",React.createElement("code",null,"y/x")," rather than ",React.createElement("code",null,"x/y")," because we're not x-shearing but y-shearing. Additionally, we don't actually want to end up at zero (which is what we did before) so we need to shear towards an offset, in this case 1:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/af412fd7df7faf35973314095ec6bf1cb28a8e34.svg",width:"147rem",height:"68.6rem"}),React.createElement("p",null,"And this generates our final set of four coordinates. Of these, we already know that points 1 through 3 are (0,0), (0,1) and (1,1), and only the last coordinate is \"free\". In fact, given any four starting coordinates, the resulting \"transformation mapped\" coordinate will be:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/66e084e9ee396b8cc40de3d0df9c4658dcd10e14.svg",width:"477.4rem",height:"95.19999999999999rem"}),React.createElement("p",null,"That looks very complex, but notice that every coordinate value is being offset by the initial translation, and a lot of terms in there repeat: it's pretty easy to calculate this fast, since there's so much we can cache and reuse while we compute this mapped coordinate!"),React.createElement("p",null,"First, let's just do that translation step as a \"preprocessing\" operation so we don't have to subtract the values all the time. What does that leave?"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d2dc58a4a6951ff27e5b83fb9be239e2fbe0f7ce.svg",width:"371rem",height:"61.599999999999994rem"}),React.createElement("p",null,"Suddenly things look a lot simpler: the mapped x is fairly straight forward to compute, and we see that the mapped y actually contains the mapped x in its entirety, so we'll have that part already available when we need to evaluate it. In fact, let's pull out all those common factors to see just how simple this is:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ebaea590e50dfce555e8ad2c63682fe9e6285f06.svg",width:"428.4rem",height:"42rem"}),React.createElement("p",null,"That's kind of super-simple to write out in code, I think you'll agree. Coding math tends to be easier than the formulae initially make it look!"),React.createElement("div",{className:"note"},React.createElement("h3",{id:"how-do-you-track-all-that-"},"How do you track all that?"),React.createElement("p",null,"Doing maths can be a pain, so whenever possible, I like to make computers do the work for me. Especially for things like this, I simply use ",React.createElement("a",{href:"http://www.wolfram.com/mathematica"},"Mathematica"),". Tracking all this math by hand is insane, and we invented computers, literally, to do this for us. I have no reason to use pen and paper when I can write out what I want to do in a program, and have the program do the math for me. And real math, too, with symbols, not with numbers. In fact, ",React.createElement("a",{href:"http://pomax.github.io/gh-weblog/downloads/canonical-curve.nb"},"here's")," the Mathematica notebook if you want to see how this works for yourself."),React.createElement("p",null,"Now, I know, you're thinking \"but Mathematica is super expensive!\" and that's true, it's ",React.createElement("a",{href:"http://www.wolfram.com/mathematica-home-edition"},"$295 for home use"),", but it's ",React.createElement("strong",null,"also")," ",React.createElement("a",{href:"http://www.wolfram.com/raspberry-pi"},"free when you buy a $35 raspberry pi"),". Obviously, I bought a raspberry pi, and I encourage you to do the same. With that, as long as you know what you want to ",React.createElement("em",null,"do"),", Mathematica can just do it for you. And we don't have to be geniusses to work out what the maths looks like. That's what we have computers for.")),React.createElement("p",null,"So, let's write up a sketch that'll show us the canonical form for any curve drawn in blue, overlaid on our canonical map, so that we can immediately tell which features our curve must have, based on where the fourth coordinate is located on the map:"),React.createElement(Graphic,{preset:"simple",title:"A cubic curve mapped to canonical form",setup:handler.setup,draw:handler.draw}));}},"arclength":{"locale":"en-GB","title":"Arc length","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"arclength",title:"Arc length",number:"21"}),React.createElement("p",null,"How long is a Bézier curve? As it turns out, that's not actually an easy question, because the answer requires maths that —much like root finding— cannot generally be solved the traditional way. If we have a parametric curve with ",React.createElement("em",null,"f",React.createElement("sub",null,"x"),"(t)")," and ",React.createElement("em",null,"f",React.createElement("sub",null,"y"),"(t)"),", then the length of the curve, measured from start point to some point ",React.createElement("em",null,"t = z"),", is computed using the following seemingly straight forward (if a bit overwhelming) formula:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/16e3f81dfc12c526ca53b477b2aa67ef7b56bfe2.svg",width:"147rem",height:"35rem"}),React.createElement("p",null,"or, more commonly written using Leibnitz notation as:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/8e2857c32b23969bca67b0ead318493a3e61dc4a.svg",width:"257.59999999999997rem",height:"36.4rem"}),React.createElement("p",null,"This formula says that the length of a parametric curve is in fact equal to the ",React.createElement("strong",null,"area")," underneath a function that looks a remarkable amount like Pythagoras' rule for computing the diagonal of a straight angled triangle. This sounds pretty simple, right? Sadly, it's far from simple... cutting straight to after the chase is over: for quadratic curves, this formula generates an ",React.createElement("a",{href:"http://www.wolframalpha.com/input/?i=antiderivative+for+sqrt%28%282*%281-t%29*t*B+%2B+t%5E2*C%29%27%5E2+%2B+%282*%281-t%29*t*E%29%27%5E2%29&incParTime=true"},"unwieldy computation"),", and we're simply not going to implement things that way. For cubic Bézier curves, things get even more fun, because there is no \"closed form\" solution, meaning that due to the way calculus works, there is no generic formula that allows you to calculate the arc length. Let me just repeat this, because it's fairly crucial: ",React.createElement("strong",null,React.createElement("em",null,"for cubic and higher Bézier curves, there is no way to solve this function if you want to use it \"for all possible coordinates\"")),"."),React.createElement("p",null,"Seriously: ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Abel%E2%80%93Ruffini_theorem"},"It cannot be done"),"."),React.createElement("p",null,"So we turn to numerical approaches again. The method we'll look at here is the ",React.createElement("a",{href:"http://www.youtube.com/watch?v=unWguclP-Ds&feature=BFa&list=PLC8FC40C714F5E60F&index=1"},"Gauss quadrature"),". This approximation is a really neat trick, because for any ",React.createElement("em",null,"n",React.createElement("sup",null,"th"))," degree polynomial it finds approximated values for an integral really efficiently. Explaining this procedure in length is way beyond the scope of this page, so if you're interested in finding out why it works, I can recommend the University of South Florida video lecture on the procedure, linked in this very paragraph. The general solution we're looking for is the following:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e6a8d7d5f1742bb926c0c992d2b89c71090edbf4.svg",width:"576.8rem",height:"74.19999999999999rem"}),React.createElement("p",null,"In plain text: an integral function can always be treated as the sum of an (infinite) number of (infinitely thin) rectangular strips sitting \"under\" the function's plotted graph. To illustrate this idea, the following graph shows the integral for a sinoid function. The more strips we use (and of course the more we use, the thinner they get) the closer we get to the true area under the curve, and thus the better the approximation:"),React.createElement("div",{className:"figure"},React.createElement(Graphic,{inline:true,"static":true,preset:"empty",title:"A function's approximated integral",setup:handler.setup,draw:handler.drawCoarseIntegral}),React.createElement(Graphic,{inline:true,"static":true,preset:"empty",title:"A better approximation",setup:handler.setup,draw:handler.drawFineIntegral}),React.createElement(Graphic,{inline:true,"static":true,preset:"empty",title:"An even better approximation",setup:handler.setup,draw:handler.drawSuperFineIntegral})),React.createElement("p",null,"Now, infinitely many terms to sum and infinitely thin rectangles are not something that computers can work with, so instead we're going to approximate the infinite summation by using a sum of a finite number of \"just thin\" rectangular strips. As long as we use a high enough number of thin enough rectangular strips, this will give us an approximation that is pretty close to what the real value is."),React.createElement("p",null,"So, the trick is to come up with useful rectangular strips. A naive way is to simply create ",React.createElement("em",null,"n")," strips, all with the same width, but there is a far better way using special values for ",React.createElement("em",null,"C")," and ",React.createElement("em",null,"f(t)")," depending on the value of ",React.createElement("em",null,"n"),", which indicates how many strips we'll use, and it's called the Legendre-Gauss quadrature."),React.createElement("p",null,"This approach uses strips that are ",React.createElement("em",null,"not")," spaced evenly, but instead spaces them in a special way that works remarkably well. If you look at the earlier sinoid graphic, you could imagine that we could probably get a result similar to the one with 99 strips if we used fewer strips, but spaced them so that the steeper the curve is, the thinner we make the strip, and conversely, the flatter the curve is (especially near the tops of the function), the wider we make the strip. That's akin to how the Legendre values work."),React.createElement("div",{className:"note"},React.createElement("p",null,"Note that one requirement for the approach we'll use is that the integral must run from -1 to 1. That's no good, because we're dealing with Bézier curves, and the length of a section of curve applies to values which run from 0 to \"some value smaller than or equal to 1\" (let's call that value ",React.createElement("em",null,"z"),"). Thankfully, we can quite easily transform any integral interval to any other integral interval, by shifting and scaling the inputs. Doing so, we get the following:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/631e6396082d9621472546b87c2e27065990d568.svg",width:"358.4rem",height:"75.6rem"}),React.createElement("p",null,"That may look a bit more complicated, but the fraction involving ",React.createElement("em",null,"z")," is a fixed number, so the summation, and the evaluation of the ",React.createElement("em",null,"f(t)")," values are still pretty simple."),React.createElement("p",null,"So, what do we need to perform this calculation? For one, we'll need an explicit formula for ",React.createElement("em",null,"f(t)"),", because that derivative notation is handy on paper, but not when we have to implement it. We'll also need to know what these ",React.createElement("em",null,"C",React.createElement("sub",null,"i"))," and ",React.createElement("em",null,"t",React.createElement("sub",null,"i"))," values should be. Luckily, that's less work because there are actually many tables available that give these values, for any ",React.createElement("em",null,"n"),", so if we want to approximate our integral with only two terms (which is a bit low, really) then ",React.createElement("a",{href:"legendre-gauss.html"},"these tables")," would tell us that for ",React.createElement("em",null,"n=2")," we must use the following values:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/6dc4299695f03c27c362e7faf47ae4474794809e.svg",width:"65.8rem",height:"98rem"}),React.createElement("p",null,"Which means that in order for us to approximate the integral, we must plug these values into the approximate function, which gives us:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/fe54606651e308caf83a65e53bc4d6104f8a4ee1.svg",width:"499.79999999999995rem",height:"46.199999999999996rem"}),React.createElement("p",null,"We can program that pretty easily, provided we have that ",React.createElement("em",null,"f(t)")," available, which we do, as we know the full description for the Bézier curve functions B",React.createElement("sub",null,"x"),"(t) and B",React.createElement("sub",null,"y"),"(t).")),React.createElement("p",null,"If we use the Legendre-Gauss values for our ",React.createElement("em",null,"C")," values (thickness for each strip) and ",React.createElement("em",null,"t")," values (location of each strip), we can determine the approximate length of a Bézier curve by computing the Legendre-Gauss sum. The following graphic shows a cubic curve, with its computed lengths; Go ahead and change the curve, to see how its length changes. One thing worth trying is to see if you can make a straight line, and see if the length matches what you'd expect. What if you form a line with the control points on the outside, and the start/end points on the inside?"),React.createElement(Graphic,{preset:"simple",title:"Arc length for a Bézier curve",setup:handler.setupCurve,draw:handler.drawCurve}));}},"arclengthapprox":{"locale":"en-GB","title":"Approximated arc length","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"arclengthapprox",title:"Approximated arc length",number:"22"}),React.createElement("p",null,"Sometimes, we don't actually need the precision of a true arc length, and we can get away with simply computing the approximate arc length instead. The by far fastest way to do this is to flatten the curve and then simply calculate the linear distance from point to point. This will come with an error, but this can be made arbitrarily small by increasing the segment count."),React.createElement("p",null,"If we combine the work done in the previous sections on curve flattening and arc length computation, we can implement these with minimal effort:"),React.createElement(Graphic,{preset:"twopanel",title:"Approximate quadratic curve arc length",setup:handler.setupQuadratic,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement(Graphic,{preset:"twopanel",title:"Approximate cubic curve arc length",setup:handler.setupCubic,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"Try clicking on the sketch and using your up and down arrow keys to lower the number of segments for both the quadratic and cubic curve. You may notice that the error in length is actually pretty significant, even if the percentage is fairly low: if the number of segments used yields an error of 0.1% or higher, the flattened curve already looks fairly obviously flattened. And of course, the longer the curve, the more significant the error will be."));}},"tracing":{"locale":"en-GB","title":"Tracing a curve at fixed distance intervals","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"tracing",title:"Tracing a curve at fixed distance intervals",number:"23"}),React.createElement("p",null,"Say you want to draw a curve with a dashed line, rather than a solid line, or you want to move something along the curve at fixed distance intervals over time, like a train along a track, and you want to use Bézier curves."),React.createElement("p",null,"Now you have a problem."),React.createElement("p",null,"The reason you have a problem is that Bézier curves are parametric functions with non-linear behaviour, whereas moving a train along a track is about as close to a practical example of linear behaviour as you can get. The problem we're faced with is that we can't just pick ",React.createElement("em",null,"t")," values at some fixed interval and expect the Bézier functions to generate points that are spaced a fixed distance apart. In fact, let's look at the relation between \"distance long a curve\" and \"",React.createElement("em",null,"t")," value\", by plotting them against one another."),React.createElement("p",null,"The following graphic shows a particularly illustrative curve, and it's length-to-t plot. For linear traversal, this line needs to be straight, running from (0,0) to (length,1). This is, it's safe to say, not what we'll see, we'll see something wobbly instead. To make matters even worse, the length-to-",React.createElement("em",null,"t")," function is also of a much higher order than our curve is: while the curve we're using for this exercise is a cubic curve, which can switch concave/convex form once at best, the plot shows that the distance function along the curve is able to switch forms three times (to see this, try creating an S curve with the start/end close together, but the control points far apart)."),React.createElement(Graphic,{preset:"twopanel",title:"The t-for-distance function",setup:handler.setup,draw:handler.plotOnly}),React.createElement("p",null,"We see a function that might be invertible, but we won't be able to do so, symbolically. You may remember from the section on arc length that we cannot actually compute the true arc length function as an expression of ",React.createElement("em",null,"t"),", which means we also can't compute the true inverted function that gives ",React.createElement("em",null,"t")," as an expression of length. So how do we fix this?"),React.createElement("p",null,"One way is to do what the graphic does: simply run through the curve, determine its ",React.createElement("em",null,"t"),"-for-length values as a set of discrete values at some high resolution (the graphic uses 100 discrete points), and then use those as a basis for finding an appropriate ",React.createElement("em",null,"t")," value, given a distance along the curve. This works quite well, actually, and is fairly fast."),React.createElement("p",null,"We can use some colour to show the difference between distance-based and time based intervals: the following graph is similar to the previous one, except it segments the curve in terms of equal-distance intervals. This shows as regular colour intervals going down the graph, but the mapping to ",React.createElement("em",null,"t")," values is not linear, so there will be (highly) irregular intervals along the horizontal axis. It also shows the curve in an alternating colouring based on the t-for-distance values we find our LUT:"),React.createElement(Graphic,{preset:"threepanel",title:"Fixed-interval coloring a curve",setup:handler.setup,draw:handler.drawColoured,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"Use your up and down arrow keys to increase or decrease the number of equidistant segments used to colour the curve."),React.createElement("p",null,"However, are there better ways? One such way is discussed in \"",React.createElement("a",{href:"http://www.geometrictools.com/Documentation/MovingAlongCurveSpecifiedSpeed.pdf"},"Moving Along a Curve with Specified Speed"),"\" by David Eberly of Geometric Tools, LLC, but basically because we have no explicit length function (or rather, one we don't have to constantly compute for different intervals), you may simply be better off with a traditional lookup table (LUT)."));}},"intersections":{"locale":"en-GB","title":"Intersections","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"intersections",title:"Intersections",number:"24"}),React.createElement("p",null,"Let's look at some more things we will want to do with Bézier curves. Almost immediately after figuring out how to get bounding boxes to work, people tend to run into the problem that even though the minimal bounding box (based on rotation) is tight, it's not sufficient to perform true collision detection. It's a good first step to make sure there ",React.createElement("em",null,"might")," be a collision (if there is no bounding box overlap, there can't be one), but in order to do real collision detection we need to know whether or not there's an intersection on the actual curve."),React.createElement("p",null,"We'll do this in steps, because it's a bit of a journey to get to curve/curve intersection checking. First, let's start simple, by implementing a line-line intersection checker. While we can solve this the traditional calculus way (determine the functions for both lines, then compute the intersection by equating them and solving for two unknowns), linear algebra actually offers a nicer solution."),React.createElement("h3",{id:"line-line-intersections"},"Line-line intersections"),React.createElement("p",null,"if we have two line segments with two coordinates each, segments A-B and C-D, we can find the intersection of the lines these segments are an intervals on by linear algebra, using the procedure outlined in this ",React.createElement("a",{href:"http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=geometry2#line_line_intersection"},"top coder")," article. Of course, we need to make sure that the intersection isn't just on the lines our line segments lie on, but also on our line segments themselves, so after we find the intersection we need to verify it lies without the bounds of our original line segments."),React.createElement("p",null,"The following graphic implements this intersection detection, showing a red point for an intersection on the lines our segments lie on (thus being a virtual intersection point), and a green point for an intersection that lies on both segments (being a real intersection point)."),React.createElement(Graphic,{preset:"simple",title:"Line/line intersections",setup:handler.setupLines,draw:handler.drawLineIntersection}),React.createElement("div",{className:"howtocode"},React.createElement("h3",{id:"implementing-line-line-intersections"},"Implementing line-line intersections"),React.createElement("p",null,"Let's have a look at how to implement a line-line intersection checking function. The basics are covered in the article mentioned above, but sometimes you need more function signatures, because you might not want to call your function with eight distinct parameters. Maybe you're using point structs or the line. Let's get coding:"),React.createElement("pre",null,"lli8 = function(x1,y1,x2,y2,x3,y3,x4,y4):\n var nx=(x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4),\n ny=(x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4),\n d=(x1-x2)*(y3-y4)-(y1-y2)*(x3-x4);\n if d=0:\n return false\n return point(nx/d, ny/d)\n\nlli4 = function(p1, p2, p3, p4):\n var x1 = p1.x, y1 = p1.y,\n x2 = p2.x, y2 = p2.y,\n x3 = p3.x, y3 = p3.y,\n x4 = p4.x, y4 = p4.y;\n return lli8(x1,y1,x2,y2,x3,y3,x4,y4)\n\nlli = function(line1, line2):\n return lli4(line1.p1, line1.p2, line2.p1, line2.p2)\n")),React.createElement("h3",{id:"what-about-curve-line-intersections-"},"What about curve-line intersections?"),React.createElement("p",null,"Curve/line intersection is more work, but we've already seen the techniques we need to use in order to perform it: first we translate/rotate both the line and curve together, in such a way that the line coincides with the x-axis. This will position the curve in a way that makes it cross the line at points where its y-function is zero. By doing this, the problem of finding intersections between a curve and a line has now become the problem of performing root finding on our translated/rotated curve, as we already covered in the section on finding extremities."),React.createElement(Graphic,{preset:"simple",title:"Quadratic curve/line intersections",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"simple",title:"Cubic curve/line intersections",setup:handler.setupCubic,draw:handler.draw}),React.createElement("p",null,"Curve/curve intersection, however, is more complicated. Since we have no straight line to align to, we can't simply align one of the curves and be left with a simple procedure. Instead, we'll need to apply two techniques we've not covered yet: de Casteljau's algorithm, and curve splitting."));}},"curveintersection":{"locale":"en-GB","title":"Curve/curve intersection","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"curveintersection",title:"Curve/curve intersection",number:"25"}),React.createElement("p",null,"Using de Casteljau's algorithm to split the curve we can now implement curve/curve intersection finding using a \"divide and conquer\" technique:"),React.createElement("ul",null,React.createElement("li",null,"Take two curves ",React.createElement("em",null,"C",React.createElement("sub",null,"1"))," and ",React.createElement("em",null,"C",React.createElement("sub",null,"2")),", and treat them as a pair."),React.createElement("li",null,"If their bounding boxes overlap, split up each curve into two sub-curves"),React.createElement("li",null,"With ",React.createElement("em",null,"C",React.createElement("sub",null,"1.1")),", ",React.createElement("em",null,"C",React.createElement("sub",null,"1.2")),", ",React.createElement("em",null,"C",React.createElement("sub",null,"2.1"))," and ",React.createElement("em",null,"C",React.createElement("sub",null,"2.2")),", form four new pairs (",React.createElement("em",null,"C",React.createElement("sub",null,"1.1")),",",React.createElement("em",null,"C",React.createElement("sub",null,"2.1")),"), (",React.createElement("em",null,"C",React.createElement("sub",null,"1.1")),", ",React.createElement("em",null,"C",React.createElement("sub",null,"2.2")),"), (",React.createElement("em",null,"C",React.createElement("sub",null,"1.2")),",",React.createElement("em",null,"C",React.createElement("sub",null,"2.1")),"), and (",React.createElement("em",null,"C",React.createElement("sub",null,"1.2")),",",React.createElement("em",null,"C",React.createElement("sub",null,"2.2")),")."),React.createElement("li",null,"For each pair, check whether their bounding boxes overlap.",React.createElement("ul",null,React.createElement("li",null,"If their bounding boxes do not overlap, discard the pair, as there is no intersection between this pair of curves."),React.createElement("li",null,"If there ",React.createElement("em",null,"is")," overlap, rerun all steps for this pair."))),React.createElement("li",null,"Once the sub-curves we form are so small that they effectively occupy sub-pixel areas, we consider an intersection found.")),React.createElement("p",null,"This algorithm will start with a single pair, \"balloon\" until it runs in parallel for a large number of potential sub-pairs, and then taper back down as it homes in on intersection coordinates, ending up with as many pairs as there are intersections."),React.createElement("p",null,"The following graphic applies this algorithm to a pair of cubic curves, one step at a time, so you can see the algorithm in action. Click the button to run a single step in the algorithm, after setting up your curves in some creative arrangement. The algorithm resets once it's found a solution, so you can try this with lots of different curves (can you find the configuration that yields the maximum number of intersections between two cubic curves? Nine intersections!)"),React.createElement(Graphic,{preset:"clipping",title:"Curve/curve intersections",setup:handler.setup,draw:handler.draw},"\\t",React.createElement("button",{onClick:handler.stepUp},"advance one step")),React.createElement("p",null,"Self-intersection is dealt with in the same way, except we turn a curve into two or more curves first based on the inflection points. We then form all possible curve pairs with the resultant segments, and run exactly the same algorithm. All non-overlapping curve pairs will be removed after the first iteration, and the remaining steps home in on the curve's self-intersection points."));}},"abc":{"locale":"en-GB","title":"The projection identity","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"abc",title:"The projection identity",number:"26"}),React.createElement("p",null,"De Casteljau's algorithm is the pivotal algorithm when it comes to Bézier curves. You can use it not just to split curves, but also to draw them efficiently (especially for high-order Bézier curves), as well as to come up with curves based on three points and a tangent. Particularly this last thing is really useful because it lets us \"mould\" a curve, by picking it up at some point, and dragging that point around to change the curve's shape."),React.createElement("p",null,"How does that work? Succinctly: we run de Casteljau's algorithm in reverse!"),React.createElement("p",null,"In order to run de Casteljau's algorithm in reverse, we need a few basic things: a start and end point, a point on the curve that want to be moving around, which has an associated ",React.createElement("em",null,"t")," value, and a point we've not explicitly talked about before, and as far as I know has no explicit name, but lives one iteration higher in the de Casteljau process then our on-curve point does. I like to call it \"A\" for reasons that will become obvious."),React.createElement("p",null,"So let's use graphics instead of text to see where this \"A\" is, because text only gets us so far: in the following graphic, click anywhere on the curves to see the identity information that we'll be using to run de Casteljau in reverse (you can manipulate the curve even after picking a point. Note the \"ratio\" value when you do so: does it change?):"),React.createElement("div",{className:"figure"},React.createElement(Graphic,{inline:true,preset:"abc",title:"Projections in a quadratic Bézier curve",setup:handler.setupQuadratic,draw:handler.draw,onClick:handler.onClick}),React.createElement(Graphic,{inline:true,preset:"abc",title:"Projections in a cubic Bézier curve",setup:handler.setupCubic,draw:handler.draw,onClick:handler.onClick})),React.createElement("p",null,"Clicking anywhere on the curves shows us three things:"),React.createElement("ol",null,React.createElement("li",null,"our on-curve point; let's call that ",React.createElement("b",null,"B"),","),React.createElement("li",null,"a point at the tip of B's \"hat\", on de Casteljau step up; let's call that ",React.createElement("b",null,"A"),", and"),React.createElement("li",null,"a point that we get by projecting B onto the start--end baseline; let's call that ",React.createElement("b",null,"C"),".")),React.createElement("p",null,"These three values ABC hide an important identity formula for quadratic and cubic Bézier curves: for any point on the curve with some ",React.createElement("em",null,"t")," value, the ratio distance of C along baseline is fixed: if some ",React.createElement("em",null,"t")," value sets up a C that is 20% away from the start and 80% away from the end, then it doesn't matter where the start, end, or control points are: for that ",React.createElement("em",null,"t")," value, C will ",React.createElement("em",null,"always")," lie at 20% from the start and 80% from the end point. Go ahead, pick an on-curve point in either graphic and then move all the other points around: if you only move the control points, start and end won't move, and so neither will C, and if you move either start or end point, C will move but its relative position will not change. The following function stays true:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/f48f095d9c37c079ff6a5f71b3047397aa7dfc6b.svg",width:"207.2rem",height:"16.799999999999997rem"}),React.createElement("p",null,"So that just leaves finding A."),React.createElement("div",{className:"note"},React.createElement("p",null,"While that relation is fixed, the function ",React.createElement("em",null,"u(t)")," differs depending on whether we're working with quadratic or cubic curves:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/cb35e42bf53bfc2b96f959e78256da01f8b91dbc.svg",width:"207.2rem",height:"91rem"}),React.createElement("p",null,"So, if we know the start and end coordinates, and we know the ",React.createElement("em",null,"t")," value, we know C:"),React.createElement("div",{className:"figure"},React.createElement(Graphic,{inline:true,preset:"abc",title:"Quadratic value of C for t",draw:handler.drawQCT,onMouseMove:handler.setCT}),React.createElement(Graphic,{inline:true,preset:"abc",title:"Cubic value of C for t",draw:handler.drawCCT,onMouseMove:handler.setCT})),React.createElement("p",null,"Mouse-over the graphs to see the expression for C, given the ",React.createElement("em",null,"t")," value at the mouse pointer.")),React.createElement("p",null,"There's also another important bit of information that is inherent to the ABC values: while the distances between A and B, and B and C, are dynamic (based on where we put B), the ",React.createElement("em",null,"ratio")," between the two distances is stable: given some ",React.createElement("em",null,"t")," value, the following always holds:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/6cb3e94fe9164128a25570a32abed15baa726f17.svg",width:"263.2rem",height:"40.599999999999994rem"}),React.createElement("p",null,"This leads to a pretty powerful bit of knowledge: merely by knowing the ",React.createElement("em",null,"t")," value of some on curve point, we know where C has to be (as per the above note), and because we know B and C, and thus have the distance between them, we know where A has to be:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1dffb79b42799c95c899e689b074361f662ec807.svg",width:"228.2rem",height:"39.199999999999996rem"}),React.createElement("p",null,"And that's it, all values found."),React.createElement("div",{className:"note"},React.createElement("p",null,"Much like the ",React.createElement("em",null,"u(t)")," function in the above note, the ",React.createElement("em",null,"ratio(t)")," function depends on whether we're looking at quadratic or cubic curves. Their form is intrinsically related to the ",React.createElement("em",null,"u(t)")," function in that they both come rolling out of the same function evalution, explained over on ",React.createElement("a",{href:"http://mathoverflow.net/questions/122257/finding-the-formula-for-Bézier-curve-ratios-hull-point-point-baseline"},"MathOverflow")," by Boris Zbarsky and myself. The ratio functions are the \"s(t)\" functions from the answers there, while the \"u(t)\" functions have the same name both here and on MathOverflow."),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7ef64890f95db9e48258edb46a3d52d5ed143155.svg",width:"257.59999999999997rem",height:"43.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5f2bb71795c615637d632da70b722938cb103b03.svg",width:"233.79999999999998rem",height:"43.4rem"}),React.createElement("p",null,"Unfortunately, this trick only works for quadratic and cubic curves. Once we hit higher order curves, things become a lot less predictable; the \"fixed point ",React.createElement("em",null,"C"),"\" is no longer fixed, moving around as we move the control points, and projections of ",React.createElement("em",null,"B")," onto the line between start and end may actually lie on that line before the start, or after the end, and there are no simple ratios that we can exploit.")),React.createElement("p",null,"So: if we know B and its corresponding ",React.createElement("em",null,"t")," value, then we know all the ABC values, which —together with a start and end coordinate— gives us the necessary information to reconstruct a curve's \"de Casteljau skeleton\", which means that two points and a value between 0 and 1, we can come up with a curve. And that opens up possibilities: curve manipulation by dragging an on-curve point, curve fitting of \"a bunch of coordinates\", these are useful things, and we'll look at both in the next sections."));}},"moulding":{"locale":"en-GB","title":"Manipulating a curve","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"moulding",title:"Manipulating a curve",number:"27"}),React.createElement("p",null,"Armed with knowledge of the \"ABC\" relation, we can now update a curve interactively, by letting people click anywhere on the curve, find the ",React.createElement("em",null,"t"),"-value matching that coordinate, and then letting them drag that point around. With every drag update we'll have a new point \"B\", which we can combine with the fixed point \"C\" to find our new point A. Once we have those, we can reconstruct the de Casteljau skeleton and thus construct a new curve with the same start/end points as the original curve, passing through the user-selected point B, with correct new control points."),React.createElement(Graphic,{preset:"moulding",title:"Moulding a quadratic Bézier curve",setup:handler.setupQuadratic,draw:handler.drawMould,onClick:handler.placeMouldPoint,onMouseDown:handler.markQB,onMouseDrag:handler.dragQB,onMouseUp:handler.saveCurve}),React.createElement("p",null,React.createElement("strong",null,"Click-dragging the curve itself")," shows what we're using to compute the new coordinates: while dragging you will see the original points B and its corresponding ",React.createElement("i",null,"t"),"-value, the original point C for that ",React.createElement("i",null,"t"),"-value, as well as the new point B' based on the mouse cursor. Since we know the ",React.createElement("i",null,"t"),"-value for this configuration, we can compute the ABC ratio for this configuration, and we know that our new point A' should like at a distance:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/e361e1235c94bbe87e95834c7fcfb6ab96e028b9.svg",width:"226.79999999999998rem",height:"37.8rem"}),React.createElement("p",null,"For quadratic curves, this means we're done, since the new point A' is equivalent to the new quadratic control point. For cubic curves, we need to do a little more work:"),React.createElement(Graphic,{preset:"moulding",title:"Moulding a cubic Bézier curve",setup:handler.setupCubic,draw:handler.drawMould,onClick:handler.placeMouldPoint,onMouseDown:handler.markCB,onMouseDrag:handler.dragCB,onMouseUp:handler.saveCurve}),React.createElement("p",null,"To help understand what's going on, the cubic graphic shows the full de Casteljau construction \"hull\" when repositioning point B. We compute A` in exactly the same way as before, but we also record the final strut line that forms B in the original curve. Given A', B', and the endpoints e1 and e2 of the strut line relative to B', we can now compute where the new control points should be. Remember that B' lies on line e1--e2 at a distance ",React.createElement("i",null,"t"),", because that's how Bézier curves work. In the same manner, we know the distance A--e1 is only line-interval [0,t] of the full segment, and A--e2 is only line-interval [t,1], so constructing the new control points is fairly easy."),React.createElement("p",null,"First, we construct the one-level-of-de-Casteljau-up points:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1833383a4800c495451abcacc2ada34e5601995d.svg",width:"140rem",height:"78.39999999999999rem"}),React.createElement("p",null,"And then we can compute the new control points:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d53cad094fddaacbb047c9d7c465a5011e3bfbfd.svg",width:"163.79999999999998rem",height:"78.39999999999999rem"}),React.createElement("p",null,"And that's cubic curve manipulation."));}},"pointcurves":{"locale":"en-GB","title":"Creating a curve from three points","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"pointcurves",title:"Creating a curve from three points",number:"28"}),React.createElement("p",null,"Given the preceding section on curve manipulation, we can also generate quadratic and cubic curves from any three points. However, unlike circle-fitting, which requires just three points, Bézier curve fitting requires three points, as well as a ",React.createElement("em",null,"t")," value, so we can figure out where point 'C' needs to be."),React.createElement("p",null,"The following graphic lets you place three points, and will use the preceding sections on the ABC ratio and curve construction to form a quadratic curve through them. You can move the points you've placed around by click-dragging, or try a new curve by drawing new points with pure clicks. (There's some freedom here, so for illustrative purposes we clamped ",React.createElement("em",null,"t")," to simply be 0.5, lets us bypass some maths, since a ",React.createElement("em",null,"t")," value of 0.5 always puts C in the middle of the start--end line segment)"),React.createElement(Graphic,{preset:"generate",title:"Fitting a quadratic Bézier curve",setup:handler.setup,draw:handler.drawQuadratic,onClick:handler.onClick}),React.createElement("p",null,"For cubic curves we also need some values to construct the \"de Casteljau line through B\" with, and that gives us quite a bit of choice. Since we've clamped ",React.createElement("em",null,"t")," to 0.5, we'll set up a line through B parallel to the line start--end, with a length that is proportional to the length of the line B--C: the further away from the baseline B is, the wider its construction line will be, and so the more \"bulby\" the curve will look. This still gives us some freedom in terms of exactly how to scale the length of the construction line as we move B closer or further away from the baseline, so I simply picked some values that sort-of-kind-of look right in that if a circle through (start,B,end) forms a perfect hemisphere, the cubic curve constructed forms something close to a hemisphere, too, and if the points lie on a line, then the curve constructed has the control points very close to B, while still lying between B and the correct curve end point:"),React.createElement(Graphic,{preset:"generate",title:"Fitting a cubic Bézier curve",setup:handler.setup,draw:handler.drawCubic,onClick:handler.onClick}),React.createElement("p",null,"In each graphic, the blue parts are the values that we \"just have\" simply by setting up our three points, combined with our decision on which ",React.createElement("em",null,"t")," value to use (and construction line orientation and length for cubic curves). There are of course many ways to determine a combination of ",React.createElement("em",null,"t")," and tangent values that lead to a more \"æsthetic\" curve, but this will be left as an exercise to the reader, since there are many, and æsthetics are often quite personal."));}},"catmullconv":{"locale":"en-GB","title":"Bézier curves and Catmull-Rom curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"catmullconv",title:"Bézier curves and Catmull-Rom curves",number:"29"}),React.createElement("p",null,"Taking an excursion to different splines, the other common design curve is the ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull.E2.80.93Rom_spline"},"Catmull-Rom spline"),". Now, a Catmull-Rom spline is a form of cubic Hermite spline, and as it so happens the cubic Bézier curve is also a cubic Hermite spline, so maybe... maybe we can convert one into the other, and back, with some simple substitutions?"),React.createElement("p",null,"Unlike Bézier curves, Catmull-Rom splines pass through each point used to define the curve, except the first and last, which makes sense if you read the \"natural language\" descriptionfor how a Catmull-Rom spline works: a Catmull-Rom spline is a curve that, at each point P",React.createElement("sub",null,"x"),", has a tangent along the line P",React.createElement("sub",null,"x-1")," to P",React.createElement("sub",null,"x+1"),". The curve runs from points P",React.createElement("sub",null,"2")," to P",React.createElement("sub",null,"n-1"),", and has a \"tension\" that determines how fast the curve passes through each point. The lower the tension, the faster the curve goes through each point, and the bigger its local tangent is."),React.createElement("p",null,"I'll be showing the conversion to and from Catmull-Rom curves for the tension that the Processing language uses for its Catmull-Rom algorithm."),React.createElement("p",null,"We start with showing the Catmull-Rom matrix form:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5fc1c44e623f2a9fbeefdaa204557479e3debf5a.svg",width:"429.79999999999995rem",height:"78.39999999999999rem"}),React.createElement("p",null,"However, there's something funny going on here: the coordinate column matrix looks weird. The reason is that Catmull-Rom curves are actually curve segments that are described by two points, and two tangents; the curve leaves a point V1 (if we have four coordinates instead, this is coordinate 2), arriving at a point V2 (coordinate 3), with the curve departing V1 with a tangent vector V'1 (equal to the tangent from coordinate 1 to coordinate 3) and arriving at V2 with tangent vector V'2 (equal to the tangent from coordinate 2 to coordinate 4). So if we want to express this as a matrix form based on four coordinates, we get this representation instead:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/40b9ca9b5755a4be49517ddfa630fef7b8e23067.svg",width:"406rem",height:"86.8rem"}),React.createElement("div",{className:"note"},React.createElement("h2",{id:"where-did-that-2-come-from-"},"Where did that 2 come from?"),React.createElement("p",null,"Catmull-Rom splines are based on the concept of tension: the higher the tensions, the shorter the tangents at the departure and arrival points. The basic Catmull-Rom curve arrives and departs with tangents equal to half the distance between the two adjacent points, so that's where that 2 came from."),React.createElement("p",null,"However, the \"real\" matrix is this:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7bf9b5e971866babedd991ccdde5c4ab104297e5.svg",width:"351.4rem",height:"88.19999999999999rem"}),React.createElement("p",null,"This bakes in the tension factor τ explicitly.")),React.createElement("p",null,"Plugging this into the \"two coordinates and two tangent vectors\" matrix form, we get:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/4818f8797c35f23c2b9883aa986b1129b2fa151a.svg",width:"299.59999999999997rem",height:"78.39999999999999rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/08f77989369f664cbc0fb7526791efd4c5299d70.svg",width:"499.79999999999995rem",height:"77rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c7ae769c5370469b16523bab6f34abf0dd6749be.svg",width:"414.4rem",height:"77rem"}),React.createElement("p",null,"So let's find out which transformation matrix we need in order to convert from Catmull-Rom to Bézier:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/7250f1c57e2bd66ec4349e4e88db4d5d74401a06.svg",width:"730.8rem",height:"77rem"}),React.createElement("p",null,"The difference is somewhere in the actual hermite matrix, since the ",React.createElement("em",null,"t")," and coordinate values are identical, so let's solve that matrix equasion:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/8a42b24fca3aaf6b8ec08e84b7e91c43e26e8acf.svg",width:"418.59999999999997rem",height:"75.6rem"}),React.createElement("p",null,"We left-multiply both sides by the inverse of the Bézier matrix, to get rid of the Bézier matrix on the right side of the equals sign:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e111d6e846f4d7204dec484005f74993e66c6c9.svg",width:"841.4rem",height:"84rem"}),React.createElement("p",null,"Which gives us:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/f94b80113772d90a4fbc93d4495cb5767e5c8123.svg",width:"183.39999999999998rem",height:"75.6rem"}),React.createElement("p",null,"Multiplying this ",React.createElement("strong",null,React.createElement("em",null,"A"))," with our coordinates will give us a proper Bézier matrix expression again:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d088274e440ceeac2916a0f32176682d776c1c57.svg",width:"448rem",height:"77rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/9e68f80b270d3445d9f9cb28ff2c5aed219aa9d2.svg",width:"365.4rem",height:"85.39999999999999rem"}),React.createElement("p",null,"So a Catmull-Rom to Bézier conversion, based on coordinates, requires turning the Catmull-Rom coordinates on the left into the Bézier coordinates on the right (with τ being our tension factor):"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/92a34d777899da97f1907e6b093db28872f02c3a.svg",width:"261.8rem",height:"89.6rem"}),React.createElement("p",null,"And the other way around, a Bézier to Catmull-Rom conversion requires turning the Bézier coordinates on the left this time into the Catmull-Rom coordinates on the right. Note that there is no tension this time, because Bézier curves don't have any. Converting from Bézier to Catmull-Rom is simply a default-tension Catmull-Rom curve:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ee3d3d219a18596dc403c0392d44bc585d738e6c.svg",width:"309.4rem",height:"81.19999999999999rem"}),React.createElement("p",null,"Done. We can now draw the curves we want using either Bézier curves or Catmull-Rom splines, the choice mostly being which drawing algorithms we have natively available."));}},"catmullmoulding":{"locale":"en-GB","title":"Creating a Catmull-Rom curve from three points","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"catmullmoulding",title:"Creating a Catmull-Rom curve from three points",number:"30"}),React.createElement("p",null,"Now, we saw how to fit a Bézier curve to three points, but if Catmull-Rom curves go through points, why can't we just use those to do curve fitting, instead?"),React.createElement("p",null,"As a matter of fact, we can, but there's a difference between the kind of curve fitting we did in the previous section, and the kind of curve fitting that we can do with Catmull-Rom curves. In the previous section we came up with a single curve that goes through three points. There was a decent amount of maths and computation involved, and the end result was three or four coordinates that described a single curve, depending on whether we were fitting a quadratic or cubic curve."),React.createElement("p",null,"Using Catmull-Rom curves, we need virtually no computation, but even though we end up with one Catmull-Rom curve of ",React.createElement("i",null,"n")," points, in order to draw the equivalent curve using cubic Bézier curves we need a massive ",React.createElement("i",null,"3n-2")," points (and that's without double-counting points that are shared by consecutive cubic curves)."),React.createElement("p",null,"In the following graphic, on the left we see three points that we want to draw a Catmull-Rom curve through (which we can move around freely, by the way), with in the second panel some of the \"interesting\" Catmull-Rom information: in black there's the baseline start--end, which will act as tangent orientation for the curve at point p2. We also see a virtual point p0 and p4, which are initially just point p2 reflected over the baseline. However, by using the up and down cursor key we can offset these points parallel to the baseline. Why would we want to do this? Because the line p0--p2 acts as departure tangent at p1, and the line p2--p4 acts as arrival tangent at p3. Play around with the graphic a bit to get an idea of what all of that meant:"),React.createElement(Graphic,{preset:"threepanel",title:"Catmull-Rom curve fitting",setup:handler.setup,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"As should be obvious by now, Catmull-Rom curves are great for \"fitting a curvature to some points\", but if we want to convert that curve to Bézier form we're going to end up with a lot of separate (but visually joined) Bézier curves. Depending on what we want to do, that'll be either unnecessary work, or exactly what we want: which it is depends entirely on you."));}},"polybezier":{"locale":"en-GB","title":"Forming poly-Bézier curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"polybezier",title:"Forming poly-Bézier curves",number:"31"}),React.createElement("p",null,"Much like lines can be chained together to form polygons, Bézier curves can be chained together to form poly-Béziers, and the only trick required is to make sure that:"),React.createElement("ol",null,React.createElement("li",null,"the end point of each section is the starting point of the following section, and"),React.createElement("li",null,"the derivatives across that dual point line up.")),React.createElement("p",null,"Unless, of course, you want discontinuities; then you don't even need 2."),React.createElement("p",null,"We'll cover three forms of poly-Bézier curves in this section. First, we'll look at the kind that just follows point 1. where the end point of a segment is the same point as the start point of the next segment. This leads to poly-Béziers that are pretty hard to work with, but they're the easiest to implement:"),React.createElement(Graphic,{preset:"poly",title:"Unlinked quadratic poly-Bézier",setup:handler.setupQuadratic,draw:handler.draw}),React.createElement(Graphic,{preset:"poly",title:"Unlinked cubic poly-Bézier",setup:handler.setupCubic,draw:handler.draw}),React.createElement("p",null,"Dragging the control points around only affects the curve segments that the control point belongs to, and moving an on-curve point leaves the control points where they are, which is not the most useful for practical modelling purposes. So, let's add in the logic we need to make things a little better. We'll start by linking up control points by ensuring that the \"incoming\" derivative at an on-curve point is the same as it's \"outgoing\" derivative:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/37740bb1a0b7b1ff48bf3454e52295fc717cacbb.svg",width:"130.2rem",height:"18.2rem"}),React.createElement("p",null,"We can effect this quite easily, because we know that the vector from a curve's last control point to its last on-curve point is equal to the derivative vector. If we want to ensure that the first control point of the next curve matches that, all we have to do is mirror that last control point through the last on-curve point. And mirroring any point A through any point B is really simple:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ce6e3939608c4ed0598107b06543c2301b91bb7f.svg",width:"319.2rem",height:"42rem"}),React.createElement("p",null,"So let's implement that and see what it gets us. The following two graphics show a quadratic and a cubic poly-Bézier curve again, but this time moving the control points around moves others, too. However, you might see something unexpected going on for quadratic curves..."),React.createElement(Graphic,{preset:"poly",title:"Loosely connected quadratic poly-Bézier",setup:handler.setupQuadratic,draw:handler.draw,onMouseMove:handler.linkDerivatives}),React.createElement(Graphic,{preset:"poly",title:"Loosely connected cubic poly-Bézier",setup:handler.setupCubic,draw:handler.draw,onMouseMove:handler.linkDerivatives}),React.createElement("p",null,"As you can see, quadratic curves are particularly ill-suited for poly-Bézier curves, as all the control points are effectively linked. Move one of them, and you move all of them. Not only that, but if we move the on-curve points, it's possible to get a situation where a control point's positions is different depending on whether it's the reflection of its left or right neighbouring control point: we can't even form a proper rule-conforming curve! This means that we cannot use quadratic poly-Béziers for anything other than really, really simple shapes. And even then, they're probably the wrong choice. Cubic curves are pretty decent, but the fact that the derivatives are linked means we can't manipulate curves as well as we might if we relaxed the constraints a little."),React.createElement("p",null,"So: let's relax the requirement a little."),React.createElement("p",null,"We can change the constraint so that we still preserve the ",React.createElement("em",null,"angle")," of the derivatives across sections (so transitions from one section to the next will still look natural), but give up the requirement that they should also have the same ",React.createElement("em",null,"vector length"),". Doing so will give us a much more useful kind of poly-Bézier curve:"),React.createElement(Graphic,{preset:"poly",title:"Loosely connected quadratic poly-Bézier",setup:handler.setupQuadratic,draw:handler.draw,onMouseMove:handler.linkDirection}),React.createElement(Graphic,{preset:"poly",title:"Loosely connected cubic poly-Bézier",setup:handler.setupCubic,draw:handler.draw,onMouseMove:handler.linkDirection}),React.createElement("p",null,"Cubic curves are now better behaved when it comes to dragging control points around, but the quadratic poly-Bézier still has the problem that moving one control points will move the control points and may ending up defining \"the next\" control point in a way that doesn't work. Quadratic curves really aren't very useful to work with..."),React.createElement("p",null,"Finally, we also want to make sure that moving the on-curve coordinates preserves the relative positions of the associated control points. With that, we get to the kind of curve control that you might be familiar with from applications like Photoshop, Inkscape, Blender, etc."),React.createElement(Graphic,{preset:"poly",title:"Loosely connected quadratic poly-Bézier",setup:handler.setupQuadratic,draw:handler.draw,onMouseDown:handler.bufferPoints,onMouseMove:handler.modelCurve}),React.createElement(Graphic,{preset:"poly",title:"Loosely connected cubic poly-Bézier",setup:handler.setupCubic,draw:handler.draw,onMouseDown:handler.bufferPoints,onMouseMove:handler.modelCurve}),React.createElement("p",null,"Again, we see that cubic curves are now rather nice to work with, but quadratic curves have a new, very serious problem: we can move an on-curve point in such a way that we can't compute what needs to \"happen next\". Move the top point down, below the left and right points, for instance. There is no way to preserve correct control points without a kink at the bottom point. Quadratic curves: just not that good..."),React.createElement("p",null,"A final improvement is to offer fine-level control over which points behave which, so that you can have \"kinks\" or individually controlled segments when you need them, with nicely well-behaved curves for the rest of the path. Implementing that, is left as an excercise for the reader."));}},"shapes":{"locale":"en-GB","title":"Boolean shape operations","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"shapes",title:"Boolean shape operations",number:"32"}),React.createElement("p",null,"We can apply the topics covered so far in this primer to effect boolean shape operations: getting the union, intersection, or exclusion, between two or more shapes that involve Bézier curves. For simplicity (well.. sort of, more homogeneity), we'll be looking at Poly-Bézier shapes only, but a shape that consists of a mix of lines and Bézier curves is technically a simplification (although it does mean we need to write a definition for the class of shapes that mix lines and Bézier curves. Since poly-Bézier curves are a superset, we'll be using those in the following examples)"),React.createElement("p",null,"The procedure for performing boolean operations consists, broadly, of four steps:"),React.createElement("ol",null,React.createElement("li",null,"Find the intersection points between both shapes,"),React.createElement("li",null,"cut up the shapes into multiple sections between these intersections,"),React.createElement("li",null,"discard any section that isn't part of the desired operation's resultant shape, and"),React.createElement("li",null,"link up the remaining sections to form the new shape.")),React.createElement("p",null,"Finding all intersections between two poly-Bézier curves, or any poly-line-section shape, is similar to the iterative algorithm discussed in the section on curve/curve intersection. For each segment in the poly-Bézier curve we check whether its bounding box overlaps with any of the segment bounding boxes in the other poly-Bézier curve. If so, we run normal intersection detection."),React.createElement("p",null,"After we found all intersection points, we split up our poly-Bézier curves, making sure to record which of the newly formed poly-Bézier curves might potentially link up at the points we split the originals up at. This will let us quickly glue poly-Bézier curves back together after the next step."),React.createElement("p",null,"Once we have all the new poly-Bézier curves, we run the first step of the desired boolean operation."),React.createElement("ul",null,React.createElement("li",null,"Union: discard all poly-Bézier curves that lie \"inside\" our union of our shapes. E.g. if we want the union of two overlapping circles, the resulting shape is the outline."),React.createElement("li",null,"Intersection: discard all poly-Bézier curves that lie \"outside\" the intersection of the two shapes. E.g. if we want the intersection of two overlapping circles, the resulting shape is the tapered ellipse where they overlap."),React.createElement("li",null,"Exclusion: none of the sections are discarded, but we will need to link the shapes back up in a special way. Flip any section that would qualify for removal under UNION rules.")),React.createElement("table",{className:"sketch"},React.createElement("tbody",null,React.createElement("tr",null,React.createElement("td",{className:"labeled-image"},React.createElement("img",{src:"images/op_base.gif",height:"169px"}),"Two overlapping shapes."),React.createElement("td",{className:"labeled-image"},React.createElement("img",{src:"images/op_union.gif",height:"169px"}),"The unified region."),React.createElement("td",{className:"labeled-image"},React.createElement("img",{src:"images/op_intersection.gif",height:"169px"}),"Their intersection."),React.createElement("td",{className:"labeled-image"},React.createElement("img",{src:"images/op_exclusion.gif",height:"169px"}),"Their exclusion regions.")))),React.createElement("p",null,"The main complication in the outlined procedure here is determining how sections qualify in terms of being \"inside\" and \"outside\" of our shapes. For this, we need to be able to perform point-in-shape detection, for which we'll use a classic algorithm: getting the \"crossing number\" by using ray casting, and then testing for \"insidedness\" by applying the ",React.createElement("a",{href:"http://folk.uio.no/bjornw/doc/bifrost-ref/bifrost-ref-12.html"},"even-odd rule"),": For any point and any shape, we can cast a ray from our point, to some point that we know lies outside of the shape (such as a corner of our drawing surface). We then count how many times that line crosses our shape (remember that we can perform line/curve intersection detection quite easily). If the number of times it crosses the shape's outline is even, the point did not actually lie inside our shape. If the number of intersections is odd, our point did lie inside out shape. With that knowledge, we can decide whether to treat a section that such a point lies on \"needs removal\" (under union rules), \"needs preserving\" (under intersection rules), or \"needs flipping\" (under exclusion rules)."),React.createElement("p",null,"These operations are expensive, and implementing your own code for this is generally a bad idea if there is already a geometry package available for your language of choice. In this case, for JavaScript the most excellent ",React.createElement("a",{href:"http://paperjs.org"},"Paper.js")," already comes with all the code in place to perform efficient boolean shape operations, so rather that implement an inferior version here, I can strongly recommend the Paper.js library if you intend to do any boolean shape work."),React.createElement("p",null,"The following graphic shows Paper.js doing its thing for two shapes: one static, and one that is linked to your mouse pointer. If you move the mouse around, you'll see how the shape intersections are resolved. The base shapes are outlined in blue, and the boolean result is coloured red."),React.createElement(Graphic,{preset:"simple",title:"Boolean shape operations with Paper.js",paperjs:true,setup:handler.setup,draw:handler.draw,onMouseMove:handler.onMouseMove},React.createElement("br",null),handler.modes.map(function(mode){var className=handler.state.mode===mode?"selected":null;return React.createElement("button",{className:className,key:mode,onClick:function onClick(){return handler.setMode(mode);}},mode);})));}},"projections":{"locale":"en-GB","title":"Projecting a point onto a Bézier curve","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"projections",title:"Projecting a point onto a Bézier curve",number:"33"}),React.createElement("p",null,"Say we have a Bézier curve and some point, not on the curve, of which we want to know which ",React.createElement("code",null,"t")," value on the curve gives us an on-curve point closest to our off-curve point. Or: say we want to find the projection of a random point onto a curve. How do we do that?"),React.createElement("p",null,"If the Bézier curve is of low enough order, we might be able to ",React.createElement("a",{href:"http://jazzros.blogspot.ca/2011/03/projecting-point-on-bezier-curve.html"},"work out the maths for how to do this"),", and get a perfect ",React.createElement("code",null,"t")," value back, but in general this is an incredibly hard problem and the easiest solution is, really, a numerical approach again. We'll be finding our ideal ",React.createElement("code",null,"t")," value using a ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Binary_search_algorithm"},"binary search"),". First, we do a coarse distance-check based on ",React.createElement("code",null,"t")," values associated with the curve's \"to draw\" coordinates (using a lookup table, or LUT). This is pretty fast. Then we run this algorithm:"),React.createElement("ol",null,React.createElement("li",null,"with the ",React.createElement("code",null,"t")," value we found, start with some small interval around ",React.createElement("code",null,"t")," (1/length_of_LUT on either side is a reasonable start),"),React.createElement("li",null,"if the distance to ",React.createElement("code",null,"t ± interval/2")," is larger than the distance to ",React.createElement("code",null,"t"),", try again with the interval reduced to half its original length."),React.createElement("li",null,"if the distance to ",React.createElement("code",null,"t ± interval/2")," is smaller than the distance to ",React.createElement("code",null,"t"),", replace ",React.createElement("code",null,"t")," with the smaller-distance value."),React.createElement("li",null,"after reducing the interval, or changing ",React.createElement("code",null,"t"),", go back to step 1.")),React.createElement("p",null,"We keep repeating this process until the interval is small enough to claim the difference in precision found is irrelevant for the purpose we're trying to find ",React.createElement("code",null,"t")," for. In this case, I'm arbitrarily fixing it at 0.0001."),React.createElement("p",null,"The following graphic demonstrates the result of this procedure.Simply move the cursor around, and if it does not lie on top of the curve, you will see a line that projects the cursor onto the curve based on an iteratively found \"ideal\" ",React.createElement("code",null,"t")," value."),React.createElement(Graphic,{preset:"simple",title:"Projecting a point onto a Bézier curve",setup:handler.setup,draw:handler.draw,onMouseMove:handler.onMouseMove}));}},"offsetting":{"locale":"en-GB","title":"Curve offsetting","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"offsetting",title:"Curve offsetting",number:"34"}),React.createElement("p",null,"Perhaps you are like me, and you've been writing various small programs that use Bézier curves in some way or another, and at some point you make the step to implementing path extrusion. But you don't want to do it pixel based, you want to stay in the vector world. You find that extruding lines is relatively easy, and tracing outlines is coming along nicely (although junction caps and fillets are a bit of a hassle), and then decide to do things properly and add Bézier curves to the mix. Now you have a problem."),React.createElement("p",null,"Unlike lines, you can't simply extrude a Bézier curve by taking a copy and moving it around, because of the curvatures; rather than a uniform thickness you get an extrusion that looks too thin in places, if you're lucky, but more likely will self-intersect. The trick, then, is to scale the curve, rather than simply copying it. But how do you scale a Bézier curve?"),React.createElement("p",null,"Bottom line: ",React.createElement("strong",null,"you can't"),". So you cheat. We're not going to do true curve scaling, or rather curve offsetting, because that's impossible. Instead we're going to try to generate 'looks good enough' offset curves."),React.createElement("div",{className:"note"},React.createElement("h3",{id:"-what-do-you-mean-you-can-t-prove-it-"},"\"What do you mean, you can't. Prove it.\""),React.createElement("p",null,"First off, when I say \"you can't\" what I really mean is \"you can't offset a Bézier curve with another Bézier curve\". not even by using a really high order curve. You can find the function that describes the offset curve, but it won't be a polynomial, and as such it cannot be represented as a Bézier curve, which ",React.createElement("strong",null,"has")," to be a polynomial. Let's look at why this is:"),React.createElement("p",null,"From a mathematical point of view, an offset curve ",React.createElement("code",null,"O(t)")," is a curve such that, given our original curve ",React.createElement("code",null,"B(t)"),", any point on ",React.createElement("code",null,"O(t)")," is a fixed distance ",React.createElement("code",null,"d")," away from coordinate ",React.createElement("code",null,"B(t)"),". So let's math that:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3aff5cef0028337bbb48ae64ad30000c4d5e238f.svg",width:"113.39999999999999rem",height:"16.799999999999997rem"}),React.createElement("p",null,"However, we're working in 2D, and ",React.createElement("code",null,"d")," is a single value, so we want to turn it into a vector. If we want a point distance ",React.createElement("code",null,"d")," \"away\" from the curve ",React.createElement("code",null,"B(t)")," then what we really mean is that we want a point at ",React.createElement("code",null,"d")," times the \"normal vector\" from point ",React.createElement("code",null,"B(t)"),", where the \"normal\" is a vector that runs perpendicular (\"at a right angle\") to the tangent at ",React.createElement("code",null,"B(t)"),". Easy enough:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/2cf48e2f8525258a3fa0fe4f10ec2acef67104b3.svg",width:"158.2rem",height:"16.799999999999997rem"}),React.createElement("p",null,"Now this still isn't very useful unless we know what the formula for ",React.createElement("code",null,"N(t)")," is, so let's find out. ",React.createElement("code",null,"N(t)")," runs perpendicular to the original curve tangent, and we know that the tangent is simply ",React.createElement("code",null,"B'(t)"),", so we could just rotate that 90 degrees and be done with it. However, we need to ensure that ",React.createElement("code",null,"N(t)")," has the same magnitude for every ",React.createElement("code",null,"t"),", or the offset curve won't be at a uniform distance, thus not being an offset curve at all. The easiest way to guarantee this is to make sure ",React.createElement("code",null,"N(t)")," always has length 1, which we can achieve by dividing ",React.createElement("code",null,"B'(t)")," by its magnitude:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/4941ecbff4c50732ba66fec53307456fc605f032.svg",width:"125.99999999999999rem",height:"42rem"}),React.createElement("p",null,"Determining the length requires computing an arc length, and this is where things get Tricky with a capital T. First off, to compute arc length from some start ",React.createElement("code",null,"a")," to end ",React.createElement("code",null,"b"),", we must use the formula we saw earlier. Noting that \"length\" is usually denoted with double vertical bars:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/f6d8c2965b02363e092acb00bbc1398cfbb170a4.svg",width:"177.79999999999998rem",height:"37.8rem"}),React.createElement("p",null,"So if we want the length of the tangent, we plug in ",React.createElement("code",null,"B'(t)"),", with ",React.createElement("code",null,"t = 0")," as start and",React.createElement("code",null,"t = 1")," as end:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1f024282044316a9e4b3de2c855d2ceb96aff056.svg",width:"219.79999999999998rem",height:"37.8rem"}),React.createElement("p",null,"And that's where things go wrong. It doesn't even really matter what the second derivative for ",React.createElement("code",null,"B(t)")," is, that square root is screwing everything up, because it turns our nice polynomials into things that are no longer polynomials."),React.createElement("p",null,"There is a small class of polynomials where the square root is also a polynomial, but they're utterly useless to us: any polynomial with unweighted binomial coefficients has a square root that is also a polynomial. Now, you might think that Bézier curves are just fine because they do, but they don't; remember that only the ",React.createElement("strong",null,"base")," function has binomial coefficients. That's before we factor in our coordinates, which turn it into a non-binomial polygon. The only way to make sure the functions stay binomial is to make all our coordinates have the same value. And that's not a curve, that's a point. We can already create offset curves for points, we call them circles, and they have much simpler functions than Bézier curves."),React.createElement("p",null,"So, since the tangent length isn't a polynomial, the normalised tangent won't be a polynomial either, which means ",React.createElement("code",null,"N(t)")," won't be a polynomial, which means that ",React.createElement("code",null,"d")," times ",React.createElement("code",null,"N(t)")," won't be a polynomial, which means that, ultimately, ",React.createElement("code",null,"O(t)")," won't be a polynomial, which means that even if we can determine the function for ",React.createElement("code",null,"O(t)")," just fine (and that's far from trivial!), it simply cannot be represented as a Bézier curve."),React.createElement("p",null,"And that's one reason why Bézier curves are tricky: there are actually a ",React.createElement("code",null,"lot")," of curves that cannot be represent as a Bézier curve at all. They can't even model their own offset curves. They're weird that way. So how do all those other programs do it? Well, much like we're about to do, they cheat. We're going to approximate an offset curve in a way that will look relatively close to what the real offset curve would look like, if we could compute it.")),React.createElement("p",null,"So, you cannot offset a Bézier curve perfectly with another Bézier curve, no matter how high-order you make that other Bézier curve. However, we can chop up a curve into \"safe\" sub-curves (where safe means that all the control points are always on a single side of the baseline, and the midpoint of the curve at ",React.createElement("code",null,"t=0.5")," is roughly in the centre of the polygon defined by the curve coordinates) and then point-scale each sub-curve with respect to its scaling origin (which is the intersection of the point normals at the start and end points)."),React.createElement("p",null,"A good way to do this reduction is to first find the curve's extreme points, as explained in the earlier section on curve extremities, and use these as initial splitting points. After this initial split, we can check each individual segment to see if it's \"safe enough\" based on where the center of the curve is. If the on-curve point for ",React.createElement("code",null,"t=0.5")," is too far off from the center, we simply split the segment down the middle. Generally this is more than enough to end up with safe segments."),React.createElement("p",null,"The following graphics show off curve offsetting, and you can use your up and down arrow keys to control the distance at which the curve gets offset. The curve first gets reduced to safe segments, each of which is then offset at the desired distance. Especially for simple curves, particularly easily set up for quadratic curves, no reduction is necessary, but the more twisty the curve gets, the more the curve needs to be reduced in order to get segments that can safely be scaled."),React.createElement(Graphic,{preset:"simple",title:"Offsetting a quadratic Bézier curve",setup:handler.setupQuadratic,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement(Graphic,{preset:"simple",title:"Offsetting a cubic Bézier curve",setup:handler.setupCubic,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"You may notice that this may still lead to small 'jumps' in the sub-curves when moving the curve around. This is caused by the fact that we're still performing a naive form of offsetting, moving the control points the same distance as the start and end points. If the curve is large enough, this may still lead to incorrect offsets."));}},"graduatedoffset":{"locale":"en-GB","title":"Graduated curve offsetting","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"graduatedoffset",title:"Graduated curve offsetting",number:"35"}),React.createElement("p",null,"What if we want to do graduated offsetting, starting at some distance ",React.createElement("code",null,"s")," but ending at some other distance ",React.createElement("code",null,"e"),"? well, if we can compute the length of a curve (which we can if we use the Legendre-Gauss quadrature approach) then we can also determine how far \"along the line\" any point on the curve is. With that knowledge, we can offset a curve so that its offset curve is not uniformly wide, but graduated between with two different offset widths at the start and end."),React.createElement("p",null,"Like normal offsetting we cut up our curve in sub-curves, and then check at which distance along the original curve each sub-curve starts and ends, as well as to which point on the curve each of the control points map. This gives us the distance-along-the-curve for each interesting point in the sub-curve. If we call the total length of all sub-curves seen prior to seeing \"the current\" sub-curve ",React.createElement("code",null,"S")," (and if the current sub-curve is the first one, ",React.createElement("code",null,"S")," is zero), and we call the full length of our original curve ",React.createElement("code",null,"L"),", then we get the following graduation values:"),React.createElement("ul",null,React.createElement("li",null,"start: map ",React.createElement("code",null,"S")," from interval (",React.createElement("code",null,"0,L"),") to interval ",React.createElement("code",null,"(s,e)")),React.createElement("li",null,"c1: ",React.createElement("code",null,"map(<strong>S+d1</strong>, 0,L, s,e)"),", d1 = distance along curve to projection of c1"),React.createElement("li",null,"c2: ",React.createElement("code",null,"map(<strong>S+d2</strong>, 0,L, s,e)"),", d2 = distance along curve to projection of c2"),React.createElement("li",null,"..."),React.createElement("li",null,"end: ",React.createElement("code",null,"map(<strong>S+length(subcurve)</strong>, 0,L, s,e)"))),React.createElement("p",null,"At each of the relevant points (start, end, and the projections of the control points onto the curve) we know the curve's normal, so offsetting is simply a matter of taking our original point, and moving it along the normal vector by the offset distance for each point. Doing so will give us the following result (these have with a starting width of 0, and an end width of 40 pixels, but can be controlled with your up and down arrow keys):"),React.createElement(Graphic,{preset:"simple",title:"Offsetting a quadratic Bézier curve",setup:handler.setupQuadratic,draw:handler.draw,onKeyDown:handler.props.onKeyDown}),React.createElement(Graphic,{preset:"simple",title:"Offsetting a cubic Bézier curve",setup:handler.setupCubic,draw:handler.draw,onKeyDown:handler.props.onKeyDown}));}},"circles":{"locale":"en-GB","title":"Circles and quadratic Bézier curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"circles",title:"Circles and quadratic Bézier curves",number:"36"}),React.createElement("p",null,"Circles and Bézier curves are very different beasts, and circles are infinitely easier to work with than Bézier curves. Their formula is much simpler, and they can be drawn more efficiently. But, sometimes you don't have the luxury of using circles, or ellipses, or arcs. Sometimes, all you have are Bézier curves. For instance, if you're doing font design, fonts have no concept of geometric shapes, they only know straight lines, and Bézier curves. OpenType fonts with TrueType outlines only know quadratic Bézier curves, and OpenType fonts with Type 2 outlines only know cubic Bézier curves. So how do you draw a circle, or an ellipse, or an arc?"),React.createElement("p",null,"You approximate."),React.createElement("p",null,"We already know that Bézier curves cannot model all curves that we can think of, and this includes perfect circles, as well as ellipses, and their arc counterparts. However, we can certainly approximate them to a degree that is visually acceptable. Quadratic and cubic curves offer us different curvature control, so in order to approximate a circle we will first need to figure out what the error is if we try to approximate arcs of increasing degree with quadratic and cubic curves, and where the coordinates even lie."),React.createElement("p",null,"Since arcs are mid-point-symmetrical, we need the control points to set up a symmetrical curve. For quadratic curves this means that the control point will be somewhere on a line that intersects the baseline at a right angle. And we don't get any choice on where that will be, since the derivatives at the start and end point have to line up, so our control point will lie at the intersection of the tangents at the start and end point."),React.createElement("p",null,"First, let's try to fit the quadratic curve onto a circular arc. In the following sketch you can move the mouse around over a unit circle, to see how well, or poorly, a quadratic curve can approximate the arc from (1,0) to where your mouse cursor is:"),React.createElement(Graphic,{preset:"arcfitting",title:"Quadratic Bézier arc approximation",setup:handler.setup,draw:handler.draw,onMouseMove:handler.onMouseMove}),React.createElement("p",null,"As you can see, things go horribly wrong quite quickly; even trying to approximate a quarter circle using a quadratic curve is a bad idea. An eighth of a turns might look okay, but how okay is okay? Let's apply some maths and find out. What we're interested in is how far off our on-curve coordinates are with respect to a circular arc, given a specific start and end angle. We'll be looking at how much space there is between the circular arc, and the quadratic curve's midpoint."),React.createElement("p",null,"We start out with our start and end point, and for convenience we will place them on a unit circle (a circle around 0,0 with radius 1), at some angle ",React.createElement("em",null,"φ"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ef34ab8f466ed3294895135a346b55ada05d779d.svg",width:"183.39999999999998rem",height:"42rem"}),React.createElement("p",null,"What we want to find is the intersection of the tangents, so we want a point C such that:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/5660e8512b07dbac7fcf04633de8002fa25aa962.svg",width:"298.2rem",height:"42rem"}),React.createElement("p",null,"i.e. we want a point that lies on the vertical line through S (at some distance ",React.createElement("em",null,"a")," from S) and also lies on the tangent line through E (at some distance ",React.createElement("em",null,"b")," from E). Solving this gives us:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/d16e7a1c1e9686e1afb82f4ffcec07078d264565.svg",width:"229.6rem",height:"42rem"}),React.createElement("p",null,"First we solve for ",React.createElement("em",null,"b"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3128b31a874166ebe4479d3002d70f280de375a1.svg",width:"588rem",height:"18.2rem"}),React.createElement("p",null,"which yields:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/02b158f9ef2191b970dc2fe69c0903eba2b1f8b5.svg",width:"106.39999999999999rem",height:"40.599999999999994rem"}),React.createElement("p",null,"which we can then substitute in the expression for ",React.createElement("em",null,"a"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3bd9c2d6740ff530aabcbe60252742032af816e9.svg",width:"242.2rem",height:"204.39999999999998rem"}),React.createElement("p",null,"A quick check shows that plugging these values for ",React.createElement("em",null,"a")," and ",React.createElement("em",null,"b")," into the expressions for C",React.createElement("sub",null,"x")," and C",React.createElement("sub",null,"y")," give the same x/y coordinates for both \"",React.createElement("em",null,"a")," away from A\" and \"",React.createElement("em",null,"b")," away from B\", so let's continue: now that we know the coordinate values for C, we know where our on-curve point T for ",React.createElement("em",null,"t=0.5")," (or angle φ/2) is, because we can just evaluate the Bézier polynomial, and we know where the circle arc's actual point P is for angle φ/2:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b80423188012451e0400f473c19729eb2bad654.svg",width:"197.39999999999998rem",height:"33.599999999999994rem"}),React.createElement("p",null,"We compute T, observing that if ",React.createElement("em",null,"t=0.5"),", the polynomial values (1-t)², 2(1-t)t, and t² are 0.25, 0.5, and 0.25 respectively:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/bc50559ff8bd9062694a449aae5f6f85f91de909.svg",width:"264.59999999999997rem",height:"36.4rem"}),React.createElement("p",null,"Which, worked out for the x and y components, gives:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c7fca7664a3acb855eeaaf412aa2331202f41097.svg",width:"428.4rem",height:"81.19999999999999rem"}),React.createElement("p",null,"And the distance between these two is the standard Euclidean distance:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3251cd91a1cffc27a1695ece4c13cc651d7007fb.svg",width:"418.59999999999997rem",height:"161rem"}),React.createElement("p",null,"So, what does this distance function look like when we plot it for a number of ranges for the angle φ, such as a half circle, quarter circle and eighth circle?"),React.createElement("table",null,React.createElement("tbody",null,React.createElement("tr",null,React.createElement("td",null,React.createElement("img",{src:"images/arc-q-pi.gif",height:"190px"}),"plotted for 0 ≤ φ ≤ π:"),React.createElement("td",null,React.createElement("img",{src:"images/arc-q-pi2.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ ½π:"),React.createElement("td",null,handler.props.showhref?"http://www.wolframalpha.com/input/?i=plot+sqrt%28%281%2F4+*+%28sin%28x%29+%2B+2tan%28x%2F2%29%29+-+sin%28x%2F2%29%29%5E2+%2B+%282sin%5E4%28x%2F4%29%29%5E2%29+for+0+%3C%3D+x+%3C%3D+pi%2F4":null,React.createElement("img",{src:"images/arc-q-pi4.gif",height:"174px"}),"plotted for 0 ≤ φ ≤ ¼π:")))),React.createElement("p",null,"We now see why the eighth circle arc looks decent, but the quarter circle arc doesn't: an error of roughly 0.06 at ",React.createElement("em",null,"t=0.5")," means we're 6% off the mark... we will already be off by one pixel on a circle with pixel radius 17. Any decent sized quarter circle arc, say with radius 100px, will be way off if approximated by a quadratic curve! For the eighth circle arc, however, the error is only roughly 0.003, or 0.3%, which explains why it looks so close to the actual eighth circle arc. In fact, if we want a truly tiny error, like 0.001, we'll have to contend with an angle of (rounded) 0.593667, which equates to roughly 34 degrees. We'd need 11 quadratic curves to form a full circle with that precision! (technically, 10 and ten seventeenth, but we can't do partial curves, so we have to round up). That's a whole lot of curves just to get a shape that can be drawn using a simple function!"),React.createElement("p",null,"In fact, let's flip the function around, so that if we plug in the precision error, labelled ε, we get back the maximum angle for that precision:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/61a938fa10b77e8c41c3c064ed39bd1145d6bbcc.svg",width:"259rem",height:"56rem"}),React.createElement("p",null,"And frankly, things are starting to look a bit ridiculous at this point, we're doing way more maths than we've ever done, but thankfully this is as far as we need the maths to take us: If we plug in the precisions 0.1, 0.01, 0.001 and 0.0001 we get the radians values 1.748, 1.038, 0.594 and 0.3356; in degrees, that means we can cover roughly 100 degrees (requiring four curves), 59.5 degrees (requiring six curves), 34 degrees (requiring 11 curves), and 19.2 degrees (requiring a whopping nineteen curves)."),React.createElement("p",null,"The bottom line? ",React.createElement("strong",null,"Quadratic curves are kind of lousy")," if you want circular (or elliptical, which are circles that have been squashed in one dimension) curves. We can do better, even if it's just by raising the order of our curve once. So let's try the same thing for cubic curves."));}},"circles_cubic":{"locale":"en-GB","title":"Circles and cubic Bézier curves","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"circles_cubic",title:"Circles and cubic Bézier curves",number:"37"}),React.createElement("p",null,"In the previous section we tried to approximate a circular arc with a quadratic curve, and it mostly made us unhappy. Cubic curves are much better suited to this task, so what do we need to do?"),React.createElement("p",null,"For cubic curves, we basically want the curve to pass through three points on the circle: the start point, the mid point at \"angle/2\", and the end point at \"angle\". We then also need to make sure the control points are such that the start and end tangent lines line up with the circle's tangent lines at the start and end point."),React.createElement("p",null,"The first thing we can do is \"guess\" what the curve should look like, based on the previously outlined curve-through-three-points procedure. This will give use a curve with correct start, mid and end points, but possibly incorrect derivatives at the start and end, because the control points might not be in the right spot. We can then slide the control points along the lines that connect them to their respective end point, until they effect the corrected derivative at the start and end points. However, if you look back at the section on fitting curves through three points, the rules used were such that they optimized for a near perfect hemisphere, so using the same guess won't be all that useful: guessing the solution based on knowing the solution is not really guessing."),React.createElement("p",null,"So have a graphical look at a \"bad\" guess versus the true fit, where we'll be using the bad guess and the description in the second paragraph to derive the maths for the true fit:"),React.createElement(Graphic,{preset:"arcfitting",title:"Cubic Bézier arc approximation",setup:handler.setup,draw:handler.draw,onMouseMove:handler.onMouseMove}),React.createElement("p",null,"We see two curves here; in blue, our \"guessed\" curve and its control points, and in grey/black, the true curve fit, with proper control points that were shifted in, along line between our guessed control points, such that the derivatives at the start and end points are correct."),React.createElement("p",null,"We can already seethat cubic curves are a lot better than quadratic curves, and don't look all that wrong until we go well past a quarter circle; ⅜th starts to hint at problems, and half a circle has an obvious \"gap\" between the real circle and the cubic approximation. Anything past that just looks plain ridiculous... but quarter curves actually look pretty okay!"),React.createElement("p",null,"So, maths time again: how okay is \"okay\"? Let's apply some more maths to find out."),React.createElement("p",null,"Unlike for the quadratic curve, we can't use ",React.createElement("i",null,"t=0.5")," as our reference point because by its very nature it's one of the three points that are actually guaranteed to lie on the circular curve. Instead, we need a different ",React.createElement("i",null,"t")," value. If we run some analysis on the curve we find that the actual ",React.createElement("i",null,"t")," value at which the curve is furthest from what it should be is 0.211325 (rounded), but we don't know \"why\", since finding this value involves root-finding, and is nearly impossible to do symbolically without pages and pages of math just to express one of the possible solutions."),React.createElement("p",null,"So instead of walking you through the derivation for that value, let's simply take that ",React.createElement("i",null,"t")," value and see what the error is for circular arcs with an angle ranging from 0 to 2π:"),React.createElement("table",null,React.createElement("tbody",null,React.createElement("tr",null,React.createElement("td",null,React.createElement("img",{src:"images/arc-c-2pi.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ 2π:"),React.createElement("td",null,React.createElement("img",{src:"images/arc-c-pi.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ π:"),React.createElement("td",null,React.createElement("img",{src:"images/arc-c-pi2.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ ½π:")))),React.createElement("p",null,"We see that cubic Bézier curves are much better when it comes to approximating circular arcs, with an error of less than 0.027 at the two \"bulge\" points for a quarter circle (which had an error of 0.06 for quadratic curves at the mid point), and an error near 0.001 for an eighth of a circle, so we're getting less than half the error for a quarter circle, or: at a slightly lower error, we're getting twice the arc. This makes cubic curves quite useful!"),React.createElement("p",null,"In fact, the precision of a cubic curve at a quarter circle is considered \"good enough\" by so many people that it's generally considered \"just fine\" to use four cubic Bézier curves to fake a full circle when no circle primitives are available; generally, people won't notice that it's not a real circle unless you also happen to overlay an actual circle, so that the difference becomes obvious."),React.createElement("p",null,"So with the error analysis out of the way, how do we actually compute the coordinates needed to get that \"true fit\" cubic curve? The first observation is that we already know the start and end points, because they're the same as for the quadratic attempt:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ef34ab8f466ed3294895135a346b55ada05d779d.svg",width:"183.39999999999998rem",height:"42rem"}),React.createElement("p",null,"But we now need to find two control points, rather than one. If we want the derivatives at the start and end point to match the circle, then the first control point can only lie somewhere on the vertical line through S, and the second control point can only lie somewhere on the line tangent to point E, which means:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/4df65dae78bc5a0e6c5f23a2faae9a9d7a8b39b3.svg",width:"118.99999999999999rem",height:"42rem"}),React.createElement("p",null,"where \"a\" is some scaling factor, and:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/cb32f8f9c3ae2b264a48003c237a798d02dc8935.svg",width:"170.79999999999998rem",height:"42rem"}),React.createElement("p",null,"where \"b\" is also some scaling factor."),React.createElement("p",null,"Starting with this information, we slowly maths our way to success, but I won't lie: the maths for this is pretty trig-heavy, and it's easy to get lost if you remember (or know!) some of the core trigonoetric identities, so if you just want to see the final result just skip past the next section!"),React.createElement("div",{className:"note"},React.createElement("h2",{id:"let-s-do-this-thing-"},"Let's do this thing."),React.createElement("p",null,"Unlike for the quadratic case, we need some more information in order to compute ",React.createElement("i",null,"a")," and ",React.createElement("i",null,"b"),", since they're no longer dependent variables. First, we observe that the curve is symmetrical, so whatever values we end up finding for C",React.createElement("sub",null,"1")," will apply to C",React.createElement("sub",null,"2")," as well (rotated along its tangent), so we'll focus on finding the location of C",React.createElement("sub",null,"1")," only. So here's where we do something that you might not expect: we're going to ignore for a moment, because we're going to have a much easier time if we just solve this problem with geometry first, then move to calculus to solve a much simpler problem."),React.createElement("p",null,"If we look at the triangle that is formed between our starting point, or initial guess C",React.createElement("sub",null,"1")," and our real C",React.createElement("sub",null,"1"),", there's something funny going on: if we treat the line ",'{',"start,guess",'}'," as our opposite side, the line ",'{',"guess,real",'}'," as our adjacent side, with ",'{',"start,real",'}'," our hypothenuse, then the angle for the corner hypothenuse/adjacent is half that of the arc we're covering. Try it: if you place the end point at a quarter circle (pi/2, or 90 degrees), the angle in our triangle is half a quarter (pi/4, or 45 degrees). With that knowledge, and a knowledge of what the length of any of our lines segments are (as a function), we can determine where our control points are, and thus have everything we need to find the error distance function. Of the three lines, the one we can easiest determine is ",'{',"start,guess",'}',", so let's find out what the guessed control point is. Again geometrically, because we have the benefit of an on-curve ",React.createElement("i",null,"t=0.5")," value."),React.createElement("p",null,"The distance from our guessed point to the start point is exactly the same as the projection distance we looked at earlier. Using ",React.createElement("i",null,"t=0.5")," as our point \"B\" in the \"A,B,C\" projection, then we know the length of the line segment ",'{',"C,A",'}',", since it's d",React.createElement("sub",null,"1")," = ",'{',"A,B",'}'," + d",React.createElement("sub",null,"2")," = ",'{',"B,C",'}',":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/b15a274c1e0a6aeeaf517b5d2c8ee0a7997dd617.svg",width:"417.2rem",height:"42rem"}),React.createElement("p",null,"So that just leaves us to find the distance from ",React.createElement("i",null,"t=0.5")," to the baseline for an arbitrary angle φ, which is the distance from the centre of the circle to our ",React.createElement("i",null,"t=0.5")," point, minus the distance from the centre to the line that runs from start point to end point. The first is the same as the point P we found for the quadratic curve:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b80423188012451e0400f473c19729eb2bad654.svg",width:"197.39999999999998rem",height:"33.599999999999994rem"}),React.createElement("p",null,"And the distance from the origin to the line start/end is another application of angles, since the triangle ",'{',"origin,start,C",'}'," has known angles, and two known sides. We can find the length of the line ",'{',"origin,C",'}',", which lets us trivially compute the coordinate for C:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/9be55fb38d5d30bbc6c7140afb1c7bc097bc044e.svg",width:"274.4rem",height:"70rem"}),React.createElement("p",null,"With the coordinate C, and knowledge of coordinate B, we can determine coordinate A, and get a vector that is identical to the vector ",'{',"start,guess",'}',":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/262f2eca63105779f30a0a5445cf76f60786039a.svg",width:"417.2rem",height:"50.4rem"}),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e83ebbac13a84ef6036bf4be57b3d1b6cb316f8.svg",width:"221.2rem",height:"49rem"}),React.createElement("p",null,"Which means we can now determine the distance ",'{',"start,guessed",'}',", which is the same as the distance ",'{',"C,A",'}',", and use that to determine the vertical distance from our start point to our C",React.createElement("sub",null,"1"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c87e454fb11ef7f15c7386e83ca1ce41a004d8a7.svg",width:"264.59999999999997rem",height:"58.8rem"}),React.createElement("p",null,"And after this tedious detour to find the coordinate for C",React.createElement("sub",null,"1"),", we can find C",React.createElement("sub",null,"2")," fairly simply, since it's lies at distance -C",React.createElement("sub",null,"1y")," along the end point's tangent:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/25f027074b6af8ca7b640e27636e3bf89c28afdb.svg",width:"550.1999999999999rem",height:"82.6rem"}),React.createElement("p",null,"And that's it, we have all four points now for an approximation of an arbitrary circular arc with angle φ.")),React.createElement("p",null,"So, to recap, given an angle φ, the new control coordinates are:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c4d82e44d1c67dda8ba26aa6da0f406d05eba618.svg",width:"215.6rem",height:"42rem"}),React.createElement("p",null,"and"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3a4b1ee00eebb7697e5513ef9df673928913252e.svg",width:"337.4rem",height:"42rem"}),React.createElement("p",null,"And, because the \"quarter curve\" special case comes up so incredibly often, let's look at what these new control points mean for the curve coordinates of a quarter curve, by simply filling in φ = π/2:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/63e0936b4849d4cdbb9a2e0909181259be951e4d.svg",width:"432.59999999999997rem",height:"35rem"}),React.createElement("p",null,"Which, in decimal values, rounded to six significant digits, is:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/fd12e65204a31319b66355c6ff99e6b3d9603b05.svg",width:"432.59999999999997rem",height:"16.799999999999997rem"}),React.createElement("p",null,"Of course, this is for a circle with radius 1, so if you have a different radius circle, simply multiply the coordinate by the radius you need. And then finally, forming a full curve is now a simple a matter of mirroring these coordinates about the origin:"),React.createElement(Graphic,{preset:"simple",title:"Cubic Bézier circle approximation",draw:handler.drawCircle,"static":true}));}},"arcapproximation":{"locale":"en-GB","title":"Approximating Bézier curves with circular arcs","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"arcapproximation",title:"Approximating Bézier curves with circular arcs",number:"38"}),React.createElement("p",null,"Let's look at doing the exact opposite of the previous section: rather than approximating circular arc using Bézier curves, let's approximate Bézier curves using circular arcs."),React.createElement("p",null,"We already saw in the section on circle approximation that this will never yield a perfect equivalent, but sometimes you need circular arcs, such as when you're working with fabrication machinery, or simple vector languages that understand lines and circles, but not much else."),React.createElement("p",null,"The approach is fairly simple: pick a starting point on the curve, and pick two points that are further along the curve. Determine the circle that goes through those three points, and see if it fits the part of the curve we're trying to approximate. Decent fit? Try spacing the points further apart. Bad fit? Try spacing the points closer together. Keep doing this until you've found the \"good approximation/bad approximation\" boundary, record the \"good\" arc, and then move the starting point up to overlap the end point we previously found. Rinse and repeat until we've covered the entire curve."),React.createElement("p",null,"So: step 1, how do we find a circle through three points? That part is actually really simple. You may remember (if you ever learned it!) that a line between two points on a circle is called a ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Chord_%28geometry%29"},"chord"),", and one property of chords is that the line from the center of any chord, perpendicular to that chord, passes through the center of the circle."),React.createElement("p",null,"So: if we have have three points, we have three (different) chords, and consequently, three (different) lines that go from those chords through the center of the circle. So we find the centers of the chords, find the perpendicular lines, find the intersection of those lines, and thus find the center of the circle."),React.createElement("p",null,"The following graphic shows this procedure with a different colour for each chord and its associated perpendicular through the center. You can move the points around as much as you like, those lines will always meet!"),React.createElement(Graphic,{preset:"simple",title:"Finding a circle through three points",setup:handler.setupCircle,draw:handler.drawCircle}),React.createElement("p",null,"So, with the procedure on how to find a circle through three points, finding the arc through those points is straight-forward: pick one of the three points as start point, pick another as an end point, and the arc has to necessarily go from the start point, over the remaining point, to the end point."),React.createElement("p",null,"So how can we convert a Bezier curve into a (sequence of) circular arc(s)?"),React.createElement("ul",null,React.createElement("li",null,"Start at ",React.createElement("em",null,"t=0")),React.createElement("li",null,"Pick two points further down the curve at some value ",React.createElement("em",null,"m = t + n")," and ",React.createElement("em",null,"e = t + 2n")),React.createElement("li",null,"Find the arc that these points define"),React.createElement("li",null,"Determine how close the found arc is to the curve:",React.createElement("ul",null,React.createElement("li",null,"Pick two additional points ",React.createElement("em",null,"e1 = t + n/2")," and ",React.createElement("em",null,"e2 = t + n + n/2"),"."),React.createElement("li",null,"These points, if the arc is a good approximation of the curve interval chosen, should lie ",React.createElement("em",null,"on")," the circle, so their distance to the center of the circle should be the same as the distance from any of the three other points to the center."),React.createElement("li",null,"For point points, determine the (absolute) error between the radius of the circle, and the",React.createElement("em",null,"actual")," distance from the center of the circle to the point on the curve."),React.createElement("li",null,"If this error is too high, we consider the arc bad, and try a smaller interval.")))),React.createElement("p",null,"The result of this is shown in the next graphic: we start at a guaranteed failure: s=0, e=1. That's the entire curve. The midpoint is simply at ",React.createElement("em",null,"t=0.5"),", and then we start performing a ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Binary_search_algorithm"},"Binary Search"),"."),React.createElement("ol",null,React.createElement("li",null,"We start with ",(0,0.5,1)),React.createElement("li",null,"That'll fail, so we retry with the interval halved: ",(0,0.25,0.5),React.createElement("ul",null,React.createElement("li",null,"If that arc's good, we move back up by half distance: ",(0,0.375,0.75),"."),React.createElement("li",null,"However, if the arc was still bad, we move ",React.createElement("em",null,"down")," by half the distance: ",(0,0.125,0.25),"."))),React.createElement("li",null,"We keep doing this over and over until we have two arcs found in sequence of which the first arc is good, and the second arc is bad. When we find that pair, we've found the boundary between a good approximation and a bad approximation, and we pick the former.")),React.createElement("p",null,"The following graphic shows the result of this approach, with a default error threshold of 0.5, meaning that if an arc is off by a ",React.createElement("em",null,"combined")," half pixel over both verification points, then we treat the arc as bad. This is an extremely simple error policy, but already works really well. Note that the graphic is still interactive, and you can use your up and down arrow keys keys to increase or decrease the error threshold, to see what the effect of a smaller or larger error threshold is."),React.createElement(Graphic,{preset:"simple",title:"Arc approximation of a Bézier curve",setup:handler.setupCubic,draw:handler.drawSingleArc,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"With that in place, all that's left now is to \"restart\" the procedure by treating the found arc's end point as the new to-be-determined arc's starting point, and using points further down the curve. We keep trying this until the found end point is for ",React.createElement("em",null,"t=1"),", at which point we are done. Again, the following graphic allows for up and down arrow key input to increase or decrease the error threshold, so you can see how picking a different threshold changes the number of arcs that are necessary to reasonably approximate a curve:"),React.createElement(Graphic,{preset:"simple",title:"Arc approximation of a Bézier curve",setup:handler.setupCubic,draw:handler.drawArcs,onKeyDown:handler.props.onKeyDown}),React.createElement("p",null,"So... what is this good for? Obviously, If you're working with technologies that can't do curves, but can do lines and circles, then the answer is pretty straight-forward, but what else? There are some reasons why you might need this technique: using circular arcs means you can determine whether a coordinate lies \"on\" your curve really easily: simply compute the distance to each circular arc center, and if any of those are close to the arc radii, at an angle betwee the arc start and end: bingo, this point can be treated as lying \"on the curve\". Another benefit is that this approximation is \"linear\": you can almost trivially travel along the arcs at fixed speed. You can also trivially compute the arc length of the approximated curve (it's a bit like curve flattening). The only thing to bear in mind is that this is a lossy equivalence: things that you compute based on the approximation are guaranteed \"off\" by some small value, and depending on how much precision you need, arc approximation is either going to be super useful, or completely useless. It's up to you to decide which, based on your application!"));}},"bsplines":{"locale":"en-GB","title":"B-Splines","getContent":function getContent(handler){return React.createElement("section",null,React.createElement(SectionHeader,{name:"bsplines",title:"B-Splines",number:"39"}),React.createElement("p",null,"No discussion on Bézier curves is complete without also giving mention of that other beast in the curve design space: B-Splines. Easily confused to mean Bézier splines, that's not actually what they are; they are \"basis function\" splines, which makes a lot of difference, which we'll be looking at in this section. We're not going to dive as deep into B-Splines as we have for Bézier curves (that would be an entire primer on its own) but we'll be looking at how B-Splines work, what kind of maths is involved in computing them, and how to draw them based on a number of parameters that you can pick for individual B-Splines."),React.createElement("p",null,"First off: B-Splines are ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Piecewise"},"piecewise polynomial interpolation curves"),", where the \"single curve\" is built by performing polynomial interpolation over a set of points, using a sliding window of a fixed number of points. For instance, a \"cubic\" B-Spline defined by twelve points will have its curve built by evaluating the polynomial interpolation of four points, and the curve can be treated as a lot of different sections, each controlled by four points at a time, such that the full curve consists of smoothly connected sections defined by points ",'{',"1,2,3,4",'}',", ",'{',"2,3,4,5",'}',", ..., ",'{',"8,9,10,11",'}',", and finally ",'{',"9,10,11,12",'}',", for eight sections."),React.createElement("p",null,"What do they look like? They look like this! .. okay that's an empty graph, but simply click to place some point, with the stipulation that you need at least four point to see any curve. More than four points simply draws a longer B-Spline curve:"),React.createElement(BSplineGraphic,{sketch:handler.basicSketch}),React.createElement("p",null,"The important part to notice here is that we are ",React.createElement("strong",null,"not")," doing the same thing with B-Splines that we do for poly-Béziers or Catmull-Rom curves: both of the latter simply define new sections as literally \"new sections based on new points\", so a 12 point cubic poly-Bézier curve is actually impossible, because we start with a four point curve, and then add three more points for each section that follows, so we can only have 4, 7, 10, 13, 16, etc point Poly-Béziers. Similarly, while Catmull-Rom curves can grow by adding single points, this addition of a single point introduces three implicit Bézier points. Cubic B-Splines, on the other hand, are smooth interpolations of ",React.createElement("em",null,"each possible curve involving four consecutive points"),", such that at any point along the curve except for our start and end points, our on-curve coordinate is defined by four control points."),React.createElement("p",null,"Consider the difference to be this:"),React.createElement("ul",null,React.createElement("li",null,"for Bézier curves, the curve is defined as an interpolation of points, but:"),React.createElement("li",null,"for B-Splines, the curve is defined as an interpolation of ",React.createElement("em",null,"curves"),".")),React.createElement("p",null,"In order to make this interpolation of curves work, the maths is necessarily more complex than the maths for Bézier curves, so let's have a look at how things work."),React.createElement("h2",{id:"how-to-compute-a-b-spline-curve-some-maths"},"How to compute a B-Spline curve: some maths"),React.createElement("p",null,"Given a B-Spline of degree ",React.createElement("code",null,"d")," and thus order ",React.createElement("code",null,"k=d+1")," (so a quadratic B-Spline is degree 2 and order 3, a cubic B-Spline is degree 3 and order 4, etc) and ",React.createElement("code",null,"n")," control points ",React.createElement("code",null,"P<sub>0</sub>")," through ",React.createElement("code",null,"P<sub>n-1</sub>"),", we can compute a point on the curve for some value ",React.createElement("code",null,"t")," in the interval [0,1] (where 0 is the start of the curve, and 1 the end, just like for Bézier curves), by evaluting the following function:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/329da80e737b0005f4dbe4c84ff868bde5dfaee0.svg",width:"177.79999999999998rem",height:"43.4rem"}),React.createElement("p",null,"Which, honestly, doesn't tell us all that much. All we can see is that a point on a B-Spline curve is defined as \"a mix of all the control points, weighted somehow\", where the weighting is achieved through the ",React.createElement("em",null,"N(...)")," function, subscipted with an obvious parameter ",React.createElement("code",null,"i"),", which comes from our summation, and some magical parameter ",React.createElement("code",null,"k"),". So we need to know two things: 1. what does N(t) do, and 2. what is that ",React.createElement("code",null,"k"),"? Let's cover both, in reverse order."),React.createElement("p",null,"The parameter ",React.createElement("code",null,"k")," represents the \"knot interval\" over which a section of curve is defined. As we learned earlier, a B-Spline curve is itself an interpoliation of curves, and we can treat each transition where a control point starts or tops influencing the total curvature as a \"knot on the curve\". Doing so for a degree ",React.createElement("code",null,"d")," B-Spline with ",React.createElement("code",null,"n")," control point gives us ",React.createElement("code",null,"d + n + 1")," knots, defining ",React.createElement("code",null,"d + n")," intervals along the curve, and it is these intervals that the above ",React.createElement("code",null,"k")," subscript to the N() function applies to."),React.createElement("p",null,"Then the N() function itself. What does it look like?"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/c10575fb591062784484357356796a4c0be4f83e.svg",width:"588rem",height:"44.8rem"}),React.createElement("p",null,"So this is where we see the interpolation: N(t) for an (i,k) pair (that is, for a step in the above summation, on a specific knot interval) is a mix between N(t) for (i,k-1) and N(t) for (i+1,k-1), so we see that this is a recursive iteration where ",React.createElement("code",null,"i")," goes up, and ",React.createElement("code",null,"k")," goes down, so it seem reasonable to expect that this recursion has to stop at some point; obviously, it does, and specifically it does so for the following ",React.createElement("code",null,"i"),"/",React.createElement("code",null,"k")," values:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/6664a4fc5832059bbc68eaa8068a4b2577e1d96a.svg",width:"251.99999999999997rem",height:"42rem"}),React.createElement("p",null,"And this function finally has a straight up evaluation: if a ",React.createElement("code",null,"t")," value lies within a knot-specific interval once we reach a ",React.createElement("code",null,"k=1")," value, it \"counts\", otherwise it doesn't. We did cheat a little, though, because for all these values we need to scale our ",React.createElement("code",null,"t")," value first, so that it lies in the interval bounded by ",React.createElement("code",null,"knots[d]")," and ",React.createElement("code",null,"knots[n]"),", which are the start point and end point where curvature is controlled by exactly ",React.createElement("code",null,"order")," control points. For instance, for degree 3 (=order 4) and 7 control points, with knot vector [1,2,3,4,5,6,7,8,9,10,11], we map ",React.createElement("code",null,"t")," from [the interval 0,1] to the interval [4,8], and then use that value in the functions above, instead."),React.createElement("h2",{id:"can-we-simplify-that-"},"Can we simplify that?"),React.createElement("p",null,"We can, yes."),React.createElement("p",null,"People far smarter than us have looked at this work, and two in particular — ",React.createElement("a",{href:"http://www.npl.co.uk/people/maurice-cox"},"Maurice Cox")," and ",React.createElement("a",{href:"https://en.wikipedia.org/wiki/Carl_R._de_Boor"},"Carl de Boor")," — came to a mathematically pleasing solution: to compute a point P(t), we can compute this point by evaluating ",React.createElement("em",null,"d(t)")," on a curve section between knots ",React.createElement("em",null,"i")," and ",React.createElement("em",null,"i+1"),":"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/3780a420cd9b1bc59bec2c49bbd29f5e58497a3c.svg",width:"295.4rem",height:"22.4rem"}),React.createElement("p",null,"This is another recursive function, with ",React.createElement("em",null,"k")," values decreasing from the curve order to 1, and the value ",React.createElement("em",null,"α")," (alpha) defined by:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/ba3b25cd54993b4601d8f415bc4cde73af4fc460.svg",width:"267.4rem",height:"40.599999999999994rem"}),React.createElement("p",null,"That looks complicated, but it's not. Computing alpha is just a fraction involving known, plain numbers and once we have our alpha value, computing (1-alpha) is literally just \"computing one minus alpha\". Computing this d() function is thus simply a matter of \"computing simple arithmetics but with recursion\", which might be computationally expensive because we're doing \"a lot of\" steps, but is also computationally cheap because each step only involves very simple maths. Of course as before the recursion has to stop:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/1405067abebab73574934e3e69d7a7158106c744.svg",width:"387.79999999999995rem",height:"42rem"}),React.createElement("p",null,"So, we see two stopping conditions: either ",React.createElement("code",null,"i")," becomes 0, in which case d() is zero, or ",React.createElement("code",null,"k")," becomes zero, in which case we get the same \"either 1 or 0\" that we saw in the N() function above."),React.createElement("p",null,"Thanks to Cox and de Boor, we can compute points on a B-Spline pretty easily: we just need to compute a triangle of interconnected values. For instance, d() for i=3, k=3 yields the following triangle:"),React.createElement("img",{className:"LaTeX SVG",src:"images/latex/a0a1069b001c75a1fab7f40ffa8bc403e1408f0d.svg",width:"438.2rem",height:"242.2rem"}),React.createElement("p",null,"That is, we compute d(3,3) as a mixture of d(2,3) and d(2,2): d(3,3) = a(3,3) x d(2,3) + (1-a(3,3)) x d(2,2)... and we simply keep expanding our triangle until we reach the terminating function parameters. Done deal!"),React.createElement("p",null,"One thing we need to keep in mind is that we're working with a spline that is contrained by its control points, so even though the ",React.createElement("code",null,"d(..., k)")," values are zero or one at the lowest level, they are really \"zero or one, times their respective control point\", so in the next section you'll see the algorithm for running through the computation in a way that starts with a copy of the control point vector and then works its way up to that single point: that's pretty essential!"),React.createElement("p",null,"If we run this computation \"down\", starting at d(3,3), then without special code in place we would be computing quite a few terms multiple times at each step. On the other hand, we can also start with that last \"column\", we can generate the terminating d() values first, then compute the a() constants, perform our multiplcations, generate the previous step's d() values, compute their a() constants, do the multiplications, etc. until we end up all the way back at the top. If we run our computation this way, we don't need any explicit caching, we can just \"recycle\" the list of numbers we start with and simply update them as we move up the triangle. So, let's implement that!"),React.createElement("h2",{id:"cool-cool-but-i-don-t-know-what-to-do-with-that-information"},"Cool, cool... but I don't know what to do with that information"),React.createElement("p",null,"I know, this is pretty mathy, so let's have a look at what happens when we change parameters here. We can't change the maths for the interpolation functions, so that gives us only one way to control what happens here: the knot vector itself. As such, let's look at the graph that shows the interpolation functions for a cubic B-Spline with seven points with a uniform knot vector (so we see seven identical functions), representing how much each point (represented by one function each) influences the total curvature, given our knot values. And, because exploration is the key to discovery, let's make the knot vector a thing we can actually manipulate. Normally a proper knot vector has a constraint that any value is strictly equal to, or larger than the previous ones, but screw it this is programming, let's ignore that hard restriction and just mess with the knots however we like."),React.createElement("div",{className:"two-column"},React.createElement(KnotController,{ref:"interpolation-graph"}),React.createElement(BSplineGraphic,{sketch:handler.interpolationGraph,controller:function controller(owner,knots){return handler.bindKnots(owner,knots,"interpolation-graph");}})),React.createElement("p",null,"Changing the values in the knot vector changes how much each point influences the total curvature (with some clever knot value manipulation, we can even make the influence of certain points disappear entirely!), so we can see that while the control points define the hull inside of which we're going to be drawing a curve, it is actually the knot vector that determines the actual ",React.createElement("em",null,"shape")," of the curve inside that hull."),React.createElement("p",null,"After reading the rest of this section you may want to come back here to try some specific knot vectors, and see if the resulting interpolation landscape makes sense given what you will now think should happen!"),React.createElement("h2",{id:"running-the-computation"},"Running the computation"),React.createElement("p",null,"Unlike the de Casteljau algorithm, where the ",React.createElement("code",null,"t")," value stays the same at every iteration, for B-Splines that is not the case, and so we end having to (for each point we evaluate) run a fairly involving bit of recursive computation. The algorithm is discussed on ",React.createElement("a",{href:"http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/de-Boor.html"},"this Michigan Tech")," page, but an easier to read version is implemented by ",React.createElement("a",{href:"https://github.com/thibauts/b-spline/blob/master/index.js#L59-L71"},"b-spline.js"),", so we'll look at its code."),React.createElement("p",null,"Given an input value ",React.createElement("code",null,"t"),", we first map the input to a value from the domain [0,1] to the domain [knots[degree], knots[knots.length - 1 - degree]. Then, we find the section number ",React.createElement("code",null,"s")," that this mapped ",React.createElement("code",null,"t")," value lies on:"),React.createElement("pre",null,"for(s=domain[0]; s < domain[1]; s++) {\n if(knots[s] <= t && t <= knots[s+1]) break;\n}\n"),React.createElement("p",null,"after running this code, ",React.createElement("code",null,"s")," is the index for the section the point will lie on. We then run the algorithm mentioned on the MU page (updated to use this description's variable names):"),React.createElement("pre",null,"let v = copy of control points\n\nfor(let L = 1; L <= order; L++) {\n for(let i=s; i > s + L - order; i--) {\n let numerator = t - knots[i]\n let denominator = knots[i - L + order] - knots[i]\n let alpha = numerator / denominator\n let v[i] = alpha * v[i] + (1-alpha) * v[i-1]\n }\n}\n"),React.createElement("p",null,"(A nice bit of behaviour in this code is that we work the interpolation \"backwards\", starting at ",React.createElement("code",null,"i=s")," at each level of the interpolation, and we stop when ",React.createElement("code",null,"i = s - order + level"),", so we always end up with a value for ",React.createElement("code",null,"i")," such that those ",React.createElement("code",null,"v[i-1]")," don't try to use an array index that doesn't exist)"),React.createElement("h2",{id:"open-vs-closed-paths"},"Open vs. closed paths"),React.createElement("p",null,"Much like poly-Béziers, B-Splines can be either open, running from the first point to the last point, or closed, where the first and last point are ",React.createElement("em",null,"the same point"),". However, because B-Splines are an interpolation of curves, not just point, we can't simply make the first and last point the same, we need to link a few point point: for an order ",React.createElement("code",null,"d")," B-Spline, we need to make the last ",React.createElement("code",null,"d")," point the same as the first ",React.createElement("code",null,"d")," points. And the easiest way to do this is to simply append ",React.createElement("code",null,"points.splice(0,d)")," to ",React.createElement("code",null,"points"),". Done!"),React.createElement("p",null,"Of course if we want to manipulate these kind of curves we need to make sure to mark them as \"closed\" so that we know the coordinate for ",React.createElement("code",null,"points[0]")," and ",React.createElement("code",null,"points[n-k]")," etc. are the same coordinate, and manipulating one will equally manipulate the other, but programming generally makes this really easy by storing references to coordinates (or other linked values such as coordinate weights, discussed in the NURBS section) rather than separate coordinate objects."),React.createElement("h2",{id:"manipulating-the-curve-through-the-knot-vector"},"Manipulating the curve through the knot vector"),React.createElement("p",null,"The most important thing to understand when it comes to B-Splines is that they work ",React.createElement("em",null,"because")," of the concept of a knot vector. As mentioned above, knots represent \"where individual control points start/stop influencing the curve\", but we never looked at the ",React.createElement("em",null,"values")," that go in the knot vector. If you look back at the N() and a() functions, you see that interpolations are based on intervals in the knot vector, rather than the actual values in the knot vector, and we can exploit this to do some pretty interesting things with clever manipulation of the knot vector. Specifically there are four things we can do that are worth looking at:"),React.createElement("ol",null,React.createElement("li",null,"we can use a uniform knot vector, with equally spaced intervals,"),React.createElement("li",null,"we can use a non-uniform knot vector, without enforcing equally spaced internvals,"),React.createElement("li",null,"we can collapse sequential knots to the same value, locally lowering curve complexity using \"null\" intervals, and"),React.createElement("li",null,"we can form a special case non-uniform vector, by combining (1) and (3) to for a vector with collapsed start and end knots, with a uniform vector in between.")),React.createElement("h3",{id:"uniform-b-splines"},"Uniform B-Splines"),React.createElement("p",null,"The most straightforward type of B-Spline is the uniform spline. In a uniform spline, the knots are distributed uniformly over the entire curve interval. For instance, if we have a knot vector of length twelve, then a uniform knot vector would be [0,1,2,3,...,9,10,11]. Or [4,5,6,...,13,14,15], which defines ",React.createElement("em",null,"the same intervals"),", or even [0,2,3,...,18,20,22], which also defines ",React.createElement("em",null,"the same intervals"),", just scaled by a constant factor, which becomes normalised during interpolation and so does not contribute to the curvature."),React.createElement("div",{className:"two-column"},React.createElement(KnotController,{ref:"uniform-spline"}),React.createElement(BSplineGraphic,{sketch:handler.uniformBSpline,controller:function controller(owner,knots){return handler.bindKnots(owner,knots,"uniform-spline");}})),React.createElement("p",null,"This is an important point: the intervals that the knot vector defines are ",React.createElement("em",null,"relative")," intervals, so it doesn't matter if every interval is size 1, or size 100 - the relative differences between the intervals is what shapes any particular curve."),React.createElement("p",null,"The problem with uniform knot vectors is that, as we need ",React.createElement("code",null,"order")," control points before we have any curve with which we can perform interpolation, the curve does not \"start\" at the first point, nor \"ends\" at the last point. Instead there are \"gaps\". We can get rid of these, by being clever about how we apply the following uniformity-breaking approach instead..."),React.createElement("h3",{id:"reducing-local-curve-complexity-by-collapsing-intervals"},"Reducing local curve complexity by collapsing intervals"),React.createElement("p",null,"By collapsing knot intervals by making two or more consecutive knots have the same value, we can reduce the curve complexity in the sections that are affected by the knots involved. This can have drastic effects: for ever interval collapse, the curve order goes down, and curve continuity goes down, to the point where collapsing ",React.createElement("code",null,"order")," knots creates a situation where all continuity is lost and the curve \"kinks\"."),React.createElement("div",{className:"two-column"},React.createElement(KnotController,{ref:"center-cut-bspline"}),React.createElement(BSplineGraphic,{sketch:handler.centerCutBSpline,controller:function controller(owner,knots){return handler.bindKnots(owner,knots,"center-cut-bspline");}})),React.createElement("h3",{id:"open-uniform-b-splines"},"Open-Uniform B-Splines"),React.createElement("p",null,"By combining knot interval collapsing at the start and end of the curve, with uniform knots in between, we can overcome the problem of the curve not starting and ending where we'd kind of like it to:"),React.createElement("p",null,"For any curve of degree ",React.createElement("code",null,"D")," with control points ",React.createElement("code",null,"N"),", we can define a knot vector of length ",React.createElement("code",null,"N+D+1")," in which the values ",React.createElement("code",null,"0 ... D+1")," are the same, the values ",React.createElement("code",null,"D+1 ... N+1")," follow the \"uniform\" pattern, and the values ",React.createElement("code",null,"N+1 ... N+D+1")," are the same again. For example, a cubic B-Spline with 7 control points can have a knot vector [0,0,0,0,1,2,3,4,4,4,4], or it might have the \"identical\" knot vector [0,0,0,0,2,4,6,8,8,8,8], etc. Again, it is the relative differences that determine the curve shape."),React.createElement("div",{className:"two-column"},React.createElement(KnotController,{ref:"open-uniform-bspline"}),React.createElement(BSplineGraphic,{sketch:handler.openUniformBSpline,controller:function controller(owner,knots){return handler.bindKnots(owner,knots,"open-uniform-bspline");}})),React.createElement("h3",{id:"non-uniform-b-splines"},"Non-uniform B-Splines"),React.createElement("p",null,"This is essentialy the \"free form\" version of a B-Spline, and also the least interesting to look at, as without any specific reason to pick specific knot intervals, there is nothing particularly interesting going on. There is one constraint to the knot vector, and that is that any value ",React.createElement("code",null,"knots[k+1]")," should be equal to, or greater than ",React.createElement("code",null,"knots[k]"),"."),React.createElement("h2",{id:"one-last-thing-rational-b-splines"},"One last thing: Rational B-Splines"),React.createElement("p",null,"While it is true that this section on B-Splines is running quite long already, there is one more thing we need to talk about, and that's \"Rational\" splines, where the rationality applies to the \"ratio\", or relative weights, of the control points themselves. By introducing a ratio vector with weights to apply to each control point, we greatly increase our influence over the final curve shape: the more weight a control point carries, the close to that point the spline curve will lie, a bit like turning up the gravity of a control point."),React.createElement("div",{className:"two-column"},React.createElement(WeightController,{ref:"rational-uniform-bspline-weights"}),React.createElement(BSplineGraphic,{scrolling:true,sketch:handler.rationalUniformBSpline,controller:function controller(owner,knots,weights,closed){// handler.bindKnots(owner, knots, "rational-uniform-bspline"); -handler.bindWeights(owner,weights,closed,"rational-uniform-bspline-weights");}})),React.createElement("p",null,"Of course this brings us to the final topic that any text on B-Splines must touch on before calling it a day: the NURBS, or Non-Uniform Rational B-Spline (NURBS is not a plural, the capital S actually just stands for \"spline\", but a lot of people mistakenly treat it as if it is, so now you know better). NURBS are an important type of curve in computer-facilitated design, used a lot in 3D modelling (as NURBS surfaces) as well as in arbitrary-precision 2D design due to the level of control a NURBS curve offers designers."),React.createElement("p",null,"While a true non-uniform rational B-Spline would be hard to work with, when we talk about NURBS we typically mean the Open-Uniform Rational B-Spline, or OURBS, but that doesn't roll off the tongue nearly as nicely, and so remember that when people talk about NURBS, they typically mean open-uniform, which has the useful property of starting the curve at the first control point, and ending it at the last."),React.createElement("h2",{id:"extending-our-implementation-to-cover-rational-splines"},"Extending our implementation to cover rational splines"),React.createElement("p",null,"The algorithm for working with Rational B-Splines is virtually identical to the regular algorithm, and the extension to work in the control point weights is fairly simple: we extend each control point from a point in its original number of dimensions (2D, 3D, etc) to one dimension higher, scaling the original dimensions by the control point's weight, and then assigning that weight as its value for the extended dimension."),React.createElement("p",null,"For example, a 2D point ",React.createElement("code",null,"(x,y)")," with weight ",React.createElement("code",null,"w")," becomes a 3D point ",React.createElement("code",null,"(w * x, w * y, w)"),"."),React.createElement("p",null,"We then run the same algorithm as before, which will automatically perform weight interpolation in addition to regular coordinate interpolation, because all we've done is pretended we have coordinates in a higher dimension. The algorithm doesn't really care about how many dimensions it needs to interpolate."),React.createElement("p",null,"In order to recover our \"real\" curve point, we take the final result of the point generation algorithm, and \"unweigh\" it: we take the final point's derived weight ",React.createElement("code",null,"w'")," and divide all the regular coordinate dimensions by it, then throw away the weight information."),React.createElement("p",null,"Based on our previous example, we take the final 3D point ",React.createElement("code",null,"(x', y', w')"),", which we then turn back into a 2D point by computing ",React.createElement("code",null,"(x'/w', y'/w')"),". And that's it, we're done!"));}},"comments":{"locale":"en-GB","title":"Comments and questions","getContent":function getContent(handler){return React.createElement("section",null,React.createElement("script",null,"/* ----------------------------------------------------------------------------- * * * PLEASE DO NOT LOCALISE THIS FILE * * I can't respond to questions that aren't asked in English, so this is one of * the few cases where there is a content.en-GB.md but you shouldn't change it. * * ----------------------------------------------------------------------------- */"),React.createElement("style",null,"#comments ",'{',"width: calc(960px + 2em), marginTop: 0, borderTop: 1px solid rgba(255, 0, 0, 0.5), paddingTop: 3em",'}'),React.createElement(SectionHeader,{name:"comments",title:"Comments and questions",number:"40"}),React.createElement("p",null,"If you enjoyed this book, or you simply found it useful for something you were trying to get done, and you were wondering how to let me know you appreciated this book, you can always ",React.createElement("a",{href:"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QPRDLNGDANJSW"},"buy me a coffee"),", however much a coffee is where you live. This work has grown over the years, from a small primer to a 70ish print-page-equivalent reader on the subject of Bézier curves, and a lot of coffee went into the making of it. I don't regret a minute I spent on writing it, but I can always do with some more coffee to keep on writing!"),React.createElement("div",{id:"disqus_thread"}),React.createElement("script",{src:"lib/site/disqus.js",async:true}));}},"locale-switcher":{"locale":"en-GB","title":"locale-switcher","getContent":function getContent(handler){return React.createElement("section",null,React.createElement("p",null,"Read this in your own language:"),React.createElement("ul",null,React.createElement("li",null,React.createElement("a",{href:"./en-GB"},"English")),React.createElement("li",null,React.createElement("a",{href:"./ja-JP"},"日本語")),React.createElement("li",null,React.createElement("a",{href:"./zh-CN"},"中文"))),React.createElement("p",null,"Don't see your language listed? ",React.createElement("a",{href:"https://github.com/Pomax/BezierInfo-2/wiki/localize"},"Help translate this content!")));}}}; - -/***/ }), -/* 208 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(70); - - -/***/ }), -/* 209 */ -/***/ (function(module, exports, __webpack_require__) { - -(function() { - "use strict"; - - var utils = __webpack_require__(71); - - /** - * Poly Bezier - * @param {[type]} curves [description] - */ - var PolyBezier = function(curves) { - this.curves = []; - this._3d = false; - if(!!curves) { - this.curves = curves; - this._3d = this.curves[0]._3d; - } - } - - PolyBezier.prototype = { - valueOf: function() { - return this.toString(); - }, - toString: function() { - return utils.pointsToString(this.points); - }, - addCurve: function(curve) { - this.curves.push(curve); - this._3d = this._3d || curve._3d; - }, - length: function() { - return this.curves.map(function(v) { return v.length(); }).reduce(function(a,b) { return a+b; }); - }, - curve: function(idx) { - return this.curves[idx]; - }, - bbox: function() { - var c = this.curves; - var bbox = c[0].bbox(); - for(var i=1; i<c.length; i++) { - utils.expandbox(bbox, c[i].bbox()); - } - return bbox; - }, - offset: function(d) { - var offset = []; - this.curves.forEach(function(v) { - offset = offset.concat(v.offset(d)); - }); - return new PolyBezier(offset); - } - }; - - module.exports = PolyBezier; -}()); - - -/***/ }), -/* 210 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(module) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; -/** +function r(e,t){if(!a.canUseDOM||t&&!("addEventListener"in document))return!1;var n="on"+e,r=n in document;if(!r){var o=document.createElement("div");o.setAttribute(n,"return;"),r="function"==typeof o[n]}return!r&&i&&"wheel"===e&&(r=document.implementation.hasFeature("Events.wheel","3.0")),r}var i,a=n(7);a.canUseDOM&&(i=document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0),e.exports=r},function(e,t,n){"use strict";function r(e,t){var n=null===e||e===!1,r=null===t||t===!1;if(n||r)return n===r;var i=typeof e,a=typeof t;return"string"===i||"number"===i?"string"===a||"number"===a:"object"===a&&e.type===t.type&&e.key===t.key}e.exports=r},function(e,t,n){"use strict";var r=(n(5),n(9)),i=(n(2),r);e.exports=i},function(e,t,n){"use strict";function r(e,t,n){function r(){o=!0,n.apply(this,arguments)}function i(){o||(a<e?t.call(this,a++,i,r):r.apply(this,arguments))}var a=0,o=!1;i()}function i(e,t,n){function r(e,t,r){o||(t?(o=!0,n(t)):(a[e]=r,o=++s===i,o&&n(null,a)))}var i=e.length,a=[];if(0===i)return n(null,a);var o=!1,s=0;e.forEach(function(e,n){t(e,n,function(e,t){r(n,e,t)})})}t.__esModule=!0,t.loopAsync=r,t.mapAsync=i},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e){for(var t in e)if(e.hasOwnProperty(t))return!0;return!1}function o(e){return function(){function t(e,t){var n=!(arguments.length<=2||void 0===arguments[2])&&arguments[2];return g.default(e,t,n,k.location,k.routes,k.params)}function n(e){var t=e.pathname,n=e.query,r=e.state;return C.createLocation(C.createPath(t,n),r,c.REPLACE)}function r(e,t){S&&S.location===e?o(S,t):b.default(x,e,function(n,r){n?t(n):r?o(s({},r,{location:e}),t):t()})}function o(e,t){var r=f.default(k,e),i=r.leaveRoutes,a=r.enterRoutes;p.runLeaveHooks(i),p.runEnterHooks(a,e,function(r,i){r?t(r):i?t(null,n(i)):w.default(e,function(n,r){n?t(n):t(null,null,k=s({},e,{components:r}))})})}function l(e){return e.__id__||(e.__id__=P++)}function u(e){return e.reduce(function(e,t){return e.push.apply(e,T[l(t)]),e},[])}function d(e,t){b.default(x,e,function(n,r){if(null==r)return void t();S=s({},r,{location:e});for(var i=u(f.default(k,S).leaveRoutes),a=void 0,o=0,l=i.length;null==a&&o<l;++o)a=i[o](e);t(a)})}function m(){if(k.routes){for(var e=u(k.routes),t=void 0,n=0,r=e.length;"string"!=typeof t&&n<r;++n)t=e[n]();return t}}function v(e,t){var n=l(e),r=T[n];if(null==r){var i=!a(T);r=T[n]=[t],i&&(M=C.listenBefore(d),C.listenBeforeUnload&&(N=C.listenBeforeUnload(m)))}else r.indexOf(t)===-1&&r.push(t);return function(){var e=T[n];if(null!=e){var r=e.filter(function(e){return e!==t});0===r.length?(delete T[n],a(T)||(M&&(M(),M=null),N&&(N(),N=null))):T[n]=r}}}function y(e){return C.listen(function(t){k.location===t?e(null,k):r(t,function(t,n,r){t?e(t):n?C.transitionTo(n):r&&e(null,r)})})}var _=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],x=_.routes,E=i(_,["routes"]),C=h.default(e)(E),k={},S=void 0,P=1,T={},M=void 0,N=void 0;return s({},C,{isActive:t,match:r,listenBeforeLeavingRoute:v,listen:y})}}t.__esModule=!0;var s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l=n(8),c=(r(l),n(27)),u=n(230),h=r(u),d=n(306),f=r(d),p=n(305),m=n(309),g=r(m),v=n(307),w=r(v),y=n(311),b=r(y);t.default=o,e.exports=t.default},function(e,t,n){"use strict";function r(e,t,n){this.props=e,this.context=t,this.refs=o,this.updater=n||a}var i=n(25),a=n(62),o=(n(101),n(26));n(1),n(2);r.prototype.isReactComponent={},r.prototype.setState=function(e,t){"object"!=typeof e&&"function"!=typeof e&&null!=e?i("85"):void 0,this.updater.enqueueSetState(this,e),t&&this.updater.enqueueCallback(this,t,"setState")},r.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this),e&&this.updater.enqueueCallback(this,e,"forceUpdate")};e.exports=r},function(e,t,n){"use strict";function r(e,t){}var i=(n(2),{isMounted:function(e){return!1},enqueueCallback:function(e,t){},enqueueForceUpdate:function(e){r(e,"forceUpdate")},enqueueReplaceState:function(e,t){r(e,"replaceState")},enqueueSetState:function(e,t){r(e,"setState")}});e.exports=i},function(e,t,n){var r=n(204),i=function(){this.data={},this.data=r};i.prototype={getSectionLocale:function(e){return this.data[e].locale},getContent:function(e,t){return this.data[e].getContent(t)},getTitle:function(e){return this.data[e].title}},e.exports=i},function(e,t,n){"use strict";var r=n(4),i=r.createClass({displayName:"SectionHeader",statics:{locale:""},render:function(){var e=i.locale;"undefined"!=typeof window&&window.location.toString().indexOf(e)===-1&&(e="");var t=(e?"./"+e+"/":".")+"#"+this.props.name;return r.createElement("h2",{id:this.props.name,"data-num":this.props.number},r.createElement("a",{href:t},this.props.title))},componentDidMount:function(){if("undefined"!=typeof window&&window.location){var e=window.location.hash;e&&(window.location=window.location.hash)}}});e.exports=i},function(e,t,n){!function(){"use strict";function t(e,t,n,r,i){"undefined"==typeof i&&(i=.5);var a=u.projectionratio(i,e),o=1-a,s={x:a*t.x+o*r.x,y:a*t.y+o*r.y},l=u.abcratio(i,e),c={x:n.x+(n.x-s.x)/l,y:n.y+(n.y-s.y)/l};return{A:c,B:n,C:s}}var r=Math.abs,i=Math.min,a=Math.max,o=Math.acos,s=Math.sqrt,l=Math.PI,c={x:0,y:0,z:0},u=n(66),h=n(206),d=function(e){var t=e&&e.forEach?e:[].slice.call(arguments),n=!1;if("object"==typeof t[0]){n=t.length;var i=[];t.forEach(function(e){["x","y","z"].forEach(function(t){"undefined"!=typeof e[t]&&i.push(e[t])})}),t=i}var a=!1,o=t.length;if(n){if(n>4){if(1!==arguments.length)throw new Error("Only new Bezier(point[]) is accepted for 4th and higher order curves");a=!0}}else if(6!==o&&8!==o&&9!==o&&12!==o&&1!==arguments.length)throw new Error("Only new Bezier(point[]) is accepted for 4th and higher order curves");var s=!a&&(9===o||12===o)||e&&e[0]&&"undefined"!=typeof e[0].z;this._3d=s;for(var l=[],c=0,h=s?3:2;c<o;c+=h){var d={x:t[c],y:t[c+1]};s&&(d.z=t[c+2]),l.push(d)}this.order=l.length-1,this.points=l;var f=["x","y"];s&&f.push("z"),this.dims=f,this.dimlen=f.length,function(e){for(var t=e.order,n=e.points,i=u.align(n,{p1:n[0],p2:n[t]}),a=0;a<i.length;a++)if(r(i[a].y)>1e-4)return void(e._linear=!1);e._linear=!0}(this),this._t1=0,this._t2=1,this.update()};d.fromSVG=function(e){var t=e.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/g).map(parseFloat),n=/[cq]/.test(e);return n?(t=t.map(function(e,n){return n<2?e:e+t[n%2]}),new d(t)):new d(t)},d.quadraticFromPoints=function(e,n,r,i){if("undefined"==typeof i&&(i=.5),0===i)return new d(n,n,r);if(1===i)return new d(e,n,n);var a=t(2,e,n,r,i);return new d(e,a.A,r)},d.cubicFromPoints=function(e,n,r,i,a){"undefined"==typeof i&&(i=.5);var o=t(3,e,n,r,i);"undefined"==typeof a&&(a=u.dist(n,o.C));var s=a*(1-i)/i,l=u.dist(e,r),c=(r.x-e.x)/l,h=(r.y-e.y)/l,f=a*c,p=a*h,m=s*c,g=s*h,v={x:n.x-f,y:n.y-p},w={x:n.x+m,y:n.y+g},y=o.A,b={x:y.x+(v.x-y.x)/(1-i),y:y.y+(v.y-y.y)/(1-i)},_={x:y.x+(w.x-y.x)/i,y:y.y+(w.y-y.y)/i},x={x:e.x+(b.x-e.x)/i,y:e.y+(b.y-e.y)/i},E={x:r.x+(_.x-r.x)/(1-i),y:r.y+(_.y-r.y)/(1-i)};return new d(e,x,E,r)};var f=function(){return u};d.getUtils=f,d.prototype={getUtils:f,valueOf:function(){return this.toString()},toString:function(){return u.pointsToString(this.points)},toSVG:function(e){if(this._3d)return!1;for(var t=this.points,n=t[0].x,r=t[0].y,i=["M",n,r,2===this.order?"Q":"C"],a=1,o=t.length;a<o;a++)i.push(t[a].x),i.push(t[a].y);return i.join(" ")},update:function(){this.dpoints=[];for(var e=this.points,t=e.length,n=t-1;t>1;t--,n--){for(var r,i=[],a=0;a<n;a++)r={x:n*(e[a+1].x-e[a].x),y:n*(e[a+1].y-e[a].y)},this._3d&&(r.z=n*(e[a+1].z-e[a].z)),i.push(r);this.dpoints.push(i),e=i}this.computedirection()},computedirection:function(){var e=this.points,t=u.angle(e[0],e[this.order],e[1]);this.clockwise=t>0},length:function(){return u.length(this.derivative.bind(this))},_lut:[],getLUT:function(e){if(e=e||100,this._lut.length===e)return this._lut;this._lut=[];for(var t=0;t<=e;t++)this._lut.push(this.compute(t/e));return this._lut},on:function(e,t){t=t||5;for(var n,r=this.getLUT(),i=[],a=0,o=0;o<r.length;o++)n=r[o],u.dist(n,e)<t&&(i.push(n),a+=o/r.length);return!!i.length&&(a/=i.length)},project:function(e){var t=this.getLUT(),n=t.length-1,r=u.closest(t,e),i=r.mdist,a=r.mpos;if(0===a||a===n){var o=a/n,s=this.compute(o);return s.t=o,s.d=i,s}var l,o,c,h,d=(a-1)/n,f=(a+1)/n,p=.1/n;for(i+=1,o=d,l=o;o<f+p;o+=p)c=this.compute(o),h=u.dist(e,c),h<i&&(i=h,l=o);return c=this.compute(l),c.t=l,c.d=i,c},get:function(e){return this.compute(e)},point:function(e){return this.points[e]},compute:function(e){if(0===e)return this.points[0];if(1===e)return this.points[this.order];var t=this.points,n=1-e;if(1===this.order)return u={x:n*t[0].x+e*t[1].x,y:n*t[0].y+e*t[1].y},this._3d&&(u.z=n*t[0].z+e*t[1].z),u;if(this.order<4){var r,i,a,o=n*n,s=e*e,l=0;2===this.order?(t=[t[0],t[1],t[2],c],r=o,i=n*e*2,a=s):3===this.order&&(r=o*n,i=o*e*3,a=n*s*3,l=e*s);var u={x:r*t[0].x+i*t[1].x+a*t[2].x+l*t[3].x,y:r*t[0].y+i*t[1].y+a*t[2].y+l*t[3].y};return this._3d&&(u.z=r*t[0].z+i*t[1].z+a*t[2].z+l*t[3].z),u}for(var h=JSON.parse(JSON.stringify(this.points));h.length>1;){for(var d=0;d<h.length-1;d++)h[d]={x:h[d].x+(h[d+1].x-h[d].x)*e,y:h[d].y+(h[d+1].y-h[d].y)*e},"undefined"!=typeof h[d].z&&(h[d]=h[d].z+(h[d+1].z-h[d].z)*e);h.splice(h.length-1,1)}return h[0]},raise:function(){for(var e,t,n,r=this.points,i=[r[0]],a=r.length,e=1;e<a;e++)t=r[e],n=r[e-1],i[e]={x:(a-e)/a*t.x+e/a*n.x,y:(a-e)/a*t.y+e/a*n.y};return i[a]=r[a-1],new d(i)},derivative:function(e){var t,n,r=1-e,i=0,a=this.dpoints[0];2===this.order&&(a=[a[0],a[1],c],t=r,n=e),3===this.order&&(t=r*r,n=r*e*2,i=e*e);var o={x:t*a[0].x+n*a[1].x+i*a[2].x,y:t*a[0].y+n*a[1].y+i*a[2].y};return this._3d&&(o.z=t*a[0].z+n*a[1].z+i*a[2].z),o},inflections:function(){return u.inflections(this.points)},normal:function(e){return this._3d?this.__normal3(e):this.__normal2(e)},__normal2:function(e){var t=this.derivative(e),n=s(t.x*t.x+t.y*t.y);return{x:-t.y/n,y:t.x/n}},__normal3:function(e){var t=this.derivative(e),n=this.derivative(e+.01),r=s(t.x*t.x+t.y*t.y+t.z*t.z),i=s(n.x*n.x+n.y*n.y+n.z*n.z);t.x/=r,t.y/=r,t.z/=r,n.x/=i,n.y/=i,n.z/=i;var a={x:n.y*t.z-n.z*t.y,y:n.z*t.x-n.x*t.z,z:n.x*t.y-n.y*t.x},o=s(a.x*a.x+a.y*a.y+a.z*a.z);a.x/=o,a.y/=o,a.z/=o;var l=[a.x*a.x,a.x*a.y-a.z,a.x*a.z+a.y,a.x*a.y+a.z,a.y*a.y,a.y*a.z-a.x,a.x*a.z-a.y,a.y*a.z+a.x,a.z*a.z],c={x:l[0]*t.x+l[1]*t.y+l[2]*t.z,y:l[3]*t.x+l[4]*t.y+l[5]*t.z,z:l[6]*t.x+l[7]*t.y+l[8]*t.z};return c},hull:function(e){var t,n=this.points,r=[],i=[],a=0,o=0,s=0;for(i[a++]=n[0],i[a++]=n[1],i[a++]=n[2],3===this.order&&(i[a++]=n[3]);n.length>1;){for(r=[],o=0,s=n.length-1;o<s;o++)t=u.lerp(e,n[o],n[o+1]),i[a++]=t,r.push(t);n=r}return i},split:function(e,t){if(0===e&&t)return this.split(t).left;if(1===t)return this.split(e).right;var n=this.hull(e),r={left:new d(2===this.order?[n[0],n[3],n[5]]:[n[0],n[4],n[7],n[9]]),right:new d(2===this.order?[n[5],n[4],n[2]]:[n[9],n[8],n[6],n[3]]),span:n};if(r.left._t1=u.map(0,0,1,this._t1,this._t2),r.left._t2=u.map(e,0,1,this._t1,this._t2),r.right._t1=u.map(e,0,1,this._t1,this._t2),r.right._t2=u.map(1,0,1,this._t1,this._t2),!t)return r;t=u.map(t,e,1,0,1);var i=r.right.split(t);return i.left},extrema:function(){var e,t,n=this.dims,r={},i=[];return n.forEach(function(n){t=function(e){return e[n]},e=this.dpoints[0].map(t),r[n]=u.droots(e),3===this.order&&(e=this.dpoints[1].map(t),r[n]=r[n].concat(u.droots(e))),r[n]=r[n].filter(function(e){return e>=0&&e<=1}),i=i.concat(r[n].sort())}.bind(this)),i=i.sort().filter(function(e,t){return i.indexOf(e)===t}),r.values=i,r},bbox:function(){var e=this.extrema(),t={};return this.dims.forEach(function(n){t[n]=u.getminmax(this,n,e[n])}.bind(this)),t},overlaps:function(e){var t=this.bbox(),n=e.bbox();return u.bboxoverlap(t,n)},offset:function(e,t){if("undefined"!=typeof t){var n=this.get(e),r=this.normal(e),i={c:n,n:r,x:n.x+r.x*t,y:n.y+r.y*t};return this._3d&&(i.z=n.z+r.z*t),i}if(this._linear){var a=this.normal(0),o=this.points.map(function(t){var n={x:t.x+e*a.x,y:t.y+e*a.y};return t.z&&r.z&&(n.z=t.z+e*a.z),n});return[new d(o)]}var s=this.reduce();return s.map(function(t){return t.scale(e)})},simple:function(){if(3===this.order){var e=u.angle(this.points[0],this.points[3],this.points[1]),t=u.angle(this.points[0],this.points[3],this.points[2]);if(e>0&&t<0||e<0&&t>0)return!1}var n=this.normal(0),i=this.normal(1),a=n.x*i.x+n.y*i.y;this._3d&&(a+=n.z*i.z);var s=r(o(a));return s<l/3},reduce:function(){var e,t,n=0,i=0,a=.01,o=[],s=[],l=this.extrema().values;for(l.indexOf(0)===-1&&(l=[0].concat(l)),l.indexOf(1)===-1&&l.push(1),n=l[0],e=1;e<l.length;e++)i=l[e],t=this.split(n,i),t._t1=n,t._t2=i,o.push(t),n=i;return o.forEach(function(e){for(n=0,i=0;i<=1;)for(i=n+a;i<=1+a;i+=a)if(t=e.split(n,i),!t.simple()){if(i-=a,r(n-i)<a)return[];t=e.split(n,i),t._t1=u.map(n,0,1,e._t1,e._t2),t._t2=u.map(i,0,1,e._t1,e._t2),s.push(t),n=i;break}n<1&&(t=e.split(n,1),t._t1=u.map(n,0,1,e._t1,e._t2),t._t2=e._t2,s.push(t))}),s},scale:function(e){var t=this.order,n=!1;if("function"==typeof e&&(n=e),n&&2===t)return this.raise().scale(n);var r=this.clockwise,i=n?n(0):e,a=n?n(1):e,o=[this.offset(0,10),this.offset(1,10)],l=u.lli4(o[0],o[0].c,o[1],o[1].c);if(!l)throw new Error("cannot scale this curve. Try reducing it first.");var c=this.points,h=[];return[0,1].forEach(function(e){var n=h[e*t]=u.copy(c[e*t]);n.x+=(e?a:i)*o[e].n.x,n.y+=(e?a:i)*o[e].n.y}.bind(this)),n?([0,1].forEach(function(i){if(2!==this.order||!i){var a=c[i+1],o={x:a.x-l.x,y:a.y-l.y},u=n?n((i+1)/t):e;n&&!r&&(u=-u);var d=s(o.x*o.x+o.y*o.y);o.x/=d,o.y/=d,h[i+1]={x:a.x+u*o.x,y:a.y+u*o.y}}}.bind(this)),new d(h)):([0,1].forEach(function(e){if(2!==this.order||!e){var n=h[e*t],r=this.derivative(e),i={x:n.x+r.x,y:n.y+r.y};h[e+1]=u.lli4(n,i,l,c[e+1])}}.bind(this)),new d(h))},outline:function(e,t,n,r){function i(e,t,n,r,i){return function(a){var o=r/n,s=(r+i)/n,l=t-e;return u.map(a,0,1,e+o*l,e+s*l)}}t="undefined"==typeof t?e:t;var a,o=this.reduce(),s=o.length,l=[],c=[],d=0,f=this.length(),p="undefined"!=typeof n&&"undefined"!=typeof r;o.forEach(function(a){x=a.length(),p?(l.push(a.scale(i(e,n,f,d,x))),c.push(a.scale(i(-t,-r,f,d,x)))):(l.push(a.scale(e)),c.push(a.scale(-t))),d+=x}),c=c.map(function(e){return a=e.points,a[3]?e.points=[a[3],a[2],a[1],a[0]]:e.points=[a[2],a[1],a[0]],e}).reverse();var m=l[0].points[0],g=l[s-1].points[l[s-1].points.length-1],v=c[s-1].points[c[s-1].points.length-1],w=c[0].points[0],y=u.makeline(v,m),b=u.makeline(g,w),_=[y].concat(l).concat([b]).concat(c),x=_.length;return new h(_)},outlineshapes:function(e,t,n){t=t||e;for(var r=this.outline(e,t).curves,i=[],a=1,o=r.length;a<o/2;a++){var s=u.makeshape(r[a],r[o-a],n);s.startcap.virtual=a>1,s.endcap.virtual=a<o/2-1,i.push(s)}return i},intersects:function(e,t){return e?e.p1&&e.p2?this.lineIntersects(e):(e instanceof d&&(e=e.reduce()),this.curveintersects(this.reduce(),e,t)):this.selfintersects(t)},lineIntersects:function(e){var t=i(e.p1.x,e.p2.x),n=i(e.p1.y,e.p2.y),r=a(e.p1.x,e.p2.x),o=a(e.p1.y,e.p2.y),s=this;return u.roots(this.points,e).filter(function(e){var i=s.get(e);return u.between(i.x,t,r)&&u.between(i.y,n,o)})},selfintersects:function(e){var t,n,r,i,a=this.reduce(),o=a.length-2,s=[];for(t=0;t<o;t++)r=a.slice(t,t+1),i=a.slice(t+2),n=this.curveintersects(r,i,e),s=s.concat(n);return s},curveintersects:function(e,t,n){var r=[];e.forEach(function(e){t.forEach(function(t){e.overlaps(t)&&r.push({left:e,right:t})})});var i=[];return r.forEach(function(e){var t=u.pairiteration(e.left,e.right,n);t.length>0&&(i=i.concat(t))}),i},arcs:function(e){e=e||.5;var t=[];return this._iterate(e,t)},_error:function(e,t,n,i){var a=(i-n)/4,o=this.get(n+a),s=this.get(i-a),l=u.dist(e,t),c=u.dist(e,o),h=u.dist(e,s);return r(c-l)+r(h-l)},_iterate:function(e,t){var n,r=0,i=1;do{n=0,i=1;var a,o,s,l,c,h=this.get(r),d=!1,f=!1,p=i,m=1,g=0;do{f=d,l=s,p=(r+i)/2,g++,a=this.get(p),o=this.get(i),s=u.getccenter(h,a,o),s.interval={start:r,end:i};var v=this._error(s,h,r,i);if(d=v<=e,c=f&&!d,c||(m=i),d){if(i>=1){m=1,l=s;break}i+=(i-r)/2}else i=p}while(!c&&n++<100);if(n>=100){console.error("arc abstraction somehow failed...");break}l=l?l:s,t.push(l),r=m}while(i<1);return t}},e.exports=d}()},function(e,t,n){!function(){"use strict";var t=Math.abs,r=Math.cos,i=Math.sin,a=Math.acos,o=Math.atan2,s=Math.sqrt,l=Math.pow,c=function(e){return e<0?-l(-e,1/3):l(e,1/3)},u=Math.PI,h=2*u,d=u/2,f=1e-6,p={Tvalues:[-.06405689286260563,.06405689286260563,-.1911188674736163,.1911188674736163,-.3150426796961634,.3150426796961634,-.4337935076260451,.4337935076260451,-.5454214713888396,.5454214713888396,-.6480936519369755,.6480936519369755,-.7401241915785544,.7401241915785544,-.820001985973903,.820001985973903,-.8864155270044011,.8864155270044011,-.9382745520027328,.9382745520027328,-.9747285559713095,.9747285559713095,-.9951872199970213,.9951872199970213],Cvalues:[.12793819534675216,.12793819534675216,.1258374563468283,.1258374563468283,.12167047292780339,.12167047292780339,.1155056680537256,.1155056680537256,.10744427011596563,.10744427011596563,.09761865210411388,.09761865210411388,.08619016153195327,.08619016153195327,.0733464814110803,.0733464814110803,.05929858491543678,.05929858491543678,.04427743881741981,.04427743881741981,.028531388628933663,.028531388628933663,.0123412297999872,.0123412297999872],arcfn:function(e,t){var n=t(e),r=n.x*n.x+n.y*n.y;return"undefined"!=typeof n.z&&(r+=n.z*n.z),s(r)},between:function(e,t,n){return t<=e&&e<=n||p.approximately(e,t)||p.approximately(e,n)},approximately:function(e,n,r){return t(e-n)<=(r||f)},length:function(e){var t,n,r=.5,i=0,a=p.Tvalues.length;for(t=0;t<a;t++)n=r*p.Tvalues[t]+r,i+=p.Cvalues[t]*p.arcfn(n,e);return r*i},map:function(e,t,n,r,i){var a=n-t,o=i-r,s=e-t,l=s/a;return r+o*l},lerp:function(e,t,n){var r={x:t.x+e*(n.x-t.x),y:t.y+e*(n.y-t.y)};return t.z&&n.z&&(r.z=t.z+e*(n.z-t.z)),r},pointToString:function(e){var t=e.x+"/"+e.y;return"undefined"!=typeof e.z&&(t+="/"+e.z),t},pointsToString:function(e){return"["+e.map(p.pointToString).join(", ")+"]"},copy:function(e){return JSON.parse(JSON.stringify(e))},angle:function(e,t,n){var r,i=t.x-e.x,a=t.y-e.y,l=n.x-e.x,c=n.y-e.y,u=i*c-a*l,h=s(i*i+a*a),d=s(l*l+c*c);return i/=h,a/=h,l/=d,c/=d,r=i*l+a*c,o(u,r)},round:function(e,t){var n=""+e,r=n.indexOf(".");return parseFloat(n.substring(0,r+1+t))},dist:function(e,t){var n=e.x-t.x,r=e.y-t.y;return s(n*n+r*r)},closest:function(e,t){var n,r,i=l(2,63);return e.forEach(function(e,a){r=p.dist(t,e),r<i&&(i=r,n=a)}),{mdist:i,mpos:n}},abcratio:function(e,n){if(2!==n&&3!==n)return!1;if("undefined"==typeof e)e=.5;else if(0===e||1===e)return e;var r=l(e,n)+l(1-e,n),i=r-1;return t(i/r)},projectionratio:function(e,t){if(2!==t&&3!==t)return!1;if("undefined"==typeof e)e=.5;else if(0===e||1===e)return e;var n=l(1-e,t),r=l(e,t)+n;return n/r},lli8:function(e,t,n,r,i,a,o,s){var l=(e*r-t*n)*(i-o)-(e-n)*(i*s-a*o),c=(e*r-t*n)*(a-s)-(t-r)*(i*s-a*o),u=(e-n)*(a-s)-(t-r)*(i-o);return 0!=u&&{x:l/u,y:c/u}},lli4:function(e,t,n,r){var i=e.x,a=e.y,o=t.x,s=t.y,l=n.x,c=n.y,u=r.x,h=r.y;return p.lli8(i,a,o,s,l,c,u,h)},lli:function(e,t){return p.lli4(e,e.c,t,t.c)},makeline:function(e,t){var r=n(65),i=e.x,a=e.y,o=t.x,s=t.y,l=(o-i)/3,c=(s-a)/3;return new r(i,a,i+l,a+c,i+2*l,a+2*c,o,s)},findbbox:function(e){var t=99999999,n=t,r=-t,i=r;return e.forEach(function(e){var a=e.bbox();t>a.x.min&&(t=a.x.min),n>a.y.min&&(n=a.y.min),r<a.x.max&&(r=a.x.max),i<a.y.max&&(i=a.y.max)}),{x:{min:t,mid:(t+r)/2,max:r,size:r-t},y:{min:n,mid:(n+i)/2,max:i,size:i-n}}},shapeintersections:function(e,t,n,r,i){if(!p.bboxoverlap(t,r))return[];var a=[],o=[e.startcap,e.forward,e.back,e.endcap],s=[n.startcap,n.forward,n.back,n.endcap];return o.forEach(function(t){t.virtual||s.forEach(function(r){if(!r.virtual){var o=t.intersects(r,i);o.length>0&&(o.c1=t,o.c2=r,o.s1=e,o.s2=n,a.push(o))}})}),a},makeshape:function(e,t,n){var r=t.points.length,i=e.points.length,a=p.makeline(t.points[r-1],e.points[0]),o=p.makeline(e.points[i-1],t.points[0]),s={startcap:a,forward:e,back:t,endcap:o,bbox:p.findbbox([a,e,t,o])},l=p;return s.intersections=function(e){return l.shapeintersections(s,s.bbox,e,e.bbox,n)},s},getminmax:function(e,t,n){if(!n)return{min:0,max:0};var r,i,a=0x10000000000000000,o=-a;n.indexOf(0)===-1&&(n=[0].concat(n)),n.indexOf(1)===-1&&n.push(1);for(var s=0,l=n.length;s<l;s++)r=n[s],i=e.get(r),i[t]<a&&(a=i[t]),i[t]>o&&(o=i[t]);return{min:a,mid:(a+o)/2,max:o,size:o-a}},align:function(e,t){var n=t.p1.x,a=t.p1.y,s=-o(t.p2.y-a,t.p2.x-n),l=function(e){return{x:(e.x-n)*r(s)-(e.y-a)*i(s),y:(e.x-n)*i(s)+(e.y-a)*r(s)}};return e.map(l)},roots:function(e,t){t=t||{p1:{x:0,y:0},p2:{x:1,y:0}};var n=e.length-1,i=p.align(e,t),o=function(e){return 0<=e&&e<=1};if(2===n){var l=i[0].y,u=i[1].y,d=i[2].y,f=l-2*u+d;if(0!==f){var m=-s(u*u-l*d),g=-l+u,v=-(m+g)/f,w=-(-m+g)/f;return[v,w].filter(o)}return u!==d&&0===f?[(2*u-d)/2*(u-d)].filter(o):[]}var y,v,b,_,x,E=i[0].y,C=i[1].y,k=i[2].y,S=i[3].y,f=-E+3*C-3*k+S,l=(3*E-6*C+3*k)/f,u=(-3*E+3*C)/f,d=E/f,i=(3*u-l*l)/3,P=i/3,T=(2*l*l*l-9*l*u+27*d)/27,M=T/2,N=M*M+P*P*P;if(N<0){var I=-i/3,L=I*I*I,A=s(L),O=-T/(2*A),B=O<-1?-1:O>1?1:O,z=a(B),R=c(A),D=2*R;return b=D*r(z/3)-l/3,_=D*r((z+h)/3)-l/3,x=D*r((z+2*h)/3)-l/3,[b,_,x].filter(o)}if(0===N)return y=M<0?c(-M):-c(M),b=2*y-l/3,_=-y-l/3,[b,_].filter(o);var j=s(N);return y=c(-M+j),v=c(M+j),[y-v-l/3].filter(o)},droots:function(e){if(3===e.length){var t=e[0],n=e[1],r=e[2],i=t-2*n+r;if(0!==i){var a=-s(n*n-t*r),o=-t+n,l=-(a+o)/i,c=-(-a+o)/i;return[l,c]}return n!==r&&0===i?[(2*n-r)/(2*(n-r))]:[]}if(2===e.length){var t=e[0],n=e[1];return t!==n?[t/(t-n)]:[]}},inflections:function(e){if(e.length<4)return[];var t=p.align(e,{p1:e[0],p2:e.slice(-1)[0]}),n=t[2].x*t[1].y,r=t[3].x*t[1].y,i=t[1].x*t[2].y,a=t[3].x*t[2].y,o=18*(-3*n+2*r+3*i-a),s=18*(3*n-r-3*i),l=18*(i-n);if(p.approximately(o,0))return[];var c=s*s-4*o*l,u=Math.sqrt(c),a=2*o;return p.approximately(a,0)?[]:[(u-s)/a,-(s+u)/a].filter(function(e){return 0<=e&&e<=1})},bboxoverlap:function(e,n){var r,i,a,o,s,l=["x","y"],c=l.length;for(r=0;r<c;r++)if(i=l[r],a=e[i].mid,o=n[i].mid,s=(e[i].size+n[i].size)/2,t(a-o)>=s)return!1;return!0},expandbox:function(e,t){t.x.min<e.x.min&&(e.x.min=t.x.min),t.y.min<e.y.min&&(e.y.min=t.y.min),t.z&&t.z.min<e.z.min&&(e.z.min=t.z.min),t.x.max>e.x.max&&(e.x.max=t.x.max),t.y.max>e.y.max&&(e.y.max=t.y.max),t.z&&t.z.max>e.z.max&&(e.z.max=t.z.max),e.x.mid=(e.x.min+e.x.max)/2,e.y.mid=(e.y.min+e.y.max)/2,e.z&&(e.z.mid=(e.z.min+e.z.max)/2),e.x.size=e.x.max-e.x.min,e.y.size=e.y.max-e.y.min,e.z&&(e.z.size=e.z.max-e.z.min)},pairiteration:function(e,t,n){var r=e.bbox(),i=t.bbox(),a=1e5,o=n||.5;if(r.x.size+r.y.size<o&&i.x.size+i.y.size<o)return[(a*(e._t1+e._t2)/2|0)/a+"/"+(a*(t._t1+t._t2)/2|0)/a];var s=e.split(.5),l=t.split(.5),c=[{left:s.left,right:l.left},{left:s.left,right:l.right},{left:s.right,right:l.right},{left:s.right,right:l.left}];c=c.filter(function(e){return p.bboxoverlap(e.left.bbox(),e.right.bbox())});var u=[];return 0===c.length?u:(c.forEach(function(e){u=u.concat(p.pairiteration(e.left,e.right,o))}),u=u.filter(function(e,t){return u.indexOf(e)===t}))},getccenter:function(e,t,n){var a,s=t.x-e.x,l=t.y-e.y,c=n.x-t.x,u=n.y-t.y,f=s*r(d)-l*i(d),m=s*i(d)+l*r(d),g=c*r(d)-u*i(d),v=c*i(d)+u*r(d),w=(e.x+t.x)/2,y=(e.y+t.y)/2,b=(t.x+n.x)/2,_=(t.y+n.y)/2,x=w+f,E=y+m,C=b+g,k=_+v,S=p.lli8(w,y,x,E,b,_,C,k),P=p.dist(S,e),T=o(e.y-S.y,e.x-S.x),M=o(t.y-S.y,t.x-S.x),N=o(n.y-S.y,n.x-S.x);return T<N?((T>M||M>N)&&(T+=h),T>N&&(a=N,N=T,T=a)):N<M&&M<T?(a=N,N=T,T=a):N+=h,S.s=T,S.e=N,S.r=P,S}};e.exports=p}()},function(e,t,n){"use strict";var r=n(9),i={listen:function(e,t,n){return e.addEventListener?(e.addEventListener(t,n,!1),{remove:function(){e.removeEventListener(t,n,!1)}}):e.attachEvent?(e.attachEvent("on"+t,n),{remove:function(){e.detachEvent("on"+t,n)}}):void 0},capture:function(e,t,n){return e.addEventListener?(e.addEventListener(t,n,!0),{remove:function(){e.removeEventListener(t,n,!0)}}):{remove:r}},registerDefault:function(){}};e.exports=i},function(e,t,n){"use strict";function r(e){try{e.focus()}catch(e){}}e.exports=r},function(e,t,n){"use strict";function r(){if("undefined"==typeof document)return null;try{return document.activeElement||document.body}catch(e){return document.body}}e.exports=r},function(e,t,n){"use strict";function r(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent("on"+t,n)}function i(e,t,n){e.removeEventListener?e.removeEventListener(t,n,!1):e.detachEvent("on"+t,n)}function a(){return window.location.href.split("#")[1]||""}function o(e){window.location.replace(window.location.pathname+window.location.search+"#"+e)}function s(){return window.location.pathname+window.location.search+window.location.hash}function l(e){e&&window.history.go(e)}function c(e,t){t(window.confirm(e))}function u(){var e=navigator.userAgent;return(e.indexOf("Android 2.")===-1&&e.indexOf("Android 4.0")===-1||e.indexOf("Mobile Safari")===-1||e.indexOf("Chrome")!==-1||e.indexOf("Windows Phone")!==-1)&&(e.indexOf("CriOS")===-1&&(window.history&&"pushState"in window.history))}function h(){var e=navigator.userAgent;return e.indexOf("Firefox")===-1}t.__esModule=!0,t.addEventListener=r,t.removeEventListener=i,t.getHashPath=a,t.replaceHashPath=o,t.getWindowPath=s,t.go=l,t.getUserConfirmation=c,t.supportsHistory=u,t.supportsGoWithoutReloadUsingHash=h},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){return Math.random().toString(36).substr(2,e)}function a(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.key===t.key&&c.default(e.state,t.state)}function o(){function e(e){return R.push(e),function(){R=R.filter(function(t){return t!==e})}}function t(){return q&&q.action===h.POP?D.indexOf(q.key):F?D.indexOf(F.key):-1}function n(e){var n=t();F=e,F.action===h.PUSH?D=[].concat(D.slice(0,n+1),[F.key]):F.action===h.REPLACE&&(D[n]=F.key),j.forEach(function(e){e(F)})}function r(e){if(j.push(e),F)e(F);else{var t=I();D=[t.key],n(t)}return function(){j=j.filter(function(t){return t!==e})}}function o(e,t){u.loopAsync(R.length,function(t,n,r){m.default(R[t],e,function(e){null!=e?r(e):n()})},function(e){z&&"string"==typeof e?z(e,function(e){t(e!==!1)}):t(e!==!1)})}function l(e){F&&a(F,e)||(q=e,o(e,function(t){if(q===e)if(t){if(e.action===h.PUSH){var r=_(F),i=_(e);i===r&&(e.action=h.REPLACE)}L(e)!==!1&&n(e)}else if(F&&e.action===h.POP){var a=D.indexOf(F.key),o=D.indexOf(e.key);a!==-1&&o!==-1&&O(a-o)}}))}function c(e){l(E(e,h.PUSH,w()))}function d(e){l(E(e,h.REPLACE,w()))}function p(){O(-1)}function g(){O(1)}function w(){return i(B)}function _(e){if(null==e||"string"==typeof e)return e;var t=e.pathname,n=e.search,r=e.hash,i=t;return n&&(i+=n),r&&(i+=r),i}function x(e){return _(e)}function E(e,t){var n=arguments.length<=2||void 0===arguments[2]?w():arguments[2];return"object"==typeof t&&("string"==typeof e&&(e=v.default(e)),e=s({},e,{state:t}),t=n,n=arguments[3]||w()),f.default(e,t,n)}function C(e){F?(k(F,e),n(F)):k(I(),e)}function k(e,t){e.state=s({},e.state,t),A(e.key,e.state)}function S(e){R.indexOf(e)===-1&&R.push(e)}function P(e){R=R.filter(function(t){return t!==e})}function T(e,t){"string"==typeof t&&(t=v.default(t)),c(s({state:e},t))}function M(e,t){"string"==typeof t&&(t=v.default(t)),d(s({state:e},t))}var N=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],I=N.getCurrentLocation,L=N.finishTransition,A=N.saveState,O=N.go,B=N.keyLength,z=N.getUserConfirmation;"number"!=typeof B&&(B=b);var R=[],D=[],j=[],F=void 0,q=void 0;return{listenBefore:e,listen:r,transitionTo:l,push:c,replace:d,go:O,goBack:p,goForward:g,createKey:w,createPath:_,createHref:x,createLocation:E,setState:y.default(C,"setState is deprecated; use location.key to save state instead"),registerTransitionHook:y.default(S,"registerTransitionHook is deprecated; use listenBefore instead"),unregisterTransitionHook:y.default(P,"unregisterTransitionHook is deprecated; use the callback returned from listenBefore instead"),pushState:y.default(T,"pushState is deprecated; use push instead"),replaceState:y.default(M,"replaceState is deprecated; use replace instead")}}t.__esModule=!0;var s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l=n(208),c=r(l),u=n(223),h=n(27),d=n(227),f=r(d),p=n(42),m=r(p),g=n(19),v=r(g),w=n(41),y=r(w),b=6;t.default=o,e.exports=t.default},function(e,t,n){"use strict";function r(e){var t=e.match(/^https?:\/\/[^\/]*/);return null==t?e:e.substring(t[0].length)}t.__esModule=!0,t.default=r,e.exports=t.default},function(e,t){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function i(e){if(u===setTimeout)return setTimeout(e,0);if((u===n||!u)&&setTimeout)return u=setTimeout,setTimeout(e,0);try{return u(e,0)}catch(t){try{return u.call(null,e,0)}catch(t){return u.call(this,e,0)}}}function a(e){if(h===clearTimeout)return clearTimeout(e);if((h===r||!h)&&clearTimeout)return h=clearTimeout,clearTimeout(e);try{return h(e)}catch(t){try{return h.call(null,e)}catch(t){return h.call(this,e)}}}function o(){m&&f&&(m=!1,f.length?p=f.concat(p):g=-1,p.length&&s())}function s(){if(!m){var e=i(o);m=!0;for(var t=p.length;t;){for(f=p,p=[];++g<t;)f&&f[g].run();g=-1,t=p.length}f=null,m=!1,a(e)}}function l(e,t){this.fun=e,this.array=t}function c(){}var u,h,d=e.exports={};!function(){try{u="function"==typeof setTimeout?setTimeout:n}catch(e){u=n}try{h="function"==typeof clearTimeout?clearTimeout:r}catch(e){h=r}}();var f,p=[],m=!1,g=-1;d.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];p.push(new l(e,t)),1!==p.length||m||i(s)},l.prototype.run=function(){this.fun.apply(null,this.array)},d.title="browser",d.browser=!0,d.env={},d.argv=[],d.version="",d.versions={},d.on=c,d.addListener=c,d.once=c,d.off=c,d.removeListener=c,d.removeAllListeners=c,d.emit=c,d.binding=function(e){throw new Error("process.binding is not supported")},d.cwd=function(){return"/"},d.chdir=function(e){throw new Error("process.chdir is not supported")},d.umask=function(){return 0}},function(e,t,n){"use strict";function r(e,t){return e+t.charAt(0).toUpperCase()+t.substring(1)}var i={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridColumn:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},a=["Webkit","ms","Moz","O"];Object.keys(i).forEach(function(e){a.forEach(function(t){i[r(t,e)]=i[e]})});var o={background:{backgroundAttachment:!0,backgroundColor:!0,backgroundImage:!0,backgroundPositionX:!0,backgroundPositionY:!0,backgroundRepeat:!0},backgroundPosition:{backgroundPositionX:!0,backgroundPositionY:!0},border:{borderWidth:!0,borderStyle:!0,borderColor:!0},borderBottom:{borderBottomWidth:!0,borderBottomStyle:!0,borderBottomColor:!0},borderLeft:{borderLeftWidth:!0,borderLeftStyle:!0,borderLeftColor:!0},borderRight:{borderRightWidth:!0,borderRightStyle:!0,borderRightColor:!0},borderTop:{borderTopWidth:!0,borderTopStyle:!0,borderTopColor:!0},font:{fontStyle:!0,fontVariant:!0,fontWeight:!0,fontSize:!0,lineHeight:!0,fontFamily:!0},outline:{outlineWidth:!0,outlineStyle:!0,outlineColor:!0}},s={isUnitlessNumber:i,shorthandPropertyExpansions:o};e.exports=s},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(3),a=n(17),o=(n(1),function(){function e(t){r(this,e),this._callbacks=null, +this._contexts=null,this._arg=t}return e.prototype.enqueue=function(e,t){this._callbacks=this._callbacks||[],this._callbacks.push(e),this._contexts=this._contexts||[],this._contexts.push(t)},e.prototype.notifyAll=function(){var e=this._callbacks,t=this._contexts,n=this._arg;if(e&&t){e.length!==t.length?i("24"):void 0,this._callbacks=null,this._contexts=null;for(var r=0;r<e.length;r++)e[r].call(t[r],n);e.length=0,t.length=0}},e.prototype.checkpoint=function(){return this._callbacks?this._callbacks.length:0},e.prototype.rollback=function(e){this._callbacks&&this._contexts&&(this._callbacks.length=e,this._contexts.length=e)},e.prototype.reset=function(){this._callbacks=null,this._contexts=null},e.prototype.destructor=function(){this.reset()},e}());e.exports=a.addPoolingTo(o)},function(e,t,n){"use strict";function r(e){return!!c.hasOwnProperty(e)||!l.hasOwnProperty(e)&&(s.test(e)?(c[e]=!0,!0):(l[e]=!0,!1))}function i(e,t){return null==t||e.hasBooleanValue&&!t||e.hasNumericValue&&isNaN(t)||e.hasPositiveNumericValue&&t<1||e.hasOverloadedBooleanValue&&t===!1}var a=n(21),o=(n(6),n(11),n(295)),s=(n(2),new RegExp("^["+a.ATTRIBUTE_NAME_START_CHAR+"]["+a.ATTRIBUTE_NAME_CHAR+"]*$")),l={},c={},u={createMarkupForID:function(e){return a.ID_ATTRIBUTE_NAME+"="+o(e)},setAttributeForID:function(e,t){e.setAttribute(a.ID_ATTRIBUTE_NAME,t)},createMarkupForRoot:function(){return a.ROOT_ATTRIBUTE_NAME+'=""'},setAttributeForRoot:function(e){e.setAttribute(a.ROOT_ATTRIBUTE_NAME,"")},createMarkupForProperty:function(e,t){var n=a.properties.hasOwnProperty(e)?a.properties[e]:null;if(n){if(i(n,t))return"";var r=n.attributeName;return n.hasBooleanValue||n.hasOverloadedBooleanValue&&t===!0?r+'=""':r+"="+o(t)}return a.isCustomAttribute(e)?null==t?"":e+"="+o(t):null},createMarkupForCustomAttribute:function(e,t){return r(e)&&null!=t?e+"="+o(t):""},setValueForProperty:function(e,t,n){var r=a.properties.hasOwnProperty(t)?a.properties[t]:null;if(r){var o=r.mutationMethod;if(o)o(e,n);else{if(i(r,n))return void this.deleteValueForProperty(e,t);if(r.mustUseProperty)e[r.propertyName]=n;else{var s=r.attributeName,l=r.attributeNamespace;l?e.setAttributeNS(l,s,""+n):r.hasBooleanValue||r.hasOverloadedBooleanValue&&n===!0?e.setAttribute(s,""):e.setAttribute(s,""+n)}}}else if(a.isCustomAttribute(t))return void u.setValueForAttribute(e,t,n)},setValueForAttribute:function(e,t,n){if(r(t)){null==n?e.removeAttribute(t):e.setAttribute(t,""+n)}},deleteValueForAttribute:function(e,t){e.removeAttribute(t)},deleteValueForProperty:function(e,t){var n=a.properties.hasOwnProperty(t)?a.properties[t]:null;if(n){var r=n.mutationMethod;if(r)r(e,void 0);else if(n.mustUseProperty){var i=n.propertyName;n.hasBooleanValue?e[i]=!1:e[i]=""}else e.removeAttribute(n.attributeName)}else a.isCustomAttribute(t)&&e.removeAttribute(t)}};e.exports=u},function(e,t,n){"use strict";var r={hasCachedChildNodes:1};e.exports=r},function(e,t,n){"use strict";function r(){if(this._rootNodeID&&this._wrapperState.pendingUpdate){this._wrapperState.pendingUpdate=!1;var e=this._currentElement.props,t=s.getValue(e);null!=t&&i(this,Boolean(e.multiple),t)}}function i(e,t,n){var r,i,a=l.getNodeFromInstance(e).options;if(t){for(r={},i=0;i<n.length;i++)r[""+n[i]]=!0;for(i=0;i<a.length;i++){var o=r.hasOwnProperty(a[i].value);a[i].selected!==o&&(a[i].selected=o)}}else{for(r=""+n,i=0;i<a.length;i++)if(a[i].value===r)return void(a[i].selected=!0);a.length&&(a[0].selected=!0)}}function a(e){var t=this._currentElement.props,n=s.executeOnChange(t,e);return this._rootNodeID&&(this._wrapperState.pendingUpdate=!0),c.asap(r,this),n}var o=n(5),s=n(48),l=n(6),c=n(12),u=(n(2),!1),h={getHostProps:function(e,t){return o({},t,{onChange:e._wrapperState.onChange,value:void 0})},mountWrapper:function(e,t){var n=s.getValue(t);e._wrapperState={pendingUpdate:!1,initialValue:null!=n?n:t.defaultValue,listeners:null,onChange:a.bind(e),wasMultiple:Boolean(t.multiple)},void 0===t.value||void 0===t.defaultValue||u||(u=!0)},getSelectValueContext:function(e){return e._wrapperState.initialValue},postUpdateWrapper:function(e){var t=e._currentElement.props;e._wrapperState.initialValue=void 0;var n=e._wrapperState.wasMultiple;e._wrapperState.wasMultiple=Boolean(t.multiple);var r=s.getValue(t);null!=r?(e._wrapperState.pendingUpdate=!1,i(e,Boolean(t.multiple),r)):n!==Boolean(t.multiple)&&(null!=t.defaultValue?i(e,Boolean(t.multiple),t.defaultValue):i(e,Boolean(t.multiple),t.multiple?[]:""))}};e.exports=h},function(e,t,n){"use strict";var r,i={injectEmptyComponentFactory:function(e){r=e}},a={create:function(e){return r(e)}};a.injection=i,e.exports=a},function(e,t,n){"use strict";var r={logTopLevelRenders:!1};e.exports=r},function(e,t,n){"use strict";function r(e){return s?void 0:o("111",e.type),new s(e)}function i(e){return new l(e)}function a(e){return e instanceof l}var o=n(3),s=(n(1),null),l=null,c={injectGenericComponentClass:function(e){s=e},injectTextComponentClass:function(e){l=e}},u={createInternalComponent:r,createInstanceForText:i,isTextComponent:a,injection:c};e.exports=u},function(e,t,n){"use strict";function r(e){return a(document.documentElement,e)}var i=n(254),a=n(213),o=n(68),s=n(69),l={hasSelectionCapabilities:function(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&"text"===e.type||"textarea"===t||"true"===e.contentEditable)},getSelectionInformation:function(){var e=s();return{focusedElem:e,selectionRange:l.hasSelectionCapabilities(e)?l.getSelection(e):null}},restoreSelection:function(e){var t=s(),n=e.focusedElem,i=e.selectionRange;t!==n&&r(n)&&(l.hasSelectionCapabilities(n)&&l.setSelection(n,i),o(n))},getSelection:function(e){var t;if("selectionStart"in e)t={start:e.selectionStart,end:e.selectionEnd};else if(document.selection&&e.nodeName&&"input"===e.nodeName.toLowerCase()){var n=document.selection.createRange();n.parentElement()===e&&(t={start:-n.moveStart("character",-e.value.length),end:-n.moveEnd("character",-e.value.length)})}else t=i.getOffsets(e);return t||{start:0,end:0}},setSelection:function(e,t){var n=t.start,r=t.end;if(void 0===r&&(r=n),"selectionStart"in e)e.selectionStart=n,e.selectionEnd=Math.min(r,e.value.length);else if(document.selection&&e.nodeName&&"input"===e.nodeName.toLowerCase()){var a=e.createTextRange();a.collapse(!0),a.moveStart("character",n),a.moveEnd("character",r-n),a.select()}else i.setOffsets(e,t)}};e.exports=l},function(e,t,n){"use strict";function r(e,t){for(var n=Math.min(e.length,t.length),r=0;r<n;r++)if(e.charAt(r)!==t.charAt(r))return r;return e.length===t.length?-1:n}function i(e){return e?e.nodeType===O?e.documentElement:e.firstChild:null}function a(e){return e.getAttribute&&e.getAttribute(I)||""}function o(e,t,n,r,i){var a;if(_.logTopLevelRenders){var o=e._currentElement.props.child,s=o.type;a="React mount: "+("string"==typeof s?s:s.displayName||s.name),console.time(a)}var l=C.mountComponent(e,n,null,y(e,t),i,0);a&&console.timeEnd(a),e._renderedComponent._topLevelWrapper=e,j._mountImageIntoNode(l,t,e,r,n)}function s(e,t,n,r){var i=S.ReactReconcileTransaction.getPooled(!n&&b.useCreateElement);i.perform(o,null,e,t,i,n,r),S.ReactReconcileTransaction.release(i)}function l(e,t,n){for(C.unmountComponent(e,n),t.nodeType===O&&(t=t.documentElement);t.lastChild;)t.removeChild(t.lastChild)}function c(e){var t=i(e);if(t){var n=w.getInstanceFromNode(t);return!(!n||!n._hostParent)}}function u(e){return!(!e||e.nodeType!==A&&e.nodeType!==O&&e.nodeType!==B)}function h(e){var t=i(e),n=t&&w.getInstanceFromNode(t);return n&&!n._hostParent?n:null}function d(e){var t=h(e);return t?t._hostContainerInfo._topLevelWrapper:null}var f=n(3),p=n(20),m=n(21),g=n(23),v=n(33),w=(n(15),n(6)),y=n(248),b=n(250),_=n(80),x=n(30),E=(n(11),n(264)),C=n(22),k=n(51),S=n(12),P=n(26),T=n(90),M=(n(1),n(37)),N=n(57),I=(n(2),m.ID_ATTRIBUTE_NAME),L=m.ROOT_ATTRIBUTE_NAME,A=1,O=9,B=11,z={},R=1,D=function(){this.rootID=R++};D.prototype.isReactComponent={},D.prototype.render=function(){return this.props.child},D.isReactTopLevelWrapper=!0;var j={TopLevelWrapper:D,_instancesByReactRootID:z,scrollMonitor:function(e,t){t()},_updateRootComponent:function(e,t,n,r,i){return j.scrollMonitor(r,function(){k.enqueueElementInternal(e,t,n),i&&k.enqueueCallbackInternal(e,i)}),e},_renderNewRootComponent:function(e,t,n,r){u(t)?void 0:f("37"),v.ensureScrollValueMonitoring();var i=T(e,!1);S.batchedUpdates(s,i,t,n,r);var a=i._instance.rootID;return z[a]=i,i},renderSubtreeIntoContainer:function(e,t,n,r){return null!=e&&x.has(e)?void 0:f("38"),j._renderSubtreeIntoContainer(e,t,n,r)},_renderSubtreeIntoContainer:function(e,t,n,r){k.validateCallback(r,"ReactDOM.render"),g.isValidElement(t)?void 0:f("39","string"==typeof t?" Instead of passing a string like 'div', pass React.createElement('div') or <div />.":"function"==typeof t?" Instead of passing a class like Foo, pass React.createElement(Foo) or <Foo />.":null!=t&&void 0!==t.props?" This may be caused by unintentionally loading two independent copies of React.":"");var o,s=g.createElement(D,{child:t});if(e){var l=x.get(e);o=l._processChildContext(l._context)}else o=P;var u=d(n);if(u){var h=u._currentElement,p=h.props.child;if(N(p,t)){var m=u._renderedComponent.getPublicInstance(),v=r&&function(){r.call(m)};return j._updateRootComponent(u,s,o,n,v),m}j.unmountComponentAtNode(n)}var w=i(n),y=w&&!!a(w),b=c(n),_=y&&!u&&!b,E=j._renderNewRootComponent(s,n,_,o)._renderedComponent.getPublicInstance();return r&&r.call(E),E},render:function(e,t,n){return j._renderSubtreeIntoContainer(null,e,t,n)},unmountComponentAtNode:function(e){u(e)?void 0:f("40");var t=d(e);if(!t){c(e),1===e.nodeType&&e.hasAttribute(L);return!1}return delete z[t._instance.rootID],S.batchedUpdates(l,t,e,!1),!0},_mountImageIntoNode:function(e,t,n,a,o){if(u(t)?void 0:f("41"),a){var s=i(t);if(E.canReuseMarkup(e,s))return void w.precacheNode(n,s);var l=s.getAttribute(E.CHECKSUM_ATTR_NAME);s.removeAttribute(E.CHECKSUM_ATTR_NAME);var c=s.outerHTML;s.setAttribute(E.CHECKSUM_ATTR_NAME,l);var h=e,d=r(h,c),m=" (client) "+h.substring(d-20,d+20)+"\n (server) "+c.substring(d-20,d+20);t.nodeType===O?f("42",m):void 0}if(t.nodeType===O?f("43"):void 0,o.useCreateElement){for(;t.lastChild;)t.removeChild(t.lastChild);p.insertTreeBefore(t,e,null)}else M(t,e),w.precacheNode(n,t.firstChild)}};e.exports=j},function(e,t,n){"use strict";var r=n(3),i=n(23),a=(n(1),{HOST:0,COMPOSITE:1,EMPTY:2,getType:function(e){return null===e||e===!1?a.EMPTY:i.isValidElement(e)?"function"==typeof e.type?a.COMPOSITE:a.HOST:void r("26",e)}});e.exports=a},function(e,t,n){"use strict";var r={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(e){r.currentScrollLeft=e.x,r.currentScrollTop=e.y}};e.exports=r},function(e,t,n){"use strict";function r(e,t){return null==t?i("30"):void 0,null==e?t:Array.isArray(e)?Array.isArray(t)?(e.push.apply(e,t),e):(e.push(t),e):Array.isArray(t)?[e].concat(t):[e,t]}var i=n(3);n(1);e.exports=r},function(e,t,n){"use strict";function r(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)}e.exports=r},function(e,t,n){"use strict";function r(e){for(var t;(t=e._renderedNodeType)===i.COMPOSITE;)e=e._renderedComponent;return t===i.HOST?e._renderedComponent:t===i.EMPTY?null:void 0}var i=n(84);e.exports=r},function(e,t,n){"use strict";function r(){return!a&&i.canUseDOM&&(a="textContent"in document.documentElement?"textContent":"innerText"),a}var i=n(7),a=null;e.exports=r},function(e,t,n){"use strict";function r(e){if(e){var t=e.getName();if(t)return" Check the render method of `"+t+"`."}return""}function i(e){return"function"==typeof e&&"undefined"!=typeof e.prototype&&"function"==typeof e.prototype.mountComponent&&"function"==typeof e.prototype.receiveComponent}function a(e,t){var n;if(null===e||e===!1)n=c.create(a);else if("object"==typeof e){var s=e,l=s.type;if("function"!=typeof l&&"string"!=typeof l){var d="";d+=r(s._owner),o("130",null==l?l:typeof l,d)}"string"==typeof s.type?n=u.createInternalComponent(s):i(s.type)?(n=new s.type(s),n.getHostNode||(n.getHostNode=n.getNativeNode)):n=new h(s)}else"string"==typeof e||"number"==typeof e?n=u.createInstanceForText(e):o("131",typeof e);return n._mountIndex=0,n._mountImage=null,n}var o=n(3),s=n(5),l=n(245),c=n(79),u=n(81),h=(n(292),n(1),n(2),function(e){this.construct(e)});s(h.prototype,l,{_instantiateReactComponent:a}),e.exports=a},function(e,t,n){"use strict";function r(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!i[e.type]:"textarea"===t}var i={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};e.exports=r},function(e,t,n){"use strict";var r=n(7),i=n(36),a=n(37),o=function(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t};r.canUseDOM&&("textContent"in document.documentElement||(o=function(e,t){return 3===e.nodeType?void(e.nodeValue=t):void a(e,i(t))})),e.exports=o},function(e,t,n){"use strict";function r(e,t){return e&&"object"==typeof e&&null!=e.key?c.escape(e.key):t.toString(36)}function i(e,t,n,a){var d=typeof e;if("undefined"!==d&&"boolean"!==d||(e=null),null===e||"string"===d||"number"===d||"object"===d&&e.$$typeof===s)return n(a,e,""===t?u+r(e,0):t),1;var f,p,m=0,g=""===t?u:t+h;if(Array.isArray(e))for(var v=0;v<e.length;v++)f=e[v],p=g+r(f,v),m+=i(f,p,n,a);else{var w=l(e);if(w){var y,b=w.call(e);if(w!==e.entries)for(var _=0;!(y=b.next()).done;)f=y.value,p=g+r(f,_++),m+=i(f,p,n,a);else for(;!(y=b.next()).done;){var x=y.value;x&&(f=x[1],p=g+c.escape(x[0])+h+r(f,0),m+=i(f,p,n,a))}}else if("object"===d){var E="",C=String(e);o("31","[object Object]"===C?"object with keys {"+Object.keys(e).join(", ")+"}":C,E)}}return m}function a(e,t,n){return null==e?0:i(e,"",t,n)}var o=n(3),s=(n(15),n(260)),l=n(291),c=(n(1),n(47)),u=(n(2),"."),h=":";e.exports=a},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function s(e){return 0===e.button}function l(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function c(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0}t.__esModule=!0;var u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},h=n(4),d=r(h),f=d.default.PropTypes,p=f.bool,m=f.object,g=f.string,v=f.func,w=function(e){function t(){a(this,t),e.apply(this,arguments)}return o(t,e),t.prototype.handleClick=function(e){var t=!0;if(this.props.onClick&&this.props.onClick(e),!l(e)&&s(e)){if(e.defaultPrevented===!0&&(t=!1),this.props.target)return void(t||e.preventDefault());if(e.preventDefault(),t){var n=this.props,r=n.state,i=n.to,a=n.query,o=n.hash;o&&(i+=o),this.context.history.pushState(r,i,a)}}},t.prototype.render=function(){var e=this,t=this.props,n=t.to,r=t.query,a=t.hash,o=(t.state,t.activeClassName),s=t.activeStyle,l=t.onlyActiveOnIndex,h=i(t,["to","query","hash","state","activeClassName","activeStyle","onlyActiveOnIndex"]);h.onClick=function(t){return e.handleClick(t)};var f=this.context.history;return f&&(h.href=f.createHref(n,r),a&&(h.href+=a),(o||null!=s&&!c(s))&&f.isActive(n,r,l)&&(o&&(h.className+=""===h.className?o:" "+o),s&&(h.style=u({},h.style,s)))),d.default.createElement("a",h)},t}(h.Component);w.contextTypes={history:m},w.propTypes={to:g.isRequired,query:m,hash:g,state:m,activeStyle:m,activeClassName:g,onlyActiveOnIndex:p.isRequired,onClick:v},w.defaultProps={onlyActiveOnIndex:!1,className:"",style:{}},t.default=w,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var o=n(10),s=r(o),l=n(4),c=r(l),u=n(16),h=n(32),d=n(18),f=c.default.PropTypes,p=f.string,m=f.object,g=function(e){function t(){i(this,t),e.apply(this,arguments)}return a(t,e),t.prototype.render=function(){s.default(!1)},t}(l.Component);g.createRouteFromReactElement=function(e){var t=u.createRouteFromReactElement(e);return t.from&&(t.path=t.from),t.onEnter=function(e,n){var r=e.location,i=e.params,a=void 0;if("/"===t.to.charAt(0))a=h.formatPattern(t.to,i);else if(t.to){var o=e.routes.indexOf(t),s=g.getRoutePattern(e.routes,o-1),l=s.replace(/\/*$/,"/")+t.to;a=h.formatPattern(l,i)}else a=r.pathname;n(t.state||r.state,a,t.query||r.query)},t},g.getRoutePattern=function(e,t){for(var n="",r=t;r>=0;r--){var i=e[r],a=i.path||"";if(n=a.replace(/\/*$/,"/")+n,0===a.indexOf("/"))break}return"/"+n},g.propTypes={path:p,from:p,to:p.isRequired,query:m,state:m,onEnter:d.falsy,children:d.falsy},t.default=g,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s=n(10),l=r(s),c=n(4),u=r(c),h=n(16),d=n(308),f=r(d),p=u.default.PropTypes,m=p.array,g=p.func,v=p.object,w=function(e){function t(){i(this,t),e.apply(this,arguments)}return a(t,e),t.prototype.getChildContext=function(){var e=this.props,t=e.history,n=e.location;return{history:t,location:n}},t.prototype.createElement=function(e,t){return null==e?null:this.props.createElement(e,t)},t.prototype.render=function(){var e=this,t=this.props,n=t.history,r=t.location,i=t.routes,a=t.params,s=t.components,c=null;return s&&(c=s.reduceRight(function(t,s,l){if(null==s)return t;var c=i[l],u=f.default(c,a),d={history:n,location:r,params:a,route:c,routeParams:u,routes:i};if(h.isReactChildren(t))d.children=t;else if(t)for(var p in t)t.hasOwnProperty(p)&&(d[p]=t[p]);if("object"==typeof s){var m={};for(var g in s)s.hasOwnProperty(g)&&(m[g]=e.createElement(s[g],o({key:g},d)));return m}return e.createElement(s,d)},c)),null===c||c===!1||u.default.isValidElement(c)?void 0:l.default(!1),c},t}(c.Component);w.propTypes={history:v.isRequired,createElement:g.isRequired,location:v.isRequired,routes:m.isRequired,params:v.isRequired,components:m.isRequired},w.defaultProps={createElement:u.default.createElement},w.childContextTypes={history:v.isRequired,location:v.isRequired},t.default=w,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(304),a=r(i);t.Router=a.default;var o=n(94),s=r(o);t.Link=s.default;var l=n(298),c=r(l);t.IndexLink=c.default;var u=n(299),h=r(u);t.IndexRedirect=h.default;var d=n(300),f=r(d);t.IndexRoute=f.default;var p=n(95),m=r(p);t.Redirect=m.default;var g=n(302),v=r(g);t.Route=v.default;var w=n(297),y=r(w);t.History=y.default;var b=n(301),_=r(b);t.Lifecycle=_.default;var x=n(303),E=r(x);t.RouteContext=E.default;var C=n(60),k=r(C);t.useRoutes=k.default;var S=n(16);t.createRoutes=S.createRoutes;var P=n(96),T=r(P);t.RoutingContext=T.default;var M=n(18),N=r(M);t.PropTypes=N.default;var I=n(310),L=r(I);t.match=L.default;var A=r(i);t.default=A.default},function(e,t,n){"use strict";function r(e){var t=Function.prototype.toString,n=Object.prototype.hasOwnProperty,r=RegExp("^"+t.call(n).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");try{var i=t.call(e);return r.test(i)}catch(e){return!1}}function i(e){var t=c(e);if(t){var n=t.childIDs;u(e),n.forEach(i)}}function a(e,t,n){return"\n in "+(e||"Unknown")+(t?" (at "+t.fileName.replace(/^.*[\\\/]/,"")+":"+t.lineNumber+")":n?" (created by "+n+")":"")}function o(e){return null==e?"#empty":"string"==typeof e||"number"==typeof e?"#text":"string"==typeof e.type?e.type:e.type.displayName||e.type.name||"Unknown"}function s(e){var t,n=k.getDisplayName(e),r=k.getElement(e),i=k.getOwnerID(e);return i&&(t=k.getDisplayName(i)),a(n,r&&r._source,t)}var l,c,u,h,d,f,p,m=n(25),g=n(15),v=(n(1),n(2),"function"==typeof Array.from&&"function"==typeof Map&&r(Map)&&null!=Map.prototype&&"function"==typeof Map.prototype.keys&&r(Map.prototype.keys)&&"function"==typeof Set&&r(Set)&&null!=Set.prototype&&"function"==typeof Set.prototype.keys&&r(Set.prototype.keys));if(v){var w=new Map,y=new Set;l=function(e,t){w.set(e,t)},c=function(e){return w.get(e)},u=function(e){w.delete(e)},h=function(){return Array.from(w.keys())},d=function(e){y.add(e)},f=function(e){y.delete(e)},p=function(){return Array.from(y.keys())}}else{var b={},_={},x=function(e){return"."+e},E=function(e){return parseInt(e.substr(1),10)};l=function(e,t){var n=x(e);b[n]=t},c=function(e){var t=x(e);return b[t]},u=function(e){var t=x(e);delete b[t]},h=function(){return Object.keys(b).map(E)},d=function(e){var t=x(e);_[t]=!0},f=function(e){var t=x(e);delete _[t]},p=function(){return Object.keys(_).map(E)}}var C=[],k={onSetChildren:function(e,t){var n=c(e);n?void 0:m("144"),n.childIDs=t;for(var r=0;r<t.length;r++){var i=t[r],a=c(i);a?void 0:m("140"),null==a.childIDs&&"object"==typeof a.element&&null!=a.element?m("141"):void 0,a.isMounted?void 0:m("71"),null==a.parentID&&(a.parentID=e),a.parentID!==e?m("142",i,a.parentID,e):void 0}},onBeforeMountComponent:function(e,t,n){var r={element:t,parentID:n,text:null,childIDs:[],isMounted:!1,updateCount:0};l(e,r)},onBeforeUpdateComponent:function(e,t){var n=c(e);n&&n.isMounted&&(n.element=t)},onMountComponent:function(e){var t=c(e);t?void 0:m("144"),t.isMounted=!0;var n=0===t.parentID;n&&d(e)},onUpdateComponent:function(e){var t=c(e);t&&t.isMounted&&t.updateCount++},onUnmountComponent:function(e){var t=c(e);if(t){t.isMounted=!1;var n=0===t.parentID;n&&f(e)}C.push(e)},purgeUnmountedComponents:function(){if(!k._preventPurging){for(var e=0;e<C.length;e++){var t=C[e];i(t)}C.length=0}},isMounted:function(e){var t=c(e);return!!t&&t.isMounted},getCurrentStackAddendum:function(e){var t="";if(e){var n=o(e),r=e._owner;t+=a(n,e._source,r&&r.getName())}var i=g.current,s=i&&i._debugID;return t+=k.getStackAddendumByID(s)},getStackAddendumByID:function(e){for(var t="";e;)t+=s(e),e=k.getParentID(e);return t},getChildIDs:function(e){var t=c(e);return t?t.childIDs:[]},getDisplayName:function(e){var t=k.getElement(e);return t?o(t):null},getElement:function(e){var t=c(e);return t?t.element:null},getOwnerID:function(e){var t=k.getElement(e);return t&&t._owner?t._owner._debugID:null},getParentID:function(e){var t=c(e);return t?t.parentID:null},getSource:function(e){var t=c(e),n=t?t.element:null,r=null!=n?n._source:null;return r},getText:function(e){var t=k.getElement(e);return"string"==typeof t?t:"number"==typeof t?""+t:null},getUpdateCount:function(e){var t=c(e);return t?t.updateCount:0},getRootIDs:p,getRegisteredIDs:h};e.exports=k},function(e,t,n){"use strict";var r="function"==typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103;e.exports=r},function(e,t,n){"use strict";var r={};e.exports=r},function(e,t,n){"use strict";var r=!1;e.exports=r},function(e,t,n){"use strict";function r(e){var t=e&&(i&&e[i]||e[a]);if("function"==typeof t)return t}var i="function"==typeof Symbol&&Symbol.iterator,a="@@iterator";e.exports=r},function(e,t,n){"use strict";var r=n(4),i=n(232),a=n(109);"undefined"!=typeof document&&i.render(r.createElement(a,null),document.getElementById("article")),e.exports={FullArticle:a}},function(e,t){e.exports=function(){}},function(e,t){e.exports=function(e,t,n,r,i,a,o){var s,l,c,u,h=n.length,d=n[0].length;if(t<1)throw new Error("degree must be at least 1 (linear)");if(t>h-1)throw new Error("degree must be less than or equal to point count - 1");if(!i)for(i=[],s=0;s<h;s++)i[s]=1;if(r){if(r.length!==h+t+1)throw new Error("bad knot vector length")}else{var r=[];for(s=0;s<h+t+1;s++)r[s]=s}var f=[t,r.length-1-t],p=r[f[0]],m=r[f[1]];if(o||(e=e*(m-p)+p),e<p||e>m)throw new Error("out of bounds");for(c=f[0];c<f[1]&&!(e>=r[c]&&e<=r[c+1]);c++);var g=[];for(s=0;s<h;s++){for(g[s]=[],l=0;l<d;l++)g[s][l]=n[s][l]*i[s];g[s][d]=i[s]}var v;for(u=1;u<=t+1;u++)for(s=c;s>c-t-1+u;s--)for(v=(e-r[s])/(r[s+t+1-u]-r[s]),l=0;l<d+1;l++)g[s][l]=(1-v)*g[s-1][l]+v*g[s][l];var a=a||[];for(s=0;s<d;s++)a[s]=g[c][s]/g[c][d];return a}},function(e,t,n){var r,i,a=new function(o){var s=new function(){function e(e,t,n,i,a){function o(r,o){o=o||(o=c(t,r))&&(o.get?o:o.value),"string"==typeof o&&"#"===o[0]&&(o=e[o.substring(1)]||o);var u,d="function"==typeof o,f=o,p=a||d&&!o.base?o&&o.get?r in e:e[r]:null;a&&p||(d&&p&&(o.base=p),d&&i!==!1&&(u=r.match(/^([gs]et|is)(([A-Z])(.*))$/))&&(l[u[3].toLowerCase()+u[4]]=u[2]),f&&!d&&f.get&&"function"==typeof f.get&&s.isPlainObject(f)||(f={value:f,writable:!0}),(c(e,r)||{configurable:!0}).configurable&&(f.configurable=!0,f.enumerable=n),h(e,r,f))}var l={};if(t){for(var u in t)t.hasOwnProperty(u)&&!r.test(u)&&o(u);for(var u in l){var d=l[u],f=e["set"+d],p=e["get"+d]||f&&e["is"+d];!p||i!==!0&&0!==p.length||o(u,{get:p,set:f})}}return e}function t(e,t,n){return e&&("length"in e&&!e.getLength&&"number"==typeof e.length?i:a).call(e,t,n=n||e),n}function n(e,t,n){for(var r in t)!t.hasOwnProperty(r)||n&&n[r]||(e[r]=t[r]);return e}var r=/^(statics|enumerable|beans|preserve)$/,i=[].forEach||function(e,t){for(var n=0,r=this.length;n<r;n++)e.call(t,this[n],n,this)},a=function(e,t){for(var n in this)this.hasOwnProperty(n)&&e.call(t,this[n],n,this)},l=Object.create||function(e){return{__proto__:e}},c=Object.getOwnPropertyDescriptor||function(e,t){var n=e.__lookupGetter__&&e.__lookupGetter__(t);return n?{get:n,set:e.__lookupSetter__(t),enumerable:!0,configurable:!0}:e.hasOwnProperty(t)?{value:e[t],enumerable:!0,configurable:!0,writable:!0}:null},u=Object.defineProperty||function(e,t,n){return(n.get||n.set)&&e.__defineGetter__?(n.get&&e.__defineGetter__(t,n.get),n.set&&e.__defineSetter__(t,n.set)):e[t]=n.value,e},h=function(e,t,n){return delete e[t],u(e,t,n)};return e(function(){for(var e=0,t=arguments.length;e<t;e++)n(this,arguments[e])},{inject:function(t){if(t){var n=t.statics===!0?t:t.statics,r=t.beans,i=t.preserve;n!==t&&e(this.prototype,t,t.enumerable,r,i),e(this,n,!0,r,i)}for(var a=1,o=arguments.length;a<o;a++)this.inject(arguments[a]);return this},extend:function(){for(var t,n,r=this,i=0,a=arguments.length;i<a&&!(t=arguments[i].initialize);i++);return t=t||function(){r.apply(this,arguments)},n=t.prototype=l(this.prototype),h(n,"constructor",{value:t,writable:!0,configurable:!0}),e(t,this,!0),arguments.length&&this.inject.apply(t,arguments),t.base=r,t}},!0).inject({inject:function(){for(var t=0,n=arguments.length;t<n;t++){var r=arguments[t];r&&e(this,r,r.enumerable,r.beans,r.preserve)}return this},extend:function(){var e=l(this);return e.inject.apply(e,arguments)},each:function(e,n){return t(this,e,n)},set:function(e){return n(this,e)},clone:function(){return new this.constructor(this)},statics:{each:t,create:l,define:h,describe:c,set:n,clone:function(e){return n(new e.constructor,e)},isPlainObject:function(e){var t=null!=e&&e.constructor;return t&&(t===Object||t===s||"Object"===t.name)},pick:function(e,t){return e!==o?e:t}}})};e.exports=s,s.inject({toString:function(){return null!=this._id?(this._class||"Object")+(this._name?" '"+this._name+"'":" @"+this._id):"{ "+s.each(this,function(e,t){if(!/^_/.test(t)){var n=typeof e;this.push(t+": "+("number"===n?h.instance.number(e):"string"===n?"'"+e+"'":e))}},[]).join(", ")+" }"},getClassName:function(){return this._class||""},exportJSON:function(e){return s.exportJSON(this,e)},toJSON:function(){return s.serialize(this)},_set:function(e,t,n){if(e&&(n||s.isPlainObject(e))){for(var r=Object.keys(e._filtering||e),i=0,a=r.length;i<a;i++){var l=r[i];if(!t||!t[l]){var c=e[l];c!==o&&(this[l]=c)}}return!0}},statics:{exports:{enumerable:!0},extend:function e(){var t=e.base.apply(this,arguments),n=t.prototype._class;return n&&!s.exports[n]&&(s.exports[n]=t),t},equals:function(e,t){if(e===t)return!0;if(e&&e.equals)return e.equals(t);if(t&&t.equals)return t.equals(e);if(e&&t&&"object"==typeof e&&"object"==typeof t){if(Array.isArray(e)&&Array.isArray(t)){var n=e.length;if(n!==t.length)return!1;for(;n--;)if(!s.equals(e[n],t[n]))return!1}else{var r=Object.keys(e),n=r.length;if(n!==Object.keys(t).length)return!1;for(;n--;){var i=r[n];if(!t.hasOwnProperty(i)||!s.equals(e[i],t[i]))return!1}}return!0}return!1},read:function(e,t,n,r){if(this===s){var i=this.peek(e,t);return e.__index++,i}var a=this.prototype,l=a._readIndex,c=t||l&&e.__index||0;r||(r=e.length-c);var u=e[c];return u instanceof this||n&&n.readNull&&null==u&&r<=1?(l&&(e.__index=c+1),u&&n&&n.clone?u.clone():u):(u=s.create(this.prototype),l&&(u.__read=!0),u=u.initialize.apply(u,c>0||r<e.length?Array.prototype.slice.call(e,c,c+r):e)||u,l&&(e.__index=c+u.__read,u.__read=o),u)},peek:function(e,t){return e[e.__index=t||e.__index||0]},remain:function(e){return e.length-(e.__index||0)},readAll:function(e,t,n){for(var r,i=[],a=t||0,o=e.length;a<o;a++)i.push(Array.isArray(r=e[a])?this.read(r,0,n):this.read(e,a,n,1));return i},readNamed:function(e,t,n,r,i){var a=this.getNamed(e,t),l=a!==o;if(l){var c=e._filtered;c||(c=e._filtered=s.create(e[0]),c._filtering=e[0]),c[t]=o}return this.read(l?[a]:e,n,r,i)},getNamed:function(e,t){var n=e[0];if(e._hasObject===o&&(e._hasObject=1===e.length&&s.isPlainObject(n)),e._hasObject)return t?n[t]:e._filtered||n},hasNamed:function(e,t){return!!this.getNamed(e,t)},isPlainValue:function(e,t){return this.isPlainObject(e)||Array.isArray(e)||t&&"string"==typeof e},serialize:function(e,t,n,r){t=t||{};var i,a=!r;if(a&&(t.formatter=new h(t.precision),r={length:0,definitions:{},references:{},add:function(e,t){var n="#"+e._id,r=this.references[n];if(!r){this.length++;var i=t.call(e),a=e._class;a&&i[0]!==a&&i.unshift(a),this.definitions[n]=i,r=this.references[n]=[n]}return r}}),e&&e._serialize){i=e._serialize(t,r);var o=e._class;!o||n||i._compact||i[0]===o||i.unshift(o)}else if(Array.isArray(e)){i=[];for(var l=0,c=e.length;l<c;l++)i[l]=s.serialize(e[l],t,n,r);n&&(i._compact=!0)}else if(s.isPlainObject(e)){i={};for(var u=Object.keys(e),l=0,c=u.length;l<c;l++){var d=u[l];i[d]=s.serialize(e[d],t,n,r)}}else i="number"==typeof e?t.formatter.number(e,t.precision):e;return a&&r.length>0?[["dictionary",r.definitions],i]:i},deserialize:function(e,t,n,r){var i=e,a=!n;if(n=n||{},Array.isArray(e)){var o=e[0],l="dictionary"===o;if(1==e.length&&/^#/.test(o))return n.dictionary[o];o=s.exports[o],i=[],r&&(n.dictionary=i);for(var c=o?1:0,u=e.length;c<u;c++)i.push(s.deserialize(e[c],t,n,l));if(o){var h=i;t?i=t(o,h):(i=s.create(o.prototype),o.apply(i,h))}}else if(s.isPlainObject(e)){i={},r&&(n.dictionary=i);for(var d in e)i[d]=s.deserialize(e[d],t,n)}return a&&e&&e.length&&"dictionary"===e[0][0]?i[1]:i},exportJSON:function(e,t){var n=s.serialize(e,t);return t&&t.asString===!1?n:JSON.stringify(n)},importJSON:function(e,t){return s.deserialize("string"==typeof e?JSON.parse(e):e,function(e,n){var r=t&&t.constructor===e?t:s.create(e.prototype),i=r===t;if(1===n.length&&r instanceof C&&(i||!(r instanceof S))){ +var a=n[0];s.isPlainObject(a)&&(a.insert=!1)}return e.apply(r,n),i&&(t=null),r})},splice:function(e,t,n,r){var i=t&&t.length,a=n===o;n=a?e.length:n,n>e.length&&(n=e.length);for(var s=0;s<i;s++)t[s]._index=n+s;if(a)return e.push.apply(e,t),[];var l=[n,r];t&&l.push.apply(l,t);for(var c=e.splice.apply(e,l),s=0,u=c.length;s<u;s++)c[s]._index=o;for(var s=n+i,u=e.length;s<u;s++)e[s]._index=s;return c},capitalize:function(e){return e.replace(/\b[a-z]/g,function(e){return e.toUpperCase()})},camelize:function(e){return e.replace(/-(.)/g,function(e,t){return t.toUpperCase()})},hyphenate:function(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}}});var l={on:function(e,t){if("string"!=typeof e)s.each(e,function(e,t){this.on(t,e)},this);else{var n=this._eventTypes,r=n&&n[e],i=this._callbacks=this._callbacks||{};i=i[e]=i[e]||[],i.indexOf(t)===-1&&(i.push(t),r&&r.install&&1===i.length&&r.install.call(this,e))}return this},off:function(e,t){if("string"!=typeof e)return void s.each(e,function(e,t){this.off(t,e)},this);var n,r=this._eventTypes,i=r&&r[e],a=this._callbacks&&this._callbacks[e];return a&&(!t||(n=a.indexOf(t))!==-1&&1===a.length?(i&&i.uninstall&&i.uninstall.call(this,e),delete this._callbacks[e]):n!==-1&&a.splice(n,1)),this},once:function(e,t){return this.on(e,function(){t.apply(this,arguments),this.off(e,t)})},emit:function(e,t){var n=this._callbacks&&this._callbacks[e];if(!n)return!1;var r=[].slice.call(arguments,1);n=n.slice();for(var i=0,a=n.length;i<a;i++)if(n[i].apply(this,r)===!1){t&&t.stop&&t.stop();break}return!0},responds:function(e){return!(!this._callbacks||!this._callbacks[e])},attach:"#on",detach:"#off",fire:"#emit",_installEvents:function(e){var t=this._callbacks,n=e?"install":"uninstall";for(var r in t)if(t[r].length>0){var i=this._eventTypes,a=i&&i[r],o=a&&a[n];o&&o.call(this,r)}},statics:{inject:function e(t){var n=t._events;if(n){var r={};s.each(n,function(e,n){var i="string"==typeof e,a=i?e:n,o=s.capitalize(a),l=a.substring(2).toLowerCase();r[l]=i?{}:e,a="_"+a,t["get"+o]=function(){return this[a]},t["set"+o]=function(e){var t=this[a];t&&this.off(l,t),e&&this.on(l,e),this[a]=e}}),t._eventTypes=r}return e.base.apply(this,arguments)}}},c=s.extend({_class:"PaperScope",initialize:function e(){a=this,this.settings=new s({applyMatrix:!0,handleSize:4,hitTolerance:0}),this.project=null,this.projects=[],this.tools=[],this.palettes=[],this._id=e._id++,e._scopes[this._id]=this;var t=e.prototype;if(!this.support){var n=ne.getContext(1,1);t.support={nativeDash:"setLineDash"in n||"mozDash"in n,nativeBlendModes:re.nativeModes},ne.release(n)}if(!this.browser){var r=navigator.userAgent.toLowerCase(),i=(/(win)/.exec(r)||/(mac)/.exec(r)||/(linux)/.exec(r)||[])[0],o=t.browser={platform:i};i&&(o[i]=!0),r.replace(/(opera|chrome|safari|webkit|firefox|msie|trident|atom)\/?\s*([.\d]+)(?:.*version\/([.\d]+))?(?:.*rv\:([.\d]+))?/g,function(e,t,n,r,i){if(!o.chrome){var a="opera"===t?r:n;"trident"===t&&(a=i,t="msie"),o.version=a,o.versionNumber=parseFloat(a),o.name=t,o[t]=!0}}),o.chrome&&delete o.webkit,o.atom&&delete o.chrome}},version:"0.9.25",getView:function(){return this.project&&this.project.getView()},getPaper:function(){return this},execute:function(e,t,n){a.PaperScript.execute(e,this,t,n),K.updateFocus()},install:function(e){var t=this;s.each(["project","view","tool"],function(n){s.define(e,n,{configurable:!0,get:function(){return t[n]}})});for(var n in this)!/^_/.test(n)&&this[n]&&(e[n]=this[n])},setup:function(e){return a=this,this.project=new x(e),this},activate:function(){a=this},clear:function(){for(var e=this.projects.length-1;e>=0;e--)this.projects[e].remove();for(var e=this.tools.length-1;e>=0;e--)this.tools[e].remove();for(var e=this.palettes.length-1;e>=0;e--)this.palettes[e].remove()},remove:function(){this.clear(),delete c._scopes[this._id]},statics:new function(){function e(e){return e+="Attribute",function(t,n){return t[e](n)||t[e]("data-paper-"+n)}}return{_scopes:{},_id:0,get:function(e){return this._scopes[e]||null},getAttribute:e("get"),hasAttribute:e("has")}}}),u=s.extend(l,{initialize:function(e){this._scope=a,this._index=this._scope[this._list].push(this)-1,!e&&this._scope[this._reference]||this.activate()},activate:function(){if(!this._scope)return!1;var e=this._scope[this._reference];return e&&e!==this&&e.emit("deactivate"),this._scope[this._reference]=this,this.emit("activate",e),!0},isActive:function(){return this._scope[this._reference]===this},remove:function(){return null!=this._index&&(s.splice(this._scope[this._list],null,this._index,1),this._scope[this._reference]==this&&(this._scope[this._reference]=null),this._scope=null,!0)}}),h=s.extend({initialize:function(e){this.precision=e||5,this.multiplier=Math.pow(10,this.precision)},number:function(e){return Math.round(e*this.multiplier)/this.multiplier},pair:function(e,t,n){return this.number(e)+(n||",")+this.number(t)},point:function(e,t){return this.number(e.x)+(t||",")+this.number(e.y)},size:function(e,t){return this.number(e.width)+(t||",")+this.number(e.height)},rectangle:function(e,t){return this.point(e,t)+(t||",")+this.size(e,t)}});h.instance=new h;var d=new function(){function e(e,t,n){return e<t?t:e>n?n:e}var t=[[.5773502691896257],[0,.7745966692414834],[.33998104358485626,.8611363115940526],[0,.5384693101056831,.906179845938664],[.2386191860831969,.6612093864662645,.932469514203152],[0,.4058451513773972,.7415311855993945,.9491079123427585],[.1834346424956498,.525532409916329,.7966664774136267,.9602898564975363],[0,.3242534234038089,.6133714327005904,.8360311073266358,.9681602395076261],[.14887433898163122,.4333953941292472,.6794095682990244,.8650633666889845,.9739065285171717],[0,.26954315595234496,.5190961292068118,.7301520055740494,.8870625997680953,.978228658146057],[.1252334085114689,.3678314989981802,.5873179542866175,.7699026741943047,.9041172563704749,.9815606342467192],[0,.2304583159551348,.44849275103644687,.6423493394403402,.8015780907333099,.9175983992229779,.9841830547185881],[.10805494870734367,.31911236892788974,.5152486363581541,.6872929048116855,.827201315069765,.9284348836635735,.9862838086968123],[0,.20119409399743451,.3941513470775634,.5709721726085388,.7244177313601701,.8482065834104272,.937273392400706,.9879925180204854],[.09501250983763744,.2816035507792589,.45801677765722737,.6178762444026438,.755404408355003,.8656312023878318,.9445750230732326,.9894009349916499]],n=[[1],[.8888888888888888,.5555555555555556],[.6521451548625461,.34785484513745385],[.5688888888888889,.47862867049936647,.23692688505618908],[.46791393457269104,.3607615730481386,.17132449237917036],[.4179591836734694,.3818300505051189,.27970539148927664,.1294849661688697],[.362683783378362,.31370664587788727,.22238103445337448,.10122853629037626],[.3302393550012598,.31234707704000286,.26061069640293544,.1806481606948574,.08127438836157441],[.29552422471475287,.26926671930999635,.21908636251598204,.1494513491505806,.06667134430868814],[.2729250867779006,.26280454451024665,.23319376459199048,.18629021092773426,.1255803694649046,.05566856711617366],[.24914704581340277,.2334925365383548,.20316742672306592,.16007832854334622,.10693932599531843,.04717533638651183],[.2325515532308739,.22628318026289723,.2078160475368885,.17814598076194574,.13887351021978725,.09212149983772845,.04048400476531588],[.2152638534631578,.2051984637212956,.18553839747793782,.15720316715819355,.12151857068790319,.08015808715976021,.03511946033175186],[.2025782419255613,.19843148532711158,.1861610000155622,.16626920581699392,.13957067792615432,.10715922046717194,.07036604748810812,.03075324199611727],[.1894506104550685,.18260341504492358,.16915651939500254,.14959598881657674,.12462897125553388,.09515851168249279,.062253523938647894,.027152459411754096]],r=Math.abs,i=Math.sqrt,a=Math.pow,o=1e-12,s=1.12e-16;return{TOLERANCE:1e-6,EPSILON:o,MACHINE_EPSILON:s,CURVETIME_EPSILON:4e-7,GEOMETRIC_EPSILON:2e-7,WINDING_EPSILON:2e-7,TRIGONOMETRIC_EPSILON:1e-7,CLIPPING_EPSILON:1e-7,KAPPA:4*(i(2)-1)/3,isZero:function(e){return e>=-o&&e<=o},integrate:function(e,r,i,a){for(var o=t[a-2],s=n[a-2],l=.5*(i-r),c=l+r,u=0,h=a+1>>1,d=1&a?s[u++]*e(c):0;u<h;){var f=l*o[u];d+=s[u++]*(e(c+f)+e(c-f))}return l*d},findRoot:function(e,t,n,i,a,o,s){for(var l=0;l<o;l++){var c=e(n),u=c/t(n),h=n-u;if(r(u)<s)return h;c>0?(a=n,n=h<=i?.5*(i+a):h):(i=n,n=h>=a?.5*(i+a):h)}return n},solveQuadratic:function(t,n,l,c,u,h){var d,f,p=0,m=u-o,g=h+o,v=1/0,w=n;if(n/=-2,f=n*n-t*l,0!==f&&r(f)<s){var y=a(r(t*n*l),1/3);if(y<1e-8){var b=a(10,r(Math.floor(Math.log(y)*Math.LOG10E)));isFinite(b)||(b=0),t*=b,n*=b,l*=b,f=n*n-t*l}}if(r(t)<o){if(r(w)<o)return r(l)<o?-1:0;d=-l/w}else if(f>=-s){var _=f<0?0:i(f),x=n+(n<0?-_:_);0===x?(d=l/t,v=-d):(d=x/t,v=l/x)}return isFinite(d)&&(null==u||d>m&&d<g)&&(c[p++]=null==u?d:e(d,u,h)),v!==d&&isFinite(v)&&(null==u||v>m&&v<g)&&(c[p++]=null==u?v:e(v,u,h)),p},solveCubic:function(t,n,l,c,u,h,f){var p,m,g,v=0;if(r(t)<o)t=n,m=l,g=c,p=1/0;else if(r(c)<o)m=n,g=l,p=0;else{var w,y,b,_,x,E,C,k=1+s;if(p=-(n/t)/3,C=t*p,m=C+n,g=m*p+l,b=(C+m)*p+g,y=g*p+c,_=y/t,x=a(r(_),1/3),E=_<0?-1:1,_=-b/t,x=_>0?1.3247179572*Math.max(x,i(_)):x,w=p-E*x,w!==p){do if(p=w,C=t*p,m=C+n,g=m*p+l,b=(C+m)*p+g,y=g*p+c,w=0===b?p:p-y/b/k,w===p){p=w;break}while(E*w>E*p);r(t)*p*p>r(c/p)&&(g=-c/p,m=(g-l)/p)}}var v=d.solveQuadratic(t,m,g,u,h,f);return isFinite(p)&&(0===v||p!==u[v-1])&&(null==h||p>h-o&&p<f+o)&&(u[v++]=null==h?p:e(p,h,f)),v}}},f={_id:1,_pools:{},get:function(e){if(e){var t=e._class,n=this._pools[t];return n||(n=this._pools[t]={_id:1}),n._id++}return this._id++}},p=s.extend({_class:"Point",_readIndex:!0,initialize:function(e,t){var n=typeof e;if("number"===n){var r="number"==typeof t;this.x=e,this.y=r?t:e,this.__read&&(this.__read=r?2:1)}else"undefined"===n||null===e?(this.x=this.y=0,this.__read&&(this.__read=null===e?1:0)):(Array.isArray(e)?(this.x=e[0],this.y=e.length>1?e[1]:e[0]):null!=e.x?(this.x=e.x,this.y=e.y):null!=e.width?(this.x=e.width,this.y=e.height):null!=e.angle?(this.x=e.length,this.y=0,this.setAngle(e.angle)):(this.x=this.y=0,this.__read&&(this.__read=0)),this.__read&&(this.__read=1))},set:function(e,t){return this.x=e,this.y=t,this},equals:function(e){return this===e||e&&(this.x===e.x&&this.y===e.y||Array.isArray(e)&&this.x===e[0]&&this.y===e[1])||!1},clone:function(){return new p(this.x,this.y)},toString:function(){var e=h.instance;return"{ x: "+e.number(this.x)+", y: "+e.number(this.y)+" }"},_serialize:function(e){var t=e.formatter;return[t.number(this.x),t.number(this.y)]},getLength:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},setLength:function(e){if(this.isZero()){var t=this._angle||0;this.set(Math.cos(t)*e,Math.sin(t)*e)}else{var n=e/this.getLength();d.isZero(n)&&this.getAngle(),this.set(this.x*n,this.y*n)}},getAngle:function(){return 180*this.getAngleInRadians.apply(this,arguments)/Math.PI},setAngle:function(e){this.setAngleInRadians.call(this,e*Math.PI/180)},getAngleInDegrees:"#getAngle",setAngleInDegrees:"#setAngle",getAngleInRadians:function(){if(arguments.length){var e=p.read(arguments),t=this.getLength()*e.getLength();if(d.isZero(t))return NaN;var n=this.dot(e)/t;return Math.acos(n<-1?-1:n>1?1:n)}return this.isZero()?this._angle||0:this._angle=Math.atan2(this.y,this.x)},setAngleInRadians:function(e){if(this._angle=e,!this.isZero()){var t=this.getLength();this.set(Math.cos(e)*t,Math.sin(e)*t)}},getQuadrant:function(){return this.x>=0?this.y>=0?1:4:this.y>=0?2:3}},{beans:!1,getDirectedAngle:function(){var e=p.read(arguments);return 180*Math.atan2(this.cross(e),this.dot(e))/Math.PI},getDistance:function(){var e=p.read(arguments),t=e.x-this.x,n=e.y-this.y,r=t*t+n*n,i=s.read(arguments);return i?r:Math.sqrt(r)},normalize:function(e){e===o&&(e=1);var t=this.getLength(),n=0!==t?e/t:0,r=new p(this.x*n,this.y*n);return n>=0&&(r._angle=this._angle),r},rotate:function(e,t){if(0===e)return this.clone();e=e*Math.PI/180;var n=t?this.subtract(t):this,r=Math.sin(e),i=Math.cos(e);return n=new p(n.x*i-n.y*r,n.x*r+n.y*i),t?n.add(t):n},transform:function(e){return e?e._transformPoint(this):this},add:function(){var e=p.read(arguments);return new p(this.x+e.x,this.y+e.y)},subtract:function(){var e=p.read(arguments);return new p(this.x-e.x,this.y-e.y)},multiply:function(){var e=p.read(arguments);return new p(this.x*e.x,this.y*e.y)},divide:function(){var e=p.read(arguments);return new p(this.x/e.x,this.y/e.y)},modulo:function(){var e=p.read(arguments);return new p(this.x%e.x,this.y%e.y)},negate:function(){return new p(-this.x,-this.y)},isInside:function(){return w.read(arguments).contains(this)},isClose:function(){var e=p.read(arguments),t=s.read(arguments);return this.getDistance(e)<t},isCollinear:function(){var e=p.read(arguments);return p.isCollinear(this.x,this.y,e.x,e.y)},isColinear:"#isCollinear",isOrthogonal:function(){var e=p.read(arguments);return p.isOrthogonal(this.x,this.y,e.x,e.y)},isZero:function(){return d.isZero(this.x)&&d.isZero(this.y)},isNaN:function(){return isNaN(this.x)||isNaN(this.y)},dot:function(){var e=p.read(arguments);return this.x*e.x+this.y*e.y},cross:function(){var e=p.read(arguments);return this.x*e.y-this.y*e.x},project:function(){var e=p.read(arguments),t=e.isZero()?0:this.dot(e)/e.dot(e);return new p(e.x*t,e.y*t)},statics:{min:function(){var e=p.read(arguments),t=p.read(arguments);return new p(Math.min(e.x,t.x),Math.min(e.y,t.y))},max:function(){var e=p.read(arguments),t=p.read(arguments);return new p(Math.max(e.x,t.x),Math.max(e.y,t.y))},random:function(){return new p(Math.random(),Math.random())},isCollinear:function(e,t,n,r){return Math.abs(e*r-t*n)<=1e-7*Math.sqrt((e*e+t*t)*(n*n+r*r))},isOrthogonal:function(e,t,n,r){return Math.abs(e*n+t*r)<=1e-7*Math.sqrt((e*e+t*t)*(n*n+r*r))}}},s.each(["round","ceil","floor","abs"],function(e){var t=Math[e];this[e]=function(){return new p(t(this.x),t(this.y))}},{})),m=p.extend({initialize:function(e,t,n,r){this._x=e,this._y=t,this._owner=n,this._setter=r},set:function(e,t,n){return this._x=e,this._y=t,n||this._owner[this._setter](this),this},getX:function(){return this._x},setX:function(e){this._x=e,this._owner[this._setter](this)},getY:function(){return this._y},setY:function(e){this._y=e,this._owner[this._setter](this)}}),g=s.extend({_class:"Size",_readIndex:!0,initialize:function(e,t){var n=typeof e;if("number"===n){var r="number"==typeof t;this.width=e,this.height=r?t:e,this.__read&&(this.__read=r?2:1)}else"undefined"===n||null===e?(this.width=this.height=0,this.__read&&(this.__read=null===e?1:0)):(Array.isArray(e)?(this.width=e[0],this.height=e.length>1?e[1]:e[0]):null!=e.width?(this.width=e.width,this.height=e.height):null!=e.x?(this.width=e.x,this.height=e.y):(this.width=this.height=0,this.__read&&(this.__read=0)),this.__read&&(this.__read=1))},set:function(e,t){return this.width=e,this.height=t,this},equals:function(e){return e===this||e&&(this.width===e.width&&this.height===e.height||Array.isArray(e)&&this.width===e[0]&&this.height===e[1])||!1},clone:function(){return new g(this.width,this.height)},toString:function(){var e=h.instance;return"{ width: "+e.number(this.width)+", height: "+e.number(this.height)+" }"},_serialize:function(e){var t=e.formatter;return[t.number(this.width),t.number(this.height)]},add:function(){var e=g.read(arguments);return new g(this.width+e.width,this.height+e.height)},subtract:function(){var e=g.read(arguments);return new g(this.width-e.width,this.height-e.height)},multiply:function(){var e=g.read(arguments);return new g(this.width*e.width,this.height*e.height)},divide:function(){var e=g.read(arguments);return new g(this.width/e.width,this.height/e.height)},modulo:function(){var e=g.read(arguments);return new g(this.width%e.width,this.height%e.height)},negate:function(){return new g(-this.width,-this.height)},isZero:function(){return d.isZero(this.width)&&d.isZero(this.height)},isNaN:function(){return isNaN(this.width)||isNaN(this.height)},statics:{min:function(e,t){return new g(Math.min(e.width,t.width),Math.min(e.height,t.height))},max:function(e,t){return new g(Math.max(e.width,t.width),Math.max(e.height,t.height))},random:function(){return new g(Math.random(),Math.random())}}},s.each(["round","ceil","floor","abs"],function(e){var t=Math[e];this[e]=function(){return new g(t(this.width),t(this.height))}},{})),v=g.extend({initialize:function(e,t,n,r){this._width=e,this._height=t,this._owner=n,this._setter=r},set:function(e,t,n){return this._width=e,this._height=t,n||this._owner[this._setter](this),this},getWidth:function(){return this._width},setWidth:function(e){this._width=e,this._owner[this._setter](this)},getHeight:function(){return this._height},setHeight:function(e){this._height=e,this._owner[this._setter](this)}}),w=s.extend({_class:"Rectangle",_readIndex:!0,beans:!0,initialize:function(e,t,n,r){var i=typeof e,a=0;if("number"===i?(this.x=e,this.y=t,this.width=n,this.height=r,a=4):"undefined"===i||null===e?(this.x=this.y=this.width=this.height=0,a=null===e?1:0):1===arguments.length&&(Array.isArray(e)?(this.x=e[0],this.y=e[1],this.width=e[2],this.height=e[3],a=1):e.x!==o||e.width!==o?(this.x=e.x||0,this.y=e.y||0,this.width=e.width||0,this.height=e.height||0,a=1):e.from===o&&e.to===o&&(this.x=this.y=this.width=this.height=0,this._set(e),a=1)),!a){var l=p.readNamed(arguments,"from"),c=s.peek(arguments);if(this.x=l.x,this.y=l.y,c&&c.x!==o||s.hasNamed(arguments,"to")){var u=p.readNamed(arguments,"to");this.width=u.x-l.x,this.height=u.y-l.y,this.width<0&&(this.x=u.x,this.width=-this.width),this.height<0&&(this.y=u.y,this.height=-this.height)}else{var h=g.read(arguments);this.width=h.width,this.height=h.height}a=arguments.__index}this.__read&&(this.__read=a)},set:function(e,t,n,r){return this.x=e,this.y=t,this.width=n,this.height=r,this},clone:function(){return new w(this.x,this.y,this.width,this.height)},equals:function(e){var t=s.isPlainValue(e)?w.read(arguments):e;return t===this||t&&this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height||!1},toString:function(){var e=h.instance;return"{ x: "+e.number(this.x)+", y: "+e.number(this.y)+", width: "+e.number(this.width)+", height: "+e.number(this.height)+" }"},_serialize:function(e){var t=e.formatter;return[t.number(this.x),t.number(this.y),t.number(this.width),t.number(this.height)]},getPoint:function(e){var t=e?p:m;return new t(this.x,this.y,this,"setPoint")},setPoint:function(){var e=p.read(arguments);this.x=e.x,this.y=e.y},getSize:function(e){var t=e?g:v;return new t(this.width,this.height,this,"setSize")},setSize:function(){var e=g.read(arguments);this._fixX&&(this.x+=(this.width-e.width)*this._fixX),this._fixY&&(this.y+=(this.height-e.height)*this._fixY),this.width=e.width,this.height=e.height,this._fixW=1,this._fixH=1},getLeft:function(){return this.x},setLeft:function(e){this._fixW||(this.width-=e-this.x),this.x=e,this._fixX=0},getTop:function(){return this.y},setTop:function(e){this._fixH||(this.height-=e-this.y),this.y=e,this._fixY=0},getRight:function(){return this.x+this.width},setRight:function(e){this._fixX!==o&&1!==this._fixX&&(this._fixW=0),this._fixW?this.x=e-this.width:this.width=e-this.x,this._fixX=1},getBottom:function(){return this.y+this.height},setBottom:function(e){this._fixY!==o&&1!==this._fixY&&(this._fixH=0),this._fixH?this.y=e-this.height:this.height=e-this.y,this._fixY=1},getCenterX:function(){return this.x+.5*this.width},setCenterX:function(e){this.x=e-.5*this.width,this._fixX=.5},getCenterY:function(){return this.y+.5*this.height},setCenterY:function(e){this.y=e-.5*this.height,this._fixY=.5},getCenter:function(e){var t=e?p:m;return new t(this.getCenterX(),this.getCenterY(),this,"setCenter")},setCenter:function(){var e=p.read(arguments);return this.setCenterX(e.x),this.setCenterY(e.y),this},getArea:function(){return this.width*this.height},isEmpty:function(){return 0===this.width||0===this.height},contains:function(e){return e&&e.width!==o||4==(Array.isArray(e)?e:arguments).length?this._containsRectangle(w.read(arguments)):this._containsPoint(p.read(arguments))},_containsPoint:function(e){var t=e.x,n=e.y;return t>=this.x&&n>=this.y&&t<=this.x+this.width&&n<=this.y+this.height},_containsRectangle:function(e){var t=e.x,n=e.y;return t>=this.x&&n>=this.y&&t+e.width<=this.x+this.width&&n+e.height<=this.y+this.height},intersects:function(){var e=w.read(arguments);return e.x+e.width>this.x&&e.y+e.height>this.y&&e.x<this.x+this.width&&e.y<this.y+this.height},touches:function(){var e=w.read(arguments);return e.x+e.width>=this.x&&e.y+e.height>=this.y&&e.x<=this.x+this.width&&e.y<=this.y+this.height},intersect:function(){var e=w.read(arguments),t=Math.max(this.x,e.x),n=Math.max(this.y,e.y),r=Math.min(this.x+this.width,e.x+e.width),i=Math.min(this.y+this.height,e.y+e.height);return new w(t,n,r-t,i-n)},unite:function(){var e=w.read(arguments),t=Math.min(this.x,e.x),n=Math.min(this.y,e.y),r=Math.max(this.x+this.width,e.x+e.width),i=Math.max(this.y+this.height,e.y+e.height);return new w(t,n,r-t,i-n)},include:function(){var e=p.read(arguments),t=Math.min(this.x,e.x),n=Math.min(this.y,e.y),r=Math.max(this.x+this.width,e.x),i=Math.max(this.y+this.height,e.y);return new w(t,n,r-t,i-n)},expand:function(){var e=g.read(arguments),t=e.width,n=e.height;return new w(this.x-t/2,this.y-n/2,this.width+t,this.height+n)},scale:function(e,t){return this.expand(this.width*e-this.width,this.height*(t===o?e:t)-this.height)}},s.each([["Top","Left"],["Top","Right"],["Bottom","Left"],["Bottom","Right"],["Left","Center"],["Top","Center"],["Right","Center"],["Bottom","Center"]],function(e,t){var n=e.join(""),r=/^[RL]/.test(n);t>=4&&(e[1]+=r?"Y":"X");var i=e[r?0:1],a=e[r?1:0],o="get"+i,s="get"+a,l="set"+i,c="set"+a,u="get"+n,h="set"+n;this[u]=function(e){var t=e?p:m;return new t(this[o](),this[s](),this,h)},this[h]=function(){var e=p.read(arguments);this[l](e.x),this[c](e.y)}},{beans:!0})),y=w.extend({initialize:function(e,t,n,r,i,a){this.set(e,t,n,r,!0),this._owner=i,this._setter=a},set:function(e,t,n,r,i){return this._x=e,this._y=t,this._width=n,this._height=r,i||this._owner[this._setter](this),this}},new function(){var e=w.prototype;return s.each(["x","y","width","height"],function(e){var t=s.capitalize(e),n="_"+e;this["get"+t]=function(){return this[n]},this["set"+t]=function(e){this[n]=e,this._dontNotify||this._owner[this._setter](this)}},s.each(["Point","Size","Center","Left","Top","Right","Bottom","CenterX","CenterY","TopLeft","TopRight","BottomLeft","BottomRight","LeftCenter","TopCenter","RightCenter","BottomCenter"],function(t){var n="set"+t;this[n]=function(){this._dontNotify=!0,e[n].apply(this,arguments),this._dontNotify=!1,this._owner[this._setter](this)}},{isSelected:function(){return this._owner._boundsSelected},setSelected:function(e){var t=this._owner;t.setSelected&&(t._boundsSelected=e,t.setSelected(e||t._selectedSegmentState>0))}}))}),b=s.extend({_class:"Matrix",initialize:function e(t){var n=arguments.length,r=!0;if(6===n?this.set.apply(this,arguments):1===n?t instanceof e?this.set(t._a,t._c,t._b,t._d,t._tx,t._ty):Array.isArray(t)?this.set.apply(this,t):r=!1:0===n?this.reset():r=!1,!r)throw new Error("Unsupported matrix parameters")},set:function(e,t,n,r,i,a,o){return this._a=e,this._c=t,this._b=n,this._d=r,this._tx=i,this._ty=a,o||this._changed(),this},_serialize:function(e){return s.serialize(this.getValues(),e)},_changed:function(){var e=this._owner;e&&(e._applyMatrix?e.transform(null,!0):e._changed(9))},clone:function(){return new b(this._a,this._c,this._b,this._d,this._tx,this._ty)},equals:function(e){return e===this||e&&this._a===e._a&&this._b===e._b&&this._c===e._c&&this._d===e._d&&this._tx===e._tx&&this._ty===e._ty||!1},toString:function(){var e=h.instance;return"[["+[e.number(this._a),e.number(this._b),e.number(this._tx)].join(", ")+"], ["+[e.number(this._c),e.number(this._d),e.number(this._ty)].join(", ")+"]]"},reset:function(e){return this._a=this._d=1,this._c=this._b=this._tx=this._ty=0,e||this._changed(),this},apply:function(e,t){var n=this._owner;return!!n&&(n.transform(null,!0,s.pick(e,!0),t),this.isIdentity())},translate:function(){var e=p.read(arguments),t=e.x,n=e.y;return this._tx+=t*this._a+n*this._b,this._ty+=t*this._c+n*this._d,this._changed(),this},scale:function(){var e=p.read(arguments),t=p.read(arguments,0,{readNull:!0});return t&&this.translate(t),this._a*=e.x,this._c*=e.x,this._b*=e.y,this._d*=e.y,t&&this.translate(t.negate()),this._changed(),this},rotate:function(e){e*=Math.PI/180;var t=p.read(arguments,1),n=t.x,r=t.y,i=Math.cos(e),a=Math.sin(e),o=n-n*i+r*a,s=r-n*a-r*i,l=this._a,c=this._b,u=this._c,h=this._d;return this._a=i*l+a*c,this._b=-a*l+i*c,this._c=i*u+a*h,this._d=-a*u+i*h,this._tx+=o*l+s*c,this._ty+=o*u+s*h,this._changed(),this},shear:function(){var e=p.read(arguments),t=p.read(arguments,0,{readNull:!0});t&&this.translate(t);var n=this._a,r=this._c;return this._a+=e.y*this._b,this._c+=e.y*this._d,this._b+=e.x*n,this._d+=e.x*r,t&&this.translate(t.negate()),this._changed(),this},skew:function(){var e=p.read(arguments),t=p.read(arguments,0,{readNull:!0}),n=Math.PI/180,r=new p(Math.tan(e.x*n),Math.tan(e.y*n));return this.shear(r,t)},concatenate:function(e){var t=this._a,n=this._b,r=this._c,i=this._d,a=e._a,o=e._b,s=e._c,l=e._d,c=e._tx,u=e._ty;return this._a=a*t+s*n,this._b=o*t+l*n,this._c=a*r+s*i,this._d=o*r+l*i,this._tx+=c*t+u*n,this._ty+=c*r+u*i,this._changed(),this},preConcatenate:function(e){var t=this._a,n=this._b,r=this._c,i=this._d,a=this._tx,o=this._ty,s=e._a,l=e._b,c=e._c,u=e._d,h=e._tx,d=e._ty;return this._a=s*t+l*r,this._b=s*n+l*i,this._c=c*t+u*r,this._d=c*n+u*i,this._tx=s*a+l*o+h,this._ty=c*a+u*o+d,this._changed(),this},chain:function(e){var t=this._a,n=this._b,r=this._c,i=this._d,a=this._tx,o=this._ty,s=e._a,l=e._b,c=e._c,u=e._d,h=e._tx,d=e._ty;return new b(s*t+c*n,s*r+c*i,l*t+u*n,l*r+u*i,a+h*t+d*n,o+h*r+d*i)},isIdentity:function(){return 1===this._a&&0===this._c&&0===this._b&&1===this._d&&0===this._tx&&0===this._ty},orNullIfIdentity:function(){return this.isIdentity()?null:this},isInvertible:function(){return!!this._getDeterminant()},isSingular:function(){return!this._getDeterminant()},transform:function(e,t,n){return arguments.length<3?this._transformPoint(p.read(arguments)):this._transformCoordinates(e,t,n)},_transformPoint:function(e,t,n){var r=e.x,i=e.y;return t||(t=new p),t.set(r*this._a+i*this._b+this._tx,r*this._c+i*this._d+this._ty,n)},_transformCoordinates:function(e,t,n){for(var r=0,i=0,a=2*n;r<a;){var o=e[r++],s=e[r++];t[i++]=o*this._a+s*this._b+this._tx,t[i++]=o*this._c+s*this._d+this._ty}return t},_transformCorners:function(e){var t=e.x,n=e.y,r=t+e.width,i=n+e.height,a=[t,n,r,n,r,i,t,i];return this._transformCoordinates(a,a,4)},_transformBounds:function(e,t,n){for(var r=this._transformCorners(e),i=r.slice(0,2),a=i.slice(),o=2;o<8;o++){var s=r[o],l=1&o;s<i[l]?i[l]=s:s>a[l]&&(a[l]=s)}return t||(t=new w),t.set(i[0],i[1],a[0]-i[0],a[1]-i[1],n)},inverseTransform:function(){return this._inverseTransform(p.read(arguments))},_getDeterminant:function(){var e=this._a*this._d-this._b*this._c;return isFinite(e)&&!d.isZero(e)&&isFinite(this._tx)&&isFinite(this._ty)?e:null},_inverseTransform:function(e,t,n){var r=this._getDeterminant();if(!r)return null;var i=e.x-this._tx,a=e.y-this._ty;return t||(t=new p),t.set((i*this._d-a*this._b)/r,(a*this._a-i*this._c)/r,n)},decompose:function(){var e=this._a,t=this._b,n=this._c,r=this._d;if(d.isZero(e*r-t*n))return null;var i=Math.sqrt(e*e+t*t);e/=i,t/=i;var a=e*n+t*r;n-=e*a,r-=t*a;var o=Math.sqrt(n*n+r*r);return n/=o,r/=o,a/=o,e*r<t*n&&(e=-e,t=-t,a=-a,i=-i),{scaling:new p(i,o),rotation:180*-Math.atan2(t,e)/Math.PI,shearing:a}},getValues:function(){return[this._a,this._c,this._b,this._d,this._tx,this._ty]},getTranslation:function(){return new p(this._tx,this._ty)},getScaling:function(){return(this.decompose()||{}).scaling},getRotation:function(){return(this.decompose()||{}).rotation},inverted:function(){var e=this._getDeterminant();return e&&new b(this._d/e,-this._c/e,-this._b/e,this._a/e,(this._b*this._ty-this._d*this._tx)/e,(this._c*this._tx-this._a*this._ty)/e)},shiftless:function(){return new b(this._a,this._c,this._b,this._d,0,0)},applyToContext:function(e){e.transform(this._a,this._c,this._b,this._d,this._tx,this._ty)}},s.each(["a","c","b","d","tx","ty"],function(e){var t=s.capitalize(e),n="_"+e;this["get"+t]=function(){return this[n]},this["set"+t]=function(e){this[n]=e,this._changed()}},{})),_=s.extend({_class:"Line",initialize:function(e,t,n,r,i){var a=!1;arguments.length>=4?(this._px=e,this._py=t,this._vx=n,this._vy=r,a=i):(this._px=e.x,this._py=e.y,this._vx=t.x,this._vy=t.y,a=n),a||(this._vx-=this._px,this._vy-=this._py)},getPoint:function(){return new p(this._px,this._py)},getVector:function(){return new p(this._vx,this._vy)},getLength:function(){return this.getVector().getLength()},intersect:function(e,t){return _.intersect(this._px,this._py,this._vx,this._vy,e._px,e._py,e._vx,e._vy,!0,t)},getSide:function(e,t){return _.getSide(this._px,this._py,this._vx,this._vy,e.x,e.y,!0,t)},getDistance:function(e){return Math.abs(_.getSignedDistance(this._px,this._py,this._vx,this._vy,e.x,e.y,!0))},isCollinear:function(e){return p.isCollinear(this._vx,this._vy,e._vx,e._vy)},isOrthogonal:function(e){return p.isOrthogonal(this._vx,this._vy,e._vx,e._vy)},statics:{intersect:function(e,t,n,r,i,a,o,s,l,c){l||(n-=e,r-=t,o-=i,s-=a);var u=n*s-r*o;if(!d.isZero(u)){var h=e-i,f=t-a,m=(o*f-s*h)/u,g=(n*f-r*h)/u,v=1e-12,w=-v,y=1+v;if(c||w<m&&m<y&&w<g&&g<y)return c||(m=m<=0?0:m>=1?1:m),new p(e+m*n,t+m*r)}},getSide:function(e,t,n,r,i,a,o,s){o||(n-=e,r-=t);var l=i-e,c=a-t,u=l*r-c*n;return 0!==u||s||(u=(l*n+l*n)/(n*n+r*r),u>=0&&u<=1&&(u=0)),u<0?-1:u>0?1:0},getSignedDistance:function(e,t,n,r,i,a,o){return o||(n-=e,r-=t),0===n?r>0?i-e:e-i:0===r?n<0?a-t:t-a:((i-e)*r-(a-t)*n)/Math.sqrt(n*n+r*r)}}}),x=u.extend({_class:"Project",_list:"projects",_reference:"project",initialize:function(e){u.call(this,!0),this.layers=[],this._activeLayer=null,this.symbols=[],this._currentStyle=new G(null,null,this),this._view=K.create(this,e||ne.getCanvas(1,1)),this._selectedItems={},this._selectedItemCount=0,this._updateVersion=0},_serialize:function(e,t){return s.serialize(this.layers,e,!0,t)},clear:function(){for(var e=this.layers.length-1;e>=0;e--)this.layers[e].remove();this.symbols=[]},isEmpty:function(){return 0===this.layers.length},remove:function e(){return!!e.base.call(this)&&(this._view&&this._view.remove(),!0)},getView:function(){return this._view},getCurrentStyle:function(){return this._currentStyle},setCurrentStyle:function(e){this._currentStyle.initialize(e)},getIndex:function(){return this._index},getOptions:function(){return this._scope.settings},getActiveLayer:function(){return this._activeLayer||new S({project:this})},getSelectedItems:function(){var e=[];for(var t in this._selectedItems){var n=this._selectedItems[t];n.isInserted()&&e.push(n)}return e},insertChild:function(e,t,n){return t instanceof S?(t._remove(!1,!0),s.splice(this.layers,[t],e,0),t._setProject(this,!0),this._changes&&t._changed(5),this._activeLayer||(this._activeLayer=t)):t instanceof C?(this._activeLayer||this.insertChild(e,new S(C.NO_INSERT))).insertChild(e,t,n):t=null,t},addChild:function(e,t){return this.insertChild(o,e,t)},_updateSelection:function(e){var t=e._id,n=this._selectedItems;e._selected?n[t]!==e&&(this._selectedItemCount++,n[t]=e):n[t]===e&&(this._selectedItemCount--,delete n[t])},selectAll:function(){for(var e=this.layers,t=0,n=e.length;t<n;t++)e[t].setFullySelected(!0)},deselectAll:function(){var e=this._selectedItems;for(var t in e)e[t].setFullySelected(!1)},hitTest:function(){for(var e=p.read(arguments),t=N.getOptions(s.read(arguments)),n=this.layers.length-1;n>=0;n--){var r=this.layers[n]._hitTest(e,t);if(r)return r}return null},getItems:function(e){return C._getItems(this.layers,e)},getItem:function(e){return C._getItems(this.layers,e,null,null,!0)[0]||null},importJSON:function(e){this.activate();var t=this._activeLayer;return s.importJSON(e,t&&t.isEmpty()&&t)},draw:function(e,t,n){this._updateVersion++,e.save(),t.applyToContext(e);for(var r=new s({ +offset:new p(0,0),pixelRatio:n,viewMatrix:t.isIdentity()?null:t,matrices:[new b],updateMatrix:!0}),i=0,a=this.layers,o=a.length;i<o;i++)a[i].draw(e,r);if(e.restore(),this._selectedItemCount>0){e.save(),e.strokeWidth=1;var l=this._selectedItems,c=this._scope.settings.handleSize,u=this._updateVersion;for(var h in l)l[h]._drawSelection(e,t,c,l,u);e.restore()}}}),E=s.extend({_class:"Symbol",initialize:function(e,t){this._id=f.get(),this.project=a.project,this.project.symbols.push(this),e&&this.setDefinition(e,t)},_serialize:function(e,t){return t.add(this,function(){return s.serialize([this._class,this._definition],e,!1,t)})},_changed:function(e){8&e&&C._clearBoundsCache(this),1&e&&(this.project._needsUpdate=!0)},getDefinition:function(){return this._definition},setDefinition:function(e,t){e._parentSymbol&&(e=e.clone()),this._definition&&(this._definition._parentSymbol=null),this._definition=e,e.remove(),e.setSelected(!1),t||e.setPosition(new p),e._parentSymbol=this,this._changed(9)},place:function(e){return new M(this,e)},clone:function(){return new E(this._definition.clone(!1))},equals:function(e){return e===this||e&&this.definition.equals(e.definition)||!1}}),C=s.extend(l,{statics:{extend:function e(t){return t._serializeFields&&(t._serializeFields=new s(this.prototype._serializeFields,t._serializeFields)),e.base.apply(this,arguments)},NO_INSERT:{insert:!1}},_class:"Item",_applyMatrix:!0,_canApplyMatrix:!0,_boundsSelected:!1,_selectChildren:!1,_serializeFields:{name:null,applyMatrix:null,matrix:new b,pivot:null,locked:!1,visible:!0,blendMode:"normal",opacity:1,guide:!1,selected:!1,clipMask:!1,data:{}},initialize:function(){},_initialize:function(e,t){var n=e&&s.isPlainObject(e),r=n&&e.internal===!0,i=this._matrix=new b,o=n&&e.project||a.project;return r||(this._id=f.get()),this._applyMatrix=this._canApplyMatrix&&a.settings.applyMatrix,t&&i.translate(t),i._owner=this,this._style=new G(o._currentStyle,this,o),this._project||(r||n&&e.insert===!1?this._setProject(o):n&&e.parent?this.setParent(e.parent):(o._activeLayer||new S).addChild(this)),n&&e!==C.NO_INSERT&&this._set(e,{insert:!0,project:!0,parent:!0},!0),n},_events:s.each(["onMouseDown","onMouseUp","onMouseDrag","onClick","onDoubleClick","onMouseMove","onMouseEnter","onMouseLeave"],function(e){this[e]={install:function(e){this.getView()._installEvent(e)},uninstall:function(e){this.getView()._uninstallEvent(e)}}},{onFrame:{install:function(){this.getView()._animateItem(this,!0)},uninstall:function(){this.getView()._animateItem(this,!1)}},onLoad:{}}),_serialize:function(e,t){function n(n){for(var a in n){var o=i[a];s.equals(o,"leading"===a?1.2*n.fontSize:n[a])||(r[a]=s.serialize(o,e,"data"!==a,t))}}var r={},i=this;return n(this._serializeFields),this instanceof k||n(this._style._defaults),[this._class,r]},_changed:function(e){var t=this._parentSymbol,n=this._parent||t,r=this._project;if(8&e&&(this._bounds=this._position=this._decomposed=this._globalMatrix=this._currentPath=o),n&&40&e&&C._clearBoundsCache(n),2&e&&C._clearBoundsCache(this),r&&(1&e&&(r._needsUpdate=!0),r._changes)){var i=r._changesById[this._id];i?i.flags|=e:(i={item:this,flags:e},r._changesById[this._id]=i,r._changes.push(i))}t&&t._changed(e)},set:function(e){return e&&this._set(e),this},getId:function(){return this._id},getName:function(){return this._name},setName:function(e,t){if(this._name&&this._removeNamed(),e===+e+"")throw new Error("Names consisting only of numbers are not supported.");var n=this._parent;if(e&&n){for(var r=n._children,i=n._namedChildren,a=e,s=1;t&&r[e];)e=a+" "+s++;(i[e]=i[e]||[]).push(this),r[e]=this}this._name=e||o,this._changed(128)},getStyle:function(){return this._style},setStyle:function(e){this.getStyle().set(e)}},s.each(["locked","visible","blendMode","opacity","guide"],function(e){var t=s.capitalize(e),e="_"+e;this["get"+t]=function(){return this[e]},this["set"+t]=function(t){t!=this[e]&&(this[e]=t,this._changed("_locked"===e?128:129))}},{}),{beans:!0,_locked:!1,_visible:!0,_blendMode:"normal",_opacity:1,_guide:!1,isSelected:function(){if(this._selectChildren)for(var e=this._children,t=0,n=e.length;t<n;t++)if(e[t].isSelected())return!0;return this._selected},setSelected:function(e,t){if(!t&&this._selectChildren)for(var n=this._children,r=0,i=n.length;r<i;r++)n[r].setSelected(e);(e=!!e)^this._selected&&(this._selected=e,this._project._updateSelection(this),this._changed(129))},_selected:!1,isFullySelected:function(){var e=this._children;if(e&&this._selected){for(var t=0,n=e.length;t<n;t++)if(!e[t].isFullySelected())return!1;return!0}return this._selected},setFullySelected:function(e){var t=this._children;if(t)for(var n=0,r=t.length;n<r;n++)t[n].setFullySelected(e);this.setSelected(e,!0)},isClipMask:function(){return this._clipMask},setClipMask:function(e){this._clipMask!=(e=!!e)&&(this._clipMask=e,e&&(this.setFillColor(null),this.setStrokeColor(null)),this._changed(129),this._parent&&this._parent._changed(1024))},_clipMask:!1,getData:function(){return this._data||(this._data={}),this._data},setData:function(e){this._data=e},getPosition:function(e){var t=this._position,n=e?p:m;if(!t){var r=this._pivot;t=this._position=r?this._matrix._transformPoint(r):this.getBounds().getCenter(!0)}return new n(t.x,t.y,this,"setPosition")},setPosition:function(){this.translate(p.read(arguments).subtract(this.getPosition(!0)))},getPivot:function(e){var t=this._pivot;if(t){var n=e?p:m;t=new n(t.x,t.y,this,"setPivot")}return t},setPivot:function(){this._pivot=p.read(arguments,0,{clone:!0,readNull:!0}),this._position=o},_pivot:null},s.each(["bounds","strokeBounds","handleBounds","roughBounds","internalBounds","internalRoughBounds"],function(e){var t="get"+s.capitalize(e),n=e.match(/^internal(.*)$/),r=n?"get"+n[1]:null;this[t]=function(n){var i=this._boundsGetter,a=!r&&("string"==typeof i?i:i&&i[t])||t,o=this._getCachedBounds(a,n,this,r);return"bounds"===e?new y(o.x,o.y,o.width,o.height,this,"setBounds"):o}},{beans:!0,_getBounds:function(e,t,n){var r=this._children;if(!r||0==r.length)return new w;C._updateBoundsCache(this,n);for(var i=1/0,a=-i,o=i,s=a,l=0,c=r.length;l<c;l++){var u=r[l];if(u._visible&&!u.isEmpty()){var h=u._getCachedBounds(e,t&&t.chain(u._matrix),n);i=Math.min(h.x,i),o=Math.min(h.y,o),a=Math.max(h.x+h.width,a),s=Math.max(h.y+h.height,s)}}return isFinite(i)?new w(i,o,a-i,s-o):new w},setBounds:function(){var e=w.read(arguments),t=this.getBounds(),n=new b,r=e.getCenter();n.translate(r),e.width==t.width&&e.height==t.height||n.scale(0!=t.width?e.width/t.width:1,0!=t.height?e.height/t.height:1),r=t.getCenter(),n.translate(-r.x,-r.y),this.transform(n)},_getCachedBounds:function(e,t,n,r){t=t&&t.orNullIfIdentity();var i=r?null:this._matrix.orNullIfIdentity(),a=(!t||t.equals(i))&&e;if(C._updateBoundsCache(this._parent||this._parentSymbol,n),a&&this._bounds&&this._bounds[a])return this._bounds[a].clone();var o=this._getBounds(r||e,t||i,n);if(a){this._bounds||(this._bounds={});var s=this._bounds[a]=o.clone();s._internal=!!r}return o},statics:{_updateBoundsCache:function(e,t){if(e){var n=t._id,r=e._boundsCache=e._boundsCache||{ids:{},list:[]};r.ids[n]||(r.list.push(t),r.ids[n]=t)}},_clearBoundsCache:function(e){var t=e._boundsCache;if(t){e._bounds=e._position=e._boundsCache=o;for(var n=0,r=t.list,i=r.length;n<i;n++){var a=r[n];a!==e&&(a._bounds=a._position=o,a._boundsCache&&C._clearBoundsCache(a))}}}}}),{beans:!0,_decompose:function(){return this._decomposed=this._matrix.decompose()},getRotation:function(){var e=this._decomposed||this._decompose();return e&&e.rotation},setRotation:function(e){var t=this.getRotation();if(null!=t&&null!=e){var n=this._decomposed;this.rotate(e-t),n.rotation=e,this._decomposed=n}},getScaling:function(e){var t=this._decomposed||this._decompose(),n=t&&t.scaling,r=e?p:m;return n&&new r(n.x,n.y,this,"setScaling")},setScaling:function(){var e=this.getScaling();if(e){var t=p.read(arguments,0,{clone:!0}),n=this._decomposed;this.scale(t.x/e.x,t.y/e.y),n.scaling=t,this._decomposed=n}},getMatrix:function(){return this._matrix},setMatrix:function(){var e=this._matrix;e.initialize.apply(e,arguments),this._applyMatrix?this.transform(null,!0):this._changed(9)},getGlobalMatrix:function(e){var t=this._globalMatrix,n=this._project._updateVersion;if(t&&t._updateVersion!==n&&(t=null),!t){t=this._globalMatrix=this._matrix.clone();var r=this._parent;r&&t.preConcatenate(r.getGlobalMatrix(!0)),t._updateVersion=n}return e?t:t.clone()},getApplyMatrix:function(){return this._applyMatrix},setApplyMatrix:function(e){(this._applyMatrix=this._canApplyMatrix&&!!e)&&this.transform(null,!0)},getTransformContent:"#getApplyMatrix",setTransformContent:"#setApplyMatrix"},{getProject:function(){return this._project},_setProject:function(e,t){if(this._project!==e){this._project&&this._installEvents(!1),this._project=e;for(var n=this._children,r=0,i=n&&n.length;r<i;r++)n[r]._setProject(e);t=!0}t&&this._installEvents(!0)},getView:function(){return this._project.getView()},_installEvents:function e(t){e.base.call(this,t);for(var n=this._children,r=0,i=n&&n.length;r<i;r++)n[r]._installEvents(t)},getLayer:function(){for(var e=this;e=e._parent;)if(e instanceof S)return e;return null},getParent:function(){return this._parent},setParent:function(e){return e.addChild(this)},getChildren:function(){return this._children},setChildren:function(e){this.removeChildren(),this.addChildren(e)},getFirstChild:function(){return this._children&&this._children[0]||null},getLastChild:function(){return this._children&&this._children[this._children.length-1]||null},getNextSibling:function(){return this._parent&&this._parent._children[this._index+1]||null},getPreviousSibling:function(){return this._parent&&this._parent._children[this._index-1]||null},getIndex:function(){return this._index},equals:function(e){return e===this||e&&this._class===e._class&&this._style.equals(e._style)&&this._matrix.equals(e._matrix)&&this._locked===e._locked&&this._visible===e._visible&&this._blendMode===e._blendMode&&this._opacity===e._opacity&&this._clipMask===e._clipMask&&this._guide===e._guide&&this._equals(e)||!1},_equals:function(e){return s.equals(this._children,e._children)},clone:function(e){return this._clone(new this.constructor(C.NO_INSERT),e)},_clone:function(e,t,n){var r=["_locked","_visible","_blendMode","_opacity","_clipMask","_guide"],i=this._children;e.setStyle(this._style);for(var a=0,l=i&&i.length;a<l;a++)e.addChild(i[a].clone(!1),!0);for(var a=0,l=r.length;a<l;a++){var c=r[a];this.hasOwnProperty(c)&&(e[c]=this[c])}return n!==!1&&e._matrix.initialize(this._matrix),e.setApplyMatrix(this._applyMatrix),e.setPivot(this._pivot),e.setSelected(this._selected),e._data=this._data?s.clone(this._data):null,(t||t===o)&&e.insertAbove(this),this._name&&e.setName(this._name,!0),e},copyTo:function(e){return e.addChild(this.clone(!1))},rasterize:function(e){var t=this.getStrokeBounds(),n=(e||this.getView().getResolution())/72,r=t.getTopLeft().floor(),i=t.getBottomRight().ceil(),a=new g(i.subtract(r)),o=ne.getCanvas(a.multiply(n)),l=o.getContext("2d"),c=(new b).scale(n).translate(r.negate());l.save(),c.applyToContext(l),this.draw(l,new s({matrices:[c]})),l.restore();var u=new T(C.NO_INSERT);return u.setCanvas(o),u.transform((new b).translate(r.add(a.divide(2))).scale(1/n)),u.insertAbove(this),u},contains:function(){return!!this._contains(this._matrix._inverseTransform(p.read(arguments)))},_contains:function(e){if(this._children){for(var t=this._children.length-1;t>=0;t--)if(this._children[t].contains(e))return!0;return!1}return e.isInside(this.getInternalBounds())},isInside:function(){return w.read(arguments).contains(this.getBounds())},_asPathItem:function(){return new z.Rectangle({rectangle:this.getInternalBounds(),matrix:this._matrix,insert:!1})},intersects:function(e,t){return e instanceof C&&this._asPathItem().getIntersections(e._asPathItem(),null,t||e._matrix,!0).length>0},hitTest:function(){return this._hitTest(p.read(arguments),N.getOptions(s.read(arguments)))},_hitTest:function(e,t){function n(t,n){var r=d["get"+n]();if(e.subtract(r).divide(l).length<=1)return new N(t,h,{name:s.hyphenate(n),point:r})}if(this._locked||!this._visible||this._guide&&!t.guides||this.isEmpty())return null;var r=this._matrix,i=t._totalMatrix,a=this.getView(),o=t._totalMatrix=i?i.chain(r):this.getGlobalMatrix().preConcatenate(a._matrix),l=t._tolerancePadding=new g(z._getPenPadding(1,o.inverted())).multiply(Math.max(t.tolerance,1e-6));if(e=r._inverseTransform(e),!this._children&&!this.getInternalRoughBounds().expand(l.multiply(2))._containsPoint(e))return null;var c,u=!(t.guides&&!this._guide||t.selected&&!this._selected||t.type&&t.type!==s.hyphenate(this._class)||t.class&&!(this instanceof t.class)),h=this;if(u&&(t.center||t.bounds)&&this._parent){var d=this.getInternalBounds();if(t.center&&(c=n("center","Center")),!c&&t.bounds)for(var f=["TopLeft","TopRight","BottomLeft","BottomRight","LeftCenter","TopCenter","RightCenter","BottomCenter"],p=0;p<8&&!c;p++)c=n("bounds",f[p])}var m=!c&&this._children;if(m)for(var v=this._getChildHitTestOptions(t),p=m.length-1;p>=0&&!c;p--)c=m[p]._hitTest(e,v);return!c&&u&&(c=this._hitTestSelf(e,t)),c&&c.point&&(c.point=r.transform(c.point)),t._totalMatrix=i,c},_getChildHitTestOptions:function(e){return e},_hitTestSelf:function(e,t){if(t.fill&&this.hasFill()&&this._contains(e))return new N("fill",this)},matches:function(e,t){function n(e,t){for(var r in e)if(e.hasOwnProperty(r)){var i=e[r],a=t[r];if(s.isPlainObject(i)&&s.isPlainObject(a)){if(!n(i,a))return!1}else if(!s.equals(i,a))return!1}return!0}var r=typeof e;if("object"===r){for(var i in e)if(e.hasOwnProperty(i)&&!this.matches(i,e[i]))return!1}else{if("function"===r)return e(this);var a=/^(empty|editable)$/.test(e)?this["is"+s.capitalize(e)]():"type"===e?s.hyphenate(this._class):this[e];if(/^(constructor|class)$/.test(e)){if(!(this instanceof t))return!1}else if(t instanceof RegExp){if(!t.test(a))return!1}else if("function"==typeof t){if(!t(a))return!1}else if(s.isPlainObject(t)){if(!n(t,a))return!1}else if(!s.equals(a,t))return!1}return!0},getItems:function(e){return C._getItems(this._children,e,this._matrix)},getItem:function(e){return C._getItems(this._children,e,this._matrix,null,!0)[0]||null},statics:{_getItems:function e(t,n,r,i,a){if(!i&&"object"==typeof n){var o=n.overlapping,l=n.inside,c=o||l,u=c&&w.read([c]);i={items:[],inside:!!l,overlapping:!!o,rect:u,path:o&&new z.Rectangle({rectangle:u,insert:!1})},c&&(n=s.set({},n,{inside:!0,overlapping:!0}))}var h=i&&i.items,u=i&&i.rect;r=u&&(r||new b);for(var d=0,f=t&&t.length;d<f;d++){var p=t[d],m=r&&r.chain(p._matrix),g=!0;if(u){var c=p.getBounds(m);if(!u.intersects(c))continue;i.inside&&u.contains(c)||i.overlapping&&(c.contains(u)||i.path.intersects(p,m))||(g=!1)}if(g&&p.matches(n)&&(h.push(p),a))break;if(e(p._children,n,m,i,a),a&&h.length>0)break}return h}}},{importJSON:function(e){var t=s.importJSON(e,this);return t!==this?this.addChild(t):t},addChild:function(e,t){return this.insertChild(o,e,t)},insertChild:function(e,t,n){var r=t?this.insertChildren(e,[t],n):null;return r&&r[0]},addChildren:function(e,t){return this.insertChildren(this._children.length,e,t)},insertChildren:function(e,t,n,r){var i=this._children;if(i&&t&&t.length>0){t=Array.prototype.slice.apply(t);for(var a=t.length-1;a>=0;a--){var o=t[a];if(!r||o instanceof r){var l=o._parent===this&&o._index<e;o._remove(!1,!0)&&l&&e--}else t.splice(a,1)}s.splice(i,t,e,0);for(var c=this._project,u=c&&c._changes,a=0,h=t.length;a<h;a++){var o=t[a];o._parent=this,o._setProject(this._project,!0),o._name&&o.setName(o._name),u&&this._changed(5)}this._changed(11)}else t=null;return t},_insertSibling:function(e,t,n){return this._parent?this._parent.insertChild(e,t,n):null},insertAbove:function(e,t){return e._insertSibling(e._index+1,this,t)},insertBelow:function(e,t){return e._insertSibling(e._index,this,t)},sendToBack:function(){return(this._parent||this instanceof S&&this._project).insertChild(0,this)},bringToFront:function(){return(this._parent||this instanceof S&&this._project).addChild(this)},appendTop:"#addChild",appendBottom:function(e){return this.insertChild(0,e)},moveAbove:"#insertAbove",moveBelow:"#insertBelow",reduce:function(){if(this._children&&1===this._children.length){var e=this._children[0].reduce();return e.insertAbove(this),e.setStyle(this._style),this.remove(),e}return this},_removeNamed:function(){var e=this._parent;if(e){var t=e._children,n=e._namedChildren,r=this._name,i=n[r],a=i?i.indexOf(this):-1;a!==-1&&(t[r]==this&&delete t[r],i.splice(a,1),i.length?t[r]=i[i.length-1]:delete n[r])}},_remove:function(e,t){var n=this._parent;if(n){if(this._name&&this._removeNamed(),null!=this._index&&s.splice(n._children,null,this._index,1),this._installEvents(!1),e){var r=this._project;r&&r._changes&&this._changed(5)}return t&&n._changed(11),this._parent=null,!0}return!1},remove:function(){return this._remove(!0,!0)},replaceWith:function(e){var t=e&&e.insertBelow(this);return t&&this.remove(),t},removeChildren:function(e,t){if(!this._children)return null;e=e||0,t=s.pick(t,this._children.length);for(var n=s.splice(this._children,null,e,t-e),r=n.length-1;r>=0;r--)n[r]._remove(!0,!1);return n.length>0&&this._changed(11),n},clear:"#removeChildren",reverseChildren:function(){if(this._children){this._children.reverse();for(var e=0,t=this._children.length;e<t;e++)this._children[e]._index=e;this._changed(11)}},isEmpty:function(){return!this._children||0===this._children.length},isEditable:function(){for(var e=this;e;){if(!e._visible||e._locked)return!1;e=e._parent}return!0},hasFill:function(){return this.getStyle().hasFill()},hasStroke:function(){return this.getStyle().hasStroke()},hasShadow:function(){return this.getStyle().hasShadow()},_getOrder:function(e){function t(e){var t=[];do t.unshift(e);while(e=e._parent);return t}for(var n=t(this),r=t(e),i=0,a=Math.min(n.length,r.length);i<a;i++)if(n[i]!=r[i])return n[i]._index<r[i]._index?1:-1;return 0},hasChildren:function(){return this._children&&this._children.length>0},isInserted:function(){return!!this._parent&&this._parent.isInserted()},isAbove:function(e){return this._getOrder(e)===-1},isBelow:function(e){return 1===this._getOrder(e)},isParent:function(e){return this._parent===e},isChild:function(e){return e&&e._parent===this},isDescendant:function(e){for(var t=this;t=t._parent;)if(t==e)return!0;return!1},isAncestor:function(e){return!!e&&e.isDescendant(this)},isSibling:function(e){return this._parent===e._parent},isGroupedWith:function(e){for(var t=this._parent;t;){if(t._parent&&/^(Group|Layer|CompoundPath)$/.test(t._class)&&e.isDescendant(t))return!0;t=t._parent}return!1},translate:function(){var e=new b;return this.transform(e.translate.apply(e,arguments))},rotate:function(e){return this.transform((new b).rotate(e,p.read(arguments,1,{readNull:!0})||this.getPosition(!0)))}},s.each(["scale","shear","skew"],function(e){this[e]=function(){var t=p.read(arguments),n=p.read(arguments,0,{readNull:!0});return this.transform((new b)[e](t,n||this.getPosition(!0)))}},{}),{transform:function(e,t,n,r){e&&e.isIdentity()&&(e=null);var i=this._matrix,a=(t||this._applyMatrix)&&(!i.isIdentity()||e||t&&n&&this._children);if(!e&&!a)return this;if(e&&i.preConcatenate(e),a=a&&this._transformContent(i,n,r)){var o=this._pivot,s=this._style,l=s.getFillColor(!0),c=s.getStrokeColor(!0);o&&i._transformPoint(o,o,!0),l&&l.transform(i),c&&c.transform(i),i.reset(!0),r&&this._canApplyMatrix&&(this._applyMatrix=!0)}var u=this._bounds,h=this._position;this._changed(9);var d=u&&e&&e.decompose();if(d&&!d.shearing&&d.rotation%90===0){for(var f in u){var p=u[f];!a&&p._internal||e._transformBounds(p,p)}var m=this._boundsGetter,p=u[m&&m.getBounds||m||"getBounds"];p&&(this._position=p.getCenter(!0)),this._bounds=u}else e&&h&&(this._position=e._transformPoint(h,h));return this},_transformContent:function(e,t,n){var r=this._children;if(r){for(var i=0,a=r.length;i<a;i++)r[i].transform(e,!0,t,n);return!0}},globalToLocal:function(){return this.getGlobalMatrix(!0)._inverseTransform(p.read(arguments))},localToGlobal:function(){return this.getGlobalMatrix(!0)._transformPoint(p.read(arguments))},parentToLocal:function(){return this._matrix._inverseTransform(p.read(arguments))},localToParent:function(){return this._matrix._transformPoint(p.read(arguments))},fitBounds:function(e,t){e=w.read(arguments);var n=this.getBounds(),r=n.height/n.width,i=e.height/e.width,a=(t?r>i:r<i)?e.width/n.width:e.height/n.height,o=new w(new p,new g(n.width*a,n.height*a));o.setCenter(e.getCenter()),this.setBounds(o)},_setStyles:function(e){var t=this._style,n=t.getFillColor(),r=t.getStrokeColor(),i=t.getShadowColor();if(n&&(e.fillStyle=n.toCanvasStyle(e)),r){var o=t.getStrokeWidth();if(o>0){e.strokeStyle=r.toCanvasStyle(e),e.lineWidth=o;var s=t.getStrokeJoin(),l=t.getStrokeCap(),c=t.getMiterLimit();if(s&&(e.lineJoin=s),l&&(e.lineCap=l),c&&(e.miterLimit=c),a.support.nativeDash){var u=t.getDashArray(),h=t.getDashOffset();u&&u.length&&("setLineDash"in e?(e.setLineDash(u),e.lineDashOffset=h):(e.mozDash=u,e.mozDashOffset=h))}}}if(i){var d=t.getShadowBlur();if(d>0){e.shadowColor=i.toCanvasStyle(e),e.shadowBlur=d;var f=this.getShadowOffset();e.shadowOffsetX=f.x,e.shadowOffsetY=f.y}}},draw:function(e,t,n){function r(e){return o?o.chain(e):e}var i=this._updateVersion=this._project._updateVersion;if(this._visible&&0!==this._opacity){var a=t.matrices,o=t.viewMatrix,s=this._matrix,l=a[a.length-1].chain(s);if(l.isInvertible()){a.push(l),t.updateMatrix&&(l._updateVersion=i,this._globalMatrix=l);var c,u,h,d=this._blendMode,f=this._opacity,p="normal"===d,m=re.nativeModes[d],g=p&&1===f||t.dontStart||t.clip||(m||p&&f<1)&&this._canComposite(),v=t.pixelRatio||1;if(!g){var w=this.getStrokeBounds(r(l));if(!w.width||!w.height)return;h=t.offset,u=t.offset=w.getTopLeft().floor(),c=e,e=ne.getContext(w.getSize().ceil().add(1).multiply(v)),1!==v&&e.scale(v,v)}e.save();var y=n?n.chain(s):!this.getStrokeScaling(!0)&&r(l),b=!g&&t.clipItem,_=!y||b;if(g?(e.globalAlpha=f,m&&(e.globalCompositeOperation=d)):_&&e.translate(-u.x,-u.y),_&&(g?s:r(l)).applyToContext(e),b&&t.clipItem.draw(e,t.extend({clip:!0})),y){e.setTransform(v,0,0,v,0,0);var x=t.offset;x&&e.translate(-x.x,-x.y)}this._draw(e,t,y),e.restore(),a.pop(),t.clip&&!t.dontFinish&&e.clip(),g||(re.process(d,e,c,f,u.subtract(h).multiply(v)),ne.release(e),t.offset=h)}}},_isUpdated:function(e){var t=this._parent;if(t instanceof R)return t._isUpdated(e);var n=this._updateVersion===e;return!n&&t&&t._visible&&t._isUpdated(e)&&(this._updateVersion=e,n=!0),n},_drawSelection:function(e,t,n,r,i){if((this._drawSelected||this._boundsSelected)&&this._isUpdated(i)){var a=this.getSelectedColor(!0)||this.getLayer().getSelectedColor(!0),o=t.chain(this.getGlobalMatrix(!0));if(e.strokeStyle=e.fillStyle=a?a.toCanvasStyle(e):"#009dec",this._drawSelected&&this._drawSelected(e,o,r),this._boundsSelected){var s=n/2,l=o._transformCorners(this.getInternalBounds());e.beginPath();for(var c=0;c<8;c++)e[0===c?"moveTo":"lineTo"](l[c],l[++c]);e.closePath(),e.stroke();for(var c=0;c<8;c++)e.fillRect(l[c]-s,l[++c]-s,n,n)}}},_canComposite:function(){return!1}},s.each(["down","drag","up","move"],function(e){this["removeOn"+s.capitalize(e)]=function(){var t={};return t[e]=!0,this.removeOn(t)}},{removeOn:function(e){for(var t in e)if(e[t]){var n="mouse"+t,r=this._project,i=r._removeSets=r._removeSets||{};i[n]=i[n]||{},i[n][this._id]=this}return this}})),k=C.extend({_class:"Group",_selectChildren:!0,_serializeFields:{children:[]},initialize:function(e){this._children=[],this._namedChildren={},this._initialize(e)||this.addChildren(Array.isArray(e)?e:arguments)},_changed:function e(t){e.base.call(this,t),1026&t&&(this._clipItem=o)},_getClipItem:function(){var e=this._clipItem;if(e===o){e=null;for(var t=0,n=this._children.length;t<n;t++){var r=this._children[t];if(r._clipMask){e=r;break}}this._clipItem=e}return e},isClipped:function(){return!!this._getClipItem()},setClipped:function(e){var t=this.getFirstChild();t&&t.setClipMask(e)},_draw:function(e,t){var n=t.clip,r=!n&&this._getClipItem(),i=!0;if(t=t.extend({clipItem:r,clip:!1}),n?this._currentPath?(e.currentPath=this._currentPath,i=!1):(e.beginPath(),t.dontStart=t.dontFinish=!0):r&&r.draw(e,t.extend({clip:!0})),i)for(var a=0,o=this._children.length;a<o;a++){var s=this._children[a];s!==r&&s.draw(e,t)}n&&(this._currentPath=e.currentPath)}}),S=k.extend({_class:"Layer",initialize:function(e){var t=s.isPlainObject(e)?new s(e):{children:Array.isArray(e)?e:arguments},n=t.insert;t.insert=!1,k.call(this,t),(n||n===o)&&(this._project.addChild(this),this.activate())},_remove:function e(t,n){if(this._parent)return e.base.call(this,t,n);if(null!=this._index){var r=this._project;return r._activeLayer===this&&(r._activeLayer=this.getNextSibling()||this.getPreviousSibling()),s.splice(r.layers,null,this._index,1),this._installEvents(!1),t&&r._changes&&this._changed(5),n&&(r._needsUpdate=!0),!0}return!1},getNextSibling:function e(){return this._parent?e.base.call(this):this._project.layers[this._index+1]||null},getPreviousSibling:function e(){return this._parent?e.base.call(this):this._project.layers[this._index-1]||null},isInserted:function e(){return this._parent?e.base.call(this):null!=this._index},activate:function(){this._project._activeLayer=this},_insertSibling:function e(t,n,r){return this._parent?e.base.call(this,t,n,r):this._project.insertChild(t,n,r)}}),P=C.extend({_class:"Shape",_applyMatrix:!1,_canApplyMatrix:!1,_boundsSelected:!0,_serializeFields:{type:null,size:null,radius:null},initialize:function(e){this._initialize(e)},_equals:function(e){return this._type===e._type&&this._size.equals(e._size)&&s.equals(this._radius,e._radius)},clone:function(e){var t=new P(C.NO_INSERT);return t.setType(this._type),t.setSize(this._size),t.setRadius(this._radius),this._clone(t,e)},getType:function(){return this._type},setType:function(e){this._type=e},getShape:"#getType",setShape:"#setType",getSize:function(){var e=this._size;return new v(e.width,e.height,this,"setSize")},setSize:function(){var e=g.read(arguments);if(this._size){if(!this._size.equals(e)){var t=this._type,n=e.width,r=e.height;if("rectangle"===t){var i=g.min(this._radius,e.divide(2));this._radius.set(i.width,i.height)}else"circle"===t?(n=r=(n+r)/2,this._radius=n/2):"ellipse"===t&&this._radius.set(n/2,r/2);this._size.set(n,r),this._changed(9)}}else this._size=e.clone()},getRadius:function(){var e=this._radius;return"circle"===this._type?e:new v(e.width,e.height,this,"setRadius")},setRadius:function(e){var t=this._type;if("circle"===t){if(e===this._radius)return;var n=2*e;this._radius=e,this._size.set(n,n)}else if(e=g.read(arguments),this._radius){if(this._radius.equals(e))return;if(this._radius.set(e.width,e.height),"rectangle"===t){var n=g.max(this._size,e.multiply(2));this._size.set(n.width,n.height)}else"ellipse"===t&&this._size.set(2*e.width,2*e.height)}else this._radius=e.clone();this._changed(9)},isEmpty:function(){return!1},toPath:function(e){var t=this._clone(new(z[s.capitalize(this._type)])({center:new p,size:this._size,radius:this._radius,insert:!1}),e);return a.settings.applyMatrix&&t.setApplyMatrix(!0),t},_draw:function(e,t,n){var r=this._style,i=r.hasFill(),a=r.hasStroke(),o=t.dontFinish||t.clip,s=!n;if(i||a||o){var l=this._type,c=this._radius,u="circle"===l;if(t.dontStart||e.beginPath(),s&&u)e.arc(0,0,c,0,2*Math.PI,!0);else{var h=u?c:c.width,d=u?c:c.height,f=this._size,p=f.width,m=f.height;if(s&&"rectangle"===l&&0===h&&0===d)e.rect(-p/2,-m/2,p,m);else{var g=p/2,v=m/2,w=.44771525016920644,y=h*w,b=d*w,_=[-g,-v+d,-g,-v+b,-g+y,-v,-g+h,-v,g-h,-v,g-y,-v,g,-v+b,g,-v+d,g,v-d,g,v-b,g-y,v,g-h,v,-g+h,v,-g+y,v,-g,v-b,-g,v-d];n&&n.transform(_,_,32),e.moveTo(_[0],_[1]),e.bezierCurveTo(_[2],_[3],_[4],_[5],_[6],_[7]),g!==h&&e.lineTo(_[8],_[9]),e.bezierCurveTo(_[10],_[11],_[12],_[13],_[14],_[15]),v!==d&&e.lineTo(_[16],_[17]),e.bezierCurveTo(_[18],_[19],_[20],_[21],_[22],_[23]),g!==h&&e.lineTo(_[24],_[25]),e.bezierCurveTo(_[26],_[27],_[28],_[29],_[30],_[31])}}e.closePath()}o||!i&&!a||(this._setStyles(e),i&&(e.fill(r.getWindingRule()),e.shadowColor="rgba(0,0,0,0)"),a&&e.stroke())},_canComposite:function(){return!(this.hasFill()&&this.hasStroke())},_getBounds:function(e,t){var n=new w(this._size).setCenter(0,0);return"getBounds"!==e&&this.hasStroke()&&(n=n.expand(this.getStrokeWidth())),t?t._transformBounds(n):n}},new function(){function e(e,t,n){var r=e._radius;if(!r.isZero())for(var i=e._size.divide(2),a=0;a<4;a++){var o=new p(1&a?1:-1,a>1?1:-1),s=o.multiply(i),l=s.subtract(o.multiply(r)),c=new w(s,l);if((n?c.expand(n):c).contains(t))return l}}function t(e,t){var n=e.getAngleInRadians(),r=2*t.width,i=2*t.height,a=r*Math.sin(n),o=i*Math.cos(n);return r*i/(2*Math.sqrt(a*a+o*o))}return{_contains:function t(n){if("rectangle"===this._type){var r=e(this,n);return r?n.subtract(r).divide(this._radius).getLength()<=1:t.base.call(this,n)}return n.divide(this.size).getLength()<=.5},_hitTestSelf:function n(r,i){var a=!1;if(this.hasStroke()){var o=this._type,s=this._radius,l=this.getStrokeWidth()+2*i.tolerance;if("rectangle"===o){var c=e(this,r,l);if(c){var u=r.subtract(c);a=2*Math.abs(u.getLength()-t(u,s))<=l}else{var h=new w(this._size).setCenter(0,0),d=h.expand(l),f=h.expand(-l);a=d._containsPoint(r)&&!f._containsPoint(r)}}else"ellipse"===o&&(s=t(r,s)),a=2*Math.abs(r.getLength()-s)<=l}return a?new N("stroke",this):n.base.apply(this,arguments)}}},{statics:new function(){function e(e,t,n,r,i){var a=new P(s.getNamed(i));return a._type=e,a._size=n,a._radius=r,a.translate(t)}return{Circle:function(){var t=p.readNamed(arguments,"center"),n=s.readNamed(arguments,"radius");return e("circle",t,new g(2*n),n,arguments)},Rectangle:function(){var t=w.readNamed(arguments,"rectangle"),n=g.min(g.readNamed(arguments,"radius"),t.getSize(!0).divide(2));return e("rectangle",t.getCenter(!0),t.getSize(!0),n,arguments)},Ellipse:function(){var t=P._readEllipse(arguments),n=t.radius;return e("ellipse",t.center,n.multiply(2),n,arguments)},_readEllipse:function(e){var t,n;if(s.hasNamed(e,"radius"))t=p.readNamed(e,"center"),n=g.readNamed(e,"radius");else{var r=w.readNamed(e,"rectangle");t=r.getCenter(!0),n=r.getSize(!0).divide(2)}return{center:t,radius:n}}}}}),T=C.extend({_class:"Raster",_applyMatrix:!1,_canApplyMatrix:!1,_boundsGetter:"getBounds",_boundsSelected:!0,_serializeFields:{crossOrigin:null,source:null},initialize:function(e,t){this._initialize(e,t!==o&&p.read(arguments,1))||("string"==typeof e?this.setSource(e):this.setImage(e)),this._size||(this._size=new g,this._loaded=!1)},_equals:function(e){return this.getSource()===e.getSource()},clone:function(e){var t=new T(C.NO_INSERT),n=this._image,r=this._canvas;if(n)t.setImage(n);else if(r){var i=ne.getCanvas(this._size);i.getContext("2d").drawImage(r,0,0),t.setImage(i)}return t._crossOrigin=this._crossOrigin,this._clone(t,e)},getSize:function(){var e=this._size;return new v(e?e.width:0,e?e.height:0,this,"setSize")},setSize:function(){var e=g.read(arguments);if(!e.equals(this._size))if(e.width>0&&e.height>0){var t=this.getElement();this.setImage(ne.getCanvas(e)),t&&this.getContext(!0).drawImage(t,0,0,e.width,e.height)}else this._canvas&&ne.release(this._canvas),this._size=e.clone()},getWidth:function(){return this._size?this._size.width:0},setWidth:function(e){this.setSize(e,this.getHeight())},getHeight:function(){return this._size?this._size.height:0},setHeight:function(e){this.setSize(this.getWidth(),e)},isEmpty:function(){var e=this._size;return!e||0===e.width&&0===e.height},getResolution:function(){var e=this._matrix,t=new p(0,0).transform(e),n=new p(1,0).transform(e).subtract(t),r=new p(0,1).transform(e).subtract(t);return new g(72/n.getLength(),72/r.getLength())},getPpi:"#getResolution",getImage:function(){return this._image},setImage:function(e){this._canvas&&ne.release(this._canvas),e&&e.getContext?(this._image=null,this._canvas=e,this._loaded=!0):(this._image=e,this._canvas=null,this._loaded=e&&e.complete),this._size=new g(e?e.naturalWidth||e.width:0,e?e.naturalHeight||e.height:0), +this._context=null,this._changed(521)},getCanvas:function(){if(!this._canvas){var e=ne.getContext(this._size);try{this._image&&e.drawImage(this._image,0,0),this._canvas=e.canvas}catch(t){ne.release(e)}}return this._canvas},setCanvas:"#setImage",getContext:function(e){return this._context||(this._context=this.getCanvas().getContext("2d")),e&&(this._image=null,this._changed(513)),this._context},setContext:function(e){this._context=e},getSource:function(){return this._image&&this._image.src||this.toDataURL()},setSource:function(e){function t(){var e=r.getView();e&&(a=e._scope,r.setImage(n),r.emit("load"),e.update())}var n,r=this,i=this._crossOrigin;n=document.getElementById(e)||new Image,i&&(n.crossOrigin=i),n.naturalWidth&&n.naturalHeight?setTimeout(t,0):(X.add(n,{load:t}),n.src||(n.src=e)),this.setImage(n)},getCrossOrigin:function(){return this._image&&this._image.crossOrigin||this._crossOrigin||""},setCrossOrigin:function(e){this._crossOrigin=e,this._image&&(this._image.crossOrigin=e)},getElement:function(){return this._canvas||this._loaded&&this._image}},{beans:!1,getSubCanvas:function(){var e=w.read(arguments),t=ne.getContext(e.getSize());return t.drawImage(this.getCanvas(),e.x,e.y,e.width,e.height,0,0,e.width,e.height),t.canvas},getSubRaster:function(){var e=w.read(arguments),t=new T(C.NO_INSERT);return t.setImage(this.getSubCanvas(e)),t.translate(e.getCenter().subtract(this.getSize().divide(2))),t._matrix.preConcatenate(this._matrix),t.insertAbove(this),t},toDataURL:function(){var e=this._image&&this._image.src;if(/^data:/.test(e))return e;var t=this.getCanvas();return t?t.toDataURL.apply(t,arguments):null},drawImage:function(e){var t=p.read(arguments,1);this.getContext(!0).drawImage(e,t.x,t.y)},getAverageColor:function(e){var t,n;e?e instanceof B?(n=e,t=e.getBounds()):e.width?t=new w(e):e.x&&(t=new w(e.x-.5,e.y-.5,1,1)):t=this.getBounds();var r=32,i=Math.min(t.width,r),a=Math.min(t.height,r),o=T._sampleContext;o?o.clearRect(0,0,r+1,r+1):o=T._sampleContext=ne.getContext(new g(r)),o.save();var l=(new b).scale(i/t.width,a/t.height).translate(-t.x,-t.y);l.applyToContext(o),n&&n.draw(o,new s({clip:!0,matrices:[l]})),this._matrix.applyToContext(o);var c=this.getElement(),u=this._size;c&&o.drawImage(c,-u.width/2,-u.height/2),o.restore();for(var h=o.getImageData(.5,.5,Math.ceil(i),Math.ceil(a)).data,d=[0,0,0],f=0,p=0,m=h.length;p<m;p+=4){var v=h[p+3];f+=v,v/=255,d[0]+=h[p]*v,d[1]+=h[p+1]*v,d[2]+=h[p+2]*v}for(var p=0;p<3;p++)d[p]/=f;return f?V.read(d):null},getPixel:function(){var e=p.read(arguments),t=this.getContext().getImageData(e.x,e.y,1,1).data;return new V("rgb",[t[0]/255,t[1]/255,t[2]/255],t[3]/255)},setPixel:function(){var e=p.read(arguments),t=V.read(arguments),n=t._convert("rgb"),r=t._alpha,i=this.getContext(!0),a=i.createImageData(1,1),o=a.data;o[0]=255*n[0],o[1]=255*n[1],o[2]=255*n[2],o[3]=null!=r?255*r:255,i.putImageData(a,e.x,e.y)},createImageData:function(){var e=g.read(arguments);return this.getContext().createImageData(e.width,e.height)},getImageData:function(){var e=w.read(arguments);return e.isEmpty()&&(e=new w(this._size)),this.getContext().getImageData(e.x,e.y,e.width,e.height)},setImageData:function(e){var t=p.read(arguments,1);this.getContext(!0).putImageData(e,t.x,t.y)},_getBounds:function(e,t){var n=new w(this._size).setCenter(0,0);return t?t._transformBounds(n):n},_hitTestSelf:function(e){if(this._contains(e)){var t=this;return new N("pixel",t,{offset:e.add(t._size.divide(2)).round(),color:{get:function(){return t.getPixel(this.offset)}}})}},_draw:function(e){var t=this.getElement();t&&(e.globalAlpha=this._opacity,e.drawImage(t,-this._size.width/2,-this._size.height/2))},_canComposite:function(){return!0}}),M=C.extend({_class:"PlacedSymbol",_applyMatrix:!1,_canApplyMatrix:!1,_boundsGetter:{getBounds:"getStrokeBounds"},_boundsSelected:!0,_serializeFields:{symbol:null},initialize:function(e,t){this._initialize(e,t!==o&&p.read(arguments,1))||this.setSymbol(e instanceof E?e:new E(e))},_equals:function(e){return this._symbol===e._symbol},getSymbol:function(){return this._symbol},setSymbol:function(e){this._symbol=e,this._changed(9)},clone:function(e){var t=new M(C.NO_INSERT);return t.setSymbol(this._symbol),this._clone(t,e)},isEmpty:function(){return this._symbol._definition.isEmpty()},_getBounds:function(e,t,n){var r=this.symbol._definition;return r._getCachedBounds(e,t&&t.chain(r._matrix),n)},_hitTestSelf:function(e,t){var n=this._symbol._definition._hitTest(e,t);return n&&(n.item=this),n},_draw:function(e,t){this.symbol._definition.draw(e,t)}}),N=s.extend({_class:"HitResult",initialize:function(e,t,n){this.type=e,this.item=t,n&&(n.enumerable=!0,this.inject(n))},statics:{getOptions:function(e){return new s({type:null,tolerance:a.settings.hitTolerance,fill:!e,stroke:!e,segments:!e,handles:!1,ends:!1,center:!1,bounds:!1,guides:!1,selected:!1},e)}}}),I=s.extend({_class:"Segment",beans:!0,initialize:function(e,t,n,r,i,a){var s,l,c,u=arguments.length;0===u||(1===u?"point"in e?(s=e.point,l=e.handleIn,c=e.handleOut):s=e:2===u&&"number"==typeof e?s=arguments:u<=3?(s=e,l=t,c=n):(s=e!==o?[e,t]:null,l=n!==o?[n,r]:null,c=i!==o?[i,a]:null)),new L(s,this,"_point"),new L(l,this,"_handleIn"),new L(c,this,"_handleOut")},_serialize:function(e){return s.serialize(this.hasHandles()?[this._point,this._handleIn,this._handleOut]:this._point,e,!0)},_changed:function(e){var t=this._path;if(t){var n,r=t._curves,i=this._index;r&&(e&&e!==this._point&&e!==this._handleIn||!(n=i>0?r[i-1]:t._closed?r[r.length-1]:null)||n._changed(),e&&e!==this._point&&e!==this._handleOut||!(n=r[i])||n._changed()),t._changed(25)}},getPoint:function(){return this._point},setPoint:function(){var e=p.read(arguments);this._point.set(e.x,e.y)},getHandleIn:function(){return this._handleIn},setHandleIn:function(){var e=p.read(arguments);this._handleIn.set(e.x,e.y)},getHandleOut:function(){return this._handleOut},setHandleOut:function(){var e=p.read(arguments);this._handleOut.set(e.x,e.y)},hasHandles:function(){return!this._handleIn.isZero()||!this._handleOut.isZero()},clearHandles:function(){this._handleIn.set(0,0),this._handleOut.set(0,0)},_selectionState:0,isSelected:function(e){var t=this._selectionState;return e?e===this._point?!!(4&t):e===this._handleIn?!!(1&t):e===this._handleOut&&!!(2&t):!!(7&t)},setSelected:function(e,t){var n=this._path,e=!!e,r=this._selectionState,i=r,a=t?t===this._point?4:t===this._handleIn?1:t===this._handleOut?2:0:7;e?r|=a:r&=~a,this._selectionState=r,n&&r!==i&&(n._updateSelection(this,i,r),n._changed(129))},getIndex:function(){return this._index!==o?this._index:null},getPath:function(){return this._path||null},getCurve:function(){var e=this._path,t=this._index;return e?(t>0&&!e._closed&&t===e._segments.length-1&&t--,e.getCurves()[t]||null):null},getLocation:function(){var e=this.getCurve();return e?new O(e,this===e._segment1?0:1):null},getNext:function(){var e=this._path&&this._path._segments;return e&&(e[this._index+1]||this._path._closed&&e[0])||null},getPrevious:function(){var e=this._path&&this._path._segments;return e&&(e[this._index-1]||this._path._closed&&e[e.length-1])||null},isFirst:function(){return 0===this._index},isLast:function(){var e=this._path;return e&&this._index===e._segments.length-1||!1},reverse:function(){var e=this._handleIn,t=this._handleOut,n=e._x,r=e._y;e.set(t._x,t._y),t.set(n,r)},reversed:function(){return new I(this._point,this._handleOut,this._handleIn)},remove:function(){return!!this._path&&!!this._path.removeSegment(this._index)},clone:function(){return new I(this._point,this._handleIn,this._handleOut)},equals:function(e){return e===this||e&&this._class===e._class&&this._point.equals(e._point)&&this._handleIn.equals(e._handleIn)&&this._handleOut.equals(e._handleOut)||!1},toString:function(){var e=["point: "+this._point];return this._handleIn.isZero()||e.push("handleIn: "+this._handleIn),this._handleOut.isZero()||e.push("handleOut: "+this._handleOut),"{ "+e.join(", ")+" }"},transform:function(e){this._transformCoordinates(e,new Array(6),!0),this._changed()},_transformCoordinates:function(e,t,n){var r=this._point,i=n&&this._handleIn.isZero()?null:this._handleIn,a=n&&this._handleOut.isZero()?null:this._handleOut,o=r._x,s=r._y,l=2;return t[0]=o,t[1]=s,i&&(t[l++]=i._x+o,t[l++]=i._y+s),a&&(t[l++]=a._x+o,t[l++]=a._y+s),e&&(e._transformCoordinates(t,t,l/2),o=t[0],s=t[1],n?(r._x=o,r._y=s,l=2,i&&(i._x=t[l++]-o,i._y=t[l++]-s),a&&(a._x=t[l++]-o,a._y=t[l++]-s)):(i||(t[l++]=o,t[l++]=s),a||(t[l++]=o,t[l++]=s))),t}}),L=p.extend({initialize:function(e,t,n){var r,i,a;if(e)if((r=e[0])!==o)i=e[1];else{var s=e;(r=s.x)===o&&(s=p.read(arguments),r=s.x),i=s.y,a=s.selected}else r=i=0;this._x=r,this._y=i,this._owner=t,t[n]=this,a&&this.setSelected(!0)},set:function(e,t){return this._x=e,this._y=t,this._owner._changed(this),this},_serialize:function(e){var t=e.formatter,n=t.number(this._x),r=t.number(this._y);return this.isSelected()?{x:n,y:r,selected:!0}:[n,r]},getX:function(){return this._x},setX:function(e){this._x=e,this._owner._changed(this)},getY:function(){return this._y},setY:function(e){this._y=e,this._owner._changed(this)},isZero:function(){return d.isZero(this._x)&&d.isZero(this._y)},setSelected:function(e){this._owner.setSelected(e,this)},isSelected:function(){return this._owner.isSelected(this)}}),A=s.extend({_class:"Curve",initialize:function(e,t,n,r,i,a,o,s){var l,c,u,h,d,f,p=arguments.length;3===p?(this._path=e,l=t,c=n):0===p?(l=new I,c=new I):1===p?"segment1"in e?(l=new I(e.segment1),c=new I(e.segment2)):"point1"in e?(u=e.point1,d=e.handle1,f=e.handle2,h=e.point2):Array.isArray(e)&&(u=[e[0],e[1]],h=[e[6],e[7]],d=[e[2]-e[0],e[3]-e[1]],f=[e[4]-e[6],e[5]-e[7]]):2===p?(l=new I(e),c=new I(t)):4===p?(u=e,d=t,f=n,h=r):8===p&&(u=[e,t],h=[o,s],d=[n-e,r-t],f=[i-o,a-s]),this._segment1=l||new I(u,null,d),this._segment2=c||new I(h,f,null)},_serialize:function(e){return s.serialize(this.hasHandles()?[this.getPoint1(),this.getHandle1(),this.getHandle2(),this.getPoint2()]:[this.getPoint1(),this.getPoint2()],e,!0)},_changed:function(){this._length=this._bounds=o},clone:function(){return new A(this._segment1,this._segment2)},toString:function(){var e=["point1: "+this._segment1._point];return this._segment1._handleOut.isZero()||e.push("handle1: "+this._segment1._handleOut),this._segment2._handleIn.isZero()||e.push("handle2: "+this._segment2._handleIn),e.push("point2: "+this._segment2._point),"{ "+e.join(", ")+" }"},remove:function(){var e=!1;if(this._path){var t=this._segment2,n=t._handleOut;e=t.remove(),e&&this._segment1._handleOut.set(n.x,n.y)}return e},getPoint1:function(){return this._segment1._point},setPoint1:function(){var e=p.read(arguments);this._segment1._point.set(e.x,e.y)},getPoint2:function(){return this._segment2._point},setPoint2:function(){var e=p.read(arguments);this._segment2._point.set(e.x,e.y)},getHandle1:function(){return this._segment1._handleOut},setHandle1:function(){var e=p.read(arguments);this._segment1._handleOut.set(e.x,e.y)},getHandle2:function(){return this._segment2._handleIn},setHandle2:function(){var e=p.read(arguments);this._segment2._handleIn.set(e.x,e.y)},getSegment1:function(){return this._segment1},getSegment2:function(){return this._segment2},getPath:function(){return this._path},getIndex:function(){return this._segment1._index},getNext:function(){var e=this._path&&this._path._curves;return e&&(e[this._segment1._index+1]||this._path._closed&&e[0])||null},getPrevious:function(){var e=this._path&&this._path._curves;return e&&(e[this._segment1._index-1]||this._path._closed&&e[e.length-1])||null},isFirst:function(){return 0===this._segment1._index},isLast:function(){var e=this._path;return e&&this._segment1._index===e._curves.length-1||!1},isSelected:function(){return this.getPoint1().isSelected()&&this.getHandle2().isSelected()&&this.getHandle2().isSelected()&&this.getPoint2().isSelected()},setSelected:function(e){this.getPoint1().setSelected(e),this.getHandle1().setSelected(e),this.getHandle2().setSelected(e),this.getPoint2().setSelected(e)},getValues:function(e){return A.getValues(this._segment1,this._segment2,e)},getPoints:function(){for(var e=this.getValues(),t=[],n=0;n<8;n+=2)t.push(new p(e[n],e[n+1]));return t},getLength:function(){return null==this._length&&(this._length=A.getLength(this.getValues(),0,1)),this._length},getArea:function(){return A.getArea(this.getValues())},getLine:function(){return new _(this._segment1._point,this._segment2._point)},getPart:function(e,t){return new A(A.getPart(this.getValues(),e,t))},getPartLength:function(e,t){return A.getLength(this.getValues(),e,t)},getIntersections:function(e){return A._getIntersections(this.getValues(),e&&e!==this?e.getValues():null,this,e,[],{})},_getParameter:function(e,t){return t?e:e&&e.curve===this?e.parameter:e===o&&t===o?.5:this.getParameterAt(e,0)},divide:function(e,t,n){var r=this._getParameter(e,t),i=4e-7,a=1-i,o=null;if(r>=i&&r<=a){var s=A.subdivide(this.getValues(),r),l=s[0],c=s[1],u=n||this.hasHandles(),h=this._segment1,d=this._segment2,f=this._path;u&&(h._handleOut.set(l[2]-l[0],l[3]-l[1]),d._handleIn.set(c[4]-c[6],c[5]-c[7]));var m=l[6],g=l[7],v=new I(new p(m,g),u&&new p(l[4]-m,l[5]-g),u&&new p(c[2]-m,c[3]-g));f?(f.insert(h._index+1,v),o=this.getNext()):(this._segment2=v,o=new A(v,d))}return o},split:function(e,t){return this._path?this._path.split(this._segment1._index,this._getParameter(e,t)):null},reversed:function(){return new A(this._segment2.reversed(),this._segment1.reversed())},clearHandles:function(){this._segment1._handleOut.set(0,0),this._segment2._handleIn.set(0,0)},statics:{getValues:function(e,t,n){var r=e._point,i=e._handleOut,a=t._handleIn,o=t._point,s=[r._x,r._y,r._x+i._x,r._y+i._y,o._x+a._x,o._y+a._y,o._x,o._y];return n&&n._transformCoordinates(s,s,4),s},subdivide:function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],s=e[4],l=e[5],c=e[6],u=e[7];t===o&&(t=.5);var h=1-t,d=h*n+t*i,f=h*r+t*a,p=h*i+t*s,m=h*a+t*l,g=h*s+t*c,v=h*l+t*u,w=h*d+t*p,y=h*f+t*m,b=h*p+t*g,_=h*m+t*v,x=h*w+t*b,E=h*y+t*_;return[[n,r,d,f,w,y,x,E],[x,E,b,_,g,v,c,u]]},solveCubic:function(e,t,n,r,i,a){var o=e[t],s=e[t+2],l=e[t+4],c=e[t+6],u=3*(s-o),h=3*(l-s)-u,f=c-o-u-h;return d.solveCubic(f,h,u,o-n,r,i,a)},getParameterOf:function(e,t){var n=new p(e[0],e[1]),r=new p(e[6],e[7]),i=1e-12,a=t.isClose(n,i)?0:t.isClose(r,i)?1:null;if(null!==a)return a;for(var o=[t.x,t.y],s=[],l=2e-7,c=0;c<2;c++)for(var u=A.solveCubic(e,c,o[c],s,0,1),h=0;h<u;h++)if(a=s[h],t.isClose(A.getPoint(e,a),l))return a;return t.isClose(n,l)?0:t.isClose(r,l)?1:null},getNearestParameter:function(e,t){function n(n){if(n>=0&&n<=1){var r=t.getDistance(A.getPoint(e,n),!0);if(r<d)return d=r,f=n,!0}}if(A.isStraight(e)){var r=e[0],i=e[1],a=e[6],o=e[7],s=a-r,l=o-i,c=s*s+l*l;if(0===c)return 0;var u=((t.x-r)*s+(t.y-i)*l)/c;return u<1e-12?0:u>.999999999999?1:A.getParameterOf(e,new p(r+u*s,i+u*l))}for(var h=100,d=1/0,f=0,m=0;m<=h;m++)n(m/h);for(var g=1/(2*h);g>4e-7;)n(f-g)||n(f+g)||(g/=2);return f},getPart:function(e,t,n){var r=t>n;if(r){var i=t;t=n,n=i}return t>0&&(e=A.subdivide(e,t)[1]),n<1&&(e=A.subdivide(e,(n-t)/(1-t))[0]),r?[e[6],e[7],e[4],e[5],e[2],e[3],e[0],e[1]]:e},hasHandles:function(e){var t=d.isZero;return!(t(e[0]-e[2])&&t(e[1]-e[3])&&t(e[4]-e[6])&&t(e[5]-e[7]))},isFlatEnough:function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],s=e[5],l=e[6],c=e[7],u=3*i-2*n-l,h=3*a-2*r-c,d=3*o-2*l-n,f=3*s-2*c-r;return Math.max(u*u,d*d)+Math.max(h*h,f*f)<10*t*t},getArea:function(e){var t=e[0],n=e[1],r=e[6],i=e[7],a=(e[2]+t)/2,o=(e[3]+n)/2,s=(e[4]+e[6])/2,l=(e[5]+e[7])/2;return 6*((t-a)*(o+n)+(a-s)*(l+o)+(s-r)*(i+l))/10},getBounds:function(e){for(var t=e.slice(0,2),n=t.slice(),r=[0,0],i=0;i<2;i++)A._addBounds(e[i],e[i+2],e[i+4],e[i+6],i,0,t,n,r);return new w(t[0],t[1],n[0]-t[0],n[1]-t[1])},_addBounds:function(e,t,n,r,i,a,o,s,l){function c(e,t){var n=e-t,r=e+t;n<o[i]&&(o[i]=n),r>s[i]&&(s[i]=r)}var u=3*(t-n)-e+r,h=2*(e+n)-4*t,f=t-e,p=d.solveQuadratic(u,h,f,l),m=4e-7,g=1-m;c(r,0);for(var v=0;v<p;v++){var w=l[v],y=1-w;m<w&&w<g&&c(y*y*y*e+3*y*y*w*t+3*y*w*w*n+w*w*w*r,a)}}}},s.each(["getBounds","getStrokeBounds","getHandleBounds","getRoughBounds"],function(e){this[e]=function(){this._bounds||(this._bounds={});var t=this._bounds[e];if(!t){var n=this._path;t=this._bounds[e]=z[e]([this._segment1,this._segment2],!1,n&&n.getStyle())}return t.clone()}},{}),s.each({isStraight:function(e,t,n){if(t.isZero()&&n.isZero())return!0;if(e.isZero())return!1;if(t.isCollinear(e)&&n.isCollinear(e)){var r=e.dot(e),i=e.dot(t)/r,a=e.dot(n)/r;return i>=0&&i<=1&&a<=0&&a>=-1}return!1},isLinear:function(e,t,n){var r=e.divide(3);return t.equals(r)&&n.negate().equals(r)}},function(e,t){this[t]=function(){var t=this._segment1,n=this._segment2;return e(n._point.subtract(t._point),t._handleOut,n._handleIn)},this.statics[t]=function(t){var n=t[0],r=t[1],i=t[6],a=t[7];return e(new p(i-n,a-r),new p(t[2]-n,t[3]-r),new p(t[4]-i,t[5]-a))}},{statics:{},hasHandles:function(){return!this._segment1._handleOut.isZero()||!this._segment2._handleIn.isZero()},isCollinear:function(e){return e&&this.isStraight()&&e.isStraight()&&this.getLine().isCollinear(e.getLine())},isHorizontal:function(){return this.isStraight()&&Math.abs(this.getTangentAt(.5,!0).y)<1e-7},isVertical:function(){return this.isStraight()&&Math.abs(this.getTangentAt(.5,!0).x)<1e-7}}),{beans:!1,getParameterAt:function(e,t){return A.getParameterAt(this.getValues(),e,t)},getParameterOf:function(){return A.getParameterOf(this.getValues(),p.read(arguments))},getLocationAt:function(e,t){var n=t?e:this.getParameterAt(e);return null!=n&&n>=0&&n<=1?new O(this,n):null},getLocationOf:function(){return this.getLocationAt(this.getParameterOf(p.read(arguments)),!0)},getOffsetOf:function(){var e=this.getLocationOf.apply(this,arguments);return e?e.getOffset():null},getNearestLocation:function(){var e=p.read(arguments),t=this.getValues(),n=A.getNearestParameter(t,e),r=A.getPoint(t,n);return new O(this,n,r,null,e.getDistance(r))},getNearestPoint:function(){return this.getNearestLocation.apply(this,arguments).getPoint()}},new function(){var e=["getPoint","getTangent","getNormal","getWeightedTangent","getWeightedNormal","getCurvature"];return s.each(e,function(e){this[e+"At"]=function(t,n){var r=this.getValues();return A[e](r,n?t:A.getParameterAt(r,t,0))}},{statics:{evaluateMethods:e}})},new function(){function e(e){var t=e[0],n=e[1],r=e[2],i=e[3],a=e[4],o=e[5],s=e[6],l=e[7],c=9*(r-a)+3*(s-t),u=6*(t+a)-12*r,h=3*(r-t),d=9*(i-o)+3*(l-n),f=6*(n+o)-12*i,p=3*(i-n);return function(e){var t=(c*e+u)*e+h,n=(d*e+f)*e+p;return Math.sqrt(t*t+n*n)}}function t(e,t){return Math.max(2,Math.min(16,Math.ceil(32*Math.abs(t-e))))}function n(e,t,n,r){if(null==t||t<0||t>1)return null;var i,a,o=e[0],s=e[1],l=e[2],c=e[3],u=e[4],h=e[5],d=e[6],f=e[7],m=4e-7,g=1-m;if(0===n&&(t<m||t>g)){var v=t<m;i=v?o:d,a=v?s:f}else{var w=3*(l-o),y=3*(u-l)-w,b=d-o-w-y,_=3*(c-s),x=3*(h-c)-_,E=f-s-_-x;if(0===n)i=((b*t+y)*t+w)*t+o,a=((E*t+x)*t+_)*t+s;else{if(t<m?(i=w,a=_):t>g?(i=3*(d-u),a=3*(f-h)):(i=(3*b*t+2*y)*t+w,a=(3*E*t+2*x)*t+_),r){0===i&&0===a&&(t<m||t>g)&&(i=u-l,a=h-c);var C=Math.sqrt(i*i+a*a);C&&(i/=C,a/=C)}if(3===n){var k=6*b*t+2*y,S=6*E*t+2*x,P=Math.pow(i*i+a*a,1.5);i=0!==P?(i*S-a*k)/P:0,a=0}}}return 2===n?new p(a,-i):new p(i,a)}return{statics:{getLength:function(n,r,i){if(r===o&&(r=0),i===o&&(i=1),0===r&&1===i&&A.isStraight(n)){var a=n[6]-n[0],s=n[7]-n[1];return Math.sqrt(a*a+s*s)}var l=e(n);return d.integrate(l,r,i,t(r,i))},getParameterAt:function(n,r,i){function a(e){return m+=d.integrate(h,i,e,t(i,e)),i=e,m-r}if(i===o&&(i=r<0?1:0),0===r)return i;var s=Math.abs,l=r>0,c=l?i:0,u=l?1:i,h=e(n),f=d.integrate(h,c,u,t(c,u));if(s(r-f)<1e-12)return l?u:c;if(s(r)>f)return null;var p=r/f,m=0;return d.findRoot(a,h,i+p,c,u,32,1e-12)},getPoint:function(e,t){return n(e,t,0,!1)},getTangent:function(e,t){return n(e,t,1,!0)},getWeightedTangent:function(e,t){return n(e,t,1,!1)},getNormal:function(e,t){return n(e,t,2,!0)},getWeightedNormal:function(e,t){return n(e,t,2,!1)},getCurvature:function(e,t){return n(e,t,3,!1).x}}}},new function(){function e(e,t,n,r,i,a,o,s,l,c,u){var h=t.startConnected,d=t.endConnected,f=4e-7,p=1-f;if(null==i&&(i=A.getParameterOf(n,a)),null!==i&&i>=(h?f:0)&&i<=(d?p:1)&&(null==l&&(l=A.getParameterOf(o,c)),null!==l&&l>=(d?f:0)&&l<=(h?p:1))){var m=t.renormalize;if(m){var g=m(i,l);i=g[0],l=g[1]}var v=new O(r,i,a||A.getPoint(n,i),u),w=new O(s,l,c||A.getPoint(o,l),u),y=v.getPath()===w.getPath()&&v.getIndex()>w.getIndex(),b=y?w:v,_=t.include;v._intersection=w,w._intersection=v,_&&!_(b)||O.insert(e,b,!0)}}function t(i,a,o,s,l,c,u,h,d,f,p,m,g){if(!(++g>=24)){var v,w,y=a[0],b=a[1],x=a[6],E=a[7],C=_.getSignedDistance,k=C(y,b,x,E,a[2],a[3]),S=C(y,b,x,E,a[4],a[5]),P=k*S>0?.75:4/9,T=P*Math.min(0,k,S),M=P*Math.max(0,k,S),N=C(y,b,x,E,i[0],i[1]),I=C(y,b,x,E,i[2],i[3]),L=C(y,b,x,E,i[4],i[5]),O=C(y,b,x,E,i[6],i[7]),B=n(N,I,L,O),z=B[0],R=B[1];if(null!=(v=r(z,R,T,M))&&null!=(w=r(z.reverse(),R.reverse(),T,M))){i=A.getPart(i,v,w);var D=w-v,j=u+(h-u)*v,F=u+(h-u)*w;if(p>.5&&D>.5)if(F-j>f-d){var q=A.subdivide(i,.5),V=j+(F-j)/2;t(a,q[0],s,o,l,c,d,f,j,V,D,!m,g),t(a,q[1],s,o,l,c,d,f,V,F,D,!m,g)}else{var q=A.subdivide(a,.5),V=d+(f-d)/2;t(q[0],i,s,o,l,c,d,V,j,F,D,!m,g),t(q[1],i,s,o,l,c,V,f,j,F,D,!m,g)}else if(Math.max(f-d,F-j)<1e-7){var U=j+(F-j)/2,W=d+(f-d)/2;i=o.getValues(),a=s.getValues(),e(l,c,m?a:i,m?s:o,m?W:U,null,m?i:a,m?o:s,m?U:W,null)}else D>1e-12&&t(a,i,s,o,l,c,d,f,j,F,D,!m,g)}}}function n(e,t,n,r){var i,a=[0,e],o=[1/3,t],s=[2/3,n],l=[1,r],c=t-(2*e+r)/3,u=n-(e+2*r)/3;if(c*u<0)i=[[a,o,l],[a,s,l]];else{var h=c/u;i=[h>=2?[a,o,l]:h<=.5?[a,s,l]:[a,o,s,l],[a,l]]}return(c||u)<0?i.reverse():i}function r(e,t,n,r){return e[0][1]<n?i(e,!0,n):t[0][1]>r?i(t,!1,r):e[0][0]}function i(e,t,n){for(var r=e[0][0],i=e[0][1],a=1,o=e.length;a<o;a++){var s=e[a][0],l=e[a][1];if(t?l>=n:l<=n)return l===n?s:r+(n-i)*(s-r)/(l-i);r=s,i=l}return null}function a(t,n,r,i,a,o){for(var s=A.isStraight(t),l=s?n:t,c=s?t:n,u=c[0],h=c[1],f=c[6],p=c[7],m=f-u,g=p-h,v=Math.atan2(-g,m),w=Math.sin(v),y=Math.cos(v),b=[],_=0;_<8;_+=2){var x=l[_]-u,E=l[_+1]-h;b.push(x*y-E*w,x*w+E*y)}for(var C=[],k=A.solveCubic(b,1,0,C,0,1),_=0;_<k;_++){var S=C[_],P=A.getPoint(l,S),T=A.getParameterOf(c,P);if(null!==T){var M=A.getPoint(c,T),N=s?T:S,I=s?S:T;(!o.endConnected||I>d.CURVETIME_EPSILON)&&e(a,o,t,r,N,s?M:P,n,i,I,s?P:M)}}}function o(t,n,r,i,a,o){var s=_.intersect(t[0],t[1],t[6],t[7],n[0],n[1],n[6],n[7]);s&&e(a,o,t,r,null,s,n,i,null,s)}return{statics:{_getIntersections:function(n,r,i,s,l,c){if(!r)return A._getSelfIntersection(n,i,l,c);var u=n[0],h=n[1],d=n[6],f=n[7],m=r[0],g=r[1],v=r[6],w=r[7],y=(3*n[2]+u)/4,b=(3*n[3]+h)/4,_=(3*n[4]+d)/4,x=(3*n[5]+f)/4,E=(3*r[2]+m)/4,C=(3*r[3]+g)/4,k=(3*r[4]+v)/4,S=(3*r[5]+w)/4,P=Math.min,T=Math.max;if(!(T(u,y,_,d)>=P(m,E,k,v)&&P(u,y,_,d)<=T(m,E,k,v)&&T(h,b,x,f)>=P(g,C,S,w)&&P(h,b,x,f)<=T(g,C,S,w)))return l;if(!c.startConnected&&!c.endConnected){var M=A.getOverlaps(n,r);if(M){for(var N=0;N<2;N++){var I=M[N];e(l,c,n,i,I[0],null,r,s,I[1],null,!0)}return l}}var L=A.isStraight(n),O=A.isStraight(r),B=L&&O,z=1e-12,R=l.length;if((B?o:L||O?a:t)(n,r,i,s,l,c,0,1,0,1,0,!1,0),B&&l.length>R)return l;var D=new p(u,h),j=new p(d,f),F=new p(m,g),q=new p(v,w);return D.isClose(F,z)&&e(l,c,n,i,0,D,r,s,0,F),!c.startConnected&&D.isClose(q,z)&&e(l,c,n,i,0,D,r,s,1,q),!c.endConnected&&j.isClose(F,z)&&e(l,c,n,i,1,j,r,s,0,F),j.isClose(q,z)&&e(l,c,n,i,1,j,r,s,1,q),l},_getSelfIntersection:function(e,t,n,r){var i=e[0],a=e[1],o=e[2],s=e[3],l=e[4],c=e[5],u=e[6],h=e[7],f=new _(i,a,u,h,!1),m=f.getSide(new p(o,s),!0),g=f.getSide(new p(l,c),!0);if(m===g){var v=(i-l)*(s-h)+(o-u)*(c-a);if(v*m>0)return n}var w=u-3*l+3*o-i,y=l-2*o+i,b=o-i,x=h-3*c+3*s-a,E=c-2*s+a,C=s-a,k=x*b-w*C,S=x*y-w*E,P=E*b-y*C;if(k*k-4*S*P<0){var T,M=[],N=d.solveCubic(w*w+x*x,3*(w*y+x*E),2*(y*y+E*E)+w*b+x*C,y*b+E*C,M,0,1);if(N>0){for(var I=0,L=0;I<N;I++){var O=Math.abs(t.getCurvatureAt(M[I],!0));O>L&&(L=O,T=M[I])}var B=A.subdivide(e,T);r.endConnected=!0,r.renormalize=function(e,t){return[e*T,t*(1-T)+T]},A._getIntersections(B[0],B[1],t,t,n,r)}}return n},getOverlaps:function(e,t){function n(e){var t=e[6]-e[0],n=e[7]-e[1];return t*t+n*n}var r=Math.abs,i=4e-7,a=2e-7,o=A.isStraight(e),s=A.isStraight(t),l=o&&s;if(l){var c=n(e)<n(t),u=c?t:e,h=c?e:t,d=new _(u[0],u[1],u[6],u[7]);if(d.getDistance(new p(h[0],h[1]))>a||d.getDistance(new p(h[6],h[7]))>a)return null}else if(o^s)return null;for(var f=[e,t],m=[],g=0,v=0;g<2&&m.length<2;g+=0===v?0:1,v^=1){var w=A.getParameterOf(f[1^g],new p(f[g][0===v?0:6],f[g][0===v?1:7]));if(null!=w){var y=0===g?[v,w]:[w,v];(0===m.length||r(y[0]-m[0][0])>i&&r(y[1]-m[0][1])>i)&&m.push(y)}if(1===g&&0===m.length)break}if(2!==m.length)m=null;else if(!l){var b=A.getPart(e,m[0][0],m[1][0]),x=A.getPart(t,m[0][1],m[1][1]);(r(x[2]-b[2])>a||r(x[3]-b[3])>a||r(x[4]-b[4])>a||r(x[5]-b[5])>a)&&(m=null)}return m}}}}),O=s.extend({_class:"CurveLocation",beans:!0,initialize:function e(t,n,r,i,a){if(n>.9999996){var o=t.getNext();o&&(n=0,t=o)}this._id=f.get(e),this._setCurve(t),this._parameter=n,this._point=r||t.getPointAt(n,!0),this._overlap=i,this._distance=a,this._intersection=this._next=this._prev=null},_setCurve:function(e){var t=e._path;this._version=t?t._version:0,this._curve=e,this._segment=null,this._segment1=e._segment1,this._segment2=e._segment2},_setSegment:function(e){this._setCurve(e.getCurve()),this._segment=e,this._parameter=e===this._segment1?0:1,this._point=e._point.clone()},getSegment:function(){var e=this.getCurve(),t=this._segment;if(!t){var n=this.getParameter();0===n?t=e._segment1:1===n?t=e._segment2:null!=n&&(t=e.getPartLength(0,n)<e.getPartLength(n,1)?e._segment1:e._segment2),this._segment=t}return t},getCurve:function(){function e(e){var t=e&&e.getCurve();if(t&&null!=(r._parameter=t.getParameterOf(r._point)))return r._setCurve(t),r._segment=e,t}var t=this._curve,n=t&&t._path,r=this;return n&&n._version!==this._version&&(t=this._parameter=this._curve=this._offset=null),t||e(this._segment)||e(this._segment1)||e(this._segment2.getPrevious())},getPath:function(){var e=this.getCurve();return e&&e._path},getIndex:function(){var e=this.getCurve();return e&&e.getIndex()},getParameter:function(){var e=this.getCurve(),t=this._parameter;return e&&null==t?this._parameter=e.getParameterOf(this._point):t},getPoint:function(){return this._point},getOffset:function(){var e=this._offset;if(null==e){e=0;var t=this.getPath(),n=this.getIndex();if(t&&null!=n)for(var r=t.getCurves(),i=0;i<n;i++)e+=r[i].getLength();this._offset=e+=this.getCurveOffset()}return e},getCurveOffset:function(){var e=this.getCurve(),t=this.getParameter();return null!=t&&e&&e.getPartLength(0,t)},getIntersection:function(){return this._intersection},getDistance:function(){return this._distance},divide:function(){var e=this.getCurve(),t=null;return e&&(t=e.divide(this.getParameter(),!0),t&&this._setSegment(t._segment1)),t},split:function(){var e=this.getCurve();return e?e.split(this.getParameter(),!0):null},equals:function(e,t){var n=this===e,r=2e-7;if(!n&&e instanceof O&&this.getPath()===e.getPath()&&this.getPoint().isClose(e.getPoint(),r)){var i=this.getCurve(),a=e.getCurve(),o=Math.abs,s=o((i.isLast()&&a.isFirst()?-1:i.getIndex())+this.getParameter()-((a.isLast()&&i.isFirst()?-1:a.getIndex())+e.getParameter()));n=(s<4e-7||(s=o(this.getOffset()-e.getOffset()))<r||o(this.getPath().getLength()-s)<r)&&(t||!this._intersection&&!e._intersection||this._intersection&&this._intersection.equals(e._intersection,!0))}return n},toString:function(){var e=[],t=this.getPoint(),n=h.instance;t&&e.push("point: "+t);var r=this.getIndex();null!=r&&e.push("index: "+r);var i=this.getParameter();return null!=i&&e.push("parameter: "+n.number(i)),null!=this._distance&&e.push("distance: "+n.number(this._distance)),"{ "+e.join(", ")+" }"},isTouching:function(){var e=this._intersection;if(e&&this.getTangent().isCollinear(e.getTangent())){var t=this.getCurve(),n=e.getCurve();return!(t.isStraight()&&n.isStraight()&&t.getLine().intersect(n.getLine()))}return!1},isCrossing:function(){function e(e,t,n){return t<n?e>t&&e<n:e>t&&e<=u||e>=-u&&e<n}var t=this._intersection;if(!t)return!1;var n=this.getParameter(),r=t.getParameter(),i=4e-7,a=1-i;if(n>=i&&n<=a||r>=i&&r<=a)return!this.isTouching();var o=this.getCurve(),s=o.getPrevious(),l=t.getCurve(),c=l.getPrevious(),u=Math.PI;if(!s||!c)return!1;var h=s.getTangentAt(a,!0).negate().getAngleInRadians(),d=o.getTangentAt(i,!0).getAngleInRadians(),f=c.getTangentAt(a,!0).negate().getAngleInRadians(),p=l.getTangentAt(i,!0).getAngleInRadians();return e(f,h,d)^e(p,h,d)&&e(f,d,h)^e(p,d,h)},isOverlap:function(){return!!this._overlap}},s.each(A.evaluateMethods,function(e){var t=e+"At";this[e]=function(){var e=this.getParameter(),n=this.getCurve();return null!=e&&n&&n[t](e,!0)}},{preserve:!0}),new function(){function e(e,t,n){function r(n,r){for(var a=n+r;a>=-1&&a<=i;a+=r){var o=e[(a%i+i)%i];if(!t.getPoint().isClose(o.getPoint(),2e-7))break;if(t.equals(o))return o}return null}for(var i=e.length,a=0,o=i-1;a<=o;){var s,l=a+o>>>1,c=e[l];if(n&&(s=t.equals(c)?c:r(l,-1)||r(l,1)))return t._overlap&&(s._overlap=s._intersection._overlap=!0),s;var u=t.getPath(),h=c.getPath(),d=u===h?t.getIndex()+t.getParameter()-(c.getIndex()+c.getParameter()):u._id-h._id;d<0?o=l-1:a=l+1}return e.splice(a,0,t),t}return{statics:{insert:e,expand:function(t){for(var n=t.slice(),r=0,i=t.length;r<i;r++)e(n,t[r]._intersection,!1);return n}}}}),B=C.extend({_class:"PathItem",initialize:function(){},getIntersections:function(e,t,n,r){var i=this===e||!e,a=this._matrix.orNullIfIdentity(),o=i?a:(n||e._matrix).orNullIfIdentity();if(!i&&!this.getBounds(a).touches(e.getBounds(o)))return[];for(var s,e,l=this.getCurves(),c=i?l:e.getCurves(),u=l.length,h=i?u:c.length,d=[],f=[],p=0;p<h;p++)d[p]=c[p].getValues(o);for(var p=0;p<u;p++){var m=l[p],g=i?d[p]:m.getValues(a),v=m.getPath();v!==e&&(e=v,s=[],f.push(s)),i&&A._getSelfIntersection(g,m,s,{include:t,startConnected:1===u&&m.getPoint1().equals(m.getPoint2())});for(var w=i?p+1:0;w<h;w++){if(r&&s.length)return s;var y=c[w];A._getIntersections(g,d[w],m,y,s,{include:t,startConnected:i&&m.getPrevious()===y,endConnected:i&&m.getNext()===y})}}s=[];for(var p=0,b=f.length;p<b;p++)s.push.apply(s,f[p]);return s},getCrossings:function(e){return this.getIntersections(e,function(e){return e.isCrossing()})},_asPathItem:function(){return this},setPathData:function(e){function t(e,t){var n=+r[e];return s&&(n+=l[t]),n}function n(e){return new p(t(e,"x"),t(e+1,"y"))}var r,i,a,o=e.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/gi),s=!1,l=new p,c=new p;this.clear();for(var u=0,h=o&&o.length;u<h;u++){var d=o[u],f=d[0],m=f.toLowerCase();r=d.match(/[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g);var v=r&&r.length;switch(s=f===m,"z"!==i||/[mz]/.test(m)||this.moveTo(l=c),m){case"m":case"l":for(var w="m"===m,y=0;y<v;y+=2)this[0===y&&w?"moveTo":"lineTo"](l=n(y));a=l,w&&(c=l);break;case"h":case"v":for(var b="h"===m?"x":"y",y=0;y<v;y++)l[b]=t(y,b),this.lineTo(l);a=l;break;case"c":for(var y=0;y<v;y+=6)this.cubicCurveTo(n(y),a=n(y+2),l=n(y+4));break;case"s":for(var y=0;y<v;y+=4)this.cubicCurveTo(/[cs]/.test(i)?l.multiply(2).subtract(a):l,a=n(y),l=n(y+2)),i=m;break;case"q":for(var y=0;y<v;y+=4)this.quadraticCurveTo(a=n(y),l=n(y+2));break;case"t":for(var y=0;y<v;y+=2)this.quadraticCurveTo(a=/[qt]/.test(i)?l.multiply(2).subtract(a):l,l=n(y)),i=m;break;case"a":for(var y=0;y<v;y+=7)this.arcTo(l=n(y+5),new g(+r[y],+r[y+1]),+r[y+2],+r[y+4],+r[y+3]);break;case"z":this.closePath(!0)}i=m}},_canComposite:function(){return!(this.hasFill()&&this.hasStroke())},_contains:function(e){var t=this._getWinding(e,!1,!0);return!!("evenodd"===this.getWindingRule()?1&t:t)}}),z=B.extend({_class:"Path",_serializeFields:{segments:[],closed:!1},initialize:function(e){this._closed=!1,this._segments=[],this._version=0;var t=Array.isArray(e)?"object"==typeof e[0]?e:arguments:!e||e.size!==o||e.x===o&&e.point===o?null:arguments;t&&t.length>0?this.setSegments(t):(this._curves=o,this._selectedSegmentState=0,t||"string"!=typeof e||(this.setPathData(e),e=null)),this._initialize(!t&&e)},_equals:function(e){ +return this._closed===e._closed&&s.equals(this._segments,e._segments)},clone:function(e){var t=new z(C.NO_INSERT);return t.setSegments(this._segments),t._closed=this._closed,this._clockwise!==o&&(t._clockwise=this._clockwise),this._clone(t,e)},_changed:function e(t){if(e.base.call(this,t),8&t){var n=this._parent;if(n&&(n._currentPath=o),this._length=this._area=this._clockwise=this._monoCurves=o,16&t)this._version++;else if(this._curves)for(var r=0,i=this._curves.length;r<i;r++)this._curves[r]._changed()}else 32&t&&(this._bounds=o)},getStyle:function(){var e=this._parent;return(e instanceof R?e:this)._style},getSegments:function(){return this._segments},setSegments:function(e){var t=this.isFullySelected();this._segments.length=0,this._selectedSegmentState=0,this._curves=o,e&&e.length>0&&this._add(I.readAll(e)),t&&this.setFullySelected(!0)},getFirstSegment:function(){return this._segments[0]},getLastSegment:function(){return this._segments[this._segments.length-1]},getCurves:function(){var e=this._curves,t=this._segments;if(!e){var n=this._countCurves();e=this._curves=new Array(n);for(var r=0;r<n;r++)e[r]=new A(this,t[r],t[r+1]||t[0])}return e},getFirstCurve:function(){return this.getCurves()[0]},getLastCurve:function(){var e=this.getCurves();return e[e.length-1]},isClosed:function(){return this._closed},setClosed:function(e){if(this._closed!=(e=!!e)){if(this._closed=e,this._curves){var t=this._curves.length=this._countCurves();e&&(this._curves[t-1]=new A(this,this._segments[t-1],this._segments[0]))}this._changed(25)}}},{beans:!0,getPathData:function(e,t){function n(t,n){t._transformCoordinates(e,m,!1),r=m[0],i=m[1],g?(v.push("M"+p.pair(r,i)),g=!1):(s=m[2],l=m[3],s===r&&l===i&&c===a&&u===o?n||v.push("l"+p.pair(r-a,i-o)):v.push("c"+p.pair(c-a,u-o)+" "+p.pair(s-a,l-o)+" "+p.pair(r-a,i-o))),a=r,o=i,c=m[4],u=m[5]}var r,i,a,o,s,l,c,u,d=this._segments,f=d.length,p=new h(t),m=new Array(6),g=!0,v=[];if(0===f)return"";for(var w=0;w<f;w++)n(d[w]);return this._closed&&f>0&&(n(d[0],!0),v.push("z")),v.join("")}},{isEmpty:function(){return 0===this._segments.length},_transformContent:function(e){for(var t=new Array(6),n=0,r=this._segments.length;n<r;n++)this._segments[n]._transformCoordinates(e,t,!0);return!0},_add:function(e,t){for(var n=this._segments,r=this._curves,i=e.length,a=null==t,t=a?n.length:t,o=0;o<i;o++){var s=e[o];s._path&&(s=e[o]=s.clone()),s._path=this,s._index=t+o,s._selectionState&&this._updateSelection(s,0,s._selectionState)}if(a)n.push.apply(n,e);else{n.splice.apply(n,[t,0].concat(e));for(var o=t+i,l=n.length;o<l;o++)n[o]._index=o}if(r){var c=this._countCurves(),u=t+i-1===c?t-1:t,h=u,d=Math.min(u+i,c);e._curves&&(r.splice.apply(r,[u,0].concat(e._curves)),h+=e._curves.length);for(var o=h;o<d;o++)r.splice(o,0,new A(this,null,null));this._adjustCurves(u,d)}return this._changed(25),e},_adjustCurves:function(e,t){for(var n,r=this._segments,i=this._curves,a=e;a<t;a++)n=i[a],n._path=this,n._segment1=r[a],n._segment2=r[a+1]||r[0],n._changed();(n=i[this._closed&&0===e?r.length-1:e-1])&&(n._segment2=r[e]||r[0],n._changed()),(n=i[t])&&(n._segment1=r[t],n._changed())},_countCurves:function(){var e=this._segments.length;return!this._closed&&e>0?e-1:e},add:function(e){return arguments.length>1&&"number"!=typeof e?this._add(I.readAll(arguments)):this._add([I.read(arguments)])[0]},insert:function(e,t){return arguments.length>2&&"number"!=typeof t?this._add(I.readAll(arguments,1),e):this._add([I.read(arguments,1)],e)[0]},addSegment:function(){return this._add([I.read(arguments)])[0]},insertSegment:function(e){return this._add([I.read(arguments,1)],e)[0]},addSegments:function(e){return this._add(I.readAll(e))},insertSegments:function(e,t){return this._add(I.readAll(t),e)},removeSegment:function(e){return this.removeSegments(e,e+1)[0]||null},removeSegments:function(e,t,n){e=e||0,t=s.pick(t,this._segments.length);var r=this._segments,i=this._curves,a=r.length,o=r.splice(e,t-e),l=o.length;if(!l)return o;for(var c=0;c<l;c++){var u=o[c];u._selectionState&&this._updateSelection(u,u._selectionState,0),u._index=u._path=null}for(var c=e,h=r.length;c<h;c++)r[c]._index=c;if(i){var d=e>0&&t===a+(this._closed?1:0)?e-1:e,i=i.splice(d,l);n&&(o._curves=i.slice(1)),this._adjustCurves(d,d)}return this._changed(25),o},clear:"#removeSegments",hasHandles:function(){for(var e=this._segments,t=0,n=e.length;t<n;t++)if(e[t].hasHandles())return!0;return!1},clearHandles:function(){for(var e=this._segments,t=0,n=e.length;t<n;t++)e[t].clearHandles()},getLength:function(){if(null==this._length){for(var e=this.getCurves(),t=0,n=0,r=e.length;n<r;n++)t+=e[n].getLength();this._length=t}return this._length},getArea:function(){if(null==this._area){for(var e=this._segments,t=e.length,n=t-1,r=0,i=0,a=this._closed?t:n;i<a;i++)r+=A.getArea(A.getValues(e[i],e[i<n?i+1:0]));this._area=r}return this._area},isClockwise:function(){return this._clockwise!==o?this._clockwise:this.getArea()>=0},setClockwise:function(e){this.isClockwise()!=(e=!!e)&&this.reverse(),this._clockwise=e},isFullySelected:function(){var e=this._segments.length;return this._selected&&e>0&&this._selectedSegmentState===7*e},setFullySelected:function(e){e&&this._selectSegments(!0),this.setSelected(e)},setSelected:function e(t){t||this._selectSegments(!1),e.base.call(this,t)},_selectSegments:function(e){var t=this._segments.length;this._selectedSegmentState=e?7*t:0;for(var n=0;n<t;n++)this._segments[n]._selectionState=e?7:0},_updateSelection:function(e,t,n){e._selectionState=n;var r=this._selectedSegmentState+=n-t;r>0&&this.setSelected(!0)},flatten:function(e){for(var t=new D(this,64,.1),n=0,r=t.length/Math.ceil(t.length/e),i=t.length+(this._closed?-r:r)/2,a=[];n<=i;)a.push(new I(t.getPointAt(n))),n+=r;this.setSegments(a)},reduce:function(){for(var e=this.getCurves(),t=e.length-1;t>=0;t--){var n=e[t];n.hasHandles()||0!==n.getLength()&&!n.isCollinear(n.getNext())||n.remove()}return this},simplify:function(e){if(this._segments.length>2){var t=new j(this,e||2.5);this.setSegments(t.fit())}},split:function(e,t){if(null===t)return null;if(1===arguments.length){var n=e;if("number"==typeof n&&(n=this.getLocationAt(n)),!n)return null;e=n.index,t=n.parameter}var r=4e-7,i=1-r;t>=i&&(e++,t--);var a=this.getCurves();if(e>=0&&e<a.length){t>=r&&a[e++].divide(t,!0);var o,s=this.removeSegments(e,this._segments.length,!0);return this._closed?(this.setClosed(!1),o=this):(o=new z(C.NO_INSERT),o.insertAbove(this,!0),this._clone(o)),o._add(s,0),this.addSegment(s[0]),o}return null},reverse:function(){this._segments.reverse();for(var e=0,t=this._segments.length;e<t;e++){var n=this._segments[e],r=n._handleIn;n._handleIn=n._handleOut,n._handleOut=r,n._index=e}this._curves=null,this._clockwise!==o&&(this._clockwise=!this._clockwise),this._changed(9)},join:function(e){if(e){var t=e._segments,n=this.getLastSegment(),r=e.getLastSegment();if(!r)return this;n&&n._point.equals(r._point)&&e.reverse();var i=e.getFirstSegment();if(n&&n._point.equals(i._point))n.setHandleOut(i._handleOut),this._add(t.slice(1));else{var a=this.getFirstSegment();a&&a._point.equals(i._point)&&e.reverse(),r=e.getLastSegment(),a&&a._point.equals(r._point)?(a.setHandleIn(r._handleIn),this._add(t.slice(0,t.length-1),0)):this._add(t.slice())}e._closed&&this._add([t[0]]),e.remove()}var o=this.getFirstSegment(),s=this.getLastSegment();return o!==s&&o._point.equals(s._point)&&(o.setHandleIn(s._handleIn),s.remove(),this.setClosed(!0)),this},toShape:function(e){function t(e,t){var n=c[e],r=n.getNext(),i=c[t],a=i.getNext();return n._handleOut.isZero()&&r._handleIn.isZero()&&i._handleOut.isZero()&&a._handleIn.isZero()&&r._point.subtract(n._point).isCollinear(a._point.subtract(i._point))}function n(e){var t=c[e],n=t.getPrevious(),r=t.getNext();return n._handleOut.isZero()&&t._handleIn.isZero()&&t._handleOut.isZero()&&r._handleIn.isZero()&&t._point.subtract(n._point).isOrthogonal(r._point.subtract(t._point))}function r(e){var t=c[e],n=t.getNext(),r=t._handleOut,i=n._handleIn,a=.5522847498307936;if(r.isOrthogonal(i)){var o=t._point,s=n._point,l=new _(o,r,!0).intersect(new _(s,i,!0),!0);return l&&d.isZero(r.getLength()/l.subtract(o).getLength()-a)&&d.isZero(i.getLength()/l.subtract(s).getLength()-a)}return!1}function i(e,t){return c[e]._point.getDistance(c[t]._point)}if(!this._closed)return null;var a,o,s,l,c=this._segments;if(!this.hasHandles()&&4===c.length&&t(0,2)&&t(1,3)&&n(1)?(a=P.Rectangle,o=new g(i(0,3),i(0,1)),l=c[1]._point.add(c[2]._point).divide(2)):8===c.length&&r(0)&&r(2)&&r(4)&&r(6)&&t(1,5)&&t(3,7)?(a=P.Rectangle,o=new g(i(1,6),i(0,3)),s=o.subtract(new g(i(0,7),i(1,2))).divide(2),l=c[3]._point.add(c[4]._point).divide(2)):4===c.length&&r(0)&&r(1)&&r(2)&&r(3)&&(d.isZero(i(0,2)-i(1,3))?(a=P.Circle,s=i(0,2)/2):(a=P.Ellipse,s=new g(i(2,0)/2,i(3,1)/2)),l=c[1]._point),a){var u=this.getPosition(!0),h=this._clone(new a({center:u,size:o,radius:s,insert:!1}),e,!1);return h.rotate(l.subtract(u).getAngle()+90),h}return null},_hitTestSelf:function(e,t){function n(t,n){return e.subtract(t).divide(n).length<=1}function r(e,r,i){if(!t.selected||r.isSelected()){var a=e._point;if(r!==a&&(r=r.add(a)),n(r,b))return new N(i,f,{segment:e,point:r})}}function i(e,n){return(n||t.segments)&&r(e,e._point,"segment")||!n&&t.handles&&(r(e,e._handleIn,"handle-in")||r(e,e._handleOut,"handle-out"))}function a(e){u.add(e)}function o(t){if(("round"!==s||"round"!==l)&&(u=new z({internal:!0,closed:!0}),w||t._index>0&&t._index<v-1?"round"!==s&&(t._handleIn.isZero()||t._handleOut.isZero())&&z._addBevelJoin(t,s,C,c,a,!0):"round"!==l&&z._addSquareCap(t,l,C,a,!0),!u.isEmpty())){var r;return u.contains(e)||(r=u.getNearestLocation(e))&&n(r.getPoint(),y)}return n(t._point,b)}var s,l,c,u,h,d,f=this,m=this.getStyle(),g=this._segments,v=g.length,w=this._closed,y=t._tolerancePadding,b=y,_=t.stroke&&m.hasStroke(),x=t.fill&&m.hasFill(),E=t.curves,C=_?m.getStrokeWidth()/2:x&&t.tolerance>0||E?0:null;if(null!==C&&(C>0?(s=m.getStrokeJoin(),l=m.getStrokeCap(),c=C*m.getMiterLimit(),b=y.add(new p(C,C))):s=l="round"),!t.ends||t.segments||w){if(t.segments||t.handles)for(var k=0;k<v;k++)if(d=i(g[k]))return d}else if(d=i(g[0],!0)||i(g[v-1],!0))return d;if(null!==C){if(h=this.getNearestLocation(e)){var S=h.getParameter();0===S||1===S&&v>1?o(h.getSegment())||(h=null):n(h.getPoint(),b)||(h=null)}if(!h&&"miter"===s&&v>1)for(var k=0;k<v;k++){var P=g[k];if(e.getDistance(P._point)<=c&&o(P)){h=P.getLocation();break}}}return!h&&x&&this._contains(e)||h&&!_&&!E?new N("fill",this):h?new N(_?"stroke":"curve",this,{location:h,point:h.getPoint()}):null}},s.each(A.evaluateMethods,function(e){this[e+"At"]=function(t,n){var r=this.getLocationAt(t,n);return r&&r[e]()}},{beans:!1,getLocationOf:function(){for(var e=p.read(arguments),t=this.getCurves(),n=0,r=t.length;n<r;n++){var i=t[n].getLocationOf(e);if(i)return i}return null},getOffsetOf:function(){var e=this.getLocationOf.apply(this,arguments);return e?e.getOffset():null},getLocationAt:function(e,t){var n=this.getCurves(),r=0;if(t){var i=~~e,a=n[i];return a?a.getLocationAt(e-i,!0):null}for(var o=0,s=n.length;o<s;o++){var l=r,a=n[o];if(r+=a.getLength(),r>e)return a.getLocationAt(e-l)}return n.length>0&&e<=this.getLength()?new O(n[n.length-1],1):null},getNearestLocation:function(){for(var e=p.read(arguments),t=this.getCurves(),n=1/0,r=null,i=0,a=t.length;i<a;i++){var o=t[i].getNearestLocation(e);o._distance<n&&(n=o._distance,r=o)}return r},getNearestPoint:function(){return this.getNearestLocation.apply(this,arguments).getPoint()}}),new function(){function e(e,t,n,r){function i(t){var n=o[t],r=o[t+1];h==n&&d==r||(e.beginPath(),e.moveTo(h,d),e.lineTo(n,r),e.stroke(),e.beginPath(),e.arc(n,r,a,0,2*Math.PI,!0),e.fill())}for(var a=r/2,o=new Array(6),s=0,l=t.length;s<l;s++){var c=t[s];c._transformCoordinates(n,o,!1);var u=c._selectionState,h=o[0],d=o[1];if(1&u&&i(2),2&u&&i(4),e.fillRect(h-a,d-a,r,r),!(4&u)){var f=e.fillStyle;e.fillStyle="#ffffff",e.fillRect(h-a+1,d-a+1,r-2,r-2),e.fillStyle=f}}}function t(e,t,n){function r(t){if(n)t._transformCoordinates(n,p,!1),i=p[0],a=p[1];else{var r=t._point;i=r._x,a=r._y}if(m)e.moveTo(i,a),m=!1;else{if(n)l=p[2],c=p[3];else{var d=t._handleIn;l=i+d._x,c=a+d._y}l===i&&c===a&&u===o&&h===s?e.lineTo(i,a):e.bezierCurveTo(u,h,l,c,i,a)}if(o=i,s=a,n)u=p[4],h=p[5];else{var d=t._handleOut;u=o+d._x,h=s+d._y}}for(var i,a,o,s,l,c,u,h,d=t._segments,f=d.length,p=new Array(6),m=!0,g=0;g<f;g++)r(d[g]);t._closed&&f>0&&r(d[0])}return{_draw:function(e,n,r){function i(e){return h[(e%d+d)%d]}var o=n.dontStart,s=n.dontFinish||n.clip,l=this.getStyle(),c=l.hasFill(),u=l.hasStroke(),h=l.getDashArray(),d=!a.support.nativeDash&&u&&h&&h.length;if(o||e.beginPath(),!o&&this._currentPath?e.currentPath=this._currentPath:(c||u&&!d||s)&&(t(e,this,r),this._closed&&e.closePath(),o||(this._currentPath=e.currentPath)),!s&&(c||u)&&(this._setStyles(e),c&&(e.fill(l.getWindingRule()),e.shadowColor="rgba(0,0,0,0)"),u)){if(d){o||e.beginPath();var f,p=new D(this,32,.25,r),m=p.length,g=-l.getDashOffset(),v=0;for(g%=m;g>0;)g-=i(v--)+i(v--);for(;g<m;)f=g+i(v++),(g>0||f>0)&&p.drawPart(e,Math.max(g,0),Math.max(f,0)),g=f+i(v++)}e.stroke()}},_drawSelected:function(n,r){n.beginPath(),t(n,this,r),n.stroke(),e(n,this._segments,r,a.settings.handleSize)}}},new function(){function e(e){var t=e.length,n=[],r=[],i=2;n[0]=e[0]/i;for(var a=1;a<t;a++)r[a]=1/i,i=(a<t-1?4:2)-r[a],n[a]=(e[a]-n[a-1])/i;for(var a=1;a<t;a++)n[t-a-1]-=r[t-a]*n[t-a];return n}return{smooth:function(){var t=this._segments,n=t.length,r=this._closed,i=n,a=0;if(!(n<=2)){r&&(a=Math.min(n,4),i+=2*Math.min(n,a));for(var o=[],s=0;s<n;s++)o[s+a]=t[s]._point;if(r)for(var s=0;s<a;s++)o[s]=t[s+n-a]._point,o[s+n+a]=t[s]._point;else i--;for(var l=[],s=1;s<i-1;s++)l[s]=4*o[s]._x+2*o[s+1]._x;l[0]=o[0]._x+2*o[1]._x,l[i-1]=3*o[i-1]._x;for(var c=e(l),s=1;s<i-1;s++)l[s]=4*o[s]._y+2*o[s+1]._y;l[0]=o[0]._y+2*o[1]._y,l[i-1]=3*o[i-1]._y;var u=e(l);if(r){for(var s=0,h=n;s<a;s++,h++){var d=s/a,f=1-d,m=s+a,g=h+a;c[h]=c[s]*d+c[h]*f,u[h]=u[s]*d+u[h]*f,c[g]=c[m]*f+c[g]*d,u[g]=u[m]*f+u[g]*d}i--}for(var v=null,s=a;s<=i-a;s++){var w=t[s-a];v&&w.setHandleIn(v.subtract(w._point)),s<i&&(w.setHandleOut(new p(c[s],u[s]).subtract(w._point)),v=s<i-1?new p(2*o[s+1]._x-c[s+1],2*o[s+1]._y-u[s+1]):new p((o[i]._x+c[i-1])/2,(o[i]._y+u[i-1])/2))}if(r&&v){var w=this._segments[0];w.setHandleIn(v.subtract(w._point))}}}}},new function(){function e(e){var t=e._segments;if(0===t.length)throw new Error("Use a moveTo() command first");return t[t.length-1]}return{moveTo:function(){var e=this._segments;1===e.length&&this.removeSegment(0),e.length||this._add([new I(p.read(arguments))])},moveBy:function(){throw new Error("moveBy() is unsupported on Path items.")},lineTo:function(){this._add([new I(p.read(arguments))])},cubicCurveTo:function(){var t=p.read(arguments),n=p.read(arguments),r=p.read(arguments),i=e(this);i.setHandleOut(t.subtract(i._point)),this._add([new I(r,n.subtract(r))])},quadraticCurveTo:function(){var t=p.read(arguments),n=p.read(arguments),r=e(this)._point;this.cubicCurveTo(t.add(r.subtract(t).multiply(1/3)),t.add(n.subtract(t).multiply(1/3)),n)},curveTo:function(){var t=p.read(arguments),n=p.read(arguments),r=s.pick(s.read(arguments),.5),i=1-r,a=e(this)._point,o=t.subtract(a.multiply(i*i)).subtract(n.multiply(r*r)).divide(2*r*i);if(o.isNaN())throw new Error("Cannot put a curve through points with parameter = "+r);this.quadraticCurveTo(o,n)},arcTo:function(){var t,n,r,i,a,o=e(this),l=o._point,c=p.read(arguments),u=s.peek(arguments),h=s.pick(u,!0);if("boolean"==typeof h)var d=l.add(c).divide(2),t=d.add(d.subtract(l).rotate(h?-90:90));else if(s.remain(arguments)<=2)t=c,c=p.read(arguments);else{var f=g.read(arguments);if(f.isZero())return this.lineTo(c);var m=s.read(arguments),h=!!s.read(arguments),v=!!s.read(arguments),d=l.add(c).divide(2),w=l.subtract(d).rotate(-m),y=w.x,x=w.y,E=Math.abs,C=E(f.width),k=E(f.height),S=C*C,P=k*k,T=y*y,M=x*x,N=Math.sqrt(T/S+M/P);if(N>1&&(C*=N,k*=N,S=C*C,P=k*k),N=(S*P-S*M-P*T)/(S*M+P*T),E(N)<1e-12&&(N=0),N<0)throw new Error("Cannot create an arc with the given arguments");n=new p(C*x/k,-k*y/C).multiply((v===h?-1:1)*Math.sqrt(N)).rotate(m).add(d),a=(new b).translate(n).rotate(m).scale(C,k),i=a._inverseTransform(l),r=i.getDirectedAngle(a._inverseTransform(c)),!h&&r>0?r-=360:h&&r<0&&(r+=360)}if(t){var L=new _(l.add(t).divide(2),t.subtract(l).rotate(90),!0),A=new _(t.add(c).divide(2),c.subtract(t).rotate(90),!0),O=new _(l,c),B=O.getSide(t);if(n=L.intersect(A,!0),!n){if(!B)return this.lineTo(c);throw new Error("Cannot create an arc with the given arguments")}i=l.subtract(n),r=i.getDirectedAngle(c.subtract(n));var z=O.getSide(n);0===z?r=B*Math.abs(r):B===z&&(r+=r<0?360:-360)}for(var R=Math.abs(r),D=R>=360?4:Math.ceil(R/90),j=r/D,F=j*Math.PI/360,q=4/3*Math.sin(F)/(1+Math.cos(F)),V=[],U=0;U<=D;U++){var w=c,W=null;if(U<D&&(W=i.rotate(90).multiply(q),a?(w=a._transformPoint(i),W=a._transformPoint(i.add(W)).subtract(w)):w=n.add(i)),0===U)o.setHandleOut(W);else{var G=i.rotate(-90).multiply(q);a&&(G=a._transformPoint(i.add(G)).subtract(w)),V.push(new I(w,G,W))}i=i.rotate(j)}this._add(V)},lineBy:function(){var t=p.read(arguments),n=e(this)._point;this.lineTo(n.add(t))},curveBy:function(){var t=p.read(arguments),n=p.read(arguments),r=s.read(arguments),i=e(this)._point;this.curveTo(i.add(t),i.add(n),r)},cubicCurveBy:function(){var t=p.read(arguments),n=p.read(arguments),r=p.read(arguments),i=e(this)._point;this.cubicCurveTo(i.add(t),i.add(n),i.add(r))},quadraticCurveBy:function(){var t=p.read(arguments),n=p.read(arguments),r=e(this)._point;this.quadraticCurveTo(r.add(t),r.add(n))},arcBy:function(){var t=e(this)._point,n=t.add(p.read(arguments)),r=s.pick(s.peek(arguments),!0);"boolean"==typeof r?this.arcTo(n,r):this.arcTo(n,t.add(p.read(arguments)))},closePath:function(e){this.setClosed(!0),e&&this.join()}}},{_getBounds:function(e,t){return z[e](this._segments,this._closed,this.getStyle(),t)},statics:{getBounds:function(e,t,n,r,i){function a(e){e._transformCoordinates(r,s,!1);for(var t=0;t<2;t++)A._addBounds(l[t],l[t+4],s[t+2],s[t],t,i?i[t]:0,c,u,h);var n=l;l=s,s=n}var o=e[0];if(!o)return new w;for(var s=new Array(6),l=o._transformCoordinates(r,new Array(6),!1),c=l.slice(0,2),u=c.slice(),h=new Array(2),d=1,f=e.length;d<f;d++)a(e[d]);return t&&a(o),new w(c[0],c[1],u[0]-c[0],u[1]-c[1])},getStrokeBounds:function(e,t,n,r){function i(e){h=h.include(r?r._transformPoint(e,e):e)}function a(e){h=h.unite(m.setCenter(r?r._transformPoint(e._point):e._point))}function o(e,t){var n=e._handleIn,r=e._handleOut;"round"===t||!n.isZero()&&!r.isZero()&&n.isCollinear(r)?a(e):z._addBevelJoin(e,t,c,p,i)}function s(e,t){"round"===t?a(e):z._addSquareCap(e,t,c,i)}if(!n.hasStroke())return z.getBounds(e,t,n,r);for(var l=e.length-(t?0:1),c=n.getStrokeWidth()/2,u=z._getPenPadding(c,r),h=z.getBounds(e,t,n,r,u),d=n.getStrokeJoin(),f=n.getStrokeCap(),p=c*n.getMiterLimit(),m=new w(new g(u).multiply(2)),v=1;v<l;v++)o(e[v],d);return t?o(e[0],d):l>0&&(s(e[0],f),s(e[e.length-1],f)),h},_getPenPadding:function(e,t){if(!t)return[e,e];var n=t.shiftless(),r=n.transform(new p(e,0)),i=n.transform(new p(0,e)),a=r.getAngleInRadians(),o=r.getLength(),s=i.getLength(),l=Math.sin(a),c=Math.cos(a),u=Math.tan(a),h=-Math.atan(s*u/o),d=Math.atan(s/(u*o));return[Math.abs(o*Math.cos(h)*c-s*Math.sin(h)*l),Math.abs(s*Math.sin(d)*c+o*Math.cos(d)*l)]},_addBevelJoin:function(e,t,n,r,i,a){var o=e.getCurve(),s=o.getPrevious(),l=o.getPointAt(0,!0),c=s.getNormalAt(1,!0),u=o.getNormalAt(0,!0),h=c.getDirectedAngle(u)<0?-n:n;if(c.setLength(h),u.setLength(h),a&&(i(l),i(l.add(c))),"miter"===t){var d=new _(l.add(c),new p(-c.y,c.x),!0).intersect(new _(l.add(u),new p(-u.y,u.x),!0),!0);if(d&&l.getDistance(d)<=r&&(i(d),!a))return}a||i(l.add(c)),i(l.add(u))},_addSquareCap:function(e,t,n,r,i){var a=e._point,o=e.getLocation(),s=o.getNormal().multiply(n);i&&(r(a.subtract(s)),r(a.add(s))),"square"===t&&(a=a.add(s.rotate(0===o.getParameter()?-90:90))),r(a.add(s)),r(a.subtract(s))},getHandleBounds:function(e,t,n,r,i,a){for(var o=new Array(6),s=1/0,l=-s,c=s,u=l,h=0,d=e.length;h<d;h++){var f=e[h];f._transformCoordinates(r,o,!1);for(var p=0;p<6;p+=2){var m=0===p?a:i,g=m?m[0]:0,v=m?m[1]:0,y=o[p],b=o[p+1],_=y-g,x=y+g,E=b-v,C=b+v;_<s&&(s=_),x>l&&(l=x),E<c&&(c=E),C>u&&(u=C)}}return new w(s,c,l-s,u-c)},getRoughBounds:function(e,t,n,r){var i=n.hasStroke()?n.getStrokeWidth()/2:0,a=i;return i>0&&("miter"===n.getStrokeJoin()&&(a=i*n.getMiterLimit()),"square"===n.getStrokeCap()&&(a=Math.max(a,i*Math.sqrt(2)))),z.getHandleBounds(e,t,n,r,z._getPenPadding(i,r),z._getPenPadding(a,r))}}});z.inject({statics:new function(){function e(e,t,n){var r=s.getNamed(n),i=new z(r&&r.insert===!1&&C.NO_INSERT);return i._add(e),i._closed=t,i.set(r)}function t(t,n,i){for(var a=new Array(4),o=0;o<4;o++){var s=r[o];a[o]=new I(s._point.multiply(n).add(t),s._handleIn.multiply(n),s._handleOut.multiply(n))}return e(a,!0,i)}var n=.5522847498307936,r=[new I([-1,0],[0,n],[0,-n]),new I([0,-1],[-n,0],[n,0]),new I([1,0],[0,-n],[0,n]),new I([0,1],[n,0],[-n,0])];return{Line:function(){return e([new I(p.readNamed(arguments,"from")),new I(p.readNamed(arguments,"to"))],!1,arguments)},Circle:function(){var e=p.readNamed(arguments,"center"),n=s.readNamed(arguments,"radius");return t(e,new g(n),arguments)},Rectangle:function(){var t,r=w.readNamed(arguments,"rectangle"),i=g.readNamed(arguments,"radius",0,{readNull:!0}),a=r.getBottomLeft(!0),o=r.getTopLeft(!0),s=r.getTopRight(!0),l=r.getBottomRight(!0);if(!i||i.isZero())t=[new I(a),new I(o),new I(s),new I(l)];else{i=g.min(i,r.getSize(!0).divide(2));var c=i.width,u=i.height,h=c*n,d=u*n;t=[new I(a.add(c,0),null,[-h,0]),new I(a.subtract(0,u),[0,d]),new I(o.add(0,u),null,[0,-d]),new I(o.add(c,0),[-h,0],null),new I(s.subtract(c,0),null,[h,0]),new I(s.add(0,u),[0,-d],null),new I(l.subtract(0,u),null,[0,d]),new I(l.subtract(c,0),[h,0])]}return e(t,!0,arguments)},RoundRectangle:"#Rectangle",Ellipse:function(){var e=P._readEllipse(arguments);return t(e.center,e.radius,arguments)},Oval:"#Ellipse",Arc:function(){var e=p.readNamed(arguments,"from"),t=p.readNamed(arguments,"through"),n=p.readNamed(arguments,"to"),r=s.getNamed(arguments),i=new z(r&&r.insert===!1&&C.NO_INSERT);return i.moveTo(e),i.arcTo(t,n),i.set(r)},RegularPolygon:function(){for(var t=p.readNamed(arguments,"center"),n=s.readNamed(arguments,"sides"),r=s.readNamed(arguments,"radius"),i=360/n,a=!(n%3),o=new p(0,a?-r:r),l=a?-1:.5,c=new Array(n),u=0;u<n;u++)c[u]=new I(t.add(o.rotate((u+l)*i)));return e(c,!0,arguments)},Star:function(){for(var t=p.readNamed(arguments,"center"),n=2*s.readNamed(arguments,"points"),r=s.readNamed(arguments,"radius1"),i=s.readNamed(arguments,"radius2"),a=360/n,o=new p(0,-1),l=new Array(n),c=0;c<n;c++)l[c]=new I(t.add(o.rotate(a*c).multiply(c%2?i:r)));return e(l,!0,arguments)}}}});var R=B.extend({_class:"CompoundPath",_serializeFields:{children:[]},initialize:function(e){this._children=[],this._namedChildren={},this._initialize(e)||("string"==typeof e?this.setPathData(e):this.addChildren(Array.isArray(e)?e:arguments))},insertChildren:function e(t,n,r){for(var i=n.length-1;i>=0;i--){var a=n[i];a instanceof R&&(n.splice.apply(n,[i,1].concat(a.removeChildren())),a.remove())}n=e.base.call(this,t,n,r,z);for(var i=0,s=!r&&n&&n.length;i<s;i++){var a=n[i];a._clockwise===o&&a.setClockwise(0===a._index)}return n},reverse:function(){for(var e=this._children,t=0,n=e.length;t<n;t++)e[t].reverse()},smooth:function(){for(var e=0,t=this._children.length;e<t;e++)this._children[e].smooth()},reduce:function e(){for(var t=this._children,n=t.length-1;n>=0;n--){var r=t[n].reduce();r.isEmpty()&&t.splice(n,1)}if(0===t.length){var r=new z(C.NO_INSERT);return r.insertAbove(this),r.setStyle(this._style),this.remove(),r}return e.base.call(this)},isClockwise:function(){var e=this.getFirstChild();return e&&e.isClockwise()},setClockwise:function(e){this.isClockwise()!==!!e&&this.reverse()},getFirstSegment:function(){var e=this.getFirstChild();return e&&e.getFirstSegment()},getLastSegment:function(){var e=this.getLastChild();return e&&e.getLastSegment()},getCurves:function(){for(var e=this._children,t=[],n=0,r=e.length;n<r;n++)t.push.apply(t,e[n].getCurves());return t},getFirstCurve:function(){var e=this.getFirstChild();return e&&e.getFirstCurve()},getLastCurve:function(){var e=this.getLastChild();return e&&e.getFirstCurve()},getArea:function(){for(var e=this._children,t=0,n=0,r=e.length;n<r;n++)t+=e[n].getArea();return t}},{beans:!0,getPathData:function(e,t){for(var n=this._children,r=[],i=0,a=n.length;i<a;i++){var o=n[i],s=o._matrix;r.push(o.getPathData(e&&!s.isIdentity()?e.chain(s):e,t))}return r.join(" ")}},{_getChildHitTestOptions:function(e){return e.class===z||"path"===e.type?e:new s(e,{fill:!1})},_draw:function(e,t,n){var r=this._children;if(0!==r.length){if(this._currentPath)e.currentPath=this._currentPath;else{t=t.extend({dontStart:!0,dontFinish:!0}),e.beginPath();for(var i=0,a=r.length;i<a;i++)r[i].draw(e,t,n);this._currentPath=e.currentPath}if(!t.clip){this._setStyles(e);var o=this._style;o.hasFill()&&(e.fill(o.getWindingRule()),e.shadowColor="rgba(0,0,0,0)"),o.hasStroke()&&e.stroke()}}},_drawSelected:function(e,t,n){for(var r=this._children,i=0,a=r.length;i<a;i++){var o=r[i],s=o._matrix;n[o._id]||o._drawSelected(e,s.isIdentity()?t:t.chain(s))}}},new function(){function e(e,t){var n=e._children;if(t&&0===n.length)throw new Error("Use a moveTo() command first");return n[n.length-1]}var t={moveTo:function(){var t=e(this),n=t&&t.isEmpty()?t:new z(C.NO_INSERT);n!==t&&this.addChild(n),n.moveTo.apply(n,arguments)},moveBy:function(){var t=e(this,!0),n=t&&t.getLastSegment(),r=p.read(arguments);this.moveTo(n?r.add(n._point):r)},closePath:function(t){e(this,!0).closePath(t)}};return s.each(["lineTo","cubicCurveTo","quadraticCurveTo","curveTo","arcTo","lineBy","cubicCurveBy","quadraticCurveBy","curveBy","arcBy"],function(n){t[n]=function(){var t=e(this,!0);t[n].apply(t,arguments)}}),t});B.inject(new function(){function e(e,t){var n=e.clone(!1).reduce().transform(null,!0,!0);return t?n.resolveCrossings().reorient():n}function t(e,t,n,r,i){var a=new e(C.NO_INSERT);return a.addChildren(t,!0),i&&(a=a.reduce()),a.insertAbove(r&&n.isSibling(r)&&n.getIndex()<r.getIndex()?r:n),a.setStyle(n._style),a}function n(n,i,o){function c(e){for(var t=0,n=e.length;t<n;t++){var r=e[t];f.push.apply(f,r._segments),p.push.apply(p,r._getMonoCurves())}}if(!n._children&&!n._closed)return r(n,i,o);var u=e(n,!0),h=i&&n!==i&&e(i,!0);h&&/^(subtract|exclude)$/.test(o)^h.isClockwise()!==u.isClockwise()&&h.reverse();var d=O.expand(u.getIntersections(h,function(e){return h&&e.isOverlap()||e.isCrossing()}));a(d);var f=[],p=[];c(u._children||[u]),h&&c(h._children||[h]);for(var m=0,g=d.length;m<g;m++)s(d[m]._segment,u,h,p,o);for(var m=0,g=f.length;m<g;m++){var v=f[m];null==v._winding&&s(v,u,h,p,o)}return t(R,l(f,o),n,i,!0)}function r(n,r,i){function a(e){if(s.contains(e.getPointAt(e.getLength()/2))^c)return u.unshift(e),!0}if(!r||!r._children&&!r._closed||!/^(subtract|intersect)$/.test(i))return null;for(var o=e(n,!1),s=e(r,!1),l=o.getIntersections(s,function(e){return e.isOverlap()||e.isCrossing()}),c="subtract"===i,u=[],h=l.length-1;h>=0;h--){var d=l[h].split();d&&(a(d)&&d.getFirstSegment().setHandleIn(0,0),o.getLastSegment().setHandleOut(0,0))}return a(o),t(k,u,n,r)}function i(e,t){for(var n=e;n;){if(n===t)return;n=n._prev}for(;e._next&&e._next!==t;)e=e._next;if(!e._next){for(;t._prev;)t=t._prev;e._next=t,t._prev=e}}function a(e){for(var t,n,r=4e-7,a=1-r,o=!1,s=[],l=e.length-1;l>=0;l--){var c=e[l],u=c._curve,h=c._parameter,d=h;u!==t?o=!u.hasHandles():n>0&&(h/=n);var f;h<r?f=u._segment1:h>a?f=u._segment2:(f=u.divide(h,!0,!0)._segment1,o&&s.push(f)),c._setSegment(f);var p=f._intersection,m=c._intersection;if(p){i(p,m);for(var g=p;g;)i(g._intersection,p),g=g._next}else f._intersection=m;t=u,n=d}for(var l=0,v=s.length;l<v;l++)s[l].clearHandles()}function o(e,t,n,r){var i=2e-7,a=4e-7,s=1-a,l=e.x,c=e.y,u=0,h=0,f=[],m=Math.abs;if(n){for(var g=-(1/0),v=1/0,w=c-i,y=c+i,b=0,_=t.length;b<_;b++){var x=t[b].values;if(A.solveCubic(x,0,l,f,0,1)>0)for(var E=f.length-1;E>=0;E--){var C=A.getPoint(x,f[E]).y;C<w&&C>g?g=C:C>y&&C<v&&(v=C)}}g=(g+c)/2,v=(v+c)/2,g>-(1/0)&&(u=o(new p(l,g),t,!1,r)),v<1/0&&(h=o(new p(l,v),t,!1,r))}else for(var k,S,P=l-i,T=l+i,M=!1,b=0,_=t.length;b<_;b++){var N=t[b],x=N.values,I=N.winding;if(I&&(1===I&&c>=x[1]&&c<=x[7]||c>=x[7]&&c<=x[1])&&1===A.solveCubic(x,1,c,f,0,1)){var L=f[0];if(!(L>s&&M&&N.next!==t[b+1]||L<a&&S>s&&N.previous===k)){var O=A.getPoint(x,L).x,B=A.getTangent(x,L).y,z=!1;d.isZero(B)&&!A.isStraight(x)||L<a&&B*A.getTangent(N.previous.values,1).y<0||L>s&&B*A.getTangent(N.next.values,0).y<0?r&&O>=P&&O<=T&&(++u,++h,z=!0):O<=P?(u+=I,z=!0):O>=T&&(h+=I,z=!0),N.previous!==t[b-1]&&(M=L<a&&z)}k=N,S=L}}return Math.max(m(u),m(h))}function s(e,t,n,r,i){var a=2e-7,s=[],l=e,c=0,u=0;do{var h=e.getCurve(),d=h.getLength();s.push({segment:e,curve:h,length:d}),c+=d,e=e.getNext()}while(e&&!e._intersection&&e!==l);for(var f=0;f<3;f++)for(var d=c*(f+1)/4,p=0,m=s.length;p<m;p++){var g=s[p],v=g.length;if(d<=v){(d<a||v-d<a)&&(d=v/2);var h=g.curve,w=h._path,y=w._parent,b=h.getPointAt(d),_=h.isHorizontal();y instanceof R&&(w=y),u+="subtract"===i&&n&&(w===t&&n._getWinding(b,_)||w===n&&!t._getWinding(b,_))?0:o(b,r,_);break}d-=v}for(var x=Math.round(u/3),E=s.length-1;E>=0;E--)s[E].segment._winding=x}function l(e,t){function n(e,t){if(e._visited)return!1;if(!u)return!0;var n=e._winding,r=e._intersection;return r&&t&&h&&r.isOverlap()&&(n=h[n]||n),u(n)}function r(e){return e===o||e===s}function i(e,t){if(!e._next)return e;for(;e;){var i=e._segment,a=i.getNext(),o=a._intersection;if(r(a)||!i._visited&&!a._visited&&(!u||(!t||n(i))&&(!(t&&o&&o.isOverlap())&&n(a)||!t&&o&&n(o._segment))))return e;e=e._next}return null}function a(e,t){for(;e;){var n=e._segment;if(r(n))return n;e=e[t?"_next":"_prev"]}}for(var o,s,l=[],u=c[t],h={unite:{1:2},intersect:{2:1}}[t],f=0,p=e.length;f<p;f++){var m=e[f],g=null,v=!1;if(n(m,!0)){for(o=s=null;!v;){var w=m._intersection,y=g&&m._handleIn;w=w&&(i(w,!0)||i(w,!1))||w;var b=w&&w._segment;if(b&&n(b)&&(m=b),m._visited){if(v=r(m),!v&&w){var _=a(w,!0)||a(w,!1);_&&(m=_,v=!0)}break}g||(g=new z(C.NO_INSERT),o=m,s=b),g.add(new I(m._point,y,m._handleOut)),m._visited=!0,m=m.getNext(),v=r(m)}v?(g.firstSegment.setHandleIn(m._handleIn),g.setClosed(!0)):g&&(console.error("Boolean operation resulted in open path","segments =",g._segments.length,"length =",g.getLength()),g=null),g&&(g._segments.length>8||!d.isZero(g.getArea()))&&(l.push(g),g=null)}}return l}var c={unite:function(e){return 1===e||0===e},intersect:function(e){return 2===e},subtract:function(e){return 1===e},exclude:function(e){return 1===e}};return{_getWinding:function(e,t,n){return o(e,this._getMonoCurves(),t,n)},unite:function(e){return n(this,e,"unite")},intersect:function(e){return n(this,e,"intersect")},subtract:function(e){return n(this,e,"subtract")},exclude:function(e){return n(this,e,"exclude")},divide:function(e){return t(k,[this.subtract(e),this.intersect(e)],this,e,!0)},resolveCrossings:function(){var e=this.getCrossings();if(!e.length)return this;a(O.expand(e));for(var n=this._children||[this],r=[],i=0,o=n.length;i<o;i++)r.push.apply(r,n[i]._segments);return t(R,l(r),this,null,!1)}}}),z.inject({_getMonoCurves:function(){function e(e){var t=e[1],i=e[7],a={values:e,winding:t===i?0:t>i?-1:1,previous:n,next:null};n&&(n.next=a),r.push(a),n=a}function t(t){if(0!==A.getLength(t)){var n=t[1],r=t[3],i=t[5],a=t[7];if(A.isStraight(t))e(t);else{var o=3*(r-i)-n+a,s=2*(n+i)-4*r,l=r-n,c=4e-7,u=1-c,h=[],f=d.solveQuadratic(o,s,l,h,c,u);if(0===f)e(t);else{h.sort();var p=h[0],m=A.subdivide(t,p);e(m[0]),f>1&&(p=(h[1]-p)/(1-p),m=A.subdivide(m[1],p),e(m[0])),e(m[1])}}}}var n,r=this._monoCurves;if(!r){r=this._monoCurves=[];for(var i=this.getCurves(),a=this._segments,o=0,s=i.length;o<s;o++)t(i[o].getValues());if(!this._closed&&a.length>1){var l=a[a.length-1]._point,c=a[0]._point,u=l._x,h=l._y,f=c._x,p=c._y;t([u,h,u,h,f,p,f,p])}if(r.length>0){var m=r[0],g=r[r.length-1];m.previous=g, +g.next=m}}return r},getInteriorPoint:function(){var e=this.getBounds(),t=e.getCenter(!0);if(!this.contains(t)){for(var n=this._getMonoCurves(),r=[],i=t.y,a=[],o=0,s=n.length;o<s;o++){var l=n[o].values;if((1===n[o].winding&&i>=l[1]&&i<=l[7]||i>=l[7]&&i<=l[1])&&A.solveCubic(l,1,i,r,0,1)>0)for(var c=r.length-1;c>=0;c--)a.push(A.getPoint(l,r[c]).x);if(a.length>1)break}t.x=(a[0]+a[1])/2}return t},reorient:function(){return this.setClockwise(!0),this}}),R.inject({_getMonoCurves:function(){for(var e=this._children,t=[],n=0,r=e.length;n<r;n++)t.push.apply(t,e[n]._getMonoCurves());return t},reorient:function(){var e=this.removeChildren().sort(function(e,t){return t.getBounds().getArea()-e.getBounds().getArea()});if(e.length>0){this.addChildren(e);for(var t=e[0].isClockwise(),n=1,r=e.length;n<r;n++){for(var i=e[n].getInteriorPoint(),a=0,o=n-1;o>=0;o--)e[o].contains(i)&&a++;e[n].setClockwise(a%2===0&&t)}}return this}});var D=s.extend({_class:"PathIterator",initialize:function(e,t,n,r){function i(e,t){var n=A.getValues(e,t,r);s.push(n),a(n,e._index,0,1)}function a(e,t,r,i){if(i-r>u&&!A.isFlatEnough(e,n||.25)){var o=A.subdivide(e,.5),s=(r+i)/2;a(o[0],t,r,s),a(o[1],t,s,i)}else{var h=e[6]-e[0],d=e[7]-e[1],f=Math.sqrt(h*h+d*d);f>1e-6&&(c+=f,l.push({offset:c,value:i,index:t}))}}for(var o,s=[],l=[],c=0,u=1/(t||32),h=e._segments,d=h[0],f=1,p=h.length;f<p;f++)o=h[f],i(d,o),d=o;e._closed&&i(o,h[0]),this.curves=s,this.parts=l,this.length=c,this.index=0},getParameterAt:function(e){for(var t,n=this.index;t=n,!(0==n||this.parts[--n].offset<e););for(var r=this.parts.length;t<r;t++){var i=this.parts[t];if(i.offset>=e){this.index=t;var a=this.parts[t-1],o=a&&a.index==i.index?a.value:0,s=a?a.offset:0;return{value:o+(i.value-o)*(e-s)/(i.offset-s),index:i.index}}}var i=this.parts[this.parts.length-1];return{value:1,index:i.index}},drawPart:function(e,t,n){t=this.getParameterAt(t),n=this.getParameterAt(n);for(var r=t.index;r<=n.index;r++){var i=A.getPart(this.curves[r],r==t.index?t.value:0,r==n.index?n.value:1);r==t.index&&e.moveTo(i[0],i[1]),e.bezierCurveTo.apply(e,i.slice(2))}}},s.each(A.evaluateMethods,function(e){this[e+"At"]=function(t,n){var r=this.getParameterAt(t);return A[e](this.curves[r.index],r.value,n)}},{})),j=s.extend({initialize:function(e,t){for(var n,r=this.points=[],i=e._segments,a=0,o=i.length;a<o;a++){var s=i[a].point.clone();n&&n.equals(s)||(r.push(s),n=s)}e._closed&&(this.closed=!0,r.unshift(r[r.length-1]),r.push(r[1])),this.error=t},fit:function(){var e=this.points,t=e.length,n=this.segments=t>0?[new I(e[0])]:[];return t>1&&this.fitCubic(0,t-1,e[1].subtract(e[0]).normalize(),e[t-2].subtract(e[t-1]).normalize()),this.closed&&(n.shift(),n.pop()),n},fitCubic:function(e,t,n,r){if(t-e==1){var i=this.points[e],a=this.points[t],o=i.getDistance(a)/3;return void this.addCurve([i,i.add(n.normalize(o)),a.add(r.normalize(o)),a])}for(var s,l=this.chordLengthParameterize(e,t),c=Math.max(this.error,this.error*this.error),u=!0,h=0;h<=4;h++){var d=this.generateBezier(e,t,l,n,r),f=this.findMaxError(e,t,d,l);if(f.error<this.error&&u)return void this.addCurve(d);if(s=f.index,f.error>=c)break;u=this.reparameterize(e,t,l,d),c=f.error}var p=this.points[s-1].subtract(this.points[s]),m=this.points[s].subtract(this.points[s+1]),g=p.add(m).divide(2).normalize();this.fitCubic(e,s,n,g),this.fitCubic(s,t,g.negate(),r)},addCurve:function(e){var t=this.segments[this.segments.length-1];t.setHandleOut(e[1].subtract(e[0])),this.segments.push(new I(e[3],e[2].subtract(e[3])))},generateBezier:function(e,t,n,r,i){for(var a=1e-12,o=this.points[e],s=this.points[t],l=[[0,0],[0,0]],c=[0,0],u=0,h=t-e+1;u<h;u++){var d=n[u],f=1-d,p=3*d*f,m=f*f*f,g=p*f,v=p*d,w=d*d*d,y=r.normalize(g),b=i.normalize(v),_=this.points[e+u].subtract(o.multiply(m+g)).subtract(s.multiply(v+w));l[0][0]+=y.dot(y),l[0][1]+=y.dot(b),l[1][0]=l[0][1],l[1][1]+=b.dot(b),c[0]+=y.dot(_),c[1]+=b.dot(_)}var x,E,C=l[0][0]*l[1][1]-l[1][0]*l[0][1];if(Math.abs(C)>a){var k=l[0][0]*c[1]-l[1][0]*c[0],S=c[0]*l[1][1]-c[1]*l[0][1];x=S/C,E=k/C}else{var P=l[0][0]+l[0][1],T=l[1][0]+l[1][1];x=E=Math.abs(P)>a?c[0]/P:Math.abs(T)>a?c[1]/T:0}var M,N,I=s.getDistance(o),L=a*I;if(x<L||E<L)x=E=I/3;else{var A=s.subtract(o);M=r.normalize(x),N=i.normalize(E),M.dot(A)-N.dot(A)>I*I&&(x=E=I/3,M=N=null)}return[o,o.add(M||r.normalize(x)),s.add(N||i.normalize(E)),s]},reparameterize:function(e,t,n,r){for(var i=e;i<=t;i++)n[i-e]=this.findRoot(r,this.points[i],n[i-e]);for(var i=1,a=n.length;i<a;i++)if(n[i]<=n[i-1])return!1;return!0},findRoot:function(e,t,n){for(var r=[],i=[],a=0;a<=2;a++)r[a]=e[a+1].subtract(e[a]).multiply(3);for(var a=0;a<=1;a++)i[a]=r[a+1].subtract(r[a]).multiply(2);var o=this.evaluate(3,e,n),s=this.evaluate(2,r,n),l=this.evaluate(1,i,n),c=o.subtract(t),u=s.dot(s)+c.dot(l);return Math.abs(u)<1e-6?n:n-c.dot(s)/u},evaluate:function(e,t,n){for(var r=t.slice(),i=1;i<=e;i++)for(var a=0;a<=e-i;a++)r[a]=r[a].multiply(1-n).add(r[a+1].multiply(n));return r[0]},chordLengthParameterize:function(e,t){for(var n=[0],r=e+1;r<=t;r++)n[r-e]=n[r-e-1]+this.points[r].getDistance(this.points[r-1]);for(var r=1,i=t-e;r<=i;r++)n[r]/=n[i];return n},findMaxError:function(e,t,n,r){for(var i=Math.floor((t-e+1)/2),a=0,o=e+1;o<t;o++){var s=this.evaluate(3,n,r[o-e]),l=s.subtract(this.points[o]),c=l.x*l.x+l.y*l.y;c>=a&&(a=c,i=o)}return{error:a,index:i}}}),F=C.extend({_class:"TextItem",_boundsSelected:!0,_applyMatrix:!1,_canApplyMatrix:!1,_serializeFields:{content:null},_boundsGetter:"getBounds",initialize:function(e){this._content="",this._lines=[];var t=e&&s.isPlainObject(e)&&e.x===o&&e.y===o;this._initialize(t&&e,!t&&p.read(arguments))},_equals:function(e){return this._content===e._content},_clone:function e(t,n,r){return t.setContent(this._content),e.base.call(this,t,n,r)},getContent:function(){return this._content},setContent:function(e){this._content=""+e,this._lines=this._content.split(/\r\n|\n|\r/gm),this._changed(265)},isEmpty:function(){return!this._content},getCharacterStyle:"#getStyle",setCharacterStyle:"#setStyle",getParagraphStyle:"#getStyle",setParagraphStyle:"#setStyle"}),q=F.extend({_class:"PointText",initialize:function(){F.apply(this,arguments)},clone:function(e){return this._clone(new q(C.NO_INSERT),e)},getPoint:function(){var e=this._matrix.getTranslation();return new m(e.x,e.y,this,"setPoint")},setPoint:function(){var e=p.read(arguments);this.translate(e.subtract(this._matrix.getTranslation()))},_draw:function(e){if(this._content){this._setStyles(e);var t=this._style,n=this._lines,r=t.getLeading(),i=e.shadowColor;e.font=t.getFontStyle(),e.textAlign=t.getJustification();for(var a=0,o=n.length;a<o;a++){e.shadowColor=i;var s=n[a];t.hasFill()&&(e.fillText(s,0,0),e.shadowColor="rgba(0,0,0,0)"),t.hasStroke()&&e.strokeText(s,0,0),e.translate(0,r)}}},_getBounds:function(e,t){var n=this._style,r=this._lines,i=r.length,a=n.getJustification(),o=n.getLeading(),s=this.getView().getTextWidth(n.getFontStyle(),r),l=0;"left"!==a&&(l-=s/("center"===a?2:1));var c=new w(l,i?-.75*o:0,s,i*o);return t?t._transformBounds(c,c):c}}),V=s.extend(new function(){function e(e){var n,r=e.match(/^#(\w{1,2})(\w{1,2})(\w{1,2})$/);if(r){n=[0,0,0];for(var a=0;a<3;a++){var o=r[a+1];n[a]=parseInt(1==o.length?o+o:o,16)/255}}else if(r=e.match(/^rgba?\((.*)\)$/)){n=r[1].split(",");for(var a=0,s=n.length;a<s;a++){var o=+n[a];n[a]=a<3?o/255:o}}else{var l=i[e];if(!l){t||(t=ne.getContext(1,1),t.globalCompositeOperation="copy"),t.fillStyle="rgba(0,0,0,0)",t.fillStyle=e,t.fillRect(0,0,1,1);var c=t.getImageData(0,0,1,1).data;l=i[e]=[c[0]/255,c[1]/255,c[2]/255]}n=l.slice()}return n}var t,n={gray:["gray"],rgb:["red","green","blue"],hsb:["hue","saturation","brightness"],hsl:["hue","saturation","lightness"],gradient:["gradient","origin","destination","highlight"]},r={},i={},a=[[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]],o={"rgb-hsb":function(e,t,n){var r=Math.max(e,t,n),i=Math.min(e,t,n),a=r-i,o=0===a?0:60*(r==e?(t-n)/a+(t<n?6:0):r==t?(n-e)/a+2:(e-t)/a+4);return[o,0===r?0:a/r,r]},"hsb-rgb":function(e,t,n){e=(e/60%6+6)%6;var r=Math.floor(e),i=e-r,r=a[r],o=[n,n*(1-t),n*(1-t*i),n*(1-t*(1-i))];return[o[r[0]],o[r[1]],o[r[2]]]},"rgb-hsl":function(e,t,n){var r=Math.max(e,t,n),i=Math.min(e,t,n),a=r-i,o=0===a,s=o?0:60*(r==e?(t-n)/a+(t<n?6:0):r==t?(n-e)/a+2:(e-t)/a+4),l=(r+i)/2,c=o?0:l<.5?a/(r+i):a/(2-r-i);return[s,c,l]},"hsl-rgb":function(e,t,n){if(e=(e/360%1+1)%1,0===t)return[n,n,n];for(var r=[e+1/3,e,e-1/3],i=n<.5?n*(1+t):n+t-n*t,a=2*n-i,o=[],s=0;s<3;s++){var l=r[s];l<0&&(l+=1),l>1&&(l-=1),o[s]=6*l<1?a+6*(i-a)*l:2*l<1?i:3*l<2?a+(i-a)*(2/3-l)*6:a}return o},"rgb-gray":function(e,t,n){return[.2989*e+.587*t+.114*n]},"gray-rgb":function(e){return[e,e,e]},"gray-hsb":function(e){return[0,0,e]},"gray-hsl":function(e){return[0,0,e]},"gradient-rgb":function(){return[]},"rgb-gradient":function(){return[]}};return s.each(n,function(e,t){r[t]=[],s.each(e,function(e,i){var a=s.capitalize(e),o=/^(hue|saturation)$/.test(e),l=r[t][i]="gradient"===e?function(e){var t=this._components[0];return e=U.read(Array.isArray(e)?e:arguments,0,{readNull:!0}),t!==e&&(t&&t._removeOwner(this),e&&e._addOwner(this)),e}:"gradient"===t?function(){return p.read(arguments,0,{readNull:"highlight"===e,clone:!0})}:function(e){return null==e||isNaN(e)?0:e};this["get"+a]=function(){return this._type===t||o&&/^hs[bl]$/.test(this._type)?this._components[i]:this._convert(t)[i]},this["set"+a]=function(e){this._type===t||o&&/^hs[bl]$/.test(this._type)||(this._components=this._convert(t),this._properties=n[t],this._type=t),this._components[i]=l.call(this,e),this._changed()}},this)},{_class:"Color",_readIndex:!0,initialize:function t(i){var a,o,s,l,c=Array.prototype.slice,u=arguments,h=0;Array.isArray(i)&&(u=i,i=u[0]);var d=null!=i&&typeof i;if("string"===d&&i in n&&(a=i,i=u[1],Array.isArray(i)?(o=i,s=u[2]):(this.__read&&(h=1),u=c.call(u,1),d=typeof i)),!o){if(l="number"===d?u:"object"===d&&null!=i.length?i:null){a||(a=l.length>=3?"rgb":"gray");var p=n[a].length;s=l[p],this.__read&&(h+=l===arguments?p+(null!=s?1:0):1),l.length>p&&(l=c.call(l,0,p))}else if("string"===d)a="rgb",o=e(i),4===o.length&&(s=o[3],o.length--);else if("object"===d)if(i.constructor===t){if(a=i._type,o=i._components.slice(),s=i._alpha,"gradient"===a)for(var m=1,g=o.length;m<g;m++){var v=o[m];v&&(o[m]=v.clone())}}else if(i.constructor===U)a="gradient",l=u;else{a="hue"in i?"lightness"in i?"hsl":"hsb":"gradient"in i||"stops"in i||"radial"in i?"gradient":"gray"in i?"gray":"rgb";var w=n[a],y=r[a];this._components=o=[];for(var m=0,g=w.length;m<g;m++){var b=i[w[m]];null==b&&0===m&&"gradient"===a&&"stops"in i&&(b={stops:i.stops,radial:i.radial}),b=y[m].call(this,b),null!=b&&(o[m]=b)}s=i.alpha}this.__read&&a&&(h=1)}if(this._type=a||"rgb",this._id=f.get(t),!o){this._components=o=[];for(var y=r[this._type],m=0,g=y.length;m<g;m++){var b=y[m].call(this,l&&l[m]);null!=b&&(o[m]=b)}}this._components=o,this._properties=n[this._type],this._alpha=s,this.__read&&(this.__read=h)},_serialize:function(e,t){var n=this.getComponents();return s.serialize(/^(gray|rgb)$/.test(this._type)?n:[this._type].concat(n),e,!0,t)},_changed:function(){this._canvasStyle=null,this._owner&&this._owner._changed(65)},_convert:function(e){var t;return this._type===e?this._components.slice():(t=o[this._type+"-"+e])?t.apply(this,this._components):o["rgb-"+e].apply(this,o[this._type+"-rgb"].apply(this,this._components))},convert:function(e){return new V(e,this._convert(e),this._alpha)},getType:function(){return this._type},setType:function(e){this._components=this._convert(e),this._properties=n[e],this._type=e},getComponents:function(){var e=this._components.slice();return null!=this._alpha&&e.push(this._alpha),e},getAlpha:function(){return null!=this._alpha?this._alpha:1},setAlpha:function(e){this._alpha=null==e?null:Math.min(Math.max(e,0),1),this._changed()},hasAlpha:function(){return null!=this._alpha},equals:function(e){var t=s.isPlainValue(e,!0)?V.read(arguments):e;return t===this||t&&this._class===t._class&&this._type===t._type&&this._alpha===t._alpha&&s.equals(this._components,t._components)||!1},toString:function(){for(var e=this._properties,t=[],n="gradient"===this._type,r=h.instance,i=0,a=e.length;i<a;i++){var o=this._components[i];null!=o&&t.push(e[i]+": "+(n?o:r.number(o)))}return null!=this._alpha&&t.push("alpha: "+r.number(this._alpha)),"{ "+t.join(", ")+" }"},toCSS:function(e){function t(e){return Math.round(255*(e<0?0:e>1?1:e))}var n=this._convert("rgb"),r=e||null==this._alpha?1:this._alpha;return n=[t(n[0]),t(n[1]),t(n[2])],r<1&&n.push(r<0?0:r),e?"#"+((1<<24)+(n[0]<<16)+(n[1]<<8)+n[2]).toString(16).slice(1):(4==n.length?"rgba(":"rgb(")+n.join(",")+")"},toCanvasStyle:function(e){if(this._canvasStyle)return this._canvasStyle;if("gradient"!==this._type)return this._canvasStyle=this.toCSS();var t,n=this._components,r=n[0],i=r._stops,a=n[1],o=n[2];if(r._radial){var s=o.getDistance(a),l=n[3];if(l){var c=l.subtract(a);c.getLength()>s&&(l=a.add(c.normalize(s-.1)))}var u=l||a;t=e.createRadialGradient(u.x,u.y,0,a.x,a.y,s)}else t=e.createLinearGradient(a.x,a.y,o.x,o.y);for(var h=0,d=i.length;h<d;h++){var f=i[h];t.addColorStop(f._rampPoint,f._color.toCanvasStyle())}return this._canvasStyle=t},transform:function(e){if("gradient"===this._type){for(var t=this._components,n=1,r=t.length;n<r;n++){var i=t[n];e._transformPoint(i,i,!0)}this._changed()}},statics:{_types:n,random:function(){var e=Math.random;return new V(e(),e(),e())}}})},new function(){var e={add:function(e,t){return e+t},subtract:function(e,t){return e-t},multiply:function(e,t){return e*t},divide:function(e,t){return e/t}};return s.each(e,function(e,t){this[t]=function(t){t=V.read(arguments);for(var n=this._type,r=this._components,i=t._convert(n),a=0,o=r.length;a<o;a++)i[a]=e(r[a],i[a]);return new V(n,i,null!=this._alpha?e(this._alpha,t.getAlpha()):null)}},{})}),U=s.extend({_class:"Gradient",initialize:function(e,t){this._id=f.get(),e&&this._set(e)&&(e=t=null),this._stops||this.setStops(e||["white","black"]),null==this._radial&&this.setRadial("string"==typeof t&&"radial"===t||t||!1)},_serialize:function(e,t){return t.add(this,function(){return s.serialize([this._stops,this._radial],e,!0,t)})},_changed:function(){for(var e=0,t=this._owners&&this._owners.length;e<t;e++)this._owners[e]._changed()},_addOwner:function(e){this._owners||(this._owners=[]),this._owners.push(e)},_removeOwner:function(e){var t=this._owners?this._owners.indexOf(e):-1;t!=-1&&(this._owners.splice(t,1),0===this._owners.length&&(this._owners=o))},clone:function(){for(var e=[],t=0,n=this._stops.length;t<n;t++)e[t]=this._stops[t].clone();return new U(e,this._radial)},getStops:function(){return this._stops},setStops:function(e){if(this.stops)for(var t=0,n=this._stops.length;t<n;t++)this._stops[t]._owner=o;if(e.length<2)throw new Error("Gradient stop list needs to contain at least two stops.");this._stops=W.readAll(e,0,{clone:!0});for(var t=0,n=this._stops.length;t<n;t++){var r=this._stops[t];r._owner=this,r._defaultRamp&&r.setRampPoint(t/(n-1))}this._changed()},getRadial:function(){return this._radial},setRadial:function(e){this._radial=e,this._changed()},equals:function(e){if(e===this)return!0;if(e&&this._class===e._class&&this._stops.length===e._stops.length){for(var t=0,n=this._stops.length;t<n;t++)if(!this._stops[t].equals(e._stops[t]))return!1;return!0}return!1}}),W=s.extend({_class:"GradientStop",initialize:function(e,t){if(e){var n,r;t===o&&Array.isArray(e)?(n=e[0],r=e[1]):e.color?(n=e.color,r=e.rampPoint):(n=e,r=t),this.setColor(n),this.setRampPoint(r)}},clone:function(){return new W(this._color.clone(),this._rampPoint)},_serialize:function(e,t){return s.serialize([this._color,this._rampPoint],e,!0,t)},_changed:function(){this._owner&&this._owner._changed(65)},getRampPoint:function(){return this._rampPoint},setRampPoint:function(e){this._defaultRamp=null==e,this._rampPoint=e||0,this._changed()},getColor:function(){return this._color},setColor:function(e){this._color=V.read(arguments),this._color===e&&(this._color=e.clone()),this._color._owner=this,this._changed()},equals:function(e){return e===this||e&&this._class===e._class&&this._color.equals(e._color)&&this._rampPoint==e._rampPoint||!1}}),G=s.extend(new function(){var e={fillColor:o,strokeColor:o,strokeWidth:1,strokeCap:"butt",strokeJoin:"miter",strokeScaling:!0,miterLimit:10,dashOffset:0,dashArray:[],windingRule:"nonzero",shadowColor:o,shadowBlur:0,shadowOffset:new p,selectedColor:o,fontFamily:"sans-serif",fontWeight:"normal",fontSize:12,font:"sans-serif",leading:null,justification:"left"},t={strokeWidth:97,strokeCap:97,strokeJoin:97,strokeScaling:105,miterLimit:97,fontFamily:9,fontWeight:9,fontSize:9,font:9,leading:9,justification:9},n={beans:!0},r={_defaults:e,_textDefaults:new s(e,{fillColor:new V}),beans:!0};return s.each(e,function(e,i){var a=/Color$/.test(i),l="shadowOffset"===i,c=s.capitalize(i),u=t[i],h="set"+c,d="get"+c;r[h]=function(e){var t=this._owner,n=t&&t._children;if(n&&n.length>0&&!(t instanceof R))for(var r=0,s=n.length;r<s;r++)n[r]._style[h](e);else{var l=this._values[i];l!==e&&(a&&(l&&(l._owner=o),e&&e.constructor===V&&(e._owner&&(e=e.clone()),e._owner=t)),this._values[i]=e,t&&t._changed(u||65))}},r[d]=function(e){var t,n=this._owner,r=n&&n._children;if(!r||0===r.length||e||n instanceof R){var t=this._values[i];if(t===o)t=this._defaults[i],t&&t.clone&&(t=t.clone());else{var c=a?V:l?p:null;!c||t&&t.constructor===c||(this._values[i]=t=c.read([t],0,{readNull:!0,clone:!0}),t&&a&&(t._owner=n))}return t}for(var u=0,h=r.length;u<h;u++){var f=r[u]._style[d]();if(0===u)t=f;else if(!s.equals(t,f))return o}return t},n[d]=function(e){return this._style[d](e)},n[h]=function(e){this._style[h](e)}}),C.inject(n),r},{_class:"Style",initialize:function(e,t,n){this._values={},this._owner=t,this._project=t&&t._project||n||a.project,t instanceof F&&(this._defaults=this._textDefaults),e&&this.set(e)},set:function(e){var t=e instanceof G,n=t?e._values:e;if(n)for(var r in n)if(r in this._defaults){var i=n[r];this[r]=i&&t&&i.clone?i.clone():i}},equals:function(e){return e===this||e&&this._class===e._class&&s.equals(this._values,e._values)||!1},hasFill:function(){return!!this.getFillColor()},hasStroke:function(){return!!this.getStrokeColor()&&this.getStrokeWidth()>0},hasShadow:function(){return!!this.getShadowColor()&&this.getShadowBlur()>0},getView:function(){return this._project.getView()},getFontStyle:function(){var e=this.getFontSize();return this.getFontWeight()+" "+e+(/[a-z]/i.test(e+"")?" ":"px ")+this.getFontFamily()},getFont:"#getFontFamily",setFont:"#setFontFamily",getLeading:function e(){var t=e.base.call(this),n=this.getFontSize();return/pt|em|%|px/.test(n)&&(n=this.getView().getPixelSize(n)),null!=t?t:1.2*n}}),H=new function(){function e(e,t,n,r){for(var i=["","webkit","moz","Moz","ms","o"],a=t[0].toUpperCase()+t.substring(1),o=0;o<6;o++){var s=i[o],l=s?s+a:t;if(l in e){if(!n)return e[l];e[l]=r;break}}}return{getStyles:function(e){var t=e&&9!==e.nodeType?e.ownerDocument:e,n=t&&t.defaultView;return n&&n.getComputedStyle(e,"")},getBounds:function(e,t){var n,r=e.ownerDocument,i=r.body,a=r.documentElement;try{n=e.getBoundingClientRect()}catch(e){n={left:0,top:0,width:0,height:0}}var o=n.left-(a.clientLeft||i.clientLeft||0),s=n.top-(a.clientTop||i.clientTop||0);if(!t){var l=r.defaultView;o+=l.pageXOffset||a.scrollLeft||i.scrollLeft,s+=l.pageYOffset||a.scrollTop||i.scrollTop}return new w(o,s,n.width,n.height)},getViewportBounds:function(e){var t=e.ownerDocument,n=t.defaultView,r=t.documentElement;return new w(0,0,n.innerWidth||r.clientWidth,n.innerHeight||r.clientHeight)},getOffset:function(e,t){return H.getBounds(e,t).getPoint()},getSize:function(e){return H.getBounds(e,!0).getSize()},isInvisible:function(e){return H.getSize(e).equals(new g(0,0))},isInView:function(e){return!H.isInvisible(e)&&H.getViewportBounds(e).intersects(H.getBounds(e,!0))},getPrefixed:function(t,n){return e(t,n)},setPrefixed:function(t,n,r){if("object"==typeof n)for(var i in n)e(t,i,!0,n[i]);else e(t,n,!0,r)}}},X={add:function(e,t){for(var n in t)for(var r=t[n],i=n.split(/[\s,]+/g),a=0,o=i.length;a<o;a++)e.addEventListener(i[a],r,!1)},remove:function(e,t){for(var n in t)for(var r=t[n],i=n.split(/[\s,]+/g),a=0,o=i.length;a<o;a++)e.removeEventListener(i[a],r,!1)},getPoint:function(e){var t=e.targetTouches?e.targetTouches.length?e.targetTouches[0]:e.changedTouches[0]:e;return new p(t.pageX||t.clientX+document.documentElement.scrollLeft,t.pageY||t.clientY+document.documentElement.scrollTop)},getTarget:function(e){return e.target||e.srcElement},getRelatedTarget:function(e){return e.relatedTarget||e.toElement},getOffset:function(e,t){return X.getPoint(e).subtract(H.getOffset(t||X.getTarget(e)))},stop:function(e){e.stopPropagation(),e.preventDefault()}};X.requestAnimationFrame=new function(){function e(){for(var t=i.length-1;t>=0;t--){var o=i[t],s=o[0],l=o[1];(!l||("true"==c.getAttribute(l,"keepalive")||a)&&H.isInView(l))&&(i.splice(t,1),s())}n&&(i.length?n(e):r=!1)}var t,n=H.getPrefixed(window,"requestAnimationFrame"),r=!1,i=[],a=!0;return X.add(window,{focus:function(){a=!0},blur:function(){a=!1}}),function(a,o){i.push([a,o]),n?r||(n(e),r=!0):t||(t=setInterval(e,1e3/60))}};var K=s.extend(l,{_class:"View",initialize:function e(t,n){function r(e){return n[e]||parseInt(n.getAttribute(e),10)}function i(){var e=H.getSize(n);return e.isNaN()||e.isZero()?new g(r("width"),r("height")):e}this._project=t,this._scope=t._scope,this._element=n;var a;this._pixelRatio||(this._pixelRatio=window.devicePixelRatio||1),this._id=n.getAttribute("id"),null==this._id&&n.setAttribute("id",this._id="view-"+e._id++),X.add(n,this._viewEvents);var o="none";if(H.setPrefixed(n.style,{userSelect:o,touchAction:o,touchCallout:o,contentZooming:o,userDrag:o,tapHighlightColor:"rgba(0,0,0,0)"}),c.hasAttribute(n,"resize")){var s=this;X.add(window,this._windowEvents={resize:function(){s.setViewSize(i())}})}if(this._setViewSize(a=i()),c.hasAttribute(n,"stats")&&"undefined"!=typeof Stats){this._stats=new Stats;var l=this._stats.domElement,u=l.style,h=H.getOffset(n);u.position="absolute",u.left=h.x+"px",u.top=h.y+"px",document.body.appendChild(l)}e._views.push(this),e._viewsById[this._id]=this,this._viewSize=a,(this._matrix=new b)._owner=this,this._zoom=1,e._focused||(e._focused=this),this._frameItems={},this._frameItemCount=0},remove:function(){return!!this._project&&(K._focused===this&&(K._focused=null),K._views.splice(K._views.indexOf(this),1),delete K._viewsById[this._id],this._project._view===this&&(this._project._view=null),X.remove(this._element,this._viewEvents),X.remove(window,this._windowEvents),this._element=this._project=null,this.off("frame"),this._animate=!1,this._frameItems={},!0)},_events:s.each(["onResize","onMouseDown","onMouseUp","onMouseMove"],function(e){this[e]={install:function(e){this._installEvent(e)},uninstall:function(e){this._uninstallEvent(e)}}},{onFrame:{install:function(){this.play()},uninstall:function(){this.pause()}}}),_animate:!1,_time:0,_count:0,_requestFrame:function(){var e=this;X.requestAnimationFrame(function(){e._requested=!1,e._animate&&(e._requestFrame(),e._handleFrame())},this._element),this._requested=!0},_handleFrame:function(){a=this._scope;var e=Date.now()/1e3,t=this._before?e-this._before:0;this._before=e,this._handlingFrame=!0,this.emit("frame",new s({delta:t,time:this._time+=t,count:this._count++})),this._stats&&this._stats.update(),this._handlingFrame=!1,this.update()},_animateItem:function(e,t){var n=this._frameItems;t?(n[e._id]={item:e,time:0,count:0},1===++this._frameItemCount&&this.on("frame",this._handleFrameItems)):(delete n[e._id],0===--this._frameItemCount&&this.off("frame",this._handleFrameItems))},_handleFrameItems:function(e){for(var t in this._frameItems){var n=this._frameItems[t];n.item.emit("frame",new s(e,{time:n.time+=e.delta,count:n.count++}))}},_update:function(){this._project._needsUpdate=!0,this._handlingFrame||(this._animate?this._handleFrame():this.update())},_changed:function(e){1&e&&(this._project._needsUpdate=!0)},_transform:function(e){this._matrix.concatenate(e),this._bounds=null,this._update()},getElement:function(){return this._element},getPixelRatio:function(){return this._pixelRatio},getResolution:function(){return 72*this._pixelRatio},getViewSize:function(){var e=this._viewSize;return new v(e.width,e.height,this,"setViewSize")},setViewSize:function(){var e=g.read(arguments),t=e.subtract(this._viewSize);t.isZero()||(this._viewSize.set(e.width,e.height),this._setViewSize(e),this._bounds=null,this.emit("resize",{size:e,delta:t}),this._update())},_setViewSize:function(e){var t=this._element;t.width=e.width,t.height=e.height},getBounds:function(){return this._bounds||(this._bounds=this._matrix.inverted()._transformBounds(new w(new p,this._viewSize))),this._bounds},getSize:function(){return this.getBounds().getSize()},getCenter:function(){return this.getBounds().getCenter()},setCenter:function(){var e=p.read(arguments);this.scrollBy(e.subtract(this.getCenter()))},getZoom:function(){return this._zoom},setZoom:function(e){this._transform((new b).scale(e/this._zoom,this.getCenter())),this._zoom=e},isVisible:function(){return H.isInView(this._element)},scrollBy:function(){this._transform((new b).translate(p.read(arguments).negate()))},play:function(){this._animate=!0,this._requested||this._requestFrame()},pause:function(){this._animate=!1},draw:function(){this.update()},projectToView:function(){return this._matrix._transformPoint(p.read(arguments))},viewToProject:function(){return this._matrix._inverseTransform(p.read(arguments))}},{statics:{_views:[],_viewsById:{},_id:0,create:function(e,t){return"string"==typeof t&&(t=document.getElementById(t)),new Q(e,t)}}},new function(){function e(e){var t=X.getTarget(e);return t.getAttribute&&K._viewsById[t.getAttribute("id")]}function t(e,t){return e.viewToProject(X.getOffset(t,e._element))}function n(){if(!K._focused||!K._focused.isVisible())for(var e=0,t=K._views.length;e<t;e++){var n=K._views[e];if(n&&n.isVisible()){K._focused=o=n;break}}}function r(e,t,n){e._handleEvent("mousemove",t,n);var r=e._scope.tool;return r&&r._handleEvent(u&&r.responds("mousedrag")?"mousedrag":"mousemove",t,n),e.update(),r}var i,a,o,s,l,c,u=!1,h=window.navigator;h.pointerEnabled||h.msPointerEnabled?(s="pointerdown MSPointerDown",l="pointermove MSPointerMove",c="pointerup pointercancel MSPointerUp MSPointerCancel"):(s="touchstart",l="touchmove",c="touchend touchcancel","ontouchstart"in window&&h.userAgent.match(/mobile|tablet|ip(ad|hone|od)|android|silk/i)||(s+=" mousedown",l+=" mousemove",c+=" mouseup"));var d={"selectstart dragstart":function(e){u&&e.preventDefault()}},f={mouseout:function(e){var n=K._focused,i=X.getRelatedTarget(e);!n||i&&"HTML"!==i.nodeName||r(n,t(n,e),e)},scroll:n};d[s]=function(n){var r=K._focused=e(n),a=t(r,n);u=!0,r._handleEvent("mousedown",a,n),(i=r._scope.tool)&&i._handleEvent("mousedown",a,n),r.update()},f[l]=function(s){var l=K._focused;if(!u){var c=e(s);c?(l!==c&&r(l,t(l,s),s),a=l,l=K._focused=o=c):o&&o===l&&(l=K._focused=a,n())}if(l){var h=t(l,s);(u||l.getBounds().contains(h))&&(i=r(l,h,s))}},f[c]=function(e){var n=K._focused;if(n&&u){var r=t(n,e);u=!1,n._handleEvent("mouseup",r,e),i&&i._handleEvent("mouseup",r,e),n.update()}},X.add(document,f),X.add(window,{load:n});var p={mousedown:{mousedown:1,mousedrag:1,click:1,doubleclick:1},mouseup:{mouseup:1,mousedrag:1,click:1,doubleclick:1},mousemove:{mousedrag:1,mousemove:1,mouseenter:1,mouseleave:1}};return{_viewEvents:d,_handleEvent:function(){},_installEvent:function(e){var t=this._eventCounters;if(t)for(var n in p)t[n]=(t[n]||0)+(p[n][e]||0)},_uninstallEvent:function(e){var t=this._eventCounters;if(t)for(var n in p)t[n]-=p[n][e]||0},statics:{updateFocus:n}}}),Q=K.extend({_class:"CanvasView",initialize:function(e,t){if(!(t instanceof HTMLCanvasElement)){var n=g.read(arguments,1);if(n.isZero())throw new Error("Cannot create CanvasView with the provided argument: "+[].slice.call(arguments,1));t=ne.getCanvas(n)}if(this._context=t.getContext("2d"),this._eventCounters={},this._pixelRatio=1,!/^off|false$/.test(c.getAttribute(t,"hidpi"))){var r=window.devicePixelRatio||1,i=H.getPrefixed(this._context,"backingStorePixelRatio")||1;this._pixelRatio=r/i}K.call(this,e,t)},_setViewSize:function(e){var t=this._element,n=this._pixelRatio,r=e.width,i=e.height;if(t.width=r*n,t.height=i*n,1!==n){if(!c.hasAttribute(t,"resize")){var a=t.style;a.width=r+"px",a.height=i+"px"}this._context.scale(n,n)}},getPixelSize:function(e){var t,n=a.browser;if(n&&n.firefox){var r=this._element.parentNode,i=document.createElement("div");i.style.fontSize=e,r.appendChild(i),t=parseFloat(H.getStyles(i).fontSize),r.removeChild(i)}else{var o=this._context,s=o.font;o.font=e+" serif",t=parseFloat(o.font),o.font=s}return t},getTextWidth:function(e,t){var n=this._context,r=n.font,i=0;n.font=e;for(var a=0,o=t.length;a<o;a++)i=Math.max(i,n.measureText(t[a]).width);return n.font=r,i},update:function(e){var t=this._project;if(!t||!e&&!t._needsUpdate)return!1;var n=this._context,r=this._viewSize;return n.clearRect(0,0,r.width+1,r.height+1),t.draw(n,this._matrix,this._pixelRatio),t._needsUpdate=!1,!0}},new function(){function e(e,t,n,r,i,a){function o(e){if(e.responds(t)&&(s||(s=new J(t,n,r,i,a?r.subtract(a):null)),e.emit(t,s)&&s.isStopped))return n.preventDefault(),!0}for(var s,l=i;l;){if(o(l))return!0;l=l.getParent()}return!!o(e)}var t,n,r,i,a,o,s,l,c;return{_handleEvent:function(u,h,d){if(this._eventCounters[u]){var f=this._project,p=f.hitTest(h,{tolerance:0,fill:!0,stroke:!0}),m=p&&p.item,g=!1;switch(u){case"mousedown":for(g=e(this,u,d,h,m),l=a==m&&Date.now()-c<300,i=a=m,t=n=r=h,s=!g&&m;s&&!s.responds("mousedrag");)s=s._parent;break;case"mouseup":g=e(this,u,d,h,m,t),s&&(n&&!n.equals(h)&&e(this,"mousedrag",d,h,s,n),m!==s&&(r=h,e(this,"mousemove",d,h,m,r))),!g&&m&&m===i&&(c=Date.now(),e(this,l&&i.responds("doubleclick")?"doubleclick":"click",d,t,m),l=!1),i=s=null;break;case"mousemove":s&&(g=e(this,"mousedrag",d,h,s,n)),g||(m!==o&&(r=h),g=e(this,u,d,h,m,r)),n=r=h,m!==o&&(e(this,"mouseleave",d,h,o),o=m,e(this,"mouseenter",d,h,m))}return g}}}}),Y=s.extend({_class:"Event",initialize:function(e){this.event=e},isPrevented:!1,isStopped:!1,preventDefault:function(){this.isPrevented=!0,this.event.preventDefault()},stopPropagation:function(){this.isStopped=!0,this.event.stopPropagation()},stop:function(){this.stopPropagation(),this.preventDefault()},getModifiers:function(){return $.modifiers}}),Z=Y.extend({_class:"KeyEvent",initialize:function(e,t,n,r){Y.call(this,r),this.type=e?"keydown":"keyup",this.key=t,this.character=n},toString:function(){return"{ type: '"+this.type+"', key: '"+this.key+"', character: '"+this.character+"', modifiers: "+this.getModifiers()+" }"}}),$=new function(){function e(n,i,u,h){var d,f=u?String.fromCharCode(u):"",p=r[i],m=p||f.toLowerCase(),g=n?"keydown":"keyup",v=K._focused,w=v&&v.isVisible()&&v._scope,y=w&&w.tool;if(c[m]=n,n?l[i]=u:delete l[i],p&&(d=s.camelize(p))in o){o[d]=n;var b=a.browser;if("command"===d&&b&&b.mac)if(n)t={};else{for(var _ in t)_ in l&&e(!1,_,t[_],h);t=null}}else n&&t&&(t[i]=u);y&&y.responds(g)&&(a=w,y.emit(g,new Z(n,m,f,h)),v&&v.update())}var t,n,r={8:"backspace",9:"tab",13:"enter",16:"shift",17:"control",18:"option",19:"pause",20:"caps-lock",27:"escape",32:"space",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",46:"delete",91:"command",93:"command",224:"command"},i={9:!0,13:!0,32:!0},o=new s({shift:!1,control:!1,option:!1,command:!1,capsLock:!1,space:!1}),l={},c={};return X.add(document,{keydown:function(t){var a=t.which||t.keyCode;a in r||o.command?e(!0,a,a in i||o.command?a:0,t):n=a},keypress:function(t){null!=n&&(e(!0,n,t.which||t.keyCode,t),n=null)},keyup:function(t){var n=t.which||t.keyCode;n in l&&e(!1,n,l[n],t)}}),X.add(window,{blur:function(t){for(var n in l)e(!1,n,l[n],t)}}),{modifiers:o,isDown:function(e){return!!c[e]}}},J=Y.extend({_class:"MouseEvent",initialize:function(e,t,n,r,i){Y.call(this,t),this.type=e,this.point=n,this.target=r,this.delta=i},toString:function(){return"{ type: '"+this.type+"', point: "+this.point+", target: "+this.target+(this.delta?", delta: "+this.delta:"")+", modifiers: "+this.getModifiers()+" }"; +}}),ee=Y.extend({_class:"ToolEvent",_item:null,initialize:function(e,t,n){this.tool=e,this.type=t,this.event=n},_choosePoint:function(e,t){return e?e:t?t.clone():null},getPoint:function(){return this._choosePoint(this._point,this.tool._point)},setPoint:function(e){this._point=e},getLastPoint:function(){return this._choosePoint(this._lastPoint,this.tool._lastPoint)},setLastPoint:function(e){this._lastPoint=e},getDownPoint:function(){return this._choosePoint(this._downPoint,this.tool._downPoint)},setDownPoint:function(e){this._downPoint=e},getMiddlePoint:function(){return!this._middlePoint&&this.tool._lastPoint?this.tool._point.add(this.tool._lastPoint).divide(2):this._middlePoint},setMiddlePoint:function(e){this._middlePoint=e},getDelta:function(){return!this._delta&&this.tool._lastPoint?this.tool._point.subtract(this.tool._lastPoint):this._delta},setDelta:function(e){this._delta=e},getCount:function(){return/^mouse(down|up)$/.test(this.type)?this.tool._downCount:this.tool._count},setCount:function(e){this.tool[/^mouse(down|up)$/.test(this.type)?"downCount":"count"]=e},getItem:function(){if(!this._item){var e=this.tool._scope.project.hitTest(this.getPoint());if(e){for(var t=e.item,n=t._parent;/^(Group|CompoundPath)$/.test(n._class);)t=n,n=n._parent;this._item=t}}return this._item},setItem:function(e){this._item=e},toString:function(){return"{ type: "+this.type+", point: "+this.getPoint()+", count: "+this.getCount()+", modifiers: "+this.getModifiers()+" }"}}),te=(u.extend({_class:"Tool",_list:"tools",_reference:"tool",_events:["onActivate","onDeactivate","onEditOptions","onMouseDown","onMouseUp","onMouseDrag","onMouseMove","onKeyDown","onKeyUp"],initialize:function(e){u.call(this),this._firstMove=!0,this._count=0,this._downCount=0,this._set(e)},getMinDistance:function(){return this._minDistance},setMinDistance:function(e){this._minDistance=e,null!=e&&null!=this._maxDistance&&e>this._maxDistance&&(this._maxDistance=e)},getMaxDistance:function(){return this._maxDistance},setMaxDistance:function(e){this._maxDistance=e,null!=this._minDistance&&null!=e&&e<this._minDistance&&(this._minDistance=e)},getFixedDistance:function(){return this._minDistance==this._maxDistance?this._minDistance:null},setFixedDistance:function(e){this._minDistance=this._maxDistance=e},_updateEvent:function(e,t,n,r,i,a,o){if(!i){if(null!=n||null!=r){var s=null!=n?n:0,l=t.subtract(this._point),c=l.getLength();if(c<s)return!1;if(null!=r&&0!=r)if(c>r)t=this._point.add(l.normalize(r));else if(o)return!1}if(a&&t.equals(this._point))return!1}switch(this._lastPoint=i&&"mousemove"==e?t:this._point,this._point=t,e){case"mousedown":this._lastPoint=this._downPoint,this._downPoint=this._point,this._downCount++;break;case"mouseup":this._lastPoint=this._downPoint}return this._count=i?0:this._count+1,!0},_fireEvent:function(e,t){var n=a.project._removeSets;if(n){"mouseup"===e&&(n.mousedrag=null);var r=n[e];if(r){for(var i in r){var o=r[i];for(var s in n){var l=n[s];l&&l!=r&&delete l[o._id]}o.remove()}n[e]=null}}return this.responds(e)&&this.emit(e,new ee(this,e,t))},_handleEvent:function(e,t,n){a=this._scope;var r=!1;switch(e){case"mousedown":this._updateEvent(e,t,null,null,!0,!1,!1),r=this._fireEvent(e,n);break;case"mousedrag":for(var i=!1,o=!1;this._updateEvent(e,t,this.minDistance,this.maxDistance,!1,i,o);)r=this._fireEvent(e,n)||r,i=!0,o=!0;break;case"mouseup":!t.equals(this._point)&&this._updateEvent("mousedrag",t,this.minDistance,this.maxDistance,!1,!1,!1)&&(r=this._fireEvent("mousedrag",n)),this._updateEvent(e,t,null,this.maxDistance,!1,!1,!1),r=this._fireEvent(e,n)||r,this._updateEvent(e,t,null,null,!0,!1,!1),this._firstMove=!0;break;case"mousemove":for(;this._updateEvent(e,t,this.minDistance,this.maxDistance,this._firstMove,!0,!1);)r=this._fireEvent(e,n)||r,this._firstMove=!1}return r&&n.preventDefault(),r}}),{request:function(e,t,n,r){r=r===o||r;var i=new(window.ActiveXObject||XMLHttpRequest)("Microsoft.XMLHTTP");return i.open(e.toUpperCase(),t,r),"overrideMimeType"in i&&i.overrideMimeType("text/plain"),i.onreadystatechange=function(){if(4===i.readyState){var e=i.status;if(0!==e&&200!==e)throw new Error("Could not load "+t+" (Error "+e+")");n.call(i,i.responseText)}},i.send(null)}}),ne={canvases:[],getCanvas:function(e,t){var n,r=!0;"object"==typeof e&&(t=e.height,e=e.width),n=this.canvases.length?this.canvases.pop():document.createElement("canvas");var i=n.getContext("2d");return n.width===e&&n.height===t?r&&i.clearRect(0,0,e+1,t+1):(n.width=e,n.height=t),i.save(),n},getContext:function(e,t){return this.getCanvas(e,t).getContext("2d")},release:function(e){var t=e.canvas?e.canvas:e;t.getContext("2d").restore(),this.canvases.push(t)}},re=new function(){function e(e,t,n){return.2989*e+.587*t+.114*n}function t(t,n,r,i){var a=i-e(t,n,r);f=t+a,p=n+a,m=r+a;var i=e(f,p,m),o=g(f,p,m),s=v(f,p,m);if(o<0){var l=i-o;f=i+(f-i)*i/l,p=i+(p-i)*i/l,m=i+(m-i)*i/l}if(s>255){var c=255-i,u=s-i;f=i+(f-i)*c/u,p=i+(p-i)*c/u,m=i+(m-i)*c/u}}function n(e,t,n){return v(e,t,n)-g(e,t,n)}function r(e,t,n,r){var i,a=[e,t,n],o=v(e,t,n),s=g(e,t,n);s=s===e?0:s===t?1:2,o=o===e?0:o===t?1:2,i=0===g(s,o)?1===v(s,o)?2:1:0,a[o]>a[s]?(a[i]=(a[i]-a[s])*r/(a[o]-a[s]),a[o]=r):a[i]=a[o]=0,a[s]=0,f=a[0],p=a[1],m=a[2]}var i,a,o,l,c,u,h,d,f,p,m,g=Math.min,v=Math.max,w=Math.abs,y={multiply:function(){f=c*i/255,p=u*a/255,m=h*o/255},screen:function(){f=c+i-c*i/255,p=u+a-u*a/255,m=h+o-h*o/255},overlay:function(){f=c<128?2*c*i/255:255-2*(255-c)*(255-i)/255,p=u<128?2*u*a/255:255-2*(255-u)*(255-a)/255,m=h<128?2*h*o/255:255-2*(255-h)*(255-o)/255},"soft-light":function(){var e=i*c/255;f=e+c*(255-(255-c)*(255-i)/255-e)/255,e=a*u/255,p=e+u*(255-(255-u)*(255-a)/255-e)/255,e=o*h/255,m=e+h*(255-(255-h)*(255-o)/255-e)/255},"hard-light":function(){f=i<128?2*i*c/255:255-2*(255-i)*(255-c)/255,p=a<128?2*a*u/255:255-2*(255-a)*(255-u)/255,m=o<128?2*o*h/255:255-2*(255-o)*(255-h)/255},"color-dodge":function(){f=0===c?0:255===i?255:g(255,255*c/(255-i)),p=0===u?0:255===a?255:g(255,255*u/(255-a)),m=0===h?0:255===o?255:g(255,255*h/(255-o))},"color-burn":function(){f=255===c?255:0===i?0:v(0,255-255*(255-c)/i),p=255===u?255:0===a?0:v(0,255-255*(255-u)/a),m=255===h?255:0===o?0:v(0,255-255*(255-h)/o)},darken:function(){f=c<i?c:i,p=u<a?u:a,m=h<o?h:o},lighten:function(){f=c>i?c:i,p=u>a?u:a,m=h>o?h:o},difference:function(){f=c-i,f<0&&(f=-f),p=u-a,p<0&&(p=-p),m=h-o,m<0&&(m=-m)},exclusion:function(){f=c+i*(255-c-c)/255,p=u+a*(255-u-u)/255,m=h+o*(255-h-h)/255},hue:function(){r(i,a,o,n(c,u,h)),t(f,p,m,e(c,u,h))},saturation:function(){r(c,u,h,n(i,a,o)),t(f,p,m,e(c,u,h))},luminosity:function(){t(c,u,h,e(i,a,o))},color:function(){t(i,a,o,e(c,u,h))},add:function(){f=g(c+i,255),p=g(u+a,255),m=g(h+o,255)},subtract:function(){f=v(c-i,0),p=v(u-a,0),m=v(h-o,0)},average:function(){f=(c+i)/2,p=(u+a)/2,m=(h+o)/2},negation:function(){f=255-w(255-i-c),p=255-w(255-a-u),m=255-w(255-o-h)}},b=this.nativeModes=s.each(["source-over","source-in","source-out","source-atop","destination-over","destination-in","destination-out","destination-atop","lighter","darker","copy","xor"],function(e){this[e]=!0},{}),_=ne.getContext(1,1);s.each(y,function(e,t){var n="darken"===t,r=!1;_.save();try{_.fillStyle=n?"#300":"#a00",_.fillRect(0,0,1,1),_.globalCompositeOperation=t,_.globalCompositeOperation===t&&(_.fillStyle=n?"#a00":"#300",_.fillRect(0,0,1,1),r=_.getImageData(0,0,1,1).data[0]!==n?170:51)}catch(e){}_.restore(),b[t]=r}),ne.release(_),this.process=function(e,t,n,r,s){var g=t.canvas,v="normal"===e;if(v||b[e])n.save(),n.setTransform(1,0,0,1,0,0),n.globalAlpha=r,v||(n.globalCompositeOperation=e),n.drawImage(g,s.x,s.y),n.restore();else{var w=y[e];if(!w)return;for(var _=n.getImageData(s.x,s.y,g.width,g.height),x=_.data,E=t.getImageData(0,0,g.width,g.height).data,C=0,k=x.length;C<k;C+=4){i=E[C],c=x[C],a=E[C+1],u=x[C+1],o=E[C+2],h=x[C+2],l=E[C+3],d=x[C+3],w();var S=l*r/255,P=1-S;x[C]=S*f+P*c,x[C+1]=S*p+P*u,x[C+2]=S*m+P*h,x[C+3]=l*r+P*d}n.putImageData(_,s.x,s.y)}}},ie=s.each({fillColor:["fill","color"],strokeColor:["stroke","color"],strokeWidth:["stroke-width","number"],strokeCap:["stroke-linecap","string"],strokeJoin:["stroke-linejoin","string"],strokeScaling:["vector-effect","lookup",{true:"none",false:"non-scaling-stroke"},function(e,t){return!t&&(e instanceof B||e instanceof P||e instanceof F)}],miterLimit:["stroke-miterlimit","number"],dashArray:["stroke-dasharray","array"],dashOffset:["stroke-dashoffset","number"],fontFamily:["font-family","string"],fontWeight:["font-weight","string"],fontSize:["font-size","number"],justification:["text-anchor","lookup",{left:"start",center:"middle",right:"end"}],opacity:["opacity","number"],blendMode:["mix-blend-mode","string"]},function(e,t){var n=s.capitalize(t),r=e[2];this[t]={type:e[1],property:t,attribute:e[0],toSVG:r,fromSVG:r&&s.each(r,function(e,t){this[e]=t},{}),exportFilter:e[3],get:"get"+n,set:"set"+n}},{}),ae={href:"http://www.w3.org/1999/xlink",xlink:"http://www.w3.org/2000/xmlns"};return new function(){function e(e,t){for(var n in t){var r=t[n],i=ae[n];"number"==typeof r&&(r=b.number(r)),i?e.setAttributeNS(i,n,r):e.setAttribute(n,r)}return e}function t(t,n){return e(document.createElementNS("http://www.w3.org/2000/svg",t),n)}function n(e,t,n){var r=new s,i=e.getTranslation();if(t){e=e.shiftless();var a=e._inverseTransform(i);r[n?"cx":"x"]=a.x,r[n?"cy":"y"]=a.y,i=null}if(!e.isIdentity()){var o=e.decompose();if(o&&!o.shearing){var l=[],c=o.rotation,u=o.scaling;i&&!i.isZero()&&l.push("translate("+b.point(i)+")"),d.isZero(u.x-1)&&d.isZero(u.y-1)||l.push("scale("+b.point(u)+")"),c&&l.push("rotate("+b.number(c)+")"),r.transform=l.join(" ")}else r.transform="matrix("+e.getValues().join(",")+")"}return r}function r(r,i){for(var a=n(r._matrix),o=r._children,s=t("g",a),l=0,c=o.length;l<c;l++){var u=o[l],h=w(u,i);if(h)if(u.isClipMask()){var d=t("clipPath");d.appendChild(h),g(u,d,"clip"),e(s,{"clip-path":"url(#"+d.id+")"})}else s.appendChild(h)}return s}function i(e,r){var i=n(e._matrix,!0),a=e.getSize(),o=e.getImage();return i.x-=a.width/2,i.y-=a.height/2,i.width=a.width,i.height=a.height,i.href=r.embedImages===!1&&o&&o.src||e.toDataURL(),t("image",i)}function a(e,r){var i=r.matchShapes;if(i){var a=e.toShape(!1);if(a)return o(a,r)}var s,l=e._segments,c=n(e._matrix);if(0===l.length)return null;if(i&&!e.hasHandles())if(l.length>=3){s=e._closed?"polygon":"polyline";for(var u=[],h=0,d=l.length;h<d;h++)u.push(b.point(l[h]._point));c.points=u.join(" ")}else{s="line";var f=l[0]._point,p=l[l.length-1]._point;c.set({x1:f.x,y1:f.y,x2:p.x,y2:p.y})}else s="path",c.d=e.getPathData(null,r.precision);return t(s,c)}function o(e){var r=e._type,i=e._radius,a=n(e._matrix,!0,"rectangle"!==r);if("rectangle"===r){r="rect";var o=e._size,s=o.width,l=o.height;a.x-=s/2,a.y-=l/2,a.width=s,a.height=l,i.isZero()&&(i=null)}return i&&("circle"===r?a.r=i:(a.rx=i.width,a.ry=i.height)),t(r,a)}function l(e,r){var i=n(e._matrix),a=e.getPathData(null,r.precision);return a&&(i.d=a),t("path",i)}function c(e,r){var i=n(e._matrix,!0),a=e.getSymbol(),o=m(a,"symbol"),s=a.getDefinition(),l=s.getBounds();return o||(o=t("symbol",{viewBox:b.rectangle(l)}),o.appendChild(w(s,r)),g(a,o,"symbol")),i.href="#"+o.id,i.x+=l.x,i.y+=l.y,i.width=b.number(l.width),i.height=b.number(l.height),i.overflow="visible",t("use",i)}function u(e){var n=m(e,"color");if(!n){var r,i=e.getGradient(),a=i._radial,o=e.getOrigin().transform(),s=e.getDestination().transform();if(a){r={cx:o.x,cy:o.y,r:o.getDistance(s)};var l=e.getHighlight();l&&(l=l.transform(),r.fx=l.x,r.fy=l.y)}else r={x1:o.x,y1:o.y,x2:s.x,y2:s.y};r.gradientUnits="userSpaceOnUse",n=t((a?"radial":"linear")+"Gradient",r);for(var c=i._stops,u=0,h=c.length;u<h;u++){var d=c[u],f=d._color,p=f.getAlpha();r={offset:d._rampPoint,"stop-color":f.toCSS(!0)},p<1&&(r["stop-opacity"]=p),n.appendChild(t("stop",r))}g(e,n,"color")}return"url(#"+n.id+")"}function f(e){var r=t("text",n(e._matrix,!0));return r.textContent=e._content,r}function p(t,n,r){var i={},a=!r&&t.getParent();return null!=t._name&&(i.id=t._name),s.each(ie,function(e){var n=e.get,r=e.type,o=t[n]();if(e.exportFilter?e.exportFilter(t,o):!a||!s.equals(a[n](),o)){if("color"===r&&null!=o){var l=o.getAlpha();l<1&&(i[e.attribute+"-opacity"]=l)}i[e.attribute]=null==o?"none":"number"===r?b.number(o):"color"===r?o.gradient?u(o,t):o.toCSS(!0):"array"===r?o.join(","):"lookup"===r?e.toSVG[o]:o}}),1===i.opacity&&delete i.opacity,t._visible||(i.visibility="hidden"),e(n,i)}function m(e,t){return _||(_={ids:{},svgs:{}}),e&&_.svgs[t+"-"+e._id]}function g(e,t,n){_||m();var r=_.ids[n]=(_.ids[n]||0)+1;t.id=n+"-"+r,_.svgs[n+"-"+e._id]=t}function v(e,n){var r=e,i=null;if(_){r="svg"===e.nodeName.toLowerCase()&&e;for(var a in _.svgs)i||(r||(r=t("svg"),r.appendChild(e)),i=r.insertBefore(t("defs"),r.firstChild)),i.appendChild(_.svgs[a]);_=null}return n.asString?(new XMLSerializer).serializeToString(r):r}function w(e,t,n){var r=E[e._class],i=r&&r(e,t);if(i){var a=t.onExport;a&&(i=a(e,i,t)||i);var o=JSON.stringify(e._data);o&&"{}"!==o&&"null"!==o&&i.setAttribute("data-paper-data",o)}return i&&p(e,i,n)}function y(e){return e||(e={}),b=new h(e.precision),e}var b,_,E={Group:r,Layer:r,Raster:i,Path:a,Shape:o,CompoundPath:l,PlacedSymbol:c,PointText:f};C.inject({exportSVG:function(e){return e=y(e),v(w(this,e,!0),e)}}),x.inject({exportSVG:function(e){e=y(e);var r=this.layers,i=this.getView(),a=i.getViewSize(),o=t("svg",{x:0,y:0,width:a.width,height:a.height,version:"1.1",xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}),s=o,l=i._matrix;l.isIdentity()||(s=o.appendChild(t("g",n(l))));for(var c=0,u=r.length;c<u;c++)s.appendChild(w(r[c],e,!0));return v(o,e)}})},new function(){function e(e,t,n,r){var i=ae[t],a=i?e.getAttributeNS(i,t):e.getAttribute(t);return"null"===a&&(a=null),null==a?r?null:n?"":0:n?a:parseFloat(a)}function t(t,n,r,i){return n=e(t,n,!1,i),r=e(t,r,!1,i),!i||null!=n&&null!=r?new p(n,r):null}function n(t,n,r,i){return n=e(t,n,!1,i),r=e(t,r,!1,i),!i||null!=n&&null!=r?new g(n,r):null}function r(e,t,n){return"none"===e?null:"number"===t?parseFloat(e):"array"===t?e?e.split(/[\s,]+/g).map(parseFloat):[]:"color"===t?v(e)||e:"lookup"===t?n[e]:e}function i(e,t,n,r){var i=e.childNodes,a="clippath"===t,o=new k,s=o._project,l=s._currentStyle,c=[];if(a||(o=m(o,e,r),s._currentStyle=o._style.clone()),r)for(var u=e.querySelectorAll("defs"),h=0,d=u.length;h<d;h++)y(u[h],n,!1);for(var h=0,d=i.length;h<d;h++){var f,p=i[h];1!==p.nodeType||"defs"===p.nodeName.toLowerCase()||!(f=y(p,n,!1))||f instanceof E||c.push(f)}return o.addChildren(c),a&&(o=m(o.reduce(),e,r)),s._currentStyle=l,(a||"defs"===t)&&(o.remove(),o=null),o}function l(e,t){for(var n=e.getAttribute("points").match(/[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g),r=[],i=0,a=n.length;i<a;i+=2)r.push(new p(parseFloat(n[i]),parseFloat(n[i+1])));var o=new z(r);return"polygon"===t&&o.closePath(),o}function c(e){var t=e.getAttribute("d"),n={pathData:t};return(t.match(/m/gi)||[]).length>1||/z\S+/i.test(t)?new R(n):new z(n)}function u(n,r){var i,a=(e(n,"href",!0)||"").substring(1),o="radialgradient"===r;if(a)i=M[a].getGradient();else{for(var s=n.childNodes,l=[],c=0,u=s.length;c<u;c++){var h=s[c];1===h.nodeType&&l.push(m(new W,h))}i=new U(l,o)}var d,f,p;return o?(d=t(n,"cx","cy"),f=d.add(e(n,"r"),0),p=t(n,"fx","fy",!0)):(d=t(n,"x1","y1"),f=t(n,"x2","y2")),m(new V(i,d,f,p),n),null}function h(e,t,n,r){for(var i=(r.getAttribute(n)||"").split(/\)\s*/g),a=new b,o=0,s=i.length;o<s;o++){var l=i[o];if(!l)break;for(var c=l.split(/\(\s*/),u=c[0],h=c[1].split(/[\s,]+/g),d=0,f=h.length;d<f;d++)h[d]=parseFloat(h[d]);switch(u){case"matrix":a.concatenate(new b(h[0],h[1],h[2],h[3],h[4],h[5]));break;case"rotate":a.rotate(h[0],h[1],h[2]);break;case"translate":a.translate(h[0],h[1]);break;case"scale":a.scale(h);break;case"skewX":a.skew(h[0],0);break;case"skewY":a.skew(0,h[0])}}e.transform(a)}function d(e,t,n){var r=e["fill-opacity"===n?"getFillColor":"getStrokeColor"]();r&&r.setAlpha(parseFloat(t))}function f(e,t,n){var r=e.attributes[t],i=r&&r.value;if(!i){var a=s.camelize(t);i=e.style[a],i||n.node[a]===n.parent[a]||(i=n.node[a])}return i?"none"===i?null:i:o}function m(e,t,n){var r={node:H.getStyles(t)||{},parent:!n&&H.getStyles(t.parentNode)||{}};return s.each(S,function(n,i){var a=f(t,i,r);a!==o&&(e=s.pick(n(e,a,i,t,r),e))}),e}function v(e){var t=e&&e.match(/\((?:#|)([^)']+)/);return t&&M[t[1]]}function y(e,t,n){function r(e){a=o;var r=y(e,t,n),i=t.onLoad,s=o.project&&o.getView();i&&i.call(this,r),s.update()}if(!e)return null;t?"function"==typeof t&&(t={onLoad:t}):t={};var i=e,o=a;if(n)if("string"!=typeof e||/^.*</.test(e)){if("undefined"!=typeof File&&e instanceof File){var l=new FileReader;return l.onload=function(){r(l.result)},l.readAsText(e)}}else{if(i=document.getElementById(e),!i)return te.request("get",e,r);e=null}if("string"==typeof e&&(i=(new DOMParser).parseFromString(e,"image/svg+xml")),!i.nodeName)throw new Error("Unsupported SVG source: "+e);var c,u=i.nodeName.toLowerCase(),h=_[u],d=i.getAttribute&&i.getAttribute("data-paper-data"),f=o.settings,p=f.applyMatrix;if(f.applyMatrix=!1,c=h&&h(i,u,t,n)||null,f.applyMatrix=p,c){"#document"===u||c instanceof k||(c=m(c,i,n));var g=t.onImport;g&&(c=g(i,c,t)||c),t.expandShapes&&c instanceof P&&(c.remove(),c=c.toPath()),d&&(c._data=JSON.parse(d))}return n&&(M={},c&&s.pick(t.applyMatrix,p)&&c.matrix.apply(!0,!0)),c}var _={"#document":function(e,t,n,r){for(var i=e.childNodes,a=0,o=i.length;a<o;a++){var s=i[a];if(1===s.nodeType){var l=s.nextSibling;document.body.appendChild(s);var c=y(s,n,r);return l?e.insertBefore(s,l):e.appendChild(s),c}}},g:i,svg:i,clippath:i,polygon:l,polyline:l,path:c,lineargradient:u,radialgradient:u,image:function(r){var i=new T(e(r,"href",!0));return i.on("load",function(){var e=n(r,"width","height");this.setSize(e);var i=this._matrix._transformPoint(t(r,"x","y").add(e.divide(2)));this.translate(i)}),i},symbol:function(e,t,n,r){return new E(i(e,t,n,r),!0)},defs:i,use:function(n){var r=(e(n,"href",!0)||"").substring(1),i=M[r],a=t(n,"x","y");return i?i instanceof E?i.place(a):i.clone().translate(a):null},circle:function(n){return new P.Circle(t(n,"cx","cy"),e(n,"r"))},ellipse:function(e){return new P.Ellipse({center:t(e,"cx","cy"),radius:n(e,"rx","ry")})},rect:function(e){var r=t(e,"x","y"),i=n(e,"width","height"),a=n(e,"rx","ry");return new P.Rectangle(new w(r,i),a)},line:function(e){return new z.Line(t(e,"x1","y1"),t(e,"x2","y2"))},text:function(e){var n=new q(t(e,"x","y").add(t(e,"dx","dy")));return n.setContent(e.textContent.trim()||""),n}},S=s.set(s.each(ie,function(e){this[e.attribute]=function(t,n){if(t[e.set](r(n,e.type,e.fromSVG)),"color"===e.type&&t instanceof P){var i=t[e.get]();i&&i.transform((new b).translate(t.getPosition(!0).negate()))}}},{}),{id:function(e,t){M[t]=e,e.setName&&e.setName(t)},"clip-path":function(e,t){var n=v(t);if(n){if(n=n.clone(),n.setClipMask(!0),!(e instanceof k))return new k(n,e);e.insertChild(0,n)}},gradientTransform:h,transform:h,"fill-opacity":d,"stroke-opacity":d,visibility:function(e,t){e.setVisible("visible"===t)},display:function(e,t){e.setVisible(null!==t)},"stop-color":function(e,t){e.setColor&&e.setColor(t)},"stop-opacity":function(e,t){e._color&&e._color.setAlpha(parseFloat(t))},offset:function(e,t){var n=t.match(/(.*)%$/);e.setRampPoint(n?n[1]/100:parseFloat(t))},viewBox:function(e,t,i,a,o){var s=new w(r(t,"array")),l=n(a,"width","height",!0);if(e instanceof k){var c=l?s.getSize().divide(l):1,u=(new b).translate(s.getPoint()).scale(c);e.transform(u.inverted())}else if(e instanceof E){l&&s.setSize(l);var h="visible"!=f(a,"overflow",o),d=e._definition;h&&!s.contains(d.getBounds())&&(h=new P.Rectangle(s).transform(d._matrix),h.setClipMask(!0),d.addChild(h))}}}),M={};C.inject({importSVG:function(e,t){return this.addChild(y(e,t,!0))}}),x.inject({importSVG:function(e,t){return this.activate(),y(e,t,!0)}})},a=new(c.inject(s.exports,{enumerable:!0,Base:s,Numerical:d,Key:$})),r=a,i="function"==typeof r?r.call(t,n,t,e):r,!(i!==o&&(e.exports=i)),a}},function(e,t,n){"use strict";var r=n(4),i=n(105),a=r.createClass({displayName:"BSplineGraphic",componentWillMount:function(){var e=this;this.cvs=void 0,this.ctx=void 0,this.key=void 0,this.keyCode=void 0,this.mouseX=void 0,this.mouseY=void 0,this.isMouseDown=void 0,this.width=0,this.height=0,this.activeDistance=9,this.points=[],this.knots=[],this.weights=[],this.nodes=[],this.cp=void 0,this.dx=void 0,this.dy=void 0;var t=this.props.sketch;Object.keys(t).forEach(function(n){e[n]=t[n],"function"==typeof e[n]&&(e[n]=e[n].bind(e))})},render:function(){return r.createElement("canvas",{className:"bspline-graphic",ref:"sketch"})},keydownlisten:function(e){this.setKeyboardValues(e),this.keyDown()},keyuplisten:function(e){this.setKeyboardValues(e),this.keyUp()},keypresslisten:function(e){this.setKeyboardValues(e),this.keyPressed()},mousedownlisten:function(e){this.setMouseValues(e),this.mouseDown()},mouseuplisten:function(e){this.setMouseValues(e),this.mouseUp()},mousemovelisten:function(e){this.setMouseValues(e),this.mouseMove(),this.isMouseDown&&this.mouseDrag&&this.mouseDrag()},wheellissten:function(e){e.preventDefault(),this.scrolled(e.deltaY<0?1:-1)},componentDidMount:function(){var e=this.cvs=this.refs.sketch;e.addEventListener("keydown",this.keydownlisten),e.addEventListener("keyup",this.keyuplisten),e.addEventListener("keypress",this.keypresslisten),e.addEventListener("mousedown",this.mousedownlisten),e.addEventListener("mouseup",this.mouseuplisten),e.addEventListener("mousemove",this.mousemovelisten),this.props.scrolling&&e.addEventListener("wheel",this.wheellissten),this.setup()},componentWillUnmount:function(){var e=this.cvs=this.refs.sketch;e.removeEventListener("keydown",this.keydownlisten),e.removeEventListener("keyup",this.keyuplisten),e.removeEventListener("keypress",this.keypresslisten),e.removeEventListener("mousedown",this.mousedownlisten),e.removeEventListener("mouseup",this.mouseuplisten),e.removeEventListener("mousemove",this.mousemovelisten),this.props.scrolling&&e.removeEventListener("wheel",this.wheellissten)},drawCurve:function(e){e=e||this.points;var t=this.ctx,n=this.weights.length>0&&this.weights;t.beginPath();var r=i(0,this.degree,e,this.knots,n);t.moveTo(r[0],r[1]);for(var a=.01;a<1;a+=.01)r=i(a,this.degree,e,this.knots,n),t.lineTo(r[0],r[1]);r=i(1,this.degree,e,this.knots,n),t.lineTo(r[0],r[1]),t.stroke(),t.closePath()},drawKnots:function(e){var t=this,n=this.knots,r=this.weights.length>0&&this.weights;n.forEach(function(a,o){if(!(o<t.degree||o>n.length-1-t.degree)){var s=i(a,t.degree,e,n,r,!1,!0);t.circle(s[0],s[1],3)}})},drawNodes:function(e){var t,n=this;this.stroke(150),this.nodes.forEach(function(r,a){try{t=i(r,n.degree,e,n.knots,!1,!1,!0),n.line(t[0],t[1],e[a][0],e[a++][1])}catch(e){console.error(e)}})},formKnots:function(e,t){if(t=t===!0,!t)return this.formUniformKnots(e);var n,r=e.length,i=[],a=r-this.degree;for(n=1;n<r-this.degree;n++)i.push(n+this.degree);for(n=0;n<=this.degree;n++)i=[this.degree].concat(i);for(n=0;n<=this.degree;n++)i.push(a+this.degree);return i},formUniformKnots:function(e){for(var t=[],n=this.points.length+this.degree;n>=0;n--)t.push(n);return t.reverse()},formNodes:function(e,t){var n,r,i,a=[this.degree,e.length-1-this.degree],o=[];for(r=0;r<this.points.length;r++){for(n=0,i=1;i<=this.degree;i++)n+=e[r+i];n/=this.degree,n<e[a[0]]||n>e[a[1]]||o.push(n)}return o},formWeights:function(e){var t=[];return e.forEach(function(e){return t.push(1)}),t},setDegree:function(e){this.degree+=e,this.knots=this.formKnots(this.points),this.nodes=this.formNodes(this.knots,this.points)},near:function(e,t,n){var r=e.x-t,i=e.y-n,a=Math.sqrt(r*r+i*i);return a<this.activeDistance},getCurrentPoint:function(e,t){for(var n=0;n<this.points.length;n++)if(this.near(this.points[n],e,t))return this.points[n]},keyDown:function(){"ArrowUp"===this.key&&this.setDegree(1),"ArrowDown"===this.key&&this.degree>1&&this.setDegree(-1),this.redraw()},keyUp:function(){},keyPressed:function(){},mouseDown:function(){this.isMouseDown=!0,this.cp=this.getCurrentPoint(this.mouseX,this.mouseY),this.cp||(this.points.push({x:this.mouseX,y:this.mouseY}),this.knots=this.formKnots(this.points),this.nodes=this.formNodes(this.knots,this.points)),this.redraw()},mouseUp:function(){this.isMouseDown=!1,this.cp=!1,this.redraw()},mouseDrag:function(){this.cp&&(this.cp.x=this.mouseX,this.cp.y=this.mouseY,this.redraw())},mouseMove:function(){},scrolled:function(e){if(this.cp=this.getCurrentPoint(this.mouseX,this.mouseY),this.cp){var t=this.points.indexOf(this.cp);this.weights.length>t&&(this.weights[t]+=.1*e,this.weights[t]<0&&(this.weights[t]=0)),t=this.points.indexOf(this.cp,t+1),t!==-1&&this.weights.length>t&&(this.weights[t]+=.1*e,this.weights[t]<0&&(this.weights[t]=0)),this.redraw()}},setKeyboardValues:function(e){e.ctrlKey||e.metaKey||e.altKey||e.preventDefault(),this.key=e.key,this.keyCode=e.code},setMouseValues:function(e){var t=this.cvs.getBoundingClientRect();this.mouseX=e.clientX-t.left,this.mouseY=e.clientY-t.top},size:function(e,t){this.width=0|e,this.height=0|(t||e),this.cvs.width=this.width,this.cvs.height=this.height,this.ctx=this.cvs.getContext("2d")},redraw:function(){this.draw()},clear:function(){this.ctx.clearRect(0,0,this.width,this.height)},grid:function(e){e=(0|(e||10))+.5,this.stroke(200,200,220);for(var t=e;t<this.width-1;t+=e)this.line(t,0,t,this.height);for(var n=e;n<this.height-1;n+=e)this.line(0,n,this.width,n)},circle:function(e,t,n){var r=this.ctx;r.beginPath(),r.moveTo(e,t),r.arc(e,t,n,0,2*Math.PI),r.stroke(),r.closePath()},line:function(e,t,n,r){var i=this.ctx;i.beginPath(),i.moveTo(e,t),i.lineTo(n,r),i.stroke(),i.closePath()},stroke:function(e,t,n,r){return"string"==typeof e?this.ctx.strokeStyle=e:(void 0===t&&(t=e,n=e),void 0===r&&(r=1),void(this.ctx.strokeStyle=this.rgba(e,t,n,r)))},noStroke:function(){this.ctx.strokeStyle="none"},fill:function(e,t,n,r){return"string"==typeof e?this.ctx.fillStyle=e:(void 0===t&&(t=e,n=e),void 0===r&&(r=1),void(this.ctx.fillStyle=this.rgba(e,t,n,r)))},noFill:function(){this.ctx.fillStyle="none"},rgba:function(e,t,n,r){return"rgba("+e+","+t+","+n+","+r+")"},beginPath:function(){this.ctx.beginPath(),this.bp=!0},vertex:function(e,t){return this.bp?(this.ctx.moveTo(e,t),void(this.bp=!1)):this.ctx.lineTo(e,t)},endPath:function(){this.ctx.stroke(),this.ctx.closePath()}});e.exports=a},function(e,t,n){"use strict";var r=n(4),i=r.createClass({displayName:"Footer",render:function(){return r.createElement("footer",{className:"copyright"},'This article is © 2011-2016 to me, Mike "Pomax" Kamermans, but the text, code, and images are ',r.createElement("a",{href:"https://github.com/Pomax/bezierinfo/blob/gh-pages/LICENSE.md"},"almost no rights reserved"),". Go do something cool with it!")}});e.exports=i},function(e,t,n){"use strict";var r=n(4),i=n(114),a=n(38),o=function(e){return Object.keys(a).map(e)},s=o(function(e,t){var n=a[e];return r.createElement(n,{key:e,name:e,number:t})}),l=r.createClass({displayName:"FullArticle",render:function(){return r.createElement(i,null,s)}});e.exports=l},function(e,t,n){"use strict";var r=n(4),i={render:function(){return r.createElement("figure",{className:!!this.props.inline&&"inline"},r.createElement("canvas",{ref:"canvas",tabIndex:"0",style:{width:this.panelCount*this.defaultWidth+"px",height:this.defaultHeight+"px"},onMouseDown:this.mouseDown,onMouseMove:this.mouseMove,onMouseUp:this.mouseUp,onClick:this.onClick,onKeyUp:this.onKeyUp,onKeyDown:this.onKeyDown,onKeyPress:this.onKeyPress}),r.createElement("figcaption",null,this.props.title," ",this.props.children))},componentDidMount:function(){var e=this.refs.canvas,t=this.getPixelRatio();e.width=this.defaultWidth*t,e.height=this.defaultHeight*t,this.cvs=e;var r=e.getContext("2d");if(this.ctx=r,this.ctx.scale(t,t),this.props.paperjs){var i=this.Paper=n(106);i.setup(e)}this.props.setup&&this.props.setup(this),this.props.draw&&this.props.draw(this,this.curve),this.props.autoplay&&this.play()}},a=n(118);Object.keys(a).forEach(function(e){i[e]=a[e]}),e.exports=r.createClass(i)},function(e,t,n){"use strict";var r=n(4),i=r.createClass({displayName:"Header",render:function(){return r.createElement("header",null,r.createElement("h1",null,"A Primer on Bézier Curves"),r.createElement("h2",null,"A free, online book for when you really need to know how to do Bézier things."))}});e.exports=i},function(e,t,n){"use strict";var r=n(4),i=r.createClass({displayName:"KnotController",getInitialState:function(){return{owner:!1,knots:[]}},bindKnots:function(e,t){this.setState({owner:e,knots:t})},render:function(){var e=this,t="range",n=0,i=this.state.knots.length,a=1;return r.createElement("section",{className:"knot-controls"},r.createElement("h2",null,"knot values"),this.state.knots.map(function(o,s){var l={type:t,min:n,max:i,step:a,value:o,onChange:function(t){var n=e.state.knots;n[s]=t.target.value,e.setState({knots:n},function(){e.state.owner.redraw()})}};return r.createElement("div",{key:"knot"+s},n,r.createElement("input",l),i," (= ",o,")")}))}});e.exports=i},function(e,t,n){"use strict";var r=n(4),i=n(97),a=i.Link,o=n(38),s=Object.keys(o),l=n(64),c=r.createClass({displayName:"Navigation",generateNavItem:function(e,t){var n=o[e],i=n.getDefaultProps().title,c=l.locale;"undefined"!=typeof window&&window.location.toString().indexOf(c)===-1&&(c="");var u=(c?"./"+c+"/":".")+"#"+e,h=r.createElement("a",{href:u},i);this.props.fullNav&&(h=r.createElement(a,{to:e},i));var d=s.length-1;return t===d&&(t=null),r.createElement("li",{key:e,"data-number":t},h)},generateNav:function(){return this.props.compact?null:r.createElement("div",{ref:"navigation"},r.createElement("navigation",{className:this.props.compact?"compact":null},r.createElement("ul",{className:"navigation"},s.map(this.generateNavItem))))},render:function(){return this.generateNav()}});e.exports=c},function(e,t,n){"use strict";var r=n(4),i=n(116),a=n(111),o=n(115),s=n(120).LocaleSwitcher,l=n(113),c=n(108),u=r.createClass({displayName:"Page",renderCompactContent:function(e){return r.createElement("div",null,r.createElement(o,{prev:this.props.prev,next:this.props.next,position:"before"}),this.props.children,r.createElement(o,{prev:this.props.prev,next:this.props.next,position:"after"}))},renderCompactRoot:function(e){return r.createElement("div",null,this.props.children,e)},renderPageContent:function(e){return r.createElement("div",null,r.createElement(s,null),e,this.props.children)},render:function(){var e,t=this.props.compact,n="/"===this.props.name,o=r.createElement(l,{compact:t&&!n});return e=t?n?this.renderCompactRoot(o):this.renderCompactContent(o):this.renderPageContent(o),r.createElement("div",null,r.createElement(i,null),r.createElement(a,null),e,r.createElement(c,null))}});e.exports=u},function(e,t,n){"use strict";var r=n(4),i=n(97),a=i.Link,o=n(38),s=Object.keys(o),l=r.createClass({displayName:"Relatives",getInitialState:function(){var e=this.props.prev;e=e>-1&&{to:s[e],title:o[s[e]].getDefaultProps().title};var t=this.props.next;return t=t<s.length&&{to:s[t],title:o[s[t]].getDefaultProps().title},{prev:e,next:t}},render:function(){return this.props.prev||this.props.next?r.createElement("table",{className:"relatives "+this.props.position},r.createElement("tbody",null,r.createElement("tr",null,r.createElement("td",null,this.state.prev?r.createElement(a,{className:"prev",to:this.state.prev.to},this.props.prev+". "+this.state.prev.title):null),r.createElement("td",{className:"toc"},r.createElement(a,{to:"/"},"ToC")),r.createElement("td",null,this.state.next?r.createElement(a,{className:"next",to:this.state.next.to},this.props.next+". "+this.state.next.title):null)))):null}});e.exports=l},function(e,t,n){"use strict";var r=n(4),i=r.createClass({displayName:"Ribbon",getInitialState:function(){return{href:"http://github.com/pomax/BezierInfo-2"}},render:function(){return r.createElement("div",{className:"ribbon"},r.createElement("img",{src:"images/ribbon.png",alt:"This page on GitHub",style:{border:"none"},useMap:"#githubmap", +width:"200px",height:"149px"}),r.createElement("map",{name:"githubmap"},r.createElement("area",{shape:"poly",coords:"30,0, 200,0, 200,114",href:this.state.href,alt:"This page on GitHub"})))}});e.exports=i},function(e,t,n){"use strict";var r=n(4),i=r.createClass({displayName:"WeightController",getInitialState:function(){return{owner:!1,weights:[],closed:!1}},bindWeights:function(e,t,n){this.setState({owner:e,weights:t,closed:n})},render:function(){var e=this,t="range",n=0,i=this.state.weights.length,a=1,o=this.state.closed,s=this.state.weights.length;return o!==!1&&(s-=o),r.createElement("section",{className:"knot-controls"},r.createElement("h2",null,"weight values"),this.state.weights.map(function(l,c){if(o&&c>=s)return null;var u={type:t,min:n,max:i,step:a,value:l,onChange:function(t){var n=e.state.weights;n[c]=t.target.value,o&&c<o&&(n[c+s]=t.target.value),e.setState({weights:n},function(){e.state.owner.redraw()})}};return r.createElement("div",{key:"knot"+c},n,r.createElement("input",u),i," (= ",l,")")}))}});e.exports=i},function(e,t,n){"use strict";var r="undefined"!=typeof window,i=n(207),a=n(205),o=function(e){e=e||window.event;var t=e.target||e.srcElement,n=t.getBoundingClientRect();e.offsetX=e.clientX-n.left,e.offsetY=e.clientY-n.top},s={Paper:!1,defaultWidth:275,defaultHeight:275,panelCount:1,Bezier:a,utils:a.getUtils(),curve:!1,mx:0,my:0,cx:0,cy:0,mp:!1,offset:{x:0,y:0},lpts:[],colorSeed:0,playing:!1,frame:0,playinterval:33,animate:function(){this.playing&&(this.frame++,setTimeout(this.animate,this.playinterval),this.props.draw(this,this.curve))},getFrame:function(){return this.frame},getPlayInterval:function(){return this.playinterval},play:function(){this.playing=!0,this.animate()},pause:function(){this.playing=!1},redraw:function(){this.props.draw&&this.props.draw(this,this.curve)},mouseDown:function(e){var t=this;o(e),this.mx=e.offsetX,this.my=e.offsetY,this.movingPoint=!1,this.dragging=!1,this.down=!0,this.lpts.forEach(function(e,n){Math.abs(t.mx-e.x)<10&&Math.abs(t.my-e.y)<10&&(t.movingPoint=!0,t.mp=e,t.mp_idx=n,t.cx=e.x,t.cy=e.y)}),this.props.onMouseDown&&this.props.onMouseDown(e,this),"setCapture"in e.target&&e.target.setCapture()},mouseMove:function(e){if(o(e),!this.props.static){this.down&&(this.dragging=!0);var t=!1;if(this.lpts.forEach(function(n){var r=e.offsetX,i=e.offsetY;Math.abs(r-n.x)<10&&Math.abs(i-n.y)<10&&(t=t||!0)}),this.cvs.style.cursor=t?"pointer":"default",this.hover={x:e.offsetX,y:e.offsetY},this.movingPoint)if(this.ox=e.offsetX-this.mx,this.oy=e.offsetY-this.my,this.mp.x=Math.max(0,Math.min(this.defaultWidth,this.cx+this.ox)),this.mp.y=Math.max(0,Math.min(this.defaultHeight,this.cy+this.oy)),this.curve.forEach){for(var n,r,i=0;i<this.curve.length;i++)if(n=this.curve[i],r=n.points,r.indexOf(this.mp)>-1){n.update();break}}else this.curve&&this.curve.update&&this.curve.update()}this.props.onMouseMove&&this.props.onMouseMove(e,this),this.dragging&&this.props.onMouseDrag&&this.props.onMouseDrag(e,this),this.props.static||this.playing||!this.props.draw||this.props.draw(this,this.curve)},mouseUp:function(e){return this.down=!1,this.movingPoint?(this.movingPoint=!1,this.mp=!1,void(this.props.onMouseUp&&this.props.onMouseUp(e,this))):void(this.props.onMouseUp&&this.props.onMouseUp(e,this))},onClick:function(e){o(e),this.mx=e.offsetX,this.my=e.offsetY,!this.dragging&&this.props.onClick&&this.props.onClick(e,this)},onKeyUp:function(e){this.props.onKeyUp&&(this.props.onKeyUp(e,this),!this.playing&&this.props.draw&&this.props.draw(this,this.curve))},onKeyDown:function(e){this.props.onKeyDown&&(this.props.onKeyDown(e,this),!this.playing&&this.props.draw&&this.props.draw(this,this.curve))},onKeyPress:function(e){this.props.onKeyPress&&(this.props.onKeyPress(e,this),!this.playing&&this.props.draw&&this.props.draw(this,this.curve))},reset:function(){this.refs.canvas.width=this.refs.canvas.width,this.ctx.strokeStyle="black",this.ctx.lineWidth=1,this.ctx.fillStyle="none";var e=this.getPixelRatio();this.ctx.scale(e,e),this.offset={x:0,y:0},this.colorSeed=0},setSize:function(e,t){this.defaultWidth=e,this.defaultHeight=t;var n=this.refs.canvas;n.style.width=this.panelCount*e+"px",n.style.height=t+"px";var r=this.getPixelRatio();n.width=this.panelCount*e*r,n.height=t*r,this.ctx.scale(r,r)},setCurves:function(e){this.setCurve(e)},setCurve:function(e){var t=[];e=e instanceof Array?e:Array.prototype.slice.call(arguments),e.forEach(function(e){t=t.concat(e.points)}),this.curve=1===e.length?e[0]:e,this.lpts=t},getPanelWidth:function(){return this.defaultWidth},getPanelHeight:function(){return this.defaultHeight},getDefaultQuadratic:function(){return new this.Bezier(70,250,20,110,250,60)},getDefaultCubic:function(){return new this.Bezier(120,160,35,200,220,260,220,40)},getPixelRatio:function(){return window.devicePixelRatio||1},toImage:function(){var e=this.refs.canvas.toDataURL(),t=new Image;return t.src=e,t.devicePixelRatio=this.getPixelRatio(),t},setPanelCount:function(e){this.panelCount=e;var t=this.refs.canvas;t.width=e*this.defaultWidth*this.getPixelRatio(),t.style.width=e*this.defaultWidth+"px"},setOffset:function(e){this.offset=e},setColor:function(e){this.ctx.strokeStyle=e},getColor:function(){return this.ctx.strokeStyle||"black"},setWeight:function(e){this.ctx.lineWidth=e},noColor:function(e){this.ctx.strokeStyle="transparent"},setRandomColor:function(e){e="undefined"==typeof e?1:e;var t=this.colorSeed%360,n=1,r=.34;this.colorSeed+=87,this.ctx.strokeStyle=i.hsl(t,n,r).alpha(e).css()},setRandomFill:function(e){e="undefined"==typeof e?1:e;var t=this.colorSeed%360,n=1,r=.34;this.colorSeed+=87,this.ctx.fillStyle=i.hsl(t,n,r).alpha(e).css()},setFill:function(e){this.ctx.fillStyle=e},getFill:function(){return this.ctx.fillStyle||"transparent"},noFill:function(){this.ctx.fillStyle="transparent"},drawSkeleton:function(e,t,n){t=t||{x:0,y:0};var r=e.points;if(r.length>2){this.ctx.strokeStyle="lightgrey",this.drawLine(r[0],r[1],t);for(var i=r.length-2,a=1;a<i;a++)this.drawLine(r[a],r[a+1],t);this.drawLine(r[i],r[i+1],t)}this.ctx.strokeStyle="black",this.drawPoints(r,t),n||this.drawCoordinates(e,t)},drawGrid:function(e,t,n){var r,i,a,o,s,l,c=this.defaultWidth,u=this.defaultHeight,h=c/e,d=h/2,f=u/t,p=f/2;for(r=0;r<e;r++)i=d+r*h,s={x:i,y:0},l={x:i,y:u},this.drawLine(s,l,n);for(a=0;a<t;a++)o=p+a*f,s={x:0,y:o},l={x:c,y:o},this.drawLine(s,l,n)},drawHull:function(e,t,n){var r=e instanceof Array?e:e.hull(t);return 6===r.length?(this.drawLine(r[0],r[1],n),this.drawLine(r[1],r[2],n),this.drawLine(r[3],r[4],n)):(this.drawLine(r[0],r[1],n),this.drawLine(r[1],r[2],n),this.drawLine(r[2],r[3],n),this.drawLine(r[4],r[5],n),this.drawLine(r[5],r[6],n),this.drawLine(r[7],r[8],n)),r},drawCoordinates:function(e,t){var n=this;t=t||{x:0,y:0};var r=e.points;this.setFill("black"),r.forEach(function(e){n.text("("+e.x+","+e.y+")",{x:e.x+t.x+5,y:e.y+t.y+10})})},drawFunction:function(e,t){var n,r,i=e.start||0,a=e(i),o=e.end||1,s=e(o),l=e.step||.01,c=e.scale||1;for(r=l;r<o;r+=l)n=e(r,c),this.drawLine(a,n,t),a=n;this.drawLine(n,s,t)},drawCurve:function(e,t){var n=this;t=t||{x:0,y:0};var r=e.points;if(r.length<=3||5<=r.length){var i=e.getLUT(100),a=i[0];return void i.forEach(function(e,r){r&&(n.drawLine(a,e,t),a=e)})}var o=t.x+this.offset.x,s=t.y+this.offset.y;this.ctx.beginPath(),this.ctx.moveTo(r[0].x+o,r[0].y+s),3===r.length?this.ctx.quadraticCurveTo(r[1].x+o,r[1].y+s,r[2].x+o,r[2].y+s):4===r.length&&this.ctx.bezierCurveTo(r[1].x+o,r[1].y+s,r[2].x+o,r[2].y+s,r[3].x+o,r[3].y+s),this.ctx.stroke(),this.ctx.closePath()},drawLine:function(e,t,n){n=n||{x:0,y:0};var r=n.x+this.offset.x,i=n.y+this.offset.y;this.ctx.beginPath(),this.ctx.moveTo(e.x+r,e.y+i),this.ctx.lineTo(t.x+r,t.y+i),this.ctx.stroke()},drawPoint:function(e,t){this.drawCircle(e,1,t)},drawPoints:function(e,t){t=t||{x:0,y:0},e.forEach(function(e){this.drawCircle(e,0!==t.x||0!==t.y?1.5:3,t)}.bind(this))},drawArc:function(e,t){t=t||{x:0,y:0};var n=t.x+this.offset.x,r=t.y+this.offset.y;this.ctx.beginPath(),this.ctx.moveTo(e.x+n,e.y+r),this.ctx.arc(e.x+n,e.y+r,e.r,e.s,e.e),this.ctx.lineTo(e.x+n,e.y+r),this.ctx.fill(),this.ctx.stroke()},drawCircle:function(e,t,n){n=n||{x:0,y:0};var r=n.x+this.offset.x,i=n.y+this.offset.y;this.ctx.beginPath(),this.ctx.arc(e.x+r,e.y+i,t,0,2*Math.PI),this.ctx.stroke()},drawbbox:function(e,t){t=t||{x:0,y:0};var n=t.x+this.offset.x,r=t.y+this.offset.y;this.ctx.beginPath(),this.ctx.moveTo(e.x.min+n,e.y.min+r),this.ctx.lineTo(e.x.min+n,e.y.max+r),this.ctx.lineTo(e.x.max+n,e.y.max+r),this.ctx.lineTo(e.x.max+n,e.y.min+r),this.ctx.closePath(),this.ctx.stroke()},drawRect:function(e,t,n){n=n||{x:0,y:0};var r=n.x+this.offset.x,i=n.y+this.offset.y,a=e.x+r,o=e.y+i,s=t.x-e.x,l=t.y-e.y;this.ctx.beginPath(),this.ctx.moveTo(a,o),this.ctx.lineTo(a+s,o),this.ctx.lineTo(a+s,o+l),this.ctx.lineTo(a,o+l),this.ctx.closePath(),this.ctx.fill(),this.ctx.stroke()},drawPath:function(e,t){var n=this;t=t||{x:0,y:0};var r=t.x+this.offset.x,i=t.y+this.offset.y;this.ctx.beginPath(),e.forEach(function(e,t){return 0===t?n.ctx.moveTo(e.x+r,e.y+i):void n.ctx.lineTo(e.x+r,e.y+i)}),closed&&this.ctx.closePath(),this.ctx.fill(),this.ctx.stroke()},drawShape:function(e,t){t=t||{x:0,y:0};var n=t.x+this.offset.x,r=t.y+this.offset.y,i=e.forward.points.length-1;this.ctx.beginPath(),this.ctx.moveTo(n+e.startcap.points[0].x,r+e.startcap.points[0].y),this.ctx.lineTo(n+e.startcap.points[3].x,r+e.startcap.points[3].y),3===i?this.ctx.bezierCurveTo(n+e.forward.points[1].x,r+e.forward.points[1].y,n+e.forward.points[2].x,r+e.forward.points[2].y,n+e.forward.points[3].x,r+e.forward.points[3].y):this.ctx.quadraticCurveTo(n+e.forward.points[1].x,r+e.forward.points[1].y,n+e.forward.points[2].x,r+e.forward.points[2].y),this.ctx.lineTo(n+e.endcap.points[3].x,r+e.endcap.points[3].y),3===i?this.ctx.bezierCurveTo(n+e.back.points[1].x,r+e.back.points[1].y,n+e.back.points[2].x,r+e.back.points[2].y,n+e.back.points[3].x,r+e.back.points[3].y):this.ctx.quadraticCurveTo(n+e.back.points[1].x,r+e.back.points[1].y,n+e.back.points[2].x,r+e.back.points[2].y),this.ctx.closePath(),this.ctx.fill(),this.ctx.stroke()},text:function(e,t,n){n=n||{x:0,y:0},this.offset&&(n.x+=this.offset.x,n.y+=this.offset.y),this.ctx.fillText(e,t.x+n.x,t.y+n.y)},image:function(e,t){var n=this;t=t||{x:0,y:0},this.offset&&(t.x+=this.offset.x,t.y+=this.offset.y);var r=e.devicePixelRatio||1;e.loaded?this.ctx.drawImage(e,t.x,t.y,e.width/r,e.height/r):e.onload=function(){e.loaded=!0,n.ctx.drawImage(e,t.x,t.y,e.width/r,e.height/r)}},drawAxes:function(e,t,n,r,i,a,o,s){s=s||{x:0,y:0};var l=this.getPanelWidth();this.drawLine({x:e,y:e},{x:l-e,y:e},s),this.drawLine({x:e,y:e},{x:e,y:l-e},s),this.setFill("black"),this.text(t+" →",{x:s.x+l/2,y:s.y+15}),this.text(n,{x:s.x+e,y:s.y+15}),this.text(r,{x:s.x+l-e,y:s.y+15}),this.text(i,{x:s.x+5,y:s.y+l/2-e}),this.text("↓",{x:s.x+5,y:s.y+l/2}),this.text(a,{x:s.x+4,y:s.y+e+5}),this.text(o,{x:s.x+2,y:s.y+l-e+10})}};r&&(window["Bezier Graphics API"]=s),e.exports=s},function(e,t,n){"use strict";var r=n(4),i=n(63),a=new i,o="locale-switcher";e.exports=function(e){return r.createElement("div",{className:"locale-switcher"},a.getContent(o,this))}},function(e,t,n){"use strict";e.exports={LocaleSwitcher:n(119)}},function(e,t,n){"use strict";e.exports={onClick:function(e,t){t.t=t.curve.on({x:e.offsetX,y:e.offsetY},7),(t.t<.05||t.t>.95)&&(t.t=!1),t.redraw()},setupQuadratic:function(e){var t=e.getDefaultQuadratic();t.points[0].y-=10,e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();t.points[2].y-=20,e.setCurve(t),e.lut=t.getLUT(100)},draw:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n=e.getPanelHeight();if(e.setColor("black"),e.t){e.drawCircle(e.curve.get(e.t),3),e.setColor("lightgrey");var r,i,a,o=e.drawHull(t,e.t),s=e.utils;6===o.length?(r=t.points[1],i=o[5],a=s.lli4(r,i,t.points[0],t.points[2]),e.setColor("lightgrey"),e.drawLine(t.points[0],t.points[2])):10===o.length&&(r=o[5],i=o[9],a=s.lli4(r,i,t.points[0],t.points[3]),e.setColor("lightgrey"),e.drawLine(t.points[0],t.points[3])),e.setColor("#00FF00"),e.drawLine(r,i),e.setColor("red"),e.drawLine(i,a),e.setColor("black"),e.drawCircle(a,3),e.setFill("black"),e.text("A",{x:10+r.x,y:r.y}),e.text("B (t = "+e.utils.round(e.t,2)+")",{x:10+i.x,y:i.y}),e.text("C",{x:10+a.x,y:a.y});var l=s.dist(r,i),c=s.dist(i,a),u=l/c;e.text("d1 (A-B): "+s.round(l,2)+", d2 (B-C): "+s.round(c,2)+", ratio (d1/d2): "+s.round(u,4),{x:10,y:n-7})}},setCT:function(e,t){t.t=e.offsetX/t.getPanelWidth()},drawCTgraph:function(e){e.reset(),e.setColor("black");var t=e.getPanelWidth(),n=20,r=t-2*n;e.drawAxes(n,"t",0,1,"u",0,1),e.setColor("blue");var i=function(t){var i=e.u(t),a={x:n+t*r,y:n+i*r};return a};if(e.drawFunction(i),e.t){var a=e.u(e.t),o=e.utils.round(a,3),s=e.utils.round(1-a,3),l=i(e.t);e.drawLine({x:l.x,y:n},l),e.drawLine({x:n,y:l.y},l),e.drawCircle(l,3),e.setFill("blue"),e.text(" t = "+e.utils.round(e.t,3),{x:l.x+10,y:l.y-7}),e.text("u(t) = "+e.utils.round(a,3),{x:l.x+10,y:l.y+7}),e.setFill("black"),e.text("C = "+o+" * start + "+s+" * end",{x:t/2-n,y:n+r})}},drawQCT:function(e){e.u=e.u||function(e){var t=(e-1)*(e-1),n=2*e*e-2*e+1;return t/n},this.drawCTgraph(e)},drawCCT:function(e){e.u=e.u||function(e){var t=(1-e)*(1-e)*(1-e),n=e*e*e+t;return t/n},this.drawCTgraph(e)}}},function(e,t,n){"use strict";var r=n(121),i=n(0);e.exports=i("abc",r)},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},align:function(e,t){var n=t.p1.x,r=t.p1.y,i=-Math.atan2(t.p2.y-r,t.p2.x-n),a=Math.cos,o=Math.sin,s=function(e){return{x:(e.x-n)*a(i)-(e.y-r)*o(i),y:(e.x-n)*o(i)+(e.y-r)*a(i)}};return e.map(s)},draw:function(e,t){e.setPanelCount(2),e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n=t.points,r={p1:n[0],p2:n[n.length-1]},i=this.align(n,r),a=new e.Bezier(i),o=e.getPanelWidth(),s=e.getPanelHeight(),l={x:o,y:0};e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:s},l),l.x+=o/4,l.y+=s/2,e.setColor("grey"),e.drawLine({x:0,y:-s/2},{x:0,y:s/2},l),e.drawLine({x:-o/4,y:0},{x:o,y:0},l),e.setFill("grey"),e.setColor("black"),e.drawSkeleton(a,l),e.drawCurve(a,l)}}},function(e,t,n){"use strict";var r=n(123),i=n(0);e.exports=i("aligning",r)},function(e,t,n){"use strict";var r=Math.atan2,i=Math.PI,a=2*i,o=Math.cos,s=Math.sin;e.exports={statics:{keyHandlingOptions:{propName:"error",values:{38:.1,40:-.1},controller:function(e){e.error<.1&&(e.error=.1)}}},setupCircle:function(e){var t=new e.Bezier(70,70,140,40,240,130);e.setCurve(t)},setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.error=.5},getCCenter:function(e,t,n,l){var c,u=n.x-t.x,h=n.y-t.y,d=l.x-n.x,f=l.y-n.y,p=u*o(i/2)-h*s(i/2),m=u*s(i/2)+h*o(i/2),g=d*o(i/2)-f*s(i/2),v=d*s(i/2)+f*o(i/2),w=(t.x+n.x)/2,y=(t.y+n.y)/2,b=(n.x+l.x)/2,_=(n.y+l.y)/2,x=w+p,E=y+m,C=b+g,k=_+v,S=e.utils.lli8(w,y,x,E,b,_,C,k),P=e.utils.dist(S,t),T=r(t.y-S.y,t.x-S.x),M=r(n.y-S.y,n.x-S.x),N=r(l.y-S.y,l.x-S.x);return T<N?((T>M||M>N)&&(T+=a),T>N&&(c=N,N=T,T=c)):N<M&&M<T?(c=N,N=T,T=c):N+=a,S.s=T,S.e=N,S.r=P,S},drawCircle:function(e,t){e.reset();var n=t.points,r=this.getCCenter(e,n[0],n[1],n[2]);e.setColor("grey"),e.drawCircle(r,e.utils.dist(r,n[0])),e.setColor("black"),n.forEach(function(t){return e.drawCircle(t,3)});var i;e.setColor("blue"),e.drawLine(n[0],n[1]),i={x:(n[0].x+n[1].x)/2,y:(n[0].y+n[1].y)/2},e.drawLine(i,{x:r.x+(r.x-i.x),y:r.y+(r.y-i.y)}),e.setColor("red"),e.drawLine(n[1],n[2]),i={x:(n[1].x+n[2].x)/2,y:(n[1].y+n[2].y)/2},e.drawLine(i,{x:r.x+(r.x-i.x),y:r.y+(r.y-i.y)}),e.setColor("green"),e.drawLine(n[2],n[0]),i={x:(n[2].x+n[0].x)/2,y:(n[2].y+n[0].y)/2},e.drawLine(i,{x:r.x+(r.x-i.x),y:r.y+(r.y-i.y)}),e.setColor("black"),e.drawPoint(r),e.setFill("black"),e.text("Intersection point",r,{x:-25,y:10})},drawSingleArc:function(e,t){e.reset();var n=t.arcs(e.error);e.drawSkeleton(t),e.drawCurve(t);var r=n[0];e.setColor("red"),e.setFill("rgba(255,0,0,0.2)"),e.debug=!0,e.drawArc(r),e.setFill("black"),e.text("Arc approximation with total error "+e.utils.round(e.error,1),{x:10,y:15})},drawArcs:function(e,t){e.reset();var n=t.arcs(e.error);e.drawSkeleton(t),e.drawCurve(t),n.forEach(function(t){e.setRandomColor(.3),e.setFill(e.getColor()),e.drawArc(t)}),e.setFill("black"),e.text("Arc approximation with total error "+e.utils.round(e.error,1)+" per arc segment",{x:10,y:15})}}},function(e,t,n){"use strict";var r=n(125),i=n(0),a=n(13);e.exports=a(i("arcapproximation",r))},function(e,t,n){"use strict";var r=Math.sin,i=2*Math.PI;e.exports={setup:function(e){var t,n=e.getPanelWidth(),a=e.getPanelHeight();this.generator||(t=function(e,t){return t=t||1,{x:e*n/i,y:t*r(e)}},t.start=0,t.end=i,t.step=.1,t.scale=a/3,this.generator=t)},drawSine:function(e,t){var n=e.getPanelWidth(),r=e.getPanelHeight(),i=this.generator;i.dheight=t,e.setColor("black"),e.drawLine({x:0,y:r/2},{x:n,y:r/2}),e.drawFunction(i,{x:0,y:r/2})},drawSlices:function(e,t){var n=e.getPanelWidth(),r=e.getPanelHeight(),a=n/i,o=0,s=t<=25?1:0;e.reset(),e.setColor("transparent"),e.setFill("rgba(150,150,255, 0.4)");for(var l,c,u,h=i/t,d=h/2;d<i+h/2;d+=h)l=this.generator(d),c={x:l.x-a*h/2+s,y:0},u={x:l.x+a*h/2-s,y:l.y*this.generator.scale},s||e.setFill("rgba(150,150,255,"+(.4+.3*Math.random())+")"),e.drawRect(c,u,{x:0,y:r/2}),o+=h*Math.abs(l.y*this.generator.scale);e.setFill("black");var f=(400*r/3|0)/100,p=(100*o|0)/100;e.text("Approximating with "+t+" strips (true area: "+f+"): "+p,{x:10,y:r-15})},drawCoarseIntegral:function(e){e.reset(),this.drawSlices(e,10),this.drawSine(e)},drawFineIntegral:function(e){e.reset(),this.drawSlices(e,24),this.drawSine(e)},drawSuperFineIntegral:function(e){e.reset(),this.drawSlices(e,99),this.drawSine(e)},setupCurve:function(e){var t=e.getDefaultCubic();e.setCurve(t)},drawCurve:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n=t.length();e.setFill("black"),e.text("Curve length: "+n+" pixels",{x:10,y:15})}}},function(e,t,n){"use strict";var r=n(127),i=n(0);e.exports=i("arclength",r)},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"steps",values:{38:1,40:-1},controller:function(e){e.steps<1&&(e.steps=1)}}},setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t),e.steps=10},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.steps=16},draw:function(e,t){e.reset(),e.drawSkeleton(t);for(var n,r=t.getLUT(e.steps),i=1/e.steps,a=t.points[0],o=i;o<1+i;o+=i)n=t.get(Math.min(o,1)),e.setColor("red"),e.drawLine(a,n),a=n;for(var s,l,c,u=t.length(),h=0,d=0;d<r.length-1;d++)a=r[d],s=r[d+1],l=s.x-a.x,c=s.y-a.y,h+=Math.sqrt(l*l+c*c);h=(100*h|0)/100,u=(100*u|0)/100,e.text("Approximate length, "+e.steps+" steps: "+h+" (true: "+u+")",{x:10,y:15})}}},function(e,t,n){"use strict";var r=n(129),i=n(0),a=n(13);e.exports=a(i("arclengthapprox",r))},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},draw:function(e,t){e.reset(),e.setColor("#00FF00"),e.drawbbox(t.bbox()),e.setColor("black"),e.drawSkeleton(t),e.drawCurve(t),e.setColor("red"),t.extrema().values.forEach(function(n){e.drawCircle(t.get(n),3)})}}},function(e,t,n){"use strict";var r=n(131),i=n(0);e.exports=i("boundingbox",r)},function(e,t,n){"use strict";e.exports={degree:3,activeDistance:9,setup:function(){this.size(600,300),this.draw()},draw:function(){var e=this;this.clear(),this.grid(25);var t=this.points[0];this.points.forEach(function(n){e.stroke(200),e.line(n.x,n.y,t.x,t.y),t=n,e.stroke(0),e.circle(t.x,t.y,4)}),this.drawSplineData()},drawSplineData:function(){if(!(this.points.length<=this.degree)){var e=this.points.map(function(e){return[e.x,e.y]});this.drawCurve(e),this.drawKnots(e)}}}},function(e,t,n){"use strict";e.exports={degree:3,activeDistance:9,setup:function(){this.size(400,400);for(var e=2*Math.PI,t=0;t<e;t+=e/9)this.points.push({x:this.width/2+100*Math.cos(t),y:this.height/2+100*Math.sin(t)});this.knots=this.formKnots(this.points);var n=0|Math.round(this.points.length/2);this.knots[n+0]=this.knots[n],this.knots[n+1]=this.knots[n],this.knots[n+2]=this.knots[n];for(var r=n+3;r<this.knots.length;r++)this.knots[r]=this.knots[r-1]+1;this.props.controller&&this.props.controller(this,this.knots),this.draw()},draw:function(){var e=this;this.clear(),this.grid(25);var t=this.points[0];this.points.forEach(function(n){e.stroke(200),e.line(n.x,n.y,t.x,t.y),t=n,e.stroke(0),e.circle(t.x,t.y,4)}),this.drawSplineData()},drawSplineData:function(){if(!(this.points.length<=this.degree)){var e=this.points.map(function(e){return[e.x,e.y]});this.drawCurve(e),this.drawKnots(e)}}}},function(e,t,n){"use strict";e.exports={basicSketch:n(133),interpolationGraph:n(137),uniformBSpline:n(140),centerCutBSpline:n(134),openUniformBSpline:n(138),rationalUniformBSpline:n(139),bindKnots:function(e,t,n){this.refs[n].bindKnots(e,t)},bindWeights:function(e,t,n,r){this.refs[r].bindWeights(e,t,n)}}},function(e,t,n){"use strict";var r=n(135),i=n(0);e.exports=i("bsplines",r)},function(e,t,n){"use strict";var r=["#C00","#CC0","#0C0","#0CC","#00C","#C0C","#600","#660","#060","#066","#006","#606"];e.exports={degree:3,activeDistance:9,cache:{N:[]},setup:function(){this.size(600,300),this.points=[{x:0,y:0},{x:100,y:-100},{x:200,y:100},{x:300,y:-100},{x:400,y:100},{x:500,y:0}],this.knots=this.formKnots(this.points),this.props.controller&&this.props.controller(this,this.knots),this.draw()},draw:function(){this.clear();var e=25;this.grid(e),this.stroke(0),this.line(e,0,e,this.height);var t=this.height-e;this.line(0,t,this.width,t);for(var n=this.degree,r=this.points.length||4,i=0;i<r+1+n;i++)this.drawN(i,n,e,(this.width-e)/(2*(r+2)),this.height-2*e)},drawN:function(e,t,n,i,a){this.stroke(r[e]);this.knots;this.beginPath();for(var o=e-1,s=o,l=.1,c=e+t+1;s<c;s+=l){var u=n+e*i+s*i,h=this.height-n-this.N(e,t,s)*a;this.vertex(u,h)}this.endPath()},N:function(e,t,n){var r=this.knots[e],i=this.knots[e+1],a=this.knots[e+t-1],o=this.knots[e+t];if(1===t)return r<=n&&n<=i?1:0;var s=n-r,l=a-r,c=0===l?0:s/l,u=o-n,h=o-i,d=0===h?0:u/h,f=0;if(0!==c){var p=this.ensureN(e,t-1,n);f=void 0===p?this.N(e,t-1,n):p}var m=0;if(0!==d){var g=this.ensureN(e+1,t-1,n);m=void 0===g?this.N(e+1,t-1,n):g}return this.cacheN(e,t,n,c*f+d*m),this.cache.N[e][t][n]},ensureN:function(e,t,n){this.cache.N||(this.cache.N=[]);var r=this.cache.N;return r[e]||(r[e]=[]),r[e][t]||(r[e][t]=[]),r[e][t][n]},cacheN:function(e,t,n,r){this.ensureN(e,t,n),this.cache.N[e][t][n]=r}}},function(e,t,n){"use strict";e.exports={degree:3,activeDistance:9,setup:function(){this.size(400,400);for(var e=2*Math.PI,t=0;t<e;t+=e/10)this.points.push({x:this.width/2+100*Math.cos(t),y:this.height/2+100*Math.sin(t)});this.knots=this.formKnots(this.points,!0),this.props.controller&&this.props.controller(this,this.knots),this.draw()},draw:function(){var e=this;this.clear(),this.grid(25);var t=this.points[0];this.points.forEach(function(n){e.stroke(200),e.line(n.x,n.y,t.x,t.y),t=n,e.stroke(0),e.circle(t.x,t.y,4)}),this.drawSplineData()},drawSplineData:function(){if(!(this.points.length<=this.degree)){var e=this.points.map(function(e){return[e.x,e.y]});this.drawCurve(e),this.drawKnots(e)}}}},function(e,t,n){"use strict";e.exports={degree:3,activeDistance:9,weights:[],setup:function(){this.size(400,400);for(var e=2*Math.PI,t=this.width/3,n=0;n<6;n++)this.points.push({x:this.width/2+t*Math.cos(n/6*e),y:this.height/2+t*Math.sin(n/6*e)});this.points=this.points.concat(this.points.slice(0,3)),this.closed=this.degree,this.knots=this.formKnots(this.points),this.weights=this.formWeights(this.points),this.props.controller&&this.props.controller(this,this.knots,this.weights,this.closed),this.draw()},draw:function(){var e=this;this.clear(),this.grid(25);var t=this.points[0];this.points.forEach(function(n){e.stroke(200),e.line(n.x,n.y,t.x,t.y),t=n,e.stroke(0),e.circle(t.x,t.y,4)}),this.drawSplineData()},drawSplineData:function(){if(!(this.points.length<=this.degree)){var e=this.points.map(function(e){return[e.x,e.y]});this.drawCurve(e),this.drawKnots(e)}}}},function(e,t,n){"use strict";e.exports={degree:3,activeDistance:9,setup:function(){this.size(400,400);for(var e=2*Math.PI,t=0;t<e;t+=e/10)this.points.push({x:this.width/2+100*Math.cos(t),y:this.height/2+100*Math.sin(t)});this.knots=this.formKnots(this.points),this.props.controller&&this.props.controller(this,this.knots),this.draw()},draw:function(){var e=this;this.clear(),this.grid(25);var t=this.points[0];this.points.forEach(function(n){e.stroke(200),e.line(n.x,n.y,t.x,t.y),t=n,e.stroke(0),e.circle(t.x,t.y,4)}),this.drawSplineData()},drawSplineData:function(){if(!(this.points.length<=this.degree)){var e=this.points.map(function(e){return[e.x,e.y]});this.drawCurve(e),this.drawKnots(e)}}}},function(e,t,n){"use strict";e.exports={setup:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.reset(),e._map_loaded=!1},draw:function(e,t){var n=400,r=n,i=this.unit,a={x:n/2,y:r/2};e.setSize(n,r),e.setPanelCount(2),e.reset(),e.drawSkeleton(t),e.drawCurve(t),e.offset.x+=400,e._map_loaded?e.image(e._map_image):setTimeout(function(){this.drawBase(e,t),this.draw(e,t)}.bind(this),100),e.drawLine({x:0,y:0},{x:0,y:r});var o=[{x:0,y:0},{x:0,y:i},{x:i,y:i},this.forwardTransform(t.points,i)],s=new e.Bezier(o);e.setColor("blue"),e.drawCurve(s,a),e.drawCircle(o[3],3,a)},forwardTransform:function(e,t){t=t||1;var n=e[0],r=e[1],i=e[2],a=e[3],o=-n.x+a.x-(-n.x+r.x)*(-n.y+a.y)/(-n.y+r.y),s=-n.x+i.x-(-n.x+r.x)*(-n.y+i.y)/(-n.y+r.y),l=t*o/s,c=t*(-n.y+a.y)/(-n.y+r.y),u=t-t*(-n.y+i.y)/(-n.y+r.y),h=u*o/s,d=c+h;return{x:l,y:d}},drawBase:function(e,t){e.reset();var n=400,r=n,i=this.unit=n/5,a={x:n/2,y:r/2};e.setSize(n,r),e.setColor("lightgrey");for(var o=0;o<n;o+=i/2)e.drawLine({x:o,y:0},{x:o,y:r});for(var s=0;s<r;s+=i/2)e.drawLine({x:0,y:s},{x:n,y:s});e.setColor("black"),e.drawLine({x:n/2,y:0},{x:n/2,y:r}),e.drawLine({x:0,y:r/2},{x:n,y:r/2}),e.setColor("green"),e.drawLine({x:-n/2,y:i},{x:n/2,y:i},a),e.setColor("black"),e.setFill("black"),e.drawCircle({x:0,y:0},4,a),e.text("(0,0)",{x:5+a.x,y:15+a.y}),e.drawCircle({x:0,y:i},4,a),e.text("(0,1)",{x:5+a.x,y:i+15+a.y}),e.drawCircle({x:i,y:i},4,a),e.text("(1,1)",{x:i+5+a.x,y:i+15+a.y}),e.setWeight(1.5),e.setColor("#FF0000"),e.setFill(e.getColor());var l=[],c=1,u=1;for(o=-10;o<=1;o+=.01)s=(-o*o+2*o+3)/4,o>-10&&(l.push({x:i*c,y:i*u}),e.drawLine({x:i*c,y:i*u},{x:i*o,y:i*s},a)),c=o,u=s;l.push({x:i*c,y:i*u}),e.text("Curve form has cusp →",{x:n/2-2*i,y:r/2+i/2.5}),e.setColor("#FF00FF"),e.setFill(e.getColor());var h=Math.sqrt;for(o=1;o>=0;o-=.005)l.push({x:i*c,y:i*u}),s=.5*(h(3)*h(4*o-o*o)-o),e.drawLine({x:i*c,y:i*u},{x:i*o,y:i*s},a),c=o,u=s;for(l.push({x:i*c,y:i*u}),e.text("← Curve forms a loop at t = 1",{x:n/2+i/4,y:r/2+i/1.5}),e.setColor("#3300FF"),e.setFill(e.getColor()),o=0;o>-n;o-=.01)l.push({x:i*c,y:i*u}),s=(-o*o+3*o)/3,e.drawLine({x:i*c,y:i*u},{x:i*o,y:i*s},a),c=o,u=s;l.push({x:i*c,y:i*u}),e.text("← Curve forms a loop at t = 0",{x:n/2-i+10,y:r/2-1.25*i}),e.setColor("transparent"),e.setFill("rgba(255,120,100,0.2)"),e.drawPath(l,a),l=[{x:-n/2,y:i},{x:n/2,y:i},{x:n/2,y:r},{x:-n/2,y:r}],e.setFill("rgba(0,200,0,0.2)"),e.drawPath(l,a),e.setColor("black"),e.setFill(e.getColor()),e.text("← Curve form has one inflection →",{x:n/2-i,y:r/2+1.75*i}),e.text("← Plain curve ↕",{x:n/2+i/2,y:r/6}),e.text("↕ Double inflection",{x:10,y:r/2-10}),e._map_image=e.toImage(),e._map_loaded=!0}}},function(e,t,n){"use strict";var r=n(141),i=n(0);e.exports=i("canonical",r)},function(e,t,n){"use strict";var r=n(0);e.exports=r("catmullconv")},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"distance",values:{38:1,40:-1}}},setup:function(e){e.setPanelCount(3),e.lpts=[{x:56,y:153},{x:144,y:83},{x:188,y:185}],e.distance=0},convert:function(e,t,n,r){var i=.5;return[t,{x:t.x+(n.x-e.x)/(6*i),y:t.y+(n.y-e.y)/(6*i)},{x:n.x-(r.x-t.x)/(6*i),y:n.y-(r.y-t.y)/(6*i)},n]},draw:function(e){e.reset(),e.setColor("lightblue"),e.drawGrid(10,10);var t=e.lpts;e.setColor("black"),e.setFill("black"),t.forEach(function(t,n){e.drawCircle(t,3),e.text("point "+(n+1),t,{x:10,y:7})});var n=e.getPanelWidth(),r=e.getPanelHeight(),i={x:n,y:0};e.setColor("lightblue"),e.drawGrid(10,10,i),e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:r},i),t.forEach(function(t,n){e.drawCircle(t,3,i)});var a=t[0],o=t[1],s=t[2],l=s.x-a.x,c=s.y-a.y,u=Math.sqrt(l*l+c*c);l/=u,c/=u,e.drawLine(a,s,i);var h={x:a.x+(s.x-o.x)-e.distance*l,y:a.y+(s.y-o.y)-e.distance*c},d={x:a.x+(s.x-o.x)+e.distance*l,y:a.y+(s.y-o.y)+e.distance*c},f=e.utils.lli4(a,s,o,{x:(h.x+d.x)/2,y:(h.y+d.y)/2});e.setColor("blue"),e.drawCircle(f,3,i),e.drawLine(t[1],f,i),e.setColor("#666"),e.drawLine(f,h,i),e.drawLine(f,d,i),e.setFill("blue"),e.text("p0",h,{x:-20+i.x,y:i.y+2}),e.text("p4",d,{x:10+i.x,y:i.y+2}),e.setColor("red"),e.drawCircle(h,3,i),e.drawLine(o,h,i),e.drawLine(a,{x:a.x+(o.x-h.x)/5,y:a.y+(o.y-h.y)/5},i),e.setColor("#00FF00"),e.drawCircle(d,3,i),e.drawLine(o,d,i),e.drawLine(s,{x:s.x+(d.x-o.x)/5,y:s.y+(d.y-o.y)/5},i);var p=new e.Bezier(this.convert(h,a,o,s)),m=new e.Bezier(this.convert(a,o,s,d));e.setColor("lightgrey"),e.drawCurve(p,i),e.drawCurve(m,i),i.x+=n,e.setColor("lightblue"),e.drawGrid(10,10,i),e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:r},i),e.drawCurve(p,i),e.drawCurve(m,i),e.drawPoints(p.points,i),e.drawPoints(m.points,i),e.setColor("lightgrey"),e.drawLine(p.points[0],p.points[1],i),e.drawLine(p.points[2],m.points[1],i),e.drawLine(m.points[2],m.points[3],i)}}},function(e,t,n){"use strict";var r=n(144),i=n(0),a=n(13);e.exports=a(i("catmullmoulding",r))},function(e,t,n){"use strict";var r=Math.sin,i=Math.cos;e.exports={setup:function(e){e.w=e.getPanelWidth(),e.h=e.getPanelHeight(),e.pad=20,e.r=e.w/2-e.pad,e.mousePt=!1,e.angle=0;var t={x:e.w-e.pad,y:e.h/2};e.setCurve(new e.Bezier(t,t,t))},draw:function(e,t){e.reset(),e.setColor("lightgrey"),e.drawGrid(1,1),e.setColor("red"),e.drawCircle({x:e.w/2,y:e.h/2},e.r),e.setColor("transparent"),e.setFill("rgba(100,255,100,0.4)");var n={x:e.w/2,y:e.h/2,r:e.r,s:e.angle<0?e.angle:0,e:e.angle<0?0:e.angle};e.drawArc(n),e.setColor("black"),e.drawSkeleton(t),e.drawCurve(t)},onMouseMove:function(e,t){var n=e.offsetX-t.w/2,a=e.offsetY-t.h/2,o=Math.atan2(a,n),s=t.curve.points,l=t.r,c=(i(o)-1)/r(o);s[1]={x:t.w/2+l*(i(o)-c*r(o)),y:t.w/2+l*(r(o)+c*i(o))},s[2]={x:t.w/2+t.r*i(o),y:t.w/2+t.r*r(o)},t.setCurve(new t.Bezier(s)),t.angle=o}}},function(e,t,n){"use strict";var r=n(146),i=n(0);e.exports=i("circles",r)},function(e,t,n){"use strict";var r=Math.sin,i=Math.cos,a=Math.tan;e.exports={setup:function(e){e.setSize(400,400),e.w=e.getPanelWidth(),e.h=e.getPanelHeight(),e.pad=80,e.r=e.w/2-e.pad,e.mousePt=!1,e.angle=0;var t={x:e.w-e.pad,y:e.h/2};e.setCurve(new e.Bezier(t,t,t,t))},guessCurve:function(e,t,n){var r={x:(e.x+n.x)/2,y:(e.y+n.y)/2},i={x:t.x+(t.x-r.x)/3,y:t.y+(t.y-r.y)/3},a=(n.x-e.x)/4,o=(n.y-e.y)/4,s={x:t.x-a,y:t.y-o},l={x:t.x+a,y:t.y+o},c={x:i.x+2*(s.x-i.x),y:i.y+2*(s.y-i.y)},u={x:i.x+2*(l.x-i.x),y:i.y+2*(l.y-i.y)},h={x:e.x+2*(c.x-e.x),y:e.y+2*(c.y-e.y)},d={x:n.x+2*(u.x-n.x),y:n.y+2*(u.y-n.y)};return[h,d]},draw:function(e,t){e.reset(),e.setColor("lightgrey"),e.drawGrid(1,1),e.setColor("rgba(255,0,0,0.4)"),e.drawCircle({x:e.w/2,y:e.h/2},e.r),e.setColor("transparent"),e.setFill("rgba(100,255,100,0.4)");var n={x:e.w/2,y:e.h/2,r:e.r,s:e.angle<0?e.angle:0,e:e.angle<0?0:e.angle};e.drawArc(n);var a={x:e.w/2+e.r*i(e.angle/2),y:e.w/2+e.r*r(e.angle/2)},o=t.points[0],s=t.points[3],l=this.guessCurve(o,a,s),c=new e.Bezier([o,l[0],l[1],s]);e.setColor("rgb(140,140,255)"),e.drawLine(c.points[0],c.points[1]),e.drawLine(c.points[1],c.points[2]),e.drawLine(c.points[2],c.points[3]),e.setColor("blue"),e.drawCurve(c),e.drawCircle(c.points[1],3),e.drawCircle(c.points[2],3),e.drawSkeleton(t),e.setColor("black"),e.drawLine(t.points[1],t.points[2]),e.drawCurve(t)},onMouseMove:function(e,t){var n=e.offsetX-t.w/2,o=e.offsetY-t.h/2;if(!(n>t.w/2)){var s=Math.atan2(o,n);s<0&&(s=2*Math.PI+s); +var l=t.curve.points,c=t.r,u=4*a(s/4)/3;l[1]={x:t.w/2+c,y:t.w/2+c*u},l[2]={x:t.w/2+t.r*(i(s)+u*r(s)),y:t.w/2+t.r*(r(s)-u*i(s))},l[3]={x:t.w/2+t.r*i(s),y:t.w/2+t.r*r(s)},t.setCurve(new t.Bezier(l)),t.angle=s}},drawCircle:function(e){e.setSize(325,325),e.reset();var t=e.getPanelWidth(),n=e.getPanelHeight(),r=60,i=t/2-r,a=.55228,o={x:-r/2,y:-r/4},s=new e.Bezier([{x:t/2+i,y:n/2},{x:t/2+i,y:n/2+a*i},{x:t/2+a*i,y:n/2+i},{x:t/2,y:n/2+i}]);e.setColor("lightgrey"),e.drawLine({x:0,y:n/2},{x:t+r,y:n/2},o),e.drawLine({x:t/2,y:0},{x:t/2,y:n+r},o);var l=s.points;e.setColor("red"),e.drawPoint(l[0],o),e.drawPoint(l[1],o),e.drawPoint(l[2],o),e.drawPoint(l[3],o),e.drawCurve(s,o),e.setColor("rgb(255,160,160)"),e.drawLine(l[0],l[1],o),e.drawLine(l[1],l[2],o),e.drawLine(l[2],l[3],o),e.setFill("red"),e.text(l[0].x-t/2+","+(l[0].y-n/2),{x:l[0].x+7,y:l[0].y+3},o),e.text(l[1].x-t/2+","+(l[1].y-n/2),{x:l[1].x+7,y:l[1].y+3},o),e.text(l[2].x-t/2+","+(l[2].y-n/2),{x:l[2].x+7,y:l[2].y+7},o),e.text(l[3].x-t/2+","+(l[3].y-n/2),{x:l[3].x,y:l[3].y+13},o),l.forEach(function(e){e.x=-(e.x-t)}),e.setColor("blue"),e.drawCurve(s,o),e.drawLine(l[2],l[3],o),e.drawPoint(l[2],o),e.setFill("blue"),e.text("reflected",{x:l[2].x-r/2,y:l[2].y+13},o),e.setColor("rgb(200,200,255)"),e.drawLine(l[1],l[0],o),e.drawPoint(l[1],o),l.forEach(function(e){e.y=-(e.y-n)}),e.setColor("green"),e.drawCurve(s,o),l.forEach(function(e){e.x=-(e.x-t)}),e.setColor("purple"),e.drawCurve(s,o),e.drawLine(l[1],l[0],o),e.drawPoint(l[1],o),e.setFill("purple"),e.text("reflected",{x:l[1].x+10,y:l[1].y+3},o),e.setColor("rgb(200,200,255)"),e.drawLine(l[2],l[3],o),e.drawPoint(l[2],o),e.setColor("black"),e.setFill("black"),e.drawLine({x:t/2,y:n/2},{x:t/2+i-2,y:n/2},o),e.drawLine({x:t/2,y:n/2},{x:t/2,y:n/2+i-2},o),e.text("r = "+i,{x:t/2+i/3,y:n/2+10},o)}}},function(e,t,n){"use strict";var r=n(148),i=n(0);e.exports=i("circles_cubic",r)},function(e,t,n){"use strict";e.exports={componentDidMount:function(){if("undefined"!=typeof document){var e=document.createElement("script");e.src="lib/site/disqus.js",e.async=!0,document.head.appendChild(e)}}}},function(e,t,n){"use strict";var r=n(150),i=n(0);e.exports=i("comments",r)},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=e.getDefaultQuadratic();t.points[2].x=210,e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},draw:function(e,t){e.setPanelCount(3),e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n=t.order,r=20,i=t.points,a=e.getPanelWidth(),o=a-2*r,s=e.getPanelHeight(),l={x:a,y:0},c=JSON.parse(JSON.stringify(i)).map(function(e,t){return{x:o*t/n,y:e.x}});e.drawLine({x:0,y:0},{x:0,y:s},l),e.drawAxes(r,"t",0,1,"x",0,a,l),l.x+=r,e.drawCurve(new e.Bezier(c),l),l.x+=a-r;var u=JSON.parse(JSON.stringify(i)).map(function(e,t){return{x:o*t/n,y:e.y}});e.drawLine({x:0,y:0},{x:0,y:s},l),e.drawAxes(r,"t",0,1,"y",0,a,l),l.x+=r,e.drawCurve(new e.Bezier(u),l)}}},function(e,t,n){"use strict";var r=n(152),i=n(0);e.exports=i("components",r)},function(e,t,n){"use strict";e.exports={drawCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},drawCurve:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t)},drawFunction:function(e,t,n,r){e.setRandomColor(),e.drawFunction(r),e.setFill(e.getColor()),t&&e.text(t,n)},drawLerpBox:function(e,t,n,r){e.noColor(),e.setFill("rgba(0,0,100,0.2)");var i={x:r.x-5,y:n},a={x:r.x+5,y:t};e.drawRect(i,a),e.setColor("black")},drawLerpPoint:function(e,t,n,r,i){i.y=n+t*r,e.drawCircle(i,3),e.setFill("black"),e.text((1e4*t|0)/100+"%",{x:i.x+10,y:i.y+4}),e.noFill()},drawQuadraticLerp:function(e){e.reset();var t=e.getPanelWidth(),n=20,r=t-2*n;e.drawAxes(n,"t",0,1,"S","0%","100%");var i=e.hover;if(i&&i.x>=n&&i.x<=t-n){this.drawLerpBox(e,t,n,i);var a=(i.x-n)/r;this.drawLerpPoint(e,(1-a)*(1-a),n,r,i),this.drawLerpPoint(e,2*(1-a)*a,n,r,i),this.drawLerpPoint(e,a*a,n,r,i)}this.drawFunction(e,"first term",{x:2*n,y:r},function(e){return{x:n+e*r,y:n+r*(1-e)*(1-e)}}),this.drawFunction(e,"second term",{x:t/2-1.5*n,y:t/2+n},function(e){return{x:n+e*r,y:n+2*r*(1-e)*e}}),this.drawFunction(e,"third term",{x:r-2.5*n,y:r},function(e){return{x:n+e*r,y:n+r*e*e}})},drawCubicLerp:function(e){e.reset();var t=e.getPanelWidth(),n=20,r=t-2*n;e.drawAxes(n,"t",0,1,"S","0%","100%");var i=e.hover;if(i&&i.x>=n&&i.x<=t-n){this.drawLerpBox(e,t,n,i);var a=(i.x-n)/r;this.drawLerpPoint(e,(1-a)*(1-a)*(1-a),n,r,i),this.drawLerpPoint(e,3*(1-a)*(1-a)*a,n,r,i),this.drawLerpPoint(e,3*(1-a)*a*a,n,r,i),this.drawLerpPoint(e,a*a*a,n,r,i)}this.drawFunction(e,"first term",{x:2*n,y:r},function(e){return{x:n+e*r,y:n+r*(1-e)*(1-e)*(1-e)}}),this.drawFunction(e,"second term",{x:t/2-4*n,y:t/2},function(e){return{x:n+e*r,y:n+3*r*(1-e)*(1-e)*e}}),this.drawFunction(e,"third term",{x:t/2+2*n,y:t/2},function(e){return{x:n+e*r,y:n+3*r*(1-e)*e*e}}),this.drawFunction(e,"fourth term",{x:r-2.5*n,y:r},function(e){return{x:n+e*r,y:n+r*e*e*e}})},draw15thLerp:function(e){e.reset();var t=e.getPanelWidth(),n=20,r=t-2*n;e.drawAxes(n,"t",0,1,"S","0%","100%");var i,a=[1,15,105,455,1365,3003,5005,6435,6435,5005,3003,1365,455,105,15,1],o=e.hover;if(o&&o.x>=n&&o.x<=t-n)for(this.drawLerpBox(e,t,n,o),i=0;i<=15;i++){var s=(o.x-n)/r,l=a[i]*Math.pow(1-s,15-i)*Math.pow(s,i);this.drawLerpPoint(e,l,n,r,o)}for(i=0;i<=15;i++){var c=!1,u=!1;0===i&&(c="first term",u={x:n+5,y:r}),15===i&&(c="last term",u={x:t-3.5*n,y:r}),this.drawFunction(e,c,u,function(e){return{x:n+e*r,y:n+r*a[i]*Math.pow(1-e,15-i)*Math.pow(e,i)}})}}}},function(e,t,n){"use strict";var r=n(154),i=n(0);e.exports=i("control",r)},function(e,t,n){"use strict";var r=Math.abs;e.exports={setup:function(e){this.api=e,e.setPanelCount(3);var t=new e.Bezier(10,100,90,30,40,140,220,220),n=new e.Bezier(5,150,180,20,80,250,210,190);e.setCurve(t,n),this.pairReset()},pairReset:function(){this.prevstep=0,this.step=0},draw:function(e,t){var n=this;e.reset();var i={x:0,y:0};t.forEach(function(t){e.drawSkeleton(t),e.drawCurve(t)});var a=e.getPanelWidth(),o=e.getPanelHeight();if(i.x+=a,e.drawLine({x:0,y:0},{x:0,y:o},i),0===this.step&&(this.pairs=[{c1:t[0],c2:t[1]}]),this.step!==this.prevstep){var s=this.pairs;this.pairs=[],this.finals=[],s.forEach(function(t){if(t.c1.length()<.6&&t.c2.length()<.6)return n.finals.push(t);var r=t.c1.split(.5);e.setColor("black"),e.drawCurve(t.c1,i),e.setColor("red"),e.drawbbox(r.left.bbox(),i),e.drawbbox(r.right.bbox(),i);var a=t.c2.split(.5);e.setColor("black"),e.drawCurve(t.c2,i),e.setColor("blue"),e.drawbbox(a.left.bbox(),i),e.drawbbox(a.right.bbox(),i),r.left.overlaps(a.left)&&n.pairs.push({c1:r.left,c2:a.left}),r.left.overlaps(a.right)&&n.pairs.push({c1:r.left,c2:a.right}),r.right.overlaps(a.left)&&n.pairs.push({c1:r.right,c2:a.left}),r.right.overlaps(a.right)&&n.pairs.push({c1:r.right,c2:a.right})}),this.prevstep=this.step}else this.pairs.forEach(function(t){e.setColor("black"),e.drawCurve(t.c1,i),e.drawCurve(t.c2,i),e.setColor("red"),e.drawbbox(t.c1.bbox(),i),e.setColor("blue"),e.drawbbox(t.c2.bbox(),i)});0===this.pairs.length&&(this.pairReset(),this.draw(e,t)),i.x+=a,e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:o},i);var l,c,u=t[0].intersects(t[1]).map(function(e){var t=e.split("/").map(function(e){return parseFloat(e)});return{t1:t[0],t2:t[1]}}),h=u[0],d=function(e,t){return r(e.t1-t.t1)<.01&&r(e.t2-t.t2)<.01};for(c=1;c<u.length;c++)l=u[c],d(h,l)?u.splice(c--,1):h=l;e.setColor("lightblue"),e.drawCurve(t[0],i),e.drawCurve(t[1],i),e.setColor("blue"),u.forEach(function(n){e.drawCircle(t[0].get(n.t1),3,i)})},stepUp:function(){this.step++,this.api.redraw()}}},function(e,t,n){"use strict";var r=n(156),i=n(0);e.exports=i("curveintersection",r)},function(e,t,n){"use strict";e.exports={setup:function(e){var t=[{x:90,y:110},{x:25,y:40},{x:230,y:40},{x:150,y:240}];e.setCurve(new e.Bezier(t))},draw:function(e,t){if(e.reset(),e.drawSkeleton(t),e.drawCurve(t),e.hover){e.setColor("rgb(200,100,100)");for(var n=e.getPanelWidth(),r=e.hover.x/n,i=e.drawHull(t,r),a=4;a<=8;a++)e.drawCircle(i[a],3);var o=t.get(r);e.drawCircle(o,5),e.setFill("black"),e.drawCircle(o,3);var s=100*r|0;r=s/100,e.text("Sequential interpolation for "+s+"% (t="+r+")",{x:10,y:15})}}}},function(e,t,n){"use strict";var r=n(158),i=n(0);e.exports=i("decasteljau",r)},function(e,t,n){"use strict";var r=n(0);e.exports=r("derivatives")},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"step",values:{38:.1,40:-.1},controller:function(e){e.step<.1&&(e.step=.1)}}},setup:function(e){e.step=5},draw:function(e,t){var n=e.getPanelWidth(),r=n,i=n,a=r/2,o=i/2,s=a/2,l=o/2;e.reset(),e.setColor("black"),e.drawLine({x:0,y:o},{x:r,y:o}),e.drawLine({x:a,y:0},{x:a,y:i});for(var c,u={x:a,y:o},h=0;h<=e.step;h+=.1){c={x:s*Math.cos(h),y:l*Math.sin(h)},e.drawPoint(c,u);var d=h%1;(d<.05||d>.95)&&(e.text("t = "+Math.round(h),{x:u.x+1.25*s*Math.cos(h)-10,y:u.y+1.25*l*Math.sin(h)+5}),e.drawCircle(c,2,u))}}}},function(e,t,n){"use strict";var r=n(161),i=n(0),a=n(13);e.exports=a(i("explanation",r))},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=new e.Bezier(70,155,20,110,100,75);e.setCurve(t)},setupCubic:function(e){var t=new e.Bezier(60,105,75,30,215,115,140,160);e.setCurve(t)},draw:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t),e.setColor("lightgrey");var n,r,i=.05,a=-10,o=t.get(a-i);for(n=a;n<=i;n+=i)r=t.get(n),e.drawLine(o,r),o=r;o=t.get(1);var s=10;for(n=1+i;n<=s;n+=i)r=t.get(n),e.drawLine(o,r),o=r}}},function(e,t,n){"use strict";var r=n(163),i=n(0);e.exports=i("extended",r)},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=e.getDefaultQuadratic();t.points[2].x=210,e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},draw:function(e,t){e.setPanelCount(3),e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n=t.order+1,r=20,i=t.points,a=e.getPanelWidth(),o=e.getPanelHeight(),s={x:a,y:0},l=JSON.parse(JSON.stringify(i)).map(function(e,t){return{x:a*t/n,y:e.x}});e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:o},s),e.drawAxes(r,"t",0,1,"x",0,a,s),s.x+=r;var c=new e.Bezier(l);e.drawCurve(c,s),e.setColor("red"),c.extrema().y.forEach(function(t){var n=c.get(t);e.drawCircle(n,3,s)}),s.x+=a-r;var u=JSON.parse(JSON.stringify(i)).map(function(e,t){return{x:a*t/n,y:e.y}});e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:o},s),e.drawAxes(r,"t",0,1,"y",0,a,s),s.x+=r;var h=new e.Bezier(u);e.drawCurve(h,s),e.setColor("red"),h.extrema().y.forEach(function(t){var n=h.get(t);e.drawCircle(n,3,s)})}}},function(e,t,n){"use strict";var r=n(165),i=n(0);e.exports=i("extremities",r)},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"steps",values:{38:1,40:-1},controller:function(e){e.steps<1&&(e.steps=1)}}},setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t),e.steps=3},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.steps=5},drawFlattened:function(e,t){e.reset(),e.setColor("#DDD"),e.drawSkeleton(t),e.setColor("#DDD"),e.drawCurve(t);for(var n,r=1/e.steps,i=t.points[0],a=r;a<1+r;a+=r)n=t.get(Math.min(a,1)),e.setColor("red"),e.drawLine(i,n),i=n;e.setFill("black"),e.text("Curve approximation using "+e.steps+" segments",{x:10,y:15})},values:{38:1,40:-1},onKeyDown:function(e,t){var n=this.values[e.keyCode];n&&(e.preventDefault(),t.steps+=n,t.steps<1&&(t.steps=1))}}},function(e,t,n){"use strict";var r=n(167),i=n(0),a=n(13);e.exports=a(i("flattening",r))},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"distance",values:{38:1,40:-1}}},setup:function(e,t){e.setCurve(t),e.distance=20},setupQuadratic:function(e){var t=e.getDefaultQuadratic();this.setup(e,t)},setupCubic:function(e){var t=e.getDefaultCubic();this.setup(e,t)},draw:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t),e.setColor("blue");var n=t.outline(0,0,e.distance,e.distance);n.curves.forEach(function(t){return e.drawCurve(t)})}}},function(e,t,n){"use strict";var r=n(169),i=n(0),a=n(13);e.exports=a(i("graduatedoffset",r))},function(e,t,n){"use strict";e.exports={setupCubic:function(e){var t=new e.Bezier(135,25,25,135,215,75,215,240);e.setCurve(t)},draw:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t),e.setColor("red"),t.inflections().forEach(function(n){e.drawCircle(t.get(n),5)})}}},function(e,t,n){"use strict";var r=n(171),i=n(0);e.exports=i("inflections",r)},function(e,t,n){"use strict";var r=Math.min,i=Math.max;e.exports={setupLines:function(e){var t=new e.Bezier([50,50,150,110]),n=new e.Bezier([50,250,170,170]);e.setCurve(t,n)},drawLineIntersection:function(e,t){e.reset();var n=e.utils.lli4,a=n(t[0].points[0],t[0].points[1],t[1].points[0],t[1].points[1]),o=0;t.forEach(function(t){if(e.drawSkeleton(t),e.setColor("black"),a){var n=t.points,s=r(n[0].x,n[1].x),l=r(n[0].y,n[1].y),c=i(n[0].x,n[1].x),u=i(n[0].y,n[1].y);s<=a.x&&l<=a.y&&c>=a.x&&u>=a.y&&(e.setColor("#00FF00"),o++)}e.drawCurve(t)}),a&&(e.setColor(o<2?"red":"#00FF00"),e.drawCircle(a,3))},setupQuadratic:function(e){var t=e.getDefaultQuadratic(),n=new e.Bezier([15,250,220,20]);e.setCurve(t,n)},setupCubic:function(e){var t=new e.Bezier([100,240,30,60,210,230,160,30]),n=new e.Bezier([25,260,230,20]);e.setCurve(t,n)},draw:function(e,t){e.reset(),t.forEach(function(t){e.drawSkeleton(t),e.drawCurve(t)});var n=e.utils,r={p1:t[1].points[0],p2:t[1].points[1]},i=n.align(t[0].points,r),a=new e.Bezier(i),o=n.roots(a.points);o.forEach(function(n){var r=t[0].get(n);e.drawCircle(r,3),e.text("t = "+n,{x:r.x+5,y:r.y+10})})}}},function(e,t,n){"use strict";var r=n(173),i=n(0);e.exports=i("intersections",r)},function(e,t,n){"use strict";e.exports={drawQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},drawCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},drawCurve:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t)}}},function(e,t,n){"use strict";var r=n(175),i=n(0);e.exports=i("introduction",r)},function(e,t,n){"use strict";var r=n(0);e.exports=r("matrix")},function(e,t,n){"use strict";var r=n(0);e.exports=r("matrixsplit")},function(e,t,n){"use strict";var r=Math.abs;e.exports={setupQuadratic:function(e){e.setPanelCount(3);var t=e.getDefaultQuadratic();t.points[2].x-=30,e.setCurve(t)},setupCubic:function(e){e.setPanelCount(3);var t=new e.Bezier([100,230,30,160,200,50,210,160]);t.points[2].y-=20,e.setCurve(t),e.lut=t.getLUT(100)},saveCurve:function(e,t){t.t&&(t.setCurve(t.newcurve),t.t=!1,t.redraw())},findTValue:function(e,t){var n=t.curve.on({x:e.offsetX,y:e.offsetY},7);return!(n<.05||n>.95)&&n},markQB:function(e,t){if(t.t=this.findTValue(e,t),t.t){var n=t.t,i=2*n,a=i*n-i,o=a+1,s=r(a/o),l=t.curve,c=t.A=l.points[1],u=t.B=l.get(n);t.C=t.utils.lli4(c,u,l.points[0],l.points[2]),t.ratio=s}},markCB:function(e,t){if(t.t=this.findTValue(e,t),t.t){var n=t.t,i=1-n,a=n*n*n,o=i*i*i,s=a+o,l=s-1,c=r(l/s),u=t.curve,h=u.hull(n),d=t.A=h[5],f=t.B=u.get(n);t.db=u.derivative(n),t.C=t.utils.lli4(d,f,u.points[0],u.points[3]),t.ratio=c}},drag:function(e,t){if(t.t){var n=t.newB={x:e.offsetX,y:e.offsetY};t.newA={x:n.x-(t.C.x-n.x)/t.ratio,y:n.y-(t.C.y-n.y)/t.ratio}}},dragQB:function(e,t){t.t&&(this.drag(e,t),t.update=[t.newA])},dragCB:function(e,t){if(t.t){this.drag(e,t);var n=t.curve,r=n.hull(t.t),i=t.B,a=r[7],o=r[8],s={x:a.x-i.x,y:a.y-i.y},l={x:o.x-i.x,y:o.y-i.y},c=n.points,u={x:t.newB.x+s.x,y:t.newB.y+s.y},h={x:t.newA.x-(t.newA.x-u.x)/(1-t.t),y:t.newA.y-(t.newA.y-u.y)/(1-t.t)},d={x:t.newB.x+l.x,y:t.newB.y+l.y},f={x:t.newA.x+(d.x-t.newA.x)/t.t,y:t.newA.y+(d.y-t.newA.y)/t.t},p={x:c[0].x+(h.x-c[0].x)/t.t,y:c[0].y+(h.y-c[0].y)/t.t},m={x:c[3].x-(c[3].x-f.x)/(1-t.t),y:c[3].y-(c[3].y-f.y)/(1-t.t)};t.p1=u,t.p2=d,t.sc1=h,t.sc2=f,t.nc1=p,t.nc2=m,t.update=[p,m]}},drawMould:function(e,t){e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n=e.getPanelWidth(),r=e.getPanelHeight(),i={x:n,y:0},a=e.utils.round;if(e.setColor("black"),e.drawLine({x:0,y:0},{x:0,y:r},i),e.drawLine({x:n,y:0},{x:n,y:r},i),e.t){e.drawCircle(t.get(e.t),3),e.npts=[t.points[0]].concat(e.update).concat([t.points.slice(-1)[0]]),e.newcurve=new e.Bezier(e.npts),e.setColor("lightgrey"),e.drawCurve(e.newcurve);var o=e.drawHull(e.newcurve,e.t,i);if(e.drawLine(e.npts[0],e.npts.slice(-1)[0],i),e.drawLine(e.newA,e.newB,i),e.setColor("grey"),e.drawCircle(e.newA,3,i),e.setColor("blue"),e.drawCircle(e.B,3,i),e.drawCircle(e.C,3,i),e.drawCircle(e.newB,3,i),e.drawLine(e.B,e.C,i),e.drawLine(e.newB,e.C,i),e.setFill("black"),e.text("A'",e.newA,{x:i.x+7,y:i.y+1}),e.text("start",t.get(0),{x:i.x+7,y:i.y+1}),e.text("end",t.get(1),{x:i.x+7,y:i.y+1}),e.setFill("blue"),e.text("B'",e.newB,{x:i.x+7,y:i.y+1}),e.text("B, at t = "+a(e.t,2),e.B,{x:i.x+7,y:i.y+1}),e.text("C",e.C,{x:i.x+7,y:i.y+1}),3===t.order){var s=t.hull(e.t);e.drawLine(s[7],s[8],i),e.drawLine(o[7],o[8],i),e.drawCircle(o[7],3,i),e.drawCircle(o[8],3,i),e.text("e1",o[7],{x:i.x+7,y:i.y+1}),e.text("e2",o[8],{x:i.x+7,y:i.y+1})}i.x+=n,e.setColor("lightgrey"),e.drawSkeleton(e.newcurve,i),e.setColor("black"),e.drawCurve(e.newcurve,i)}else i.x+=n,e.drawCurve(t,i)}}},function(e,t,n){"use strict";var r=n(179),i=n(0);e.exports=i("moulding",r)},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"distance",values:{38:1,40:-1}}},setup:function(e,t){e.setCurve(t),e.distance=20},setupQuadratic:function(e){var t=e.getDefaultQuadratic();this.setup(e,t)},setupCubic:function(e){var t=e.getDefaultCubic();this.setup(e,t)},draw:function(e,t){e.reset(),e.drawSkeleton(t);var n=t.reduce();n.forEach(function(t){e.setRandomColor(),e.drawCurve(t),e.drawCircle(t.points[0],1)});var r=n.slice(-1)[0];e.drawPoint(r.points[3]||r.points[2]),e.setColor("red");var i=t.offset(e.distance);i.forEach(function(t){e.drawPoint(t.points[0]),e.drawCurve(t)}),r=i.slice(-1)[0],e.drawPoint(r.points[3]||r.points[2]),e.setColor("blue"),i=t.offset(-e.distance),i.forEach(function(t){e.drawPoint(t.points[0]),e.drawCurve(t)}),r=i.slice(-1)[0],e.drawPoint(r.points[3]||r.points[2])}}},function(e,t,n){"use strict";var r=n(181),i=n(0),a=n(13);e.exports=a(i("offsetting",r))},function(e,t,n){"use strict";var r=Math.abs;e.exports={setup:function(e){e.lpts=[{x:56,y:153},{x:144,y:83},{x:188,y:185}]},onClick:function(e,t){3==t.lpts.length&&(t.lpts=[]),t.lpts.push({x:e.offsetX,y:e.offsetY}),t.redraw()},getQRatio:function(e){var t=2*e,n=t*e-t,i=n+1;return r(n/i)},getCRatio:function(e){var t=1-e,n=e*e*e,i=t*t*t,a=n+i,o=a-1;return r(o/a)},drawQuadratic:function(e,t){var n=["start","t=0.5","end"];if(e.reset(),e.setColor("lightblue"),e.drawGrid(10,10),e.setFill("black"),e.setColor("black"),e.lpts.forEach(function(t,r){e.drawCircle(t,3),e.text(n[r],t,{x:5,y:2})}),3===e.lpts.length){var r=e.lpts[0],i=e.lpts[2],a=e.lpts[1],o={x:(r.x+i.x)/2,y:(r.y+i.y)/2};e.setColor("blue"),e.drawLine(r,i),e.drawLine(a,o),e.drawCircle(o,3);var s=this.getQRatio(.5),l={x:a.x+(a.x-o.x)/s,y:a.y+(a.y-o.y)/s};t=new e.Bezier([r,l,i]),e.setColor("lightgrey"),e.drawLine(l,a),e.drawLine(l,r),e.drawLine(l,i),e.setColor("black"),e.drawCircle(l,1),e.drawCurve(t)}},drawCubic:function(e,t){var n=["start","t=0.5","end"];if(e.reset(),e.setFill("black"),e.setColor("black"),e.lpts.forEach(function(t,r){e.drawCircle(t,3),e.text(n[r],t,{x:5,y:2})}),e.setColor("lightblue"),e.drawGrid(10,10),3===e.lpts.length){var r=e.lpts[0],i=e.lpts[2],a=e.lpts[1],o={x:(r.x+i.x)/2,y:(r.y+i.y)/2};e.setColor("blue"),e.drawLine(r,i),e.drawLine(a,o),e.drawCircle(o,1);var s=this.getCRatio(.5),l={x:a.x+(a.x-o.x)/s,y:a.y+(a.y-o.y)/s},c=e.utils.dist(r,i),u=c/8,h=e.utils.dist(a,o),d=4,f=u+h/d,p=f*(i.x-r.x)/c,m=f*(i.y-r.y)/c,g={x:a.x-p,y:a.y-m},v={x:a.x+p,y:a.y+m},w={x:l.x+2*(g.x-l.x),y:l.y+2*(g.y-l.y)},y={x:l.x+2*(v.x-l.x),y:l.y+2*(v.y-l.y)},b={x:r.x+2*(w.x-r.x),y:r.y+2*(w.y-r.y)},_={x:i.x+2*(y.x-i.x),y:i.y+2*(y.y-i.y)};t=new e.Bezier([r,b,_,i]),e.drawLine(g,v),e.setColor("lightgrey"),e.drawLine(l,o),e.drawLine(l,w),e.drawLine(l,y),e.drawLine(r,b),e.drawLine(i,_),e.drawLine(b,_),e.setColor("black"),e.drawCircle(l,1),e.drawCircle(b,1),e.drawCircle(_,1),e.drawCurve(t)}}}},function(e,t,n){"use strict";var r=n(183),i=n(0);e.exports=i("pointcurves",r)},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},draw:function(e,t){e.reset(),e.drawSkeleton(t);var n,r,i,a,o,s,l=20;for(n=0;n<=10;n++)r=n/10,i=t.get(r),a=t.derivative(r),s=Math.sqrt(a.x*a.x+a.y*a.y),a={x:a.x/s,y:a.y/s},o=t.normal(r),e.setColor("blue"),e.drawLine(i,{x:i.x+a.x*l,y:i.y+a.y*l}),e.setColor("red"),e.drawLine(i,{x:i.x+o.x*l,y:i.y+o.y*l}),e.setColor("black"),e.drawCircle(i,3)}}},function(e,t,n){"use strict";var r=n(185),i=n(0);e.exports=i("pointvectors",r)},function(e,t,n){"use strict";var r=Math.atan2,i=Math.sqrt,a=Math.sin,o=Math.cos;e.exports={setupQuadratic:function(e){var t=e.getPanelWidth(),n=e.getPanelHeight(),r=t/2,i=n/2,a=40,o=[{x:r,y:a},{x:t-a,y:a},{x:t-a,y:i},{x:t-a,y:n-a},{x:r,y:n-a},{x:a,y:n-a},{x:a,y:i},{x:a,y:a}];e.lpts=o},setupCubic:function(e){var t=e.getPanelWidth(),n=e.getPanelHeight(),r=t/2,i=n/2,a=40,o=(t-2*a)/2,s=.55228,l=s*o,c=[{x:r,y:a},{x:r+l,y:a},{x:t-a,y:i-l},{x:t-a,y:i},{x:t-a,y:i+l},{x:r+l,y:n-a},{x:r,y:n-a},{x:r-l,y:n-a},{x:a,y:i+l},{x:a,y:i},{x:a,y:i-l},{x:r-l,y:a}];e.lpts=c},movePointsQuadraticLD:function(e,t){for(var n,r,i,a=1;a<4;a++)n=t+(2*a-2)+e.lpts.length,n=e.lpts[n%e.lpts.length],r=t+(2*a-1),r=e.lpts[r%e.lpts.length],i=t+2*a,i=e.lpts[i%e.lpts.length],i.x=r.x+(r.x-n.x),i.y=r.y+(r.y-n.y);i=t+6,i=e.lpts[i%e.lpts.length],e.problem=i},movePointsCubicLD:function(e,t){var n,r;t%3===1?(r=t-1,r+=r<0?e.lpts.length:0,n=t-2,n+=n<0?e.lpts.length:0):(r=(t+1)%e.lpts.length,n=(t+2)%e.lpts.length),r=e.lpts[r],n=e.lpts[n],n.x=r.x+(r.x-e.mp.x),n.y=r.y+(r.y-e.mp.y)},linkDerivatives:function(e,t){if(t.mp){var n=8===t.lpts.length,r=t.mp_idx;n?r%2!==0&&this.movePointsQuadraticLD(t,r):r%3!==0&&this.movePointsCubicLD(t,r)}},movePointsQuadraticDirOnly:function(e,t){var n,s,l;[-1,1].forEach(function(c){n=e.mp,s=t+c+e.lpts.length,s=e.lpts[s%e.lpts.length],l=t+2*c+e.lpts.length,l=e.lpts[l%e.lpts.length];var u=r(s.y-n.y,s.x-n.x),h=l.x-s.x,d=l.y-s.y,f=i(h*h+d*d);l.x=s.x+f*o(u),l.y=s.y+f*a(u)}),l=t+4,l=e.lpts[l%e.lpts.length],e.problem=l},movePointsCubicDirOnly:function(e,t){var n,s;t%3===1?(s=t-1,s+=s<0?e.lpts.length:0,n=t-2,n+=n<0?e.lpts.length:0):(s=(t+1)%e.lpts.length,n=(t+2)%e.lpts.length),s=e.lpts[s],n=e.lpts[n];var l=r(s.y-e.mp.y,s.x-e.mp.x),c=n.x-s.x,u=n.y-s.y,h=i(c*c+u*u);n.x=s.x+h*o(l),n.y=s.y+h*a(l)},linkDirection:function(e,t){if(t.mp){var n=8===t.lpts.length,r=t.mp_idx;n?r%2!==0&&this.movePointsQuadraticDirOnly(t,r):r%3!==0&&this.movePointsCubicDirOnly(t,r)}},bufferPoints:function(e,t){t.bpts=JSON.parse(JSON.stringify(t.lpts))},moveQuadraticPoint:function(e,t){this.moveCubicPoint(e,t),[-1,1].forEach(function(n){var s=t-n+e.lpts.length;s=e.lpts[s%e.lpts.length];var l=t-2*n+e.lpts.length;l=e.lpts[l%e.lpts.length];var c=t-3*n+e.lpts.length;c=e.lpts[c%e.lpts.length];var u=r(l.y-s.y,l.x-s.x),h=c.x-l.x,d=c.y-l.y,f=i(h*h+d*d);c.x=l.x+f*o(u),c.y=l.y+f*a(u)});var n=t+4;n=e.lpts[n%e.lpts.length],e.problem=n},moveCubicPoint:function(e,t){var n=e.bpts[t],r=e.lpts[t],i=r.x-n.x,a=r.y-n.y,o=e.lpts.length,s=t-1+o,l=t+1,c=e.bpts[s%o],u=e.bpts[l%o],h=e.lpts[s%o],d=e.lpts[l%o];return h.x=c.x+i,h.y=c.y+a,d.x=u.x+i,d.y=u.y+a,{x:i,y:a}},modelCurve:function(e,t){if(t.mp){var n=8===t.lpts.length,r=t.mp_idx;n?r%2!==0?this.movePointsQuadraticDirOnly(t,r):this.moveQuadraticPoint(t,r):r%3!==0?this.movePointsCubicDirOnly(t,r):this.moveCubicPoint(t,r)}},draw:function(e,t){e.reset();var n=e.lpts,r=8===n.length,i=r?new e.Bezier(n[0],n[1],n[2]):new e.Bezier(n[0],n[1],n[2],n[3]);e.drawSkeleton(i,!1,!0),e.drawCurve(i);var a=r?new e.Bezier(n[2],n[3],n[4]):new e.Bezier(n[3],n[4],n[5],n[6]);e.drawSkeleton(a,!1,!0),e.drawCurve(a);var o=r?new e.Bezier(n[4],n[5],n[6]):new e.Bezier(n[6],n[7],n[8],n[9]);e.drawSkeleton(o,!1,!0),e.drawCurve(o);var s=r?new e.Bezier(n[6],n[7],n[0]):new e.Bezier(n[9],n[10],n[11],n[0]);e.drawSkeleton(s,!1,!0),e.drawCurve(s),e.problem&&(e.setColor("red"),e.drawCircle(e.problem,5))}}},function(e,t,n){"use strict";var r=n(187),i=n(0);e.exports=i("polybezier",r)},function(e,t,n){"use strict";var r=n(0);e.exports=r("preface")},function(e,t,n){"use strict";e.exports={setup:function(e){e.setSize(320,320);var t=new e.Bezier([{x:248,y:188},{x:218,y:294},{x:45,y:290},{x:12,y:236},{x:14,y:82},{x:186,y:177},{x:221,y:90},{x:18,y:156},{x:34,y:57},{x:198,y:18}]);e.setCurve(t),e._lut=t.getLUT()},findClosest:function(e,t,n){var r,i,a=e.length,o=n(e[0],t),s=0;for(r=1;r<a;r++)i=n(e[r],t),i<o&&(s=r,o=i);return s/(a-1)},draw:function(e,t){if(e.reset(),e.drawSkeleton(t),e.drawCurve(t),e.mousePt){e.setColor("red"),e.setFill("red"),e.drawCircle(e.mousePt,3);var n=this.findClosest(e._lut,e.mousePt,e.utils.dist),r=t.get(n);e.drawLine(r,e.mousePt),e.drawCircle(r,3),e.text("t = "+e.utils.round(n,2),r,{x:10,y:3})}},onMouseMove:function(e,t){t.mousePt={x:e.offsetX,y:e.offsetY},t._lut=t.curve.getLUT()}}},function(e,t,n){"use strict";var r=n(190),i=n(0);e.exports=i("projections",r)},function(e,t,n){"use strict";var r={statics:{lower:function(e){var t=e.points,n=[],r=t.length;return t.forEach(function(e,i){if(!i)return n[i]=e;var a=i/r,o=1-a;n[i]={x:a*e.x+o*t[i-1].x,y:a*e.y+o*t[i-1].y}}),n.splice(r-1,1),n[r-2]=t[r-1],e.points=n,e},keyHandlingOptions:{values:{38:function(e){e.setCurve(e.curve.raise())},40:function(e){e.setCurve(r.lower(e.curve))}}}},getInitialState:function(){return{order:0}},setup:function(e){for(var t=[],n=e.getPanelWidth(),r=e.getPanelHeight(),i=0;i<10;i++)t.push({x:n/2+20*Math.random()+Math.cos(2*Math.PI*i/10)*(n/2-40),y:r/2+20*Math.random()+Math.sin(2*Math.PI*i/10)*(r/2-40)});var a=new e.Bezier(t);e.setCurve(a)},draw:function(e,t){e.reset();var n=t.points;this.setState({order:n.length});for(var r=n[0],i=0;i<=1;i+=.01){for(var a=JSON.parse(JSON.stringify(n));a.length>1;){for(var o=0;o<a.length-1;o++)a[o]={x:a[o].x+(a[o+1].x-a[o].x)*i,y:a[o].y+(a[o+1].y-a[o].y)*i};a.splice(a.length-1,1)}e.drawLine(r,a[0]),r=a[0]}r=n[0],e.setColor("black"),e.drawCircle(r,3),n.forEach(function(t){t!==r&&(e.setColor("#DDD"),e.drawLine(r,t),e.setColor("black"),e.drawCircle(t,3),r=t)})},getOrder:function(){var e=this.state.order;return e+=e%10===1&&11!==e?"st":e%10===2&&12!==e?"nd":e%10===3&&13!==e?"rd":"th"}};e.exports=r},function(e,t,n){"use strict";var r=n(192),i=n(0),a=n(13);e.exports=a(i("reordering",r))},function(e,t,n){"use strict";var r;e.exports={getInitialState:function(){return r=this.modes=["unite","intersect","exclude","subtract"],{mode:r[0]}},setMode:function(e){this.setState({mode:e})},formPath:function(e,t,n,r,i){t=t||0,n=n||0;var a=30,o=a/2;r=r||8*a,i=i||4*a;var s=r/2,l=i/2,c=s/3,u=l/3,h=e.Paper,d=h.Path,f=h.Point,p=new d;return p.moveTo(new f(t-s+2*a,n-l)),p.cubicCurveTo(new f(t-s+o,n-l+o),new f(t-s+o,n+l-o),new f(t-s+2*a,n+l)),p.cubicCurveTo(new f(t-c,n+u),new f(t+c,n+u),new f(t+s-2*a,n+l)),p.cubicCurveTo(new f(t+s-o,n+l-o),new f(t+s-o,n-l+o),new f(t+s-2*a,n-l)),p.cubicCurveTo(new f(t+c,n-u),new f(t-c,n-u),new f(t-s+2*a,n-l)),p.closePath(!0),p.strokeColor="rgb(100,100,255)",p},setup:function(e){var t=e.getPanelWidth(),n=40,i=t/2,a=t/2;e.c1=this.formPath(e,i,a),i+=n,a+=n,e.c2=this.formPath(e,i,a),this.state.mode=r[0]},onMouseMove:function(e,t){var n=e.offsetX,r=e.offsetY;t.c2.position={x:n,y:r}},draw:function(e){e.c3&&e.c3.remove();var t=e.c1,n=e.c2,r=t[this.state.mode].bind(t),i=e.c3=r(n);i.strokeColor="red",i.fillColor="rgba(255,100,100,0.4)",e.Paper.view.draw()}}},function(e,t,n){"use strict";var r=n(194),i=n(0);e.exports=i("shapes",r)},function(e,t,n){"use strict";e.exports={setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.forward=!0},drawSplit:function(e,t){e.setPanelCount(2),e.reset(),e.drawSkeleton(t),e.drawCurve(t);var n={x:0,y:0},r=.5,i=t.get(.5),a=t.split(r);e.drawCurve(a.left),e.drawCurve(a.right),e.setColor("red"),e.drawCircle(i,3),e.setColor("black"),n.x=e.getPanelWidth(),e.drawLine({x:0,y:0},{x:0,y:e.getPanelHeight()},n),e.setColor("lightgrey"),e.drawCurve(t,n),e.drawCircle(i,4),n.x-=20,n.y-=20,e.drawSkeleton(a.left,n,!0),e.drawCurve(a.left,n),n.x+=40,n.y+=40,e.drawSkeleton(a.right,n,!0),e.drawCurve(a.right,n)},drawAnimated:function(e,t){e.setPanelCount(3),e.reset();var n=e.getFrame(),r=5*e.getPlayInterval(),i=n%r/r,a=n%(2*r)<r;a?i%=1:i=1-i%1;var o={x:0,y:0};e.setColor("lightblue"),e.drawHull(t,i),e.drawSkeleton(t),e.drawCurve(t);var s=t.get(i);e.drawCircle(s,4),e.setColor("black"),o.x+=e.getPanelWidth(),e.drawLine({x:0,y:0},{x:0,y:e.getPanelHeight()},o);var l=t.split(i);e.setColor("lightgrey"),e.drawCurve(t,o),e.drawHull(t,i,o),e.setColor("black"),e.drawCurve(l.left,o),e.drawPoints(l.left.points,o),e.setFill("black"),e.text("Left side of curve split at t = "+(100*i|0)/100,{x:10+o.x,y:15+o.y}),o.x+=e.getPanelWidth(),e.drawLine({x:0,y:0},{x:0,y:e.getPanelHeight()},o),e.setColor("lightgrey"),e.drawCurve(t,o),e.drawHull(t,i,o),e.setColor("black"),e.drawCurve(l.right,o),e.drawPoints(l.right.points,o),e.setFill("black"),e.text("Right side of curve split at t = "+(100*i|0)/100,{x:10+o.x,y:15+o.y})},togglePlay:function(e,t){t.playing?t.pause():t.play()}}},function(e,t,n){"use strict";var r=n(196),i=n(0);e.exports=i("splitting",r)},function(e,t,n){"use strict";e.exports={setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t)},align:function(e,t){var n=t.p1.x,r=t.p1.y,i=-Math.atan2(t.p2.y-r,t.p2.x-n),a=Math.cos,o=Math.sin,s=function(e){return{x:(e.x-n)*a(i)-(e.y-r)*o(i),y:(e.x-n)*o(i)+(e.y-r)*a(i),a:i}};return e.map(s)},transpose:function(e,t,n){var r=n.x,i=n.y,a=Math.cos,o=Math.sin,s=[e.x.min,e.y.min,e.x.max,e.y.max];return[{x:s[0],y:s[1]},{x:s[2],y:s[1]},{x:s[2],y:s[3]},{x:s[0],y:s[3]}].map(function(e){var n=e.x,s=e.y;return{x:n*a(t)-s*o(t)+r,y:n*o(t)+s*a(t)+i}})},draw:function(e,t){e.reset();var n=t.points,r={p1:n[0],p2:n[n.length-1]},i=this.align(n,r),a=-i[0].a,o=new e.Bezier(i),s=o.bbox(),l=this.transpose(s,a,n[0]);e.setColor("#00FF00"),e.drawLine(l[0],l[1]),e.drawLine(l[1],l[2]),e.drawLine(l[2],l[3]),e.drawLine(l[3],l[0]),e.setColor("black"),e.drawSkeleton(t),e.drawCurve(t)}}},function(e,t,n){"use strict";var r=n(198),i=n(0);e.exports=i("tightbounds",r)},function(e,t,n){"use strict";e.exports={statics:{keyHandlingOptions:{propName:"steps",values:{38:1,40:-1},controller:function(e){e.steps<1&&(e.steps=1)}}},setup:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.steps=8},generate:function(e,t,n,r,i){n.x+=r,n.y+=r;for(var a,o,s=t.length(),l=[{x:0,y:0,d:0}],c=1;c<=100;c++)a=c/100,o=t.split(a).left.length(),l.push({x:e.utils.map(a,0,1,0,i),y:e.utils.map(o,0,s,0,i),d:o,t:a});return l},draw:function(e,t,n){e.reset(),e.drawSkeleton(t),e.drawCurve(t);var r=t.length(),i=e.getPanelWidth(),a=e.getPanelHeight(),o=20,s=i-2*o;return n.x+=i,e.drawLine({x:0,y:0},{x:0,y:a},n),e.drawAxes(o,"t",0,1,"d",0,r,n),this.generate(e,t,n,o,s)},plotOnly:function(e,t){e.setPanelCount(2);for(var n={x:0,y:0},r=this.draw(e,t,n),i=0;i<r.length-1;i++)e.drawLine(r[i],r[i+1],n)},drawColoured:function(e,t){e.setPanelCount(3);var n,r,i=e.getPanelWidth(),a=e.getPanelHeight(),o=20,s=i-2*o,l={x:0,y:0},c=t.length(),u=this.draw(e,t,l),h=e.steps,d=[];for(n=0;n<=h;n++){var f=n*c/h;for(r=0;r<u.length;r++)if(u[r].d>f){r--;break}r<0&&(r=0),r===u.length&&(r=u.length-1),d.push(u[r])}for(n=0;n<u.length-1;n++)e.drawLine(u[n],u[n+1],l);d.forEach(function(t){var n={x:e.utils.map(t.t,0,1,0,s),y:0},r={x:0,y:e.utils.map(t.d,0,c,0,s)};e.setColor("black"),e.drawCircle(n,3,l),e.drawCircle(r,3,l),e.setColor("lightgrey"),e.drawLine(n,{x:n.x,y:r.y},l),e.drawLine(r,{x:n.x,y:r.y},l)}),l={x:2*i,y:0},e.drawLine({x:0,y:0},{x:0,y:a},l);var p=0,m=["rgb(240,0,200)","rgb(0,40,200)"];e.setColor(m[p]);var g,v=t.get(u[0].t);for(e.drawCircle(t.get(0),4,l),n=1,g;n<u.length;n++)g=t.get(u[n].t),e.drawLine(v,g,l),d.indexOf(u[n])!==-1&&(e.setColor(m[++p%m.length]),e.drawCircle(g,4,l)),v=g}}},function(e,t,n){"use strict";var r=n(200),i=n(0),a=n(13);e.exports=a(i("tracing",r))},function(e,t,n){"use strict";e.exports={setup:function(e){e.setPanelCount(3);var t=e.getDefaultQuadratic(); +e.setCurve(t),e.step=25},draw:function(e,t){var n,r,i,a,o,s,l,c,u=e.getPanelWidth(),h=t.points,d=h[0],f=h[1],p=h[2],m={x:0,y:0};for(e.reset(),e.setColor("black"),e.setFill("black"),e.drawSkeleton(t,m),e.text("First linear interpolation at "+e.step+"% steps",{x:5,y:15},m),m.x+=u,e.drawLine({x:0,y:0},{x:0,y:this.dim},m),e.drawSkeleton(t,m),e.text("Second interpolation at "+e.step+"% steps",{x:5,y:15},m),m.x+=u,e.drawLine({x:0,y:0},{x:0,y:this.dim},m),e.drawSkeleton(t,m),e.text("Curve points generated this way",{x:5,y:15},m),e.setColor("lightgrey"),a=1,s=20,c;a<s;a++)l=a/s,c=t.get(l),e.drawCircle(c,2,m);for(o=3*e.step;o>0;o-=e.step)a=o/100,a>1||(e.setRandomColor(),n={x:d.x+a*(f.x-d.x),y:d.y+a*(f.y-d.y)},r={x:f.x+a*(p.x-f.x),y:f.y+a*(p.y-f.y)},i={x:n.x+a*(r.x-n.x),y:n.y+a*(r.y-n.y)},m={x:0,y:0},e.drawCircle(n,3,m),e.drawCircle(r,3,m),e.setWeight(.5),e.drawLine(n,r,m),e.setWeight(1.5),e.drawLine(d,n,m),e.drawLine(f,r,m),e.setWeight(1),m.x+=u,e.drawCircle(n,3,m),e.drawCircle(r,3,m),e.setWeight(.5),e.drawLine(n,r,m),e.setWeight(1.5),e.drawLine(n,i,m),e.setWeight(1),e.drawCircle(i,3,m),m.x+=u,e.drawCircle(i,3,m),e.text(o+"%, or t = "+e.utils.round(a,2),{x:i.x+10+m.x,y:i.y+10+m.y}))},values:{38:1,40:-1},onKeyDown:function(e,t){var n=this.values[e.keyCode];n&&(e.preventDefault(),t.step+=n,t.step<1&&(t.step=1))}}},function(e,t,n){"use strict";var r=n(202),i=n(0);e.exports=i("whatis",r)},function(e,t,n){"use strict";var r=n(4),i=n(110),a=n(64),o=n(107),s=n(112),l=n(117);a.locale="en-GB",e.exports={locale:"en-GB",preface:{locale:"en-GB",title:"Preface",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"preface",title:"Preface"}),r.createElement("p",null,"In order to draw things in 2D, we usually rely on lines, which typically get classified into two categories: straight lines, and curves. The first of these are as easy to draw as they are easy to make a computer draw. Give a computer the first and last point in the line, and BAM! straight line. No questions asked."),r.createElement("p",null,"Curves, however, are a much bigger problem. While we can draw curves with ridiculous ease freehand, computers are a bit handicapped in that they can't draw curves unless there is a mathematical function that describes how it should be drawn. In fact, they even need this for straight lines, but the function is ridiculously easy, so we tend to ignore that as far as computers are concerned, all lines are \"functions\", regardless of whether they're straight or curves. However, that does mean that we need to come up with fast-to-compute functions that lead to nice looking curves on a computer. There's a number of these, and in this article we'll focus on a particular function that has received quite a bit of attention, and is used in pretty much anything that can draw curves: \"Bézier\" curves"),r.createElement("p",null,"They're named after ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Pierre_B%C3%A9zier"},"Pierre Bézier"),', who is principally responsible for getting them known to the world as a curve well-suited for design work (working for Renault and publishing his investigations in 1962), although he was not the first, or only one, to "invent" these type of curves. One might be tempted to say that the mathematician ',r.createElement("a",{href:"https://en.wikipedia.org/wiki/Paul_de_Casteljau"},"Paul de Casteljau"),' was first, investigating the nature of these curves in 1959 while working at Citroën, coming up with a really elegant way of figuring out how to draw them. However, de Casteljau did not publish his work, making the question "who was first" hard to answer in any absolute sense. Or is it? Bézier curves are, at their core, "Bernstein polynomials", a family of mathematical functions investigated by ',r.createElement("a",{href:"https://en.wikipedia.org/wiki/Sergei_Natanovich_Bernstein"},"Sergei Natanovich Bernstein"),", with publications on them at least as far back as 1912. Anyway, that's mostly trivia, what you are more likely to care about is that these curves are handy: you can link up multiple Bézier curves so that the combination looks like a single curve. If you've ever drawn Photoshop \"paths\" or worked with vector drawing programs like Flash, Illustrator or nkscape, those curves you've been drawing are Bézier curves."),r.createElement("p",null,"So, what if you need to program them yourself? What are the pitfalls? How do you draw them? What are the bounding boxes, how do you determine intersections, how can you extrude a curve, in short: how do you do everything that you might want when you do with these curves? That's what this page is for. Prepare to be mathed!"),r.createElement("p",null,"—Pomax (or in the tweetworld, ",r.createElement("a",{href:"https://twitter.com/TheRealPomax"},"@TheRealPomax"),")"),r.createElement("div",{className:"note"},r.createElement("h2",{id:"note-virtually-all-b-zier-graphics-are-interactive-"},"Note: virtually all Bézier graphics are interactive."),r.createElement("p",null,"This page uses interactive examples, relying heavily on ",r.createElement("a",{href:"http://pomax.github.io/bezierjs"},"Bezier.js"),', as well as "real" maths (in LaTeX form) which is typeset using the most excellent ',r.createElement("a",{href:"http://MathJax.org"},"MathJax")," library. The page is generated offline as a React application, using Webpack, which has made adding \"view source\" options considerably more challenging. I'm still trying to figure out how to add them back in, but it didn't feel like it should hold up deploying this update compared to the previous years' version."),r.createElement("h2",{id:"this-book-is-open-source-"},"This book is open source."),r.createElement("p",null,"This book is an open source software project, and lives on two github repositorites. The first is ",r.createElement("a",{href:"https://github.com/pomax/bezierinfo"},"https://github.com/pomax/bezierinfo")," and is the purely-for-presentation version you are viewing right now. The other repository is ",r.createElement("a",{href:"https://github.com/pomax/BezierInfo-2"},"https://github.com/pomax/BezierInfo-2"),", which is the development version, housing all the html, javascript, and css. You can fork either of these, and pretty much do with them as you please, except for passing it off as your own work wholesale, of course =)"),r.createElement("h2",{id:"how-complicated-is-the-maths-going-to-be-"},"How complicated is the maths going to be?"),r.createElement("p",null,"Most of the mathematics in this Primer are early high school maths. If you understand basic arithmetic, and you know how to read English, you should be able to get by just fine. There will at times be ",r.createElement("em",null,"far"),' more complicated maths, but if you don\'t feel like digesting them, you can safely skip over them by either skipping over the "detail boxes" in section or by just jumping to the end of a section with maths that looks too involving. The end of sections typically simply list the conclusions so you can just work with those values directly.'),r.createElement("h2",{id:"questions-comments-"},"Questions, comments:"),r.createElement("p",null,"If you have suggestions for new sections, hit up the ",r.createElement("a",{href:"https://github.com/pomax/BezierInfo-2/issues"},"Github issue tracker")," (also reachable from the repo linked to in the upper right). If you have questions about the material, there's currently no comment section while I'm doing the rewrite, but you can use the issue tracker for that as well. Once the rewrite is done, I'll add a general comment section back in, and maybe a more topical \"select this section of text and hit the 'question' button to ask a question about it\" system. We'll see."),r.createElement("h2",{id:"buy-me-a-coffee-"},"Buy me a coffee?"),r.createElement("p",null,"If you enjoyed this book, or you simply found it useful for something you were trying to get done, and you were wondering how to let me know you appreciated this book, you can always ",r.createElement("a",{href:"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QPRDLNGDANJSW"},"buy me a coffee"),", however-much a coffee is where you live. This work has grown over the years, from a small primer to a 70ish print-page-equivalent reader on the subject of Bézier curves, and a lot of coffee went into the making of it. I don't regret a minute I spent on writing it, but I can always do with some more coffee to keep on writing!")))}},introduction:{locale:"en-GB",title:"A lightning introduction",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"introduction",title:"A lightning introduction",number:"1"}),r.createElement("p",null,"Let's start with the good stuff: when we're talking about Bézier curves, we're talking about the things that you can see in the following graphics. They run from some start point to some end point, with their curvature influenced by one or more \"intermediate\" control points. Now, because all the graphics on this page are interactive, go manipulate those curves a bit: click-drag the points, and see how their shape changes based on what you do."),r.createElement("div",{className:"figure"},r.createElement(i,{inline:!0,title:"Quadratic Bézier curves",setup:e.drawQuadratic,draw:e.drawCurve}),r.createElement(i,{inline:!0,title:"Cubic Bézier curves",setup:e.drawCubic,draw:e.drawCurve})),r.createElement("p",null,"These curves are used a lot in computer aided design and computer aided manufacturing (CAD/CAM) applications, as well as in graphic design programs like Adobe Illustrator and Photoshop, Inkscape, the Gimp, etc. and in graphic technologies like scalable vector graphics (SVG) and OpenType fonts (ttf/otf). A lot of things use Bézier curves, so if you want to learn more about them... prepare to get your learn on!"))}},whatis:{locale:"en-GB",title:"So what makes a Bézier Curve?",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"whatis",title:"So what makes a Bézier Curve?",number:"2"}),r.createElement("p",null,"Playing with the points for curves may have given you a feel for how Bézier curves behave, but what ",r.createElement("em",null,"are")," Bézier curves, really? There are two ways to explain what a Bézier curve is, and they turn out to be the entirely equivalent, but one of them uses complicated maths, and the other uses really simple maths. So... let's start with the simple explanation:"),r.createElement("p",null,"Bezier curves are the result of ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Linear_interpolation"},"linear interpolations"),". That sounds complicated but you've been doing linear interpolation since you were very young: any time you had to point at something between two other things, you've been applying linear interpolation. It's simply \"picking a point between two points\"."),r.createElement("p",null,"If we know the distance between those two points, and we want a new point that is, say, 20% the distance away from the first point (and thus 80% the distance away from the second point) then we can compute that really easily:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/8090904d6448ed0c8e6151aecf62f361d51ead96.svg",width:"526.4rem",height:"107.8rem"}),r.createElement("p",null,"So let's look at that in action: the following graphic is interactive in that you can use your up and down arrow keys to increase or decrease the interpolation ratio, to see what happens. We start with three points, which gives us two lines. Linear interpolation over those lines gives use two points, between which we can again perform linear interpolation, yielding a single point. And that point —and all points we can form in this way for all ratios taken together— form our Bézier curve:"),r.createElement(i,{title:"Linear Interpolation leading to Bézier curves",setup:e.setup,draw:e.draw,onKeyDown:e.onKeyDown}),r.createElement("p",null,"And that brings us to the complicated maths: calculus."),r.createElement("p",null,'While it doesn\'t look like that\'s what we\'ve just done, we actually just drew a quadratic curve, in steps, rather than in a single go. One of the fascinating parts about Bézier curves is that they can both be described in terms of polynomial functions, as well as in terms of very simple interpolations of interpolations of [...]. That, in turn, means we can look at what these curves can do based on both "real maths" (by examining the functions, their derivatives, and all that stuff), as well as by looking at the "mechanical" composition (which tells us that a curve will never extend beyond the points we used to construct it, for instance)'),r.createElement("p",null,"So let's start looking at Bézier curves a bit more in depth. Their mathematical expressions, the properties we can derive from those, and the various things we can do to, and with, Bézier curves."))}},explanation:{locale:"en-GB",title:"The mathematics of Bézier curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"explanation",title:"The mathematics of Bézier curves",number:"3"}),r.createElement("p",null,'Bézier curves are a form of "parametric" function. Mathematically speaking, parametric functions are cheats: a "function" is actually a well defined term representing a mapping from any number of inputs to a ',r.createElement("strong",null,"single")," output. Numbers go in, a single number comes out. Change the numbers that go in, and the number that comes out is still a single number. Parametric functions cheat. They basically say \"alright, well, we want multiple values coming out, so we'll just use more than one function\". An illustration: Let's say we have a function that maps some value, let's call it ",r.createElement("i",null,"x"),", to some other value, using some kind of number manipulation:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/785e792c343b71d4e674ac94d8800940b30917ac.svg",width:"100.8rem",height:"18.2rem"}),r.createElement("p",null,"The notation ",r.createElement("i",null,"f(x)")," is the standard way to show that it's a function (by convention called ",r.createElement("i",null,"f")," if we're only listing one) and its output changes based on one variable (in this case, ",r.createElement("i",null,"x"),"). Change ",r.createElement("i",null,"x"),", and the output for ",r.createElement("i",null,"f(x)")," changes."),r.createElement("p",null,"So far so good. Now, let's look at parametric functions, and how they cheat. Let's take the following two functions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0dfe7562b43441e72201ff4cdd2e8b6e2e3ecb2d.svg",width:"98rem",height:"37.8rem"}),r.createElement("p",null,"There's nothing really remarkable about them, they're just a sine and cosine function, but you'll notice the inputs have different names. If we change the value for ",r.createElement("i",null,"a"),", we're not going to change the output value for ",r.createElement("i",null,"f(b)"),", since ",r.createElement("i",null,"a")," isn't used in that function. Parametric functions cheat by changing that. In a parametric function all the different functions share a variable, like this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ed6f533530199d1e99b3319ba137c1327b0459c0.svg",width:"105rem",height:"42rem"}),r.createElement("p",null,"Multiple functions, but only one variable. If we change the value for ",r.createElement("i",null,"t"),", we change the outcome of both ",r.createElement("i",null,"f",r.createElement("sub",null,"a"),"(t)")," and ",r.createElement("i",null,"f",r.createElement("sub",null,"b"),"(t)"),". You might wonder how that's useful, and the answer is actually pretty simple: if we change the labels ",r.createElement("i",null,"f",r.createElement("sub",null,"a"),"(t)")," and ",r.createElement("i",null,"f",r.createElement("sub",null,"b"),"(t)")," with what we usually mean with them for parametric curves, things might be a lot more obvious:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ea632ea75d6a2aeb6fe69c07feb6e76f81884746.svg",width:"81.19999999999999rem",height:"42rem"}),r.createElement("p",null,"There we go. ",r.createElement("i",null,"x"),"/",r.createElement("i",null,"y")," coordinates, linked through some mystery value ",r.createElement("i",null,"t"),"."),r.createElement("p",null,"So, parametric curves don't define a ",r.createElement("i",null,"y")," coordinate in terms of an ",r.createElement("i",null,"x"),' coordinate, like normal functions do, but they instead link the values to a "control" variable. If we vary the value of ',r.createElement("i",null,"t"),", then with every change we get ",r.createElement("strong",null,"two")," values, which we can use as (",r.createElement("i",null,"x"),",",r.createElement("i",null,"y"),") coordinates in a graph. The above set of functions, for instance, generates points on a circle: We can range ",r.createElement("i",null,"t")," from negative to positive infinity, and the resulting (",r.createElement("i",null,"x"),",",r.createElement("i",null,"y"),") coordinates will always lie on a circle with radius 1 around the origin (0,0). If we plot it for ",r.createElement("i",null,"t")," from 0 to 5, we get this (use your up and down arrow keys to change the plot end value):"),r.createElement(i,{preset:"empty",title:"A (partial) circle: x=sin(t), y=cos(t)",static:!0,setup:e.setup,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"Bézier curves are (one in many classes of) parametric functions, and are characterised by using the same base function for all its dimensions. Unlike the above example, where the ",r.createElement("i",null,"x")," and ",r.createElement("i",null,"y"),' values use different functions (one uses a sine, the other a cosine), Bézier curves use the "binomial polynomial" for both ',r.createElement("i",null,"x")," and ",r.createElement("i",null,"y"),". So what are binomial polynomials?"),r.createElement("p",null,"You may remember polynomials from high school, where they're those sums that look like:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3e8b26cf8833db7089d65e9c6b3953a3140bb19f.svg",width:"224rem",height:"21rem"}),r.createElement("p",null,"If they have a highest order term ",r.createElement("i",null,"x³")," they're called \"cubic\" polynomials, if it's ",r.createElement("i",null,"x²")," it's a \"square\" polynomial, if it's just ",r.createElement("i",null,"x")," it's a line (and if there aren't even any terms with ",r.createElement("i",null,"x")," it's not a polynomial!)"),r.createElement("p",null,"Bézier curves are polynomials of ",r.createElement("i",null,"t"),", rather than ",r.createElement("i",null,"x"),", with the value for ",r.createElement("i",null,"t")," fixed being between 0 and 1, with coefficients ",r.createElement("i",null,"a"),", ",r.createElement("i",null,"b"),' etc. taking the "binomial" form, which sounds fancy but is actually a pretty simple description for mixing values:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/565d935cab46bc995f53190102dadfdd1afc08f6.svg",width:"385rem",height:"68.6rem"}),r.createElement("p",null,"I know what you're thinking: that doesn't look too simple, but if we remove ",r.createElement("i",null,"t"),' and add in "times one", things suddenly look pretty easy. Check out these binomial terms:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/8c618738924e53a313a31fa407b3d91155525ee1.svg",width:"219.79999999999998rem",height:"91rem"}),r.createElement("p",null,'Notice that 2 is the same as 1+1, and 3 is 2+1 and 1+2, and 6 is 3+3... As you can see, each time we go up a dimension, we simply start and end with 1, and everything in between is just "the two numbers above it, added together". Now ',r.createElement("i",null,"that's")," easy to remember."),r.createElement("p",null,"There's an equally simple way to figure out how the polynomial terms work: if we rename ",r.createElement("i",null,"(1-t)")," to ",r.createElement("i",null,"a")," and ",r.createElement("i",null,"t")," to ",r.createElement("i",null,"b"),", and remove the weights for a moment, we get this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c8740a3a9a63b592e1480883a54024ebdaffaf05.svg",width:"316.4rem",height:"62.99999999999999rem"}),r.createElement("p",null,"It's basically just a sum of \"every combination of ",r.createElement("i",null,"a")," and ",r.createElement("i",null,"b"),'", progressively replacing ',r.createElement("i",null,"a"),"'s with ",r.createElement("i",null,"b"),"'s after every + sign. So that's actually pretty simple too. So now you know binomial polynomials, and just for completeness I'm going to show you the generic function for this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/444a01611e5709f702c36f6ca17aa2761c0877a9.svg",width:"315rem",height:"57.4rem"}),r.createElement("p",null,"And that's the full description for Bézier curves. Σ in this function indicates that this is a series of additions (using the variable listed below the Σ, starting at ...=<value> and ending at the value listed on top of the Σ)."),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"how-to-implement-the-basis-function"},"How to implement the basis function"),r.createElement("p",null,"We could naively implement the basis function as a mathematical construct, using the function as our guide, like this:"),r.createElement("pre",null,"function Bezier(n,t):\n sum = 0\n for(k=0; k<n; k++):\n sum += n!/(k!*(n-k)!) * (1-t)^(n-k) * t^(k)\n return sum\n"),r.createElement("p",null,"I say we could, because we're not going to: the factorial function is ",r.createElement("em",null,"incredibly"),' expensive. And, as we can see from the above explanation, we can actually create Pascal\'s triangle quite easily without it: just start at [1], then [1,1], then [1,2,1], then [1,3,3,1], and so on, with each next row fitting 1 more number than the previous row, starting and ending with "1", with all the numbers in between being the sum of the previous row\'s elements on either side "above" the one we\'re computing.'),r.createElement("p",null,"We can generate this as a list of lists lightning fast, and then never have to compute the binomial terms because we have a lookup table:"),r.createElement("pre",null,"lut = [ [1], // n=0\n [1,1], // n=1\n [1,2,1], // n=2\n [1,3,3,1], // n=3\n [1,4,6,4,1], // n=4\n [1,5,10,10,5,1], // n=5\n [1,6,15,20,15,6,1]] // n=6\n\nbinomial(n,k):\n while(n >= lut.length):\n s = lut.length\n nextRow = new array(size=s+1)\n nextRow[0] = 1\n for(i=1, prev=s-1; i<prev; i++):\n nextRow[i] = lut[prev][i-1] + lut[prev][i]\n nextRow[s] = 1\n lut.add(nextRow)\n return lut[n][k]\n"),r.createElement("p",null,"So what's going on here? First, we declare a lookup table with a size that's reasonably large enough to accommodate most lookups. Then, we declare a function to get us the values we need, and we make sure that if an n/k pair is requested that isn't in the LUT yet, we expand it first. Our basis function now looks like this:"),r.createElement("pre",null,"function Bezier(n,t):\n sum = 0\n for(k=0; k<=n; k++):\n sum += binomial(n,k) * (1-t)^(n-k) * t^(k)\n return sum\n"),r.createElement("p",null,"Perfect. Of course, we can optimize further. For most computer graphics purposes, we don't need arbitrary curves. We need quadratic and cubic curves (this primer actually does do arbitrary curves, so you'll find code similar to shown here), which means we can drastically simplify the code:"),r.createElement("pre",null,"function Bezier(2,t):\n t2 = t * t\n mt = 1-t\n mt2 = mt * mt\n return mt2 + 2*mt*t + t2\n\nfunction Bezier(3,t):\n t2 = t * t\n t3 = t2 * t\n mt = 1-t\n mt2 = mt * mt\n mt3 = mt2 * mt\n return mt3 + 3*mt2*t + 3*mt*t2 + t3\n"),r.createElement("p",null,"And now we know how to program the basis function. Exellent.")),r.createElement("p",null,"So, now we know what the base function(s) look(s) like, time to add in the magic that makes Bézier curves so special: control points."))}},control:{locale:"en-GB",title:"Controlling Bézier curvatures",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"control",title:"Controlling Bézier curvatures",number:"4"}),r.createElement("p",null,'Bézier curves are (like all "splines") interpolation functions, meaning they take a set of points, and generate values somewhere "between" those points. (One of the consequences of this is that you\'ll never be able to generate a point that lies outside the outline for the control points, commonly called the "hull" for the curve. Useful information!). In fact, we can visualize how each point contributes to the value generated by the function, so we can see which points are important, where, in the curve.'),r.createElement("p",null,'The following graphs show the interpolation functions for quadratic and cubic curves, with "S" being the strength of a point\'s contribution to the total sum of the Bézier function. Click or click-drag to see the interpolation percentages for each curve-defining point at a specific ',r.createElement("i",null,"t")," value."),r.createElement("div",{className:"figure"},r.createElement(i,{inline:!0,preset:"simple",title:"Quadratic interpolations",draw:e.drawQuadraticLerp}),r.createElement(i,{inline:!0,preset:"simple",title:"Cubic interpolations",draw:e.drawCubicLerp}),r.createElement(i,{inline:!0,preset:"simple",title:"15th order interpolations",draw:e.draw15thLerp})),r.createElement("p",null,"Also shown is the interpolation function for a 15",r.createElement("sup",null,"th")," order Bézier function. As you can see, the start and end point contribute considerably more to the curve's shape than any other point in the control point set."),r.createElement("p",null,'If we want to change the curve, we need to change the weights of each point, effectively changing the interpolations. The way to do this is about as straight forward as possible: just multiply each point with a value that changes its strength. These values are conventionally called "Weights", and we can add them to our original Bézier function:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/cc82da74955e71db3f5f0ab77dcc4664c0387bec.svg",width:"369.59999999999997rem",height:"57.4rem"}),r.createElement("p",null,'That looks complicated, but as it so happens, the "weights" are actually just the coordinate values we want our curve to have: for an ',r.createElement("i",null,"n",r.createElement("sup",null,"th"))," order curve, w",r.createElement("sub",null,"0")," is our start coordinate, w",r.createElement("sub",null,"n")," is our last coordinate, and everything in between is a controlling coordinate. Say we want a cubic curve that starts at (120,160), is controlled by (35,200) and (220,260) and ends at (220,40), we use this Bézier curve:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/853858526831a7ef3eb170efe49de397bb4913a1.svg",width:"496.99999999999994rem",height:"42rem"}),r.createElement("p",null,"Which gives us the curve we saw at the top of the article:"),r.createElement(i,{preset:"simple",title:"Our cubic Bézier curve",setup:e.drawCubic,draw:e.drawCurve}),r.createElement("p",null,"What else can we do with Bézier curves? Quite a lot, actually. The rest of this article covers a multitude of possible operations and algorithms that we can apply, and the tasks they achieve."),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"how-to-implement-the-weighted-basis-function"},"How to implement the weighted basis function"),r.createElement("p",null,"Given that we already know how to implement basis function, adding in the control points is remarkably easy:"),r.createElement("pre",null,"function Bezier(n,t,w[]):\n sum = 0\n for(k=0; k<n; k++):\n sum += w[k] * binomial(n,k) * (1-t)^(n-k) * t^(k)\n return sum\n"),r.createElement("p",null,"And for the extremely optimized versions:"),r.createElement("pre",null,"function Bezier(2,t,w[]):\n t2 = t * t\n mt = 1-t\n mt2 = mt * mt\n return w[0]*mt2 + w[1]*2*mt*t + w[2]*t2\n\nfunction Bezier(3,t,w[]):\n t2 = t * t\n t3 = t2 * t\n mt = 1-t\n mt2 = mt * mt\n mt3 = mt2 * mt\n return w[0]*mt3 + 3*w[1]*mt2*t + 3*w[2]*mt*t2 + w[3]*t3\n"),r.createElement("p",null,"And now we know how to program the weighted basis function.")))}},extended:{locale:"en-GB",title:"The Bézier interval [0,1]",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"extended",title:"The Bézier interval [0,1]",number:"5"}),r.createElement("p",null,"Now that we know the mathematics behind Bézier curves, there's one curious thing that you may have noticed: they always run from ",r.createElement("code",null,"t=0")," to ",r.createElement("code",null,"t=1"),". Why that particular interval?"),r.createElement("p",null,'It all has to do with how we run from "the start" of our curve to "the end" of our curve. If we have a value that is a mixture of two other values, then the general formula for this is:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7f5ebb8489a8d04beb28f47c8aac2632b78ae764.svg",width:"225.39999999999998rem",height:"16.799999999999997rem"}),r.createElement("p",null,"The obvious start and end values here need to be ",r.createElement("code",null,"a=1, b=0"),", so that the mixed value is 100% value 1, and 0% value 2, and ",r.createElement("code",null,"a=0, b=1"),', so that the mixed value is 0% value 1 and 100% value 2. Additionally, we don\'t want "a" and "b" to be independent: if they are, then we could just pick whatever values we like, and end up with a mixed value that is, for example, 100% value 1 ',r.createElement("strong",null,"and")," 100% value 2. In principle that's fine, but for Bézier curves we always want mixed values ",r.createElement("em",null,"between"),' the start and end point, so we need to make sure we can never set "a" and "b" to some values that lead to a mix value that sums to more than 100%. And that\'s easy:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d326c8f323ccd2da00d998b533ac26a1c04fcfba.svg",width:"225.39999999999998rem",height:"16.799999999999997rem"}),r.createElement("p",null,"With this we can guarantee that we never sum above 100%. By restricting ",r.createElement("code",null,"a")," to values in the interval [0,1], we will always be somewhere between our two values (inclusively), and we will always sum to a 100% mix."),r.createElement("p",null,'But... what if we use this form, used in the assumption that we will only ever use values between 0 and 1, and instead use values outside of that interval? Do things go horribly wrong? Well... not really, but we get to "see more".'),r.createElement("p",null,'In the case of Bézier curves, extending the interval simply makes our curve "keep going". Bézier curves are simply segments on some polynomial curve, so if we pick a wider interval we simply get to see more of the curve. So what do they look like?'),r.createElement("p",null,'The following two graphics show you Bézier curves rendered "the usual way", as well as the curves they "lie on" if we were to extend the ',r.createElement("code",null,"t"),' values much further. As you can see, there\'s a lot more "shape" hidden in the rest of the curve, and we can model those parts by moving the curve points around.'),r.createElement(i,{preset:"simple",title:"Quadratic infinite interval Bézier curve",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"simple",title:"Cubic infinite interval Bézier curve",setup:e.setupCubic,draw:e.draw}),r.createElement("p",null,"In fact, there are curves used in graphics design and computer modelling that do the opposite of Bézier curves, where rather than fixing the interval, and giving you free coordinates, they fix the coordinates, but give you freedom over the interval. A great example of this is the ",r.createElement("a",{ +href:"http://levien.com/phd/phd.html"},'"Spiro" curve'),", which is a curve based on part of a ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Euler_spiral"},"Cornu Spiral, also known as Euler's Spiral"),". It's a very aesthetically pleasing curve and you'll find it in quite a few graphics packages like ",r.createElement("a",{href:"https://fontforge.github.io"},"FontForge")," and ",r.createElement("a",{href:"https://inkscape.org"},"Inkscape"),", having even been used in font design (such as for the Inconsolata font)."))}},matrix:{locale:"en-GB",title:"Bézier curvatures as matrix operations",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"matrix",title:"Bézier curvatures as matrix operations",number:"6"}),r.createElement("p",null,"We can also represent Bézier as matrix operations, by expressing the Bézier formula as a polynomial basis function and a coefficients matrix, and the actual coordinates as matrix. Let's look at what this means for the cubic curve:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d961171d6d1dfc22bb1756901e79102147914360.svg",width:"491.4rem",height:"21rem"}),r.createElement("p",null,"Disregarding our actual coordinates for a moment, we have:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/f925c339011e6c38e47b9c3a571e02fca80eb5c3.svg",width:"371rem",height:"19.599999999999998rem"}),r.createElement("p",null,"We can write this as a sum of four expressions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/30d76165668bf15f62986503bea100f39c5b9fec.svg",width:"147rem",height:"78.39999999999999rem"}),r.createElement("p",null,"And we can expand these expressions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7ca5abe1124ba1e51b7f12e0469cb4b1407593b8.svg",width:"417.2rem",height:"78.39999999999999rem"}),r.createElement("p",null,"Furthermore, we can make all the 1 and 0 factors explicit:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/bccbb94942e3ff79579e4719106f4701c157727e.svg",width:"228.2rem",height:"78.39999999999999rem"}),r.createElement("p",null,"And ",r.createElement("em",null,"that"),", we can view as a series of four matrix operations:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d5f85d80fbbc62e1e8d58621b76f3d0224876b62.svg",width:"637rem",height:"75.6rem"}),r.createElement("p",null,"If we compact this into a single matrix operation, we get:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7140be48f45b2e7190fa8dffef5c05c47c038ab0.svg",width:"237.99999999999997rem",height:"75.6rem"}),r.createElement("p",null,"This kind of polynomial basis representation is generally written with the bases in increasing order, which means we need to flip our ",r.createElement("code",null,"t"),' matrix horizontally, and our big "mixing" matrix upside down:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/4e1849950a5c13f5135aa3412e0ee634cdc67301.svg",width:"237.99999999999997rem",height:"75.6rem"}),r.createElement("p",null,"And then finally, we can add in our original coordinates as a single third matrix:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5910e25a46d9e86ab34513017f1274628a40e5a7.svg",width:"338.79999999999995rem",height:"77rem"}),r.createElement("p",null,"We can perform the same trick for the quadratic curve, in which case we end up with:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e56e78e406d625c2a5ec584216f79a5fee00d8ea.svg",width:"275.79999999999995rem",height:"57.4rem"}),r.createElement("p",null,"If we plug in a ",r.createElement("code",null,"t")," value, and then multiply the matrices, we will get exactly the same values as when we evaluate the original polynomial function, or as when we evaluate the curve using progessive linear interpolation."),r.createElement("p",null,r.createElement("strong",null,"So: why would we bother with matrices?")," Matrix representations allow us to discover things about functions that would otherwise be hard to tell. It turns out that the curves form ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Triangular_matrix"},"triangular matrices"),", and they have a determinant equal to the product of the actual coordinates we use for our curve. It's also invertible, which means there's ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Invertible_matrix#The_invertible_matrix_theorem"},"a ton of properties")," that are all satisfied. Of course, the main question is: \"Why is this useful to us, now?\", and the answer to that is that it's not immediately useful, but you'll be seeing some instances where certain curve properties can be either computed via function manipulation, or via clever use of matrices, and sometimes the matrix approach can be (drastically) faster."),r.createElement("p",null,"So for now, just remember that we can represent curves this way, and let's move on."))}},decasteljau:{locale:"en-GB",title:"de Casteljau's algorithm",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"decasteljau",title:"de Casteljau's algorithm",number:"7"}),r.createElement("p",null,"If we want to draw Bézier curves we can run through all values of ",r.createElement("code",null,"t")," from 0 to 1 and then compute the weighted basis function, getting the ",r.createElement("code",null,"x/y"),' values we need to plot, but the more complex the curve gets, the more expensive this becomes. Instead, we can use "de Casteljau\'s algorithm" to draw curves, which is a geometric approach to drawing curves, and really easy to implement. So easy, in fact, you can do it by hand with a pencil and ruler.'),r.createElement("p",null,"Rather than using our calculus function to find ",r.createElement("code",null,"x/y")," values for ",r.createElement("code",null,"t"),", let's do this instead:"),r.createElement("ul",null,r.createElement("li",null,"treat ",r.createElement("code",null,"t")," as a ratio (which it is). t=0 is 0% along a line, t=1 is 100% along a line."),r.createElement("li",null,"Take all lines between the curve's defining points. For an order ",r.createElement("code",null,"n")," curve, that's ",r.createElement("code",null,"n")," lines."),r.createElement("li",null,"Place markers along each of these line, at distance ",r.createElement("code",null,"t"),". So if ",r.createElement("code",null,"t")," is 0.2, place the mark at 20% from the start, 80% from the end."),r.createElement("li",null,"Now form lines between ",r.createElement("code",null,"those")," points. This gives ",r.createElement("code",null,"n-1")," lines."),r.createElement("li",null,"Place markers along each of these line at distance ",r.createElement("code",null,"t"),"."),r.createElement("li",null,"Form lines between ",r.createElement("code",null,"those")," points. This'll be ",r.createElement("code",null,"n-2")," lines."),r.createElement("li",null,"place markers, form lines, place markers, etc."),r.createElement("li",null,"repeat this until you have only one line left. The point ",r.createElement("code",null,"t")," on that line coincides with the original curve point at ",r.createElement("code",null,"t"),".")),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"how-to-implement-de-casteljau-s-algorithm"},"How to implement de Casteljau's algorithm"),r.createElement("p",null,"Let's just use the algorithm we just specified, and implement that:"),r.createElement("pre",null,"function drawCurve(points[], t):\n if(points.length==1):\n draw(points[0])\n else:\n newpoints=array(points.size-1)\n for(i=0; i<newpoints.length; i++):\n newpoints[i] = (1-t) * points[i] + t * points[i+1]\n drawCurve(newpoints, t)\n"),r.createElement("p",null,"And done, that's the algorithm implemented. Except usually you don't get the luxury of overloading the \"+\" operator, so let's also give the code for when you need to work with ",r.createElement("code",null,"x")," and ",r.createElement("code",null,"y")," values:"),r.createElement("pre",null,"function drawCurve(points[], t):\n if(points.length==1):\n draw(points[0])\n else:\n newpoints=array(points.size-1)\n for(i=0; i<newpoints.length; i++):\n x = (1-t) * points[i].x + t * points[i+1].x\n y = (1-t) * points[i].y + t * points[i+1].y\n newpoints[i] = new point(x,y)\n drawCurve(newpoints, t)\n"),r.createElement("p",null,"So what does this do? This draws a point, if the passed list of points is only 1 point long. Otherwise it will create a new list of points that sit at the ",r.createElement("i",null,"t"),' ratios (i.e. the "markers" outlined in the above algorithm), and then call the draw function for this new list.')),r.createElement("p",null,"To see this in action, mouse-over the following sketch. Moving the mouse changes which curve point is explicitly evaluated using de Casteljau's algorithm, moving the cursor left-to-right (or, of course, right-to-left), shows you how a curve is generated using this approach."),r.createElement(i,{preset:"simple",title:"Traversing a curve using de Casteljau's algorithm",setup:e.setup,draw:e.draw}))}},flattening:{locale:"en-GB",title:"Simplified drawing",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"flattening",title:"Simplified drawing",number:"8"}),r.createElement("p",null,'We can also simplify the drawing process by "sampling" the curve at certain points, and then joining those points up with straight lines, a process known as "flattening", as we are reducing a curve to a simple sequence of straight, "flat" lines.'),r.createElement("p",null,'We can do this is by saying "we want X segments", and then sampling the curve at intervals that are spaced such that we end up with the number of segments we wanted. The advantage of this method is that it\'s fast: instead of evaluating 100 or even 1000 curve coordinates, we can sample a much lower number and still end up with a curve that sort-of-kind-of looks good enough. The disadvantage of course is that we lose the precision of working with "the real curve", so we usually can\'t use the flattened for for doing true intersection detection, or curvature alignment.'),r.createElement(i,{preset:"twopanel",title:"Flattening a quadratic curve",setup:e.setupQuadratic,draw:e.drawFlattened,onKeyDown:e.onKeyDown}),r.createElement(i,{preset:"twopanel",title:"Flattening a cubic curve",setup:e.setupCubic,draw:e.drawFlattened,onKeyDown:e.onKeyDown}),r.createElement("p",null,"Try clicking on the sketch and using your up and down arrow keys to lower the number of segments for both the quadratic and cubic curve. You'll notice that for certain curvatures, a low number of segments works quite well, but for more complex curvatures (try this for the cubic curve), a higher number is required to capture the curvature changes properly."),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"how-to-implement-curve-flattening"},"How to implement curve flattening"),r.createElement("p",null,"Let's just use the algorithm we just specified, and implement that:"),r.createElement("pre",null,"function flattenCurve(curve, segmentCount):\n step = 1/segmentCount;\n coordinates = [curve.getXValue(0), curve.getYValue(0)]\n for(i=1; i <= segmentCount; i++):\n t = i*step;\n coordinates.push[curve.getXValue(t), curve.getYValue(t)]\n return coordinates;\n"),r.createElement("p",null,'And done, that\'s the algorithm implemented. That just leaves drawing the resulting "curve" as a sequence of lines:'),r.createElement("pre",null,"function drawFlattenedCurve(curve, segmentCount):\n coordinates = flattenCurve(curve, segmentCount)\n coord = coordinates[0], _coords;\n for(i=1; i < coordinates.length; i++):\n _coords = coordinates[i]\n line(coords, _coords)\n coords = _coords\n"),r.createElement("p",null,"We start with the first coordinate as reference point, and then just draw lines between each point and its next point.")))}},splitting:{locale:"en-GB",title:"Splitting curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"splitting",title:"Splitting curves",number:"9"}),r.createElement("p",null,"With de Casteljau's algorithm we also find all the points we need to split up a Bézier curve into two, smaller curves, which taken together form the original curve. When we construct de Casteljau's skeleton for some value ",r.createElement("code",null,"t"),", the procedure gives us all the points we need to split a curve at that ",r.createElement("code",null,"t")," value: one curve is defined by all the inside skeleton points found prior to our on-curve point, with the other curve being defined by all the inside skeleton points after our on-curve point."),r.createElement(i,{title:"Splitting a curve",setup:e.setupCubic,draw:e.drawSplit}),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"implementing-curve-splitting"},"implementing curve splitting"),r.createElement("p",null,"We can implement curve splitting by bolting some extra logging onto the de Casteljau function:"),r.createElement("pre",null,"left=[]\nright=[]\nfunction drawCurve(points[], t):\n if(points.length==1):\n left.add(points[0])\n right.add(points[0])\n draw(points[0])\n else:\n newpoints=array(points.size-1)\n for(i=0; i<newpoints.length; i++):\n if(i==0):\n left.add(points[i])\n if(i==newpoints.length-1):\n right.add(points[i+1])\n newpoints[i] = (1-t) * points[i] + t * points[i+1]\n drawCurve(newpoints, t)\n"),r.createElement("p",null,"After running this function for some value ",r.createElement("code",null,"t"),", the ",r.createElement("code",null,"left")," and ",r.createElement("code",null,"right"),' arrays will contain all the coordinates for two new curves - one to the "left" of our ',r.createElement("code",null,"t"),' value, the other on the "right", of the same order as the original curve, and overlayed exactly on the original curve.')),r.createElement("p",null,"This is best illustrated with an animated graphic (click to play/pause):"),r.createElement(i,{preset:"threepanel",title:"Bézier curve splitting",setup:e.setupCubic,draw:e.drawAnimated,onClick:e.togglePlay}))}},matrixsplit:{locale:"en-GB",title:"Splitting curves using matrices",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"matrixsplit",title:"Splitting curves using matrices",number:"10"}),r.createElement("p",null,"Another way to split curves is to exploit the matrix representation of a Bézier curve. In ",r.createElement("a",{href:"#matrix"},"the section on matrices")," we saw that we can represent curves as matrix multiplications. Specifically, we saw these two forms for the quadratic, and cubic curves, respectively (using the reversed Bézier coefficients vector for legibility):"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e56e78e406d625c2a5ec584216f79a5fee00d8ea.svg",width:"275.79999999999995rem",height:"57.4rem"}),r.createElement("p",null,"and"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/01ea4f74c4785a19bedf18034b51510c5ce2ad8f.svg",width:"338.79999999999995rem",height:"77rem"}),r.createElement("p",null,"Let's say we want to split the curve at some point ",r.createElement("code",null,"t = z"),', forming two new (obviously smaller) Bézier curves. To find the coordinates for these two Bézier curves, we can use the matrix representation and some linear algebra. First, we split out the the actual "point on the curve" information as a new matrix multiplication:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d6fa091a86782480968c232ef86513c578030004.svg",width:"680.4rem",height:"57.4rem"}),r.createElement("p",null,"and"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d487e1e0181420995be49b25bc6595c9d0360435.svg",width:"845.5999999999999rem",height:"78.39999999999999rem"}),r.createElement("p",null,"If we could compact these matrices back to a form ",r.createElement("strong",null,"[t values] · [bezier matrix] · [column matrix]"),", with the first two staying the same, then that column matrix on the right would be the coordinates of a new Bézier curve that describes the first segment, from ",r.createElement("code",null,"t = 0")," to ",r.createElement("code",null,"t = z"),". As it turns out, we can do this quite easily, by exploiting some simple rules of linear algebra (and if you don't care about the derivations, just skip to the end of the box for the results!)."),r.createElement("div",{className:"note"},r.createElement("h2",{id:"deriving-new-hull-coordinates"},"Deriving new hull coordinates"),r.createElement("p",null,"Deriving the two segments upon splitting a curve takes a few steps, and the higher the curve order, the more work it is, so let's look at the quadratic curve first:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d4b8355c3f1f80aacfc2766423a30151c5180a02.svg",width:"365.4rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/fe5f623585a9bbb836f54164aecaadd3fc4ec953.svg",width:"259rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1eb9833685c9189c64d9cbdfdbb24a94e70e493f.svg",width:"259rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/55f9d31b32a3e8855f2d28c3253201c8963eefd1.svg",width:"257.59999999999997rem",height:"57.4rem"}),r.createElement("p",null,"We do this, because [",r.createElement("em",null,"M · M",r.createElement("sup",null,"-1")),"] is the identity matrix (a bit like multiplying something by x/x in calculus. It doesn't do anything to the function, but it does allow you to rewrite it to something that may be easier to work with, or can be broken up differently). Adding that as matrix multiplication has no effect on the total formula, but it does allow us to change the matrix sequence [",r.createElement("em",null,"something · M"),"] to a sequence [",r.createElement("em",null,"M · something"),"], and that makes a world of difference: if we know what [",r.createElement("em",null,"M",r.createElement("sup",null,"-1")," · Z · M"),"] is, we can apply that to our coordinates, and be left with a proper matrix representation of a quadratic Bézier curve (which is [",r.createElement("em",null,"T · M · P"),"]), with a new set of coordinates that represent the curve from ",r.createElement("em",null,"t = 0")," to ",r.createElement("em",null,"t = z"),". So let's get computing:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1dbabc115128a85389cbbcc75fbced48e5a2ca25.svg",width:"658rem",height:"58.8rem"}),r.createElement("p",null,"Excellent! Now we can form our new quadratic curve:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/2972cd74dab6560ea68189c2e53f247287cbefae.svg",width:"438.2rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/39b64e07c41ef6d734064f017036f6391321e924.svg",width:"502.59999999999997rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d615960f862664749c54858520c364efeb4a4c5a.svg",width:"516.6rem",height:"57.4rem"}),r.createElement("p",null,r.createElement("strong",null,r.createElement("em",null,"Brilliant")),": if we want a subcurve from ",r.createElement("code",null,"t = 0")," to ",r.createElement("code",null,"t = z"),", we can keep the first coordinate the same (which makes sense), our control point becomes a z-ratio mixture of the original control point and the start point, and the new end point is a mixture that looks oddly similar to a bernstein polynomial of degree two, except it uses (z-1) rather than (1-z)... These new coordinates are actually really easy to compute directly!"),r.createElement("p",null,"Of course, that's only one of the two curves. Getting the section from ",r.createElement("code",null,"t = z")," to ",r.createElement("code",null,"t = 1")," requires doing this again. We first observe what what we just did is actually evaluate the general interval [0,",r.createElement("code",null,"z"),"], which we wrote down simplified becuase of that zero, but we actually evaluated this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/a51e64df3cb31acf32d0ad5814c8c6cff41ae611.svg",width:"400.4rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b50cdfed6656e681d5885a14a3af3e67efa4ccb.svg",width:"329rem",height:"57.4rem"}),r.createElement("p",null,"If we want the interval [",r.createElement("em",null,"z"),",1], we will be evaluating this instead:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/eca8cfda9b7a3f0819ec38acc53f95af67bb26bb.svg",width:"484.4rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e8c983a3efd47356c971fe46add4d0cdf103cced.svg",width:"432.59999999999997rem",height:"60.199999999999996rem"}),r.createElement("p",null,"We're going to do the same trick, to turn ",r.createElement("code",null,"[something · M]")," into ",r.createElement("code",null,"[M · something]"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/a28b6dcc1335de19a065b6a04d8bb45d86122bb7.svg",width:"765.8rem",height:"60.199999999999996rem"}),r.createElement("p",null,"So, our final second curve looks like:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5851c9191acb59456e3706a8f6f1a0f85e691eda.svg",width:"442.4rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0333e63f50b3d43067dc299280f70e9eb98711bb.svg",width:"496.99999999999994rem",height:"60.199999999999996rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/00a133860115d7a4db4ddf62781b5ae2bffef088.svg",width:"516.6rem",height:"60.199999999999996rem"}),r.createElement("p",null,r.createElement("strong",null,r.createElement("em",null,"Nice")),": we see the same as before; can keep the last coordinate the same (which makes sense), our control point becomes a z-ratio mixture of the original control point and the end point, and the new start point is a mixture that looks oddly similar to a bernstein polynomial of degree two, except it uses (z-1) rather than (1-z). These new coordinates are ",r.createElement("em",null,"also")," really easy to compute directly!")),r.createElement("p",null,"So, using linear algebra rather than de Casteljau's algorithm, we have determined that for any quadratic curve split at some value ",r.createElement("code",null,"t = z"),", we get two subcurves that are described as Bézier curves with simple-to-derive coordinates."),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5769f44aea3344c32c497a3a77d236f524222b95.svg",width:"604.8rem",height:"57.4rem"}),r.createElement("p",null,"and"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1fdde935dc357642358bdf5e632d6539c9d4debd.svg",width:"599.1999999999999rem",height:"60.199999999999996rem"}),r.createElement("p",null,"We can do the same for cubic curves. However, I'll spare you the actual derivation (don't let that stop you from writing that out yourself, though) and simply show you the resulting new coordinate sets:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/44db09290062827525a9b23cbaf91e65063d86d7.svg",width:"883.4rem",height:"78.39999999999999rem"}),r.createElement("p",null,"and"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d6b1abe72bac1b55d184f2c4254769404371d06f.svg",width:"886.1999999999999rem",height:"81.19999999999999rem"}),r.createElement("p",null,"So, looking at our matrices, did we really need to compute the second segment matrix? No, we didn't. Actually having one segment's matrix means we implicitly have the other: push the values of each row in the matrix ",r.createElement("strong",null,r.createElement("em",null,"Q")),' to the right, with zeroes getting pushed off the right edge and appearing back on the left, and then flip the matrix vertically. Presto, you just "calculated" ',r.createElement("strong",null,r.createElement("em",null,"Q'")),"."),r.createElement("p",null,"Implementing curve splitting this way requires less recursion, and is just straight arithmetic with cached values, so can be cheaper on systems were recursion is expensive. If you're doing computation with devices that are good at matrix multiplication, chopping up a Bézier curve with this method will be a lot faster than applying de Casteljau."))}},reordering:{locale:"en-GB",title:"Lowering and elevating curve order",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"reordering",title:"Lowering and elevating curve order",number:"11"}),r.createElement("p",null,"One interesting property of Bézier curves is that an ",r.createElement("em",null,"n",r.createElement("sup",null,"th"))," order curve can always be perfectly represented by an ",r.createElement("em",null,"(n+1)",r.createElement("sup",null,"th"))," order curve, by giving the higher order curve specific control points."),r.createElement("p",null,'If we have a curve with three points, then we can create a four point curve that exactly reproduce the original curve as long as we give it the same start and end points, and for its two control points we pick "1/3',r.createElement("sup",null,"rd")," start + 2/3",r.createElement("sup",null,"rd"),' control" and "2/3',r.createElement("sup",null,"rd")," control + 1/3",r.createElement("sup",null,"rd"),' end", and now we have exactly the same curve as before, except represented as a cubic curve, rather than a quadratic curve.'),r.createElement("p",null,"The general rule for raising an ",r.createElement("em",null,"n",r.createElement("sup",null,"th"))," order curve to an ",r.createElement("em",null,"(n+1)",r.createElement("sup",null,"th"))," order curve is as follows (observing that the start and end weights are the same as the start and end weights for the old curve):"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c69c811b7fa790fbc7d082f29855b6f66243b454.svg",width:"803.5999999999999rem",height:"64.39999999999999rem"}),r.createElement("p",null,"However, this rule also has as direct consequence that you ",r.createElement("strong",null,"cannot")," generally safely lower a curve from ",r.createElement("em",null,"n",r.createElement("sup",null,"th"))," order to ",r.createElement("em",null,"(n-1)",r.createElement("sup",null,"th")),' order, because the control points cannot be "pulled apart" cleanly. We can try to, but the resulting curve will not be identical to the original, and may in fact look completely different.'),r.createElement("p",null,"We can apply this to a (semi) random curve, as is done in the following graphic. Select the sketch and press your up and down arrow keys to elevate or lower the curve order."),r.createElement(i,{preset:"simple",title:"A "+e.getOrder()+" order Bézier curve",setup:e.setup,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"There is a good, if mathematical, explanation on the matrices necessary for optimal reduction over on ",r.createElement("a",{href:"http://www.sirver.net/blog/2011/08/23/degree-reduction-of-bezier-curves"},"Sirver's Castle"),", which given time will find its way in a more direct description into this article."))}},derivatives:{locale:"en-GB",title:"Derivatives",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"derivatives",title:"Derivatives",number:"12"}),r.createElement("p",null,"There's a number of useful things that you can do with Bézier curves based on their derivative, and one of the more amusing observations about Bézier curves is that their derivatives are, in fact, also Bézier curves. In fact, the derivation of a Bézier curve is relatively straight forward, although we do need a bit of math. First, let's look at the derivative rule for Bézier curves, which is:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/17c8e825e1d2ae198cd7c33427870a3cf8ff31a1.svg",width:"350rem",height:"46.199999999999996rem"}),r.createElement("p",null,"which we can also write (observing that ",r.createElement("i",null,"b")," in this formula is the same as our ",r.createElement("i",null,"w")," weights, and that ",r.createElement("i",null,"n")," times a summation is the same as a summation where each term is multiplied by ",r.createElement("i",null,"n"),") as:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/a3a62e074a592e2c6497046261452ef89d1893d3.svg",width:"359.79999999999995rem",height:"46.199999999999996rem"}),r.createElement("p",null,"Or, in plain text: the derivative of an n",r.createElement("sup",null,"th")," degree Bézier curve is an (n-1)",r.createElement("sup",null,"th")," degree Bézier curve, with one fewer term, and new weights w'",r.createElement("sub",null,"0"),"...w'",r.createElement("sub",null,"n-1")," derived from the original weights as n(w",r.createElement("sub",null,"i+1")," - w",r.createElement("sub",null,"i"),"), so for a 3rd degree curve, with four weights, the derivative has three new weights w'",r.createElement("sub",null,"0")," = 3(w",r.createElement("sub",null,"1"),"-w",r.createElement("sub",null,"0"),"), w'",r.createElement("sub",null,"1")," = 3(w",r.createElement("sub",null,"2"),"-w",r.createElement("sub",null,"1"),") and w'",r.createElement("sub",null,"2")," = 3(w",r.createElement("sub",null,"3"),"-w",r.createElement("sub",null,"2"),")."),r.createElement("div",{className:"note"},r.createElement("h3",{id:"-slow-down-why-is-that-true-"},'"Slow down, why is that true?"'),r.createElement("p",null,"Sometimes just being told \"this is the derivative\" is nice, but you might want to see why this is indeed the case. As such, let's have a look at the proof for this derivative. First off, the weights are independent of the full Bézier function, so the derivative involves only the derivative of the polynomial basis function. So, let's find that:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1f8148ecaac6af494a8bb96d2f96f7a96f85d9e0.svg",width:"219.79999999999998rem",height:"37.8rem"}),r.createElement("p",null,"Applying the ",r.createElement("a",{href:"http://en.wikipedia.org/wiki/Product_rule"},"product")," and ",r.createElement("a",{href:"http://en.wikipedia.org/wiki/Chain_rule"},"chain")," rules gives us:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5dbfaadcef0cb26159cedb26c9c7c54ac008064d.svg",width:"432.59999999999997rem",height:"29.4rem"}),r.createElement("p",null,"Which is hard to work with, so let's expand that properly:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ebfac729364de2cfd10ba3b8b4a6a6c44e7b4578.svg",width:"361.2rem",height:"28rem"}),r.createElement("p",null,'Now, the trick is to turn this expression into something that has binomial coefficients again, so we want to end up with things that look like "x! over y!(x-y)!". If we can do that in a way that involves terms of ',r.createElement("i",null,"n-1")," and ",r.createElement("i",null,"k-1"),", we'll be on the right track."),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b2a6fe8fe85ddf02a05f618b9ab12d65cc60cb3c.svg",width:"574rem",height:"79.8rem"}),r.createElement("p",null,"And that's the first part done: the two components inside the parentheses are actually regular, lower order Bezier expressions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/222b5aafd8b8fca6dcfc04ca7ac4248f652752fd.svg",width:"560rem",height:"50.4rem"}),r.createElement("p",null,"Now to apply this to our weighted Bezier curves. We'll write out the plain curve formula that we saw earlier, and then work our way through to its derivative:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e2f7ff20e5f540af4cb96cae56a241f3ea3f52f0.svg",width:"553rem",height:"117.6rem"}),r.createElement("p",null,"If we expand this (with some color to show how terms line up), and reorder the terms by increasing values for ",r.createElement("i",null,"k")," we see the following:"),r.createElement("img",{ +className:"LaTeX SVG",src:"images/latex/2505458c9422a6a1dcc59ad2f5b134c1daf0c860.svg",width:"315rem",height:"114.8rem"}),r.createElement("p",null,"Two of these terms fall way: the first term falls away because there is no -1",r.createElement("sup",null,"st"),' term in a summation. As such, it always contributes "nothing", so we can safely completely ignore it for the purpose of finding the derivative function. The other term is the very last term in this expansion: one involving ',r.createElement("i",null,"B",r.createElement("sub",null,"n-1,n")),". This term would have a binomial coefficient of [",r.createElement("i",null,"i")," choose ",r.createElement("i",null,"i+1"),'], which is a non-existent binomial coefficient. Again, this term would contribute "nothing", so we can ignore it, too. This means we\'re left with:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/f058419c1a80d98e6f74ceaf385a1c4e1fc3c645.svg",width:"309.4rem",height:"74.19999999999999rem"}),r.createElement("p",null,"And that's just a summation of lower order curves:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/08a399ed22fbf888982020848612ab348e4cbfc3.svg",width:"751.8rem",height:"37.8rem"}),r.createElement("p",null,"We can rewrite this as a normal summation, and we're done:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b66421144e6848bbbe434a23b3a7b311ce9ff770.svg",width:"572.5999999999999rem",height:"53.199999999999996rem"})),r.createElement("p",null,"Let's rewrite that in a form similar to our original formula, so we can see the difference. We will first list our original formula for Bézier curves, and then the derivative:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/cc82da74955e71db3f5f0ab77dcc4664c0387bec.svg",width:"369.59999999999997rem",height:"57.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/6c95e389e593152cd24eb52e891db7c7b37c4e97.svg",width:"560rem",height:"61.599999999999994rem"}),r.createElement("p",null,"What are the differences? In terms of the actual Bézier curve, virtually nothing! We lowered the order (rather than ",r.createElement("i",null,"n"),", it's now ",r.createElement("i",null,"n-1"),"), but it's still the same Bézier function. The only real difference is in how the weights change when we derive the curve's function. If we have four points A, B, C, and D, then the derivative will have three points, the second derivative two, and the third derivative one:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/34e8aadefa9d0ee443efe27a1fc76210eedb373c.svg",width:"548.8rem",height:"77rem"}),r.createElement("p",null,"We can keep performing this trick for as long as we have more than one weight. Once we have one weight left, the next step will see ",r.createElement("i",null,"k = 0"),', and the result of our "Bézier function" summation is zero, because we\'re not adding anything at all. As such, a quadratic curve has no second derivative, a cubic curve has no third derivative, and generalized: an ',r.createElement("i",null,"n",r.createElement("sup",null,"th"))," order curve has ",r.createElement("i",null,"n-1")," (meaningful) derivatives, with any further derivative being zero."))}},pointvectors:{locale:"en-GB",title:"Tangents and normals",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"pointvectors",title:"Tangents and normals",number:"13"}),r.createElement("p",null,'If you want to move objects along a curve, or "away from" a curve, the two vectors you\'re most interested in are the tangent vector and normal vector for curve points. These are actually really easy to find. For moving, and orienting, along a curve we use the tangent, which indicates the direction travel at specific points, and is literally just the first derivative of our curve:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/2271ae26977a681a1695d14ea8255564e716916e.svg",width:"148.39999999999998rem",height:"42rem"}),r.createElement("p",null,"This gives us the directional vector we want. We can normalize it to give us uniform directional vectors (having a length of 1.0) at each point, and then do whatever it is we want to do based on those directions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3cb2c4f5806142e83c66e1312520d0783d15201c.svg",width:"263.2rem",height:"26.599999999999998rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/72826b8f5053c299dbb2082678191e3564bb50a6.svg",width:"303.79999999999995rem",height:"60.199999999999996rem"}),r.createElement("p",null,"The tangent is very useful for moving along a line, but what if we want to move away from the curve instead, perpendicular to the curve at some point ",r.createElement("i",null,"t"),'? In that case we want the "normal" vector. This vector runs at a right angle to the direction of the curve, and is typically of length 1.0, so all we have to do is rotate the normalized directional vector and we\'re done:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/6cb29c325e059e236343bdd448c149ecc6d8795f.svg",width:"355.59999999999997rem",height:"62.99999999999999rem"}),r.createElement("div",{className:"note"},r.createElement("p",null,'Rotating coordinates is actually very easy, if you know the rule for it. You might find it explained as "applying a ',r.createElement("a",{href:"https://en.wikipedia.org/wiki/Rotation_matrix"},"rotation matrix"),', which is what we\'ll look at here, too. Essentially, the idea is to take the circles over which we can rotate, and simply "sliding the coordinates" over these circles by the desired angle. If we want a quarter circle turn, we take the coordinate, slide it along the cirle by a quarter turn, and done.'),r.createElement("p",null,"To turn any point ",r.createElement("i",null,"(x,y)")," into a rotated point ",r.createElement("i",null,"(x',y')")," (over 0,0) by some angle φ, we apply this nicely easy computation:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d3932ac925ad9f238029d888dc5432f6678f6491.svg",width:"191.79999999999998rem",height:"39.199999999999996rem"}),r.createElement("p",null,'Which is the "long" version of the following matrix transformation:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7297632eb150a8f5f37178612f71e5d0f2c367b1.svg",width:"221.2rem",height:"42rem"}),r.createElement("p",null,"And that's all we need to rotate any coordinate. Note that for quarter, half and three quarter turns these functions become even easier, since ",r.createElement("em",null,"sin")," and ",r.createElement("em",null,"cos")," for these angles are, respectively: 0 and 1, -1 and 0, and 0 and -1."),r.createElement("p",null,"But ",r.createElement("strong",null,r.createElement("em",null,"why"))," does this work? Why this matrix multiplication? ",r.createElement("a",{href:"http://en.wikipedia.org/wiki/Rotation_matrix#Decomposition_into_shears"},"Wikipedia")," (Technically, Thomas Herter and Klaus Lott) tells us that a rotation matrix can be treated as a sequence of three (elementary) shear operations. When we combine this into a single matrix operation (because all matrix multiplications can be collapsed), we get the matrix that you see above. ",r.createElement("a",{href:"http://datagenetics.com/blog/august32013/index.html"},"DataGenetics")," have an excellent article about this very thing: it's really quite cool, and I strongly recommend taking a quick break from this primer to read that article.")),r.createElement("p",null,"The following two graphics show the tangent and normal along a quadratic and cubic curve, with the direction vector coloured blue, and the normal vector coloured red (the markers are spaced out evenly as ",r.createElement("em",null,"t"),"-intervals, not spaced equidistant)."),r.createElement("div",{className:"figure"},r.createElement(i,{preset:"simple",title:"Quadratic Bézier tangents and normals",inline:!0,setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"simple",title:"Cubic Bézier tangents and normals",inline:!0,setup:e.setupCubic,draw:e.draw})))}},components:{locale:"en-GB",title:"Component functions",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"components",title:"Component functions",number:"14"}),r.createElement("p",null,'One of the first things people run into when they start using Bézier curves in their own programs is "I know how to draw the curve, but how do I determine the bounding box?". It\'s actually reasonably straight forward to do so, but it requires having some knowledge on exploiting math to get the values we need. For bounding boxes, we aren\'t actually interested in the curve itself, but only in its "extremities": the minimum and maximum values the curve has for its x- and y-axis values. If you remember your calculus (provided you ever took calculus, otherwise it\'s going to be hard to remember) we can determine function extremities using the first derivative of that function, but this poses a problem, since our function is parametric: every axis has its own function.'),r.createElement("p",null,"The solution: compute the derivative for each axis separately, and then fit them back together in the same way we do for the original."),r.createElement("p",null,'Let\'s look at how a parametric Bézier curve "splits up" into two normal functions, one for the x-axis and one for the y-axis. Note the left-most figure is again an interactive curve, without labeled axes (you get coordinates in the graph instead). The center and right-most figures are the component functions for computing the x-axis value, given a value for ',r.createElement("i",null,"t")," (between 0 and 1 inclusive), and the y-axis value, respectively."),r.createElement("p",null,"If you move points in a curve sideways, you should only see the middle graph change; likely, moving points vertically should only show a change in the right graph."),r.createElement(i,{preset:"simple",title:"Quadratic Bézier curve components",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"simple",title:"Cubic Bézier curve components",setup:e.setupCubic,draw:e.draw}))}},extremities:{locale:"en-GB",title:"Finding extremities: root finding",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"extremities",title:"Finding extremities: root finding",number:"15"}),r.createElement("p",null,"Now that we understand (well, superficially anyway) the component functions, we can find the extremities of our Bézier curve by finding maxima and minima on the component functions, by solving the equations B'(t) = 0 and B''(t) = 0. Although, in the case of quadratic curves there is no B''(t), so we only need to compute B'(t) = 0. So, how do we compute the first and second derivatives? Fairly easily, actually, until our derivatives are 4th order or higher... then things get really hard. But let's start simple:"),r.createElement("h3",{id:"quadratic-curves-linear-derivatives-"},"Quadratic curves: linear derivatives."),r.createElement("p",null,'Finding the solution for "where is this line 0" should be trivial:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/baa66be2d93813bf9ef4aef1dbfac3db772e30e2.svg",width:"138.6rem",height:"109.19999999999999rem"}),r.createElement("p",null,"Done. And quadratic curves have no meaningful second derivative, so we're ",r.createElement("em",null,"really")," done."),r.createElement("h3",{id:"cubic-curves-the-quadratic-formula-"},"Cubic curves: the quadratic formula."),r.createElement("p",null,"The derivative of a cubic curve is a quadratic curve, and finding the roots for a quadratic Bézier curve means we can apply the ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Quadratic_formula"},"Quadratic formula"),". If you've seen it before, you'll remember it, and if you haven't, it looks like this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d5882cc83b002196c8e701ad273ced103e2b4484.svg",width:"431.2rem",height:"42rem"}),r.createElement("p",null,"So, if we can express a Bézier component function as a plain polynomial, we're done: we just plug in the values into the quadratic formula, check if that square root is negative or not (if it is, there are no roots) and then just compute the two values that come out (because of that plus/minus sign we get two). Any value between 0 and 1 is a root that matters for Bézier curves, anything below or above that is irrelevant (because Bézier curves are only defined over the interval [0,1]). So, how do we convert?"),r.createElement("p",null,"First we turn our cubic Bézier function into a quadratic one, by following the rule mentioned at the end of the ",r.createElement("a",{href:"#derivatives"},"derivatives section"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d38fc2ce8c5af65b94b56897b8ae8d304c84a4b7.svg",width:"561.4rem",height:"37.8rem"}),r.createElement("p",null,"And then, using these ",r.createElement("em",null,"v")," values, we can find out what our ",r.createElement("em",null,"a"),", ",r.createElement("em",null,"b"),", and ",r.createElement("em",null,"c")," should be:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/292b2b9178aca5486da7e1a596e66091ba2ed282.svg",width:"330.4rem",height:"124.6rem"}),r.createElement("p",null,"This gives us thee coefficients ",r.createElement("em",null,"a"),", ",r.createElement("em",null,"b"),", and ",r.createElement("em",null,"c")," that are expressed in terms of ",r.createElement("em",null,"v")," values, where the ",r.createElement("em",null,"v")," values are just convenient expressions of our original ",r.createElement("em",null,"p")," values, so we can do some trivial substitution to get:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/2de779b7b9c6aa130b9aeadbb8c46878b94920a1.svg",width:"323.4rem",height:"65.8rem"}),r.createElement("p",null,"Easy peasy. We can now almost trivially find the roots by plugging those values into the quadratic formula. We also note that the second derivative of a cubic curve means computing the first derivative of a quadratic curve, and we just saw how to do that in the section above."),r.createElement("h3",{id:"quartic-curves-cardano-s-algorithm-"},"Quartic curves: Cardano's algorithm."),r.createElement("p",null,"Quartic—fourth degree—curves have a cubic function as derivative. Now, cubic functions are a bit of a problem because they're really hard to solve. But, way back in the 16",r.createElement("sup",null,"th")," century, ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Gerolamo_Cardano"},"Gerolamo Cardano"),' figured out that even if the general cubic function is really hard to solve, it can be rewritten to a form for which finding the roots is "easy", and then the only hard part is figuring out how to go from that form to the generic form. So:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/a16a0da87e138b1307973397275c296eb475b1b1.svg",width:"478.79999999999995rem",height:"21rem"}),r.createElement("p",null,'This is easier because for the "easier formula" we can use ',r.createElement("a",{href:"http://www.wolframalpha.com/input/?i=t^3+%2B+pt+%2B+q"},"regular calculus")," to find the roots (as a cubic function, however, it can have up to three roots, but two of those can be complex. For the purpose of Bézier curve extremities, we can completely ignore those complex roots, since our ",r.createElement("em",null,"t")," is a plain real number from 0 to 1)."),r.createElement("p",null,"So, the trick is to figure out how to turn the first formula into the second formula, and to then work out the maths that gives us the roots. This is explained in detail over at ",r.createElement("a",{href:"http://www.trans4mind.com/personal_development/mathematics/polynomials/cubicAlgebra.htm"},"Ken J. Ward's page")," for solving the cubic equation, so instead of showing the maths, I'm simply going to show the programming code for solving the cubic equation, with the complex roots getting totally ignored."),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"implementing-cardano-s-algorithm-for-finding-all-real-roots"},"Implementing Cardano's algorithm for finding all real roots"),r.createElement("p",null,'The "real roots" part is fairly important, because while you cannot take a square, cube, etc. root of a negative number in the "real" number space (denoted with ℝ), this is perfectly fine in the ',r.createElement("a",{href:"https://en.wikipedia.org/wiki/Complex_number"},'"complex" number')," space (denoted with ℂ). And, as it so happens, Cardano is also attributed as the first mathematician in history to have made use of complex numbers in his calculations. For this very algorithm!"),r.createElement("pre",null,"// A helper function to filter for values in the [0,1] interval:\nfunction accept(t) {\n return 0<=t && t <=1;\n}\n\n// A real-cuberoots-only function:\nfunction crt(v) {\n if(v<0) return -Math.pow(-v,1/3);\n return Math.pow(v,1/3);\n}\n\n// Now then: given cubic coordinates {pa, pb, pc, pd} find all roots.\nfunction getCubicRoots(pa, pb, pc, pd) {\n var d = (-pa + 3*pb - 3*pc + pd),\n a = (3*pa - 6*pb + 3*pc) / d,\n b = (-3*pa + 3*pb) / d,\n c = pa / d;\n\n var p = (3*b - a*a)/3,\n p3 = p/3,\n q = (2*a*a*a - 9*a*b + 27*c)/27,\n q2 = q/2,\n discriminant = q2*q2 + p3*p3*p3;\n\n // and some variables we're going to use later on:\n var u1,v1,root1,root2,root3;\n\n // three possible real roots:\n if (discriminant < 0) {\n var mp3 = -p/3,\n mp33 = mp3*mp3*mp3,\n r = sqrt( mp33 ),\n t = -q / (2*r),\n cosphi = t<-1 ? -1 : t>1 ? 1 : t,\n phi = acos(cosphi),\n crtr = cuberoot(r),\n t1 = 2*crtr;\n root1 = t1 * cos(phi/3) - a/3;\n root2 = t1 * cos((phi+2*pi)/3) - a/3;\n root3 = t1 * cos((phi+4*pi)/3) - a/3;\n return [root1, root2, root3].filter(accept);\n }\n\n // three real roots, but two of them are equal:\n if(discriminant === 0) {\n u1 = q2 < 0 ? cuberoot(-q2) : -cuberoot(q2);\n root1 = 2*u1 - a/3;\n root2 = -u1 - a/3;\n return [root1, root2].filter(accept);\n }\n\n // one real root, two complex roots\n var sd = sqrt(discriminant);\n u1 = cuberoot(sd - q2);\n v1 = cuberoot(sd + q2);\n root1 = u1 - v1 - a/3;\n return [root1].filter(accept);\n}\n")),r.createElement("p",null,'And that\'s it. The maths is complicated, but the code is pretty much just "follow the maths, while caching as many values as we can to reduce recomputing things as much as possible" and now we have a way to find all roots for a cubic function and can just move on with using that to find extremities of our curves.'),r.createElement("h3",{id:"quintic-and-higher-order-curves-finding-numerical-solutions"},"Quintic and higher order curves: finding numerical solutions"),r.createElement("p",null,"The problem with this is that as the order of the curve goes up, we can't actually solve those equations the normal way. We can't take the function, and then work out what the solutions are. Not to mention that even solving a third order derivative (for a fourth order curve) is already a royal pain in the backside. We need a better solution. We need numerical approaches."),r.createElement("p",null,'That\'s a fancy word for saying "rather than solve the function, treat the problem as a sequence of identical operations, the performing of which gets us closer and closer to the real answer". As it turns out, there is a really nice numerical root finding algorithm, called the ',r.createElement("a",{href:"http://en.wikipedia.org/wiki/Newton-Raphson"},"Newton-Raphson")," root finding method (yes, after ",r.createElement("em",null,r.createElement("a",{href:"https://en.wikipedia.org/wiki/Isaac_Newton"},"that"))," Newton), which we can make use of."),r.createElement("p",null,"The Newton-Raphson approach consists of picking a value ",r.createElement("em",null,"t")," (any will do), and getting the corresponding value at that ",r.createElement("em",null,"t")," value. For normal functions, we can treat that value as a height. If the height is zero, we're done, we have found a root. If it's not, we take the tangent of the curve at that point, and extend it until it passes the x-axis, which will be at some new point ",r.createElement("em",null,"t"),". We then repeat the procedure with this new value, and we keep doing this until we find our root."),r.createElement("p",null,"Mathematically, this means that for some ",r.createElement("em",null,"t"),", at step ",r.createElement("em",null,"n=1"),", we perform the following calculation until ",r.createElement("em",null,"f",r.createElement("sub",null,"y")),"(",r.createElement("em",null,"t"),") is zero, so that the next ",r.createElement("em",null,"t")," is the same as the one we already have:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b563256be7016370365935944308cf878cdbc29c.svg",width:"130.2rem",height:"47.599999999999994rem"}),r.createElement("p",null,"(The wikipedia article has a decent animation for this process, so I'm not adding a sketch for that here unless there are requests for it)"),r.createElement("p",null,"Now, this works well only if we can pick good starting points, and our curve is continuously differentiable and doesn't have oscillations. Glossing over the exact meaning of those terms, the curves we're dealing with conform to those constraints, so as long as we pick good starting points, this will work. So the question is: which starting points do we pick?"),r.createElement("p",null,"As it turns out, Newton-Raphson is so blindingly fast, so we could get away with just not picking: we simply run the algorithm from ",r.createElement("em",null,"t=0")," to ",r.createElement("em",null,"t=1")," at small steps (say, 1/200",r.createElement("sup",null,"th"),") and the result will be all the roots we want. Of course, this may pose problems for high order Bézier curves: 200 steps for a 200",r.createElement("sup",null,"th")," order Bézier curve is going to go wrong, but that's okay: there is no reason, ever, to use Bézier curves of crazy high orders. You might use a fifth order curve to get the \"nicest still remotely workable\" approximation of a full circle with a single Bézier curve, that's pretty much as high as you'll ever need to go."),r.createElement("h3",{id:"in-conclusion-"},"In conclusion:"),r.createElement("p",null,"So now that we know how to do root finding, we can determine the first and second derivative roots for our Bézier curves, and show those roots overlaid on the previous graphics:"),r.createElement(i,{preset:"simple",title:"Quadratic Bézier curve extremities",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"simple",title:"Cubic Bézier curve extremities",setup:e.setupCubic,draw:e.draw}))}},boundingbox:{locale:"en-GB",title:"Bounding boxes",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"boundingbox",title:"Bounding boxes",number:"16"}),r.createElement("p",null,"If we have the extremities, and the start/end points, a simple for loop that tests for min/max values for x and y means we have the four values we need to box in our curve:"),r.createElement("p",null,r.createElement("em",null,"Computing the bounding box for a Bézier curve"),":"),r.createElement("ol",null,r.createElement("li",null,"Find all ",r.createElement("em",null,"t")," value(s) for the curve derivative's x- and y-roots."),r.createElement("li",null,"Discard any ",r.createElement("em",null,"t")," value that's lower than 0 or higher than 1, because Bézier curves only use the interval [0,1]."),r.createElement("li",null,"Determine the lowest and highest value when plugging the values ",r.createElement("em",null,"t=0"),", ",r.createElement("em",null,"t=1")," and each of the found roots into the original functions: the lowest value is the lower bound, and the highest value is the upper bound for the bounding box we want to construct.")),r.createElement("p",null,"Applying this approach to our previous root finding, we get the following bounding boxes (with all curve extremity points shown on the curve):"),r.createElement(i,{preset:"simple",title:"Quadratic Bézier bounding box",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"simple",title:"Cubic Bézier bounding box",setup:e.setupCubic,draw:e.draw}),r.createElement("p",null,"We can construct even nicer boxes by aligning them along our curve, rather than along the x- and y-axis, but in order to do so we first need to look at how aligning works."))}},aligning:{locale:"en-GB",title:"Aligning curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"aligning",title:"Aligning curves",number:"17"}),r.createElement("p",null,'While there are an incredible number of curves we can define by varying the x- and y-coordinates for the control points, not all curves are actually distinct. For instance, if we define a curve, and then rotate it 90 degrees, it\'s still the same curve, and we\'ll find its extremities in the same spots, just at different draw coordinates. As such, one way to make sure we\'re working with a "unique" curve is to "axis-align" it.'),r.createElement("p",null,"Aligning also simplifies a curve's functions. We can translate (move) the curve so that the first point lies on (0,0), which turns our ",r.createElement("em",null,"n")," term polynomial functions into ",r.createElement("em",null,"n-1")," term functions. The order stays the same, but we have less terms. Then, we can rotate the curves so that the last point always lies on the x-axis, too, making its coordinate (...,0). This further simplifies the function for the y-component to an ",r.createElement("em",null,"n-2")," term function. For instance, if we have a cubic curve such as this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d253dc7ff011a8ae46f3351975f1d4beedd7a794.svg",width:"499.79999999999995rem",height:"42rem"}),r.createElement("p",null,"Then translating it so that the first coordinate lies on (0,0), moving all ",r.createElement("em",null,"x")," coordinates by -120, and all ",r.createElement("em",null,"y")," coordinates by -160, gives us:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b3ec747086a146c1b2c682afea6b1eae016c9a7a.svg",width:"482.99999999999994rem",height:"42rem"}),r.createElement("p",null,"If we then rotate the curve so that its end point lies on the x-axis, the coordinates (integer-rounded for illustrative purposes here) become:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/fd82fad845da25b074dff33bbc4aa563d5f367a7.svg",width:"474.59999999999997rem",height:"42rem"}),r.createElement("p",null,"If we drop all the zero-terms, this gives us:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b4d6e220358b2d00f0cf516f433fbe5ecb58f25d.svg",width:"386.4rem",height:"42rem"}),r.createElement("p",null,"We can see that our original curve definition has been simplified considerably. The following graphics illustrate the result of aligning our example curves to the x-axis, with the cubic case using the coordinates that were just used in the example formulae:"),r.createElement(i,{preset:"twopanel",title:"Aligning a quadratic curve",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"twopanel",title:"Aligning a cubic curve",setup:e.setupCubic,draw:e.draw}))}},tightbounds:{locale:"en-GB",title:"Tight boxes",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"tightbounds",title:"Tight boxes",number:"18"}),r.createElement("p",null,'With our knowledge of bounding boxes, and curve alignment, We can now form the "tight" bounding box for curves. We first align our curve, recording the translation we performed, "T", and the rotation angle we used, "R". We then determine the aligned curve\'s normal bounding box. Once we have that, we can map that bounding box back to our original curve by rotating it by -R, and then translating it by -T. We now have nice tight bounding boxes for our curves:'),r.createElement(i,{preset:"twopanel",title:"Aligning a quadratic curve",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"twopanel",title:"Aligning a cubic curve",setup:e.setupCubic,draw:e.draw}),r.createElement("p",null,"These are, strictly speaking, not necessarily the tightest possible bounding boxes. It is possible to compute the optimal bounding box by determining which spanning lines we need to effect a minimal box area, but because of the parametric nature of Bézier curves this is actually a rather costly operation, and the gain in bounding precision is often not worth it. If there is high demand for it, I'll add a section on how to precisely compute the best fit bounding box, but the maths is fairly gruelling and just not really worth spending time on."))}},inflections:{locale:"en-GB",title:"Curve inflections",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"inflections",title:"Curve inflections",number:"19"}),r.createElement("p",null,"Now that we know how to align a curve, there's one more thing we can calculate: inflection points. Imagine we have a variable size circle that we can slide up against our curve. We place it against the curve and adjust its radius so that where it touches the curve, the curvatures of the curve and the circle are the same, and then we start to slide the circle along the curve - for quadratic curves, we can always do this without the circle behaving oddly: we might have to change the radius of the circle as we slide it along, but it'll always sit against the same side of the curve."),r.createElement("p",null,'But what happens with cubic curves? Imagine we have an S curve and we place our circle at the start of the curve, and start sliding it along. For a while we can simply adjust the radius and things will be fine, but once we get to the midpoint of that S, something odd happens: the circle "flips" from one side of the curve to the other side, in order for the curvatures to keep matching. This is called an inflection, and we can find out where those happen relatively easily.'),r.createElement("p",null,"What we need to do is solve a simple equation:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b039194e01b6081628efaf4aa169a4c50fa4aae4.svg",width:"61.599999999999994rem",height:"16.799999999999997rem"}),r.createElement("p",null,"What we're saying here is that given the curvature function ",r.createElement("em",null,"C(t)"),", we want to know for which values of ",r.createElement("em",null,"t"),' this function is zero, meaning there is no "curvature", which will be exactly at the point between our circle being on one side of the curve, and our circle being on the other side of the curve. So what does ',r.createElement("em",null,"C(t)")," look like? Actually something that seems not too hard:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/297d1e13000b19d351e5884a40909652a2ee83e2.svg",width:"404.59999999999997rem",height:"22.4rem"}),r.createElement("p",null,"So the function ",r.createElement("em",null,"C(t)")," is wholly defined by the first and second derivative functions for the parametric dimensions of our curve. And as already shown, derivatives of Bézier curves are just simpler Bézier curves, with very easy to compute new coefficients, so this should be pretty easy."),r.createElement("p",null,"However as we've seen in the section on aligning, aligning lets us simplify things ",r.createElement("em",null,"a lot"),", by completely removing the contributions of the first coordinate from most mathematical evaluations, and removing the last ",r.createElement("em",null,"y")," coordinate as well by virtue of the last point lying on the x-axis. So, while we can evaluate ",r.createElement("em",null,"C(t) = 0")," for our curve, it'll be much easier to first axis-align the curve and ",r.createElement("em",null,"then")," evalutating the curvature function."),r.createElement("div",{ +className:"note"},r.createElement("h3",{id:"let-s-derive-the-full-formula-anyway"},"Let's derive the full formula anyway"),r.createElement("p",null,"Of course, before we do our aligned check, let's see what happens if we compute the curvature function without axis-aligning. We start with the first and second derivatives, given our basis functions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e522d174844a5a31f585cc04cab944a3c4593781.svg",width:"631.4rem",height:"74.19999999999999rem"}),r.createElement("p",null,"And of course the same functions for ",r.createElement("em",null,"y"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/57d857282b8c91da5caf94dcfbe85145dbd760a8.svg",width:"418.59999999999997rem",height:"72.8rem"}),r.createElement("p",null,"Asking a computer to now compose the ",r.createElement("em",null,"C(t)")," function for us (and to expand it to a readable form of simple terms) gives us this rather overly complicated set of arithmetic expressions:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e69d797dc67f0bd2d826fcf8c48c22ff5decf23.svg",width:"579.5999999999999rem",height:"102.19999999999999rem"}),r.createElement("p",null,"That is... unwieldy. So, we note that there are a lot of terms that involve multiplications involving x1, y1, and y4, which would all disappear if we axis-align our curve, which is why aligning is a great idea.")),r.createElement("p",null,"Aligning our curve so that three of the eight coefficients become zero, we end up with the following simple term function for ",r.createElement("em",null,"C(t)"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/f61c01094f0de8ca4c7f26a229f0206d54b13930.svg",width:"589.4rem",height:"22.4rem"}),r.createElement("p",null,"That's a lot easier to work with: we see a fair number of terms that we can compute and then cache, giving us the following simplification:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c1e427616a8a2502abf3cf46415971d0df9a273c.svg",width:"534.8rem",height:"77rem"}),r.createElement("p",null,"This is a plain quadratic curve, and we know how to solve ",r.createElement("em",null,"C(t) = 0"),"; we use the quadratic formula:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/368099657b735b0d17becbbe7be915e88e8c04c5.svg",width:"456.4rem",height:"57.4rem"}),r.createElement("p",null,"We can easily compute this value ",r.createElement("em",null,"if")," the descriminator isn't a negative number (because we only want real roots, not complex roots), and ",r.createElement("em",null,"if")," ",r.createElement("em",null,"x")," is not zero, because divisions by zero are rather useless."),r.createElement("p",null,"Taking that into account, we compute ",r.createElement("em",null,"t"),", we disregard any ",r.createElement("em",null,"t")," value that isn't in the Bézier interval [0,1], and we now know at which ",r.createElement("em",null,"t")," value(s) our curve will inflect."),r.createElement(i,{title:"Finding cubic Bézier curve inflections",setup:e.setupCubic,draw:e.draw}))}},canonical:{locale:"en-GB",title:"Canonical form (for cubic curves)",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"canonical",title:"Canonical form (for cubic curves)",number:"20"}),r.createElement("p",null,"While quadratic curves are relatively simple curves to analyze, the same cannot be said of the cubic curve. As a curvature controlled by more than one control points, it exhibits all kinds of features like loops, cusps, odd colinear features, and up to two inflection points because the curvature can change direction up to three times. Now, knowing what kind of curve we're dealing with means that some algorithms can be run more efficiently than if we have to implement them as generic solvers, so is there a way to determine the curve type without lots of work?"),r.createElement("p",null,"As it so happens, the answer is yes and the solution we're going to look at was presented by Maureen C. Stone from Xerox PARC and Tony D. deRose from the University of Washington in their joint paper ",r.createElement("a",{href:"http://graphics.pixar.com/people/derose/publications/CubicClassification/paper.pdf"},'"A Geometric Characterization of Parametric Cubic curves"'),'. It was published in 1989, and defines curves as having a "canonical" form (i.e. a form that all curves can be reduced to) from which we can immediately tell which features a curve will have. So how does it work?'),r.createElement("p",null,'The first observation that makes things work is that if we have a cubic curve with four points, we can apply a linear transformation to these points such that three of the points end up on (0,0), (0,1) and (1,1), with the last point then being "somewhere". After applying that transformation, the location of that last point can then tell us what kind of curve we\'re dealing with. Specifically, we see the following breakdown:'),r.createElement(i,{static:!0,preset:"simple",title:"The canonical curve map",setup:e.setup,draw:e.drawBase}),r.createElement("p",null,"This is a fairly funky image, so let's see how it breaks down. We see the three fixed points at (0,0), (0,1) and (1,1), and then the fourth point is somewhere. Depending on where it is, our curve will have certain features. Namely, if the fourth point is..."),r.createElement("ol",null,r.createElement("li",null,"anywhere on and in the red zone, the curve will be self-intersecting, yielding either a cusp or a loop. Anywhere inside the the red zone, this will be a loop. We won't know ",r.createElement("i",null,"where")," that loop is (in terms of ",r.createElement("i",null,"t")," values), but we are guaranteed that there is one."),r.createElement("li",null,"on the left (red) edge, the curve will have a cusp. We again don't know ",r.createElement("em",null,"where"),", just that it has one. This edge is described by the function:")),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ae5a63e86bb367e6266a394962387344d0a92b10.svg",width:"189rem",height:"39.199999999999996rem"}),r.createElement("ol",null,r.createElement("li",null,"on the lower right (pink) edge, the curve will have a loop at t=1, so we know the end coordinate of the curve also lies ",r.createElement("em",null,"on")," the curve. This edge is described by the function:")),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d389fcde05a773be99f84db5fc9ed7ef043bf406.svg",width:"242.2rem",height:"40.599999999999994rem"}),r.createElement("ol",null,r.createElement("li",null,"on the top (blue) edge, the curve will have a loop at t=0, so we know the start coordinate of the curve also lies ",r.createElement("em",null,"on")," the curve. This edge is described by the function:")),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d97181a9d0ada19862a0ff2cebb08bdee00868d7.svg",width:"161rem",height:"39.199999999999996rem"}),r.createElement("ol",null,r.createElement("li",null,"inside the green zone, the curve will have a single inflection, switching concave/convex once."),r.createElement("li",null,"between the red and green zones, the curve has two inflections, meaning its curvature switches between concave/convex form twice."),r.createElement("li",null,"anywhere on the right of the red zone, the curve will have no inflections. It'll just be a well-behaved arch.")),r.createElement("p",null,"Of course, this map is fairly small, but the regions extend to infinity, with well defined boundaries."),r.createElement("div",{className:"note"},r.createElement("h3",{id:"wait-where-do-those-lines-come-from-"},"Wait, where do those lines come from?"),r.createElement("p",null,'Without repeating the paper mentioned at the top of this section, the loop-boundaries come from rewriting the curve into canonical form, and then solving the formulae for which constraints must hold for which possible curve properties. In the paper these functions yield formulae for where you will find cusp points, or loops where we know t=0 or t=1, but those functions are derived for the full cubic expression, meaning they apply to t=-∞ to t=∞... For Bézier curves we only care about the "clipped interval" t=0 to t=1, so some of the properties that apply when you look at the curve over an infinite interval simply don\'t apply to the Bézier curve interval.'),r.createElement("p",null,'The right bound for the loop region, indicating where the curve switches from "having inflections" to "having a loop", for the general cubic curve, is actually mirrored over x=1, but for Bézier curves this right half doesn\'t apply, so we don\'t need to pay attention to it. Similarly, the boundaries for t=0 and t=1 loops are also nice clean curves but get "cut off" when we only look at what the general curve does over the interval t=0 to t=1.'),r.createElement("p",null,'For the full details, head over to the paper and read through sections 3 and 4. If you still remember your high school precalculus, you can probably follow along with this paper, although you might have to read it a few times before all the bits "click".')),r.createElement("p",null,"So now the question becomes: how do we manipulate our curve so that it fits this canonical form, with three fixed points, and one \"free\" point? Enter linear algerba. Don't worry, I'll be doing all the math for you, as well as show you what the effect is on our curves, but basically we're going to be using linear algebra, rather than calculus, because \"it's way easier\". Sometimes a calculus approach is very hard to work with, when the equivalent geometrical solution is super obvious."),r.createElement("p",null,"The approach is going to start with a curve that doesn't have all-colinear points (so we need to make sure the points don't all fall on a straight line), and then applying four graphics operations that you will probably have heard of: translation (moving all points by some fixed x- and y-distance), scaling (multiplying all points by some x and y scale factor), and shearing (an operation that turns rectangles into parallelograms)."),r.createElement("p",null,"Step 1: we translate any curve by -p1.x and -p1.y, so that the curve starts at (0,0). We're going to make use of an interesting trick here, by pretending our 2D coordinates are 3D, with the ",r.createElement("i",null,"z")," coordinate simply always being 1. This is an old trick in graphics to overcome the limitations of 2D transformations: without it, we can only turn (x,y) coordinates into new coordinates of the form (ax + by, cx + dy), which means we can't do translation, since that requires we end up with some kind of (x + a, y + b). If we add a bogus ",r.createElement("i",null,"z")," coordinate that is always 1, then we can suddenly add arbitrary values. For example:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/00ca2970fccea8f0883af6db4fbc3a60efd2539d.svg",width:"495.59999999999997rem",height:"57.4rem"}),r.createElement("p",null,"Sweet! ",r.createElement("i",null,"z")," stays 1, so we can effectively ignore it entirely, but we added some plain values to our x and y coordinates. So, if we want to subtract p1.x and p1.y, we use:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1a48a27661f19f066ddd591fb4fc0d553b34c944.svg",width:"477.4rem",height:"60.199999999999996rem"}),r.createElement("p",null,"Running all our coordinates through this transformation gives a new set of coordinates, let's call those ",r.createElement("b",null,"U"),", where the first coordinate lies on (0,0), and the rest is still somewhat free. Our next job is to make sure point 2 ends up lying on the ",r.createElement("i",null,"x=0")," line, so what we want is a transformation matrix that, when we run it, subtracts ",r.createElement("i",null,"x")," from whatever ",r.createElement("i",null,"x")," we currently have. This is called ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Shear_matrix"},"shearing"),", and the typical x-shear matrix and its transformation looks like this:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/8e98c870c9d5b60bccf196d29e290f9de6657ce7.svg",width:"204.39999999999998rem",height:"56rem"}),r.createElement("p",null,"So we want some shearing value that, when multiplied by ",r.createElement("i",null,"y"),", yields ",r.createElement("i",null,"-x"),", so our x coordinate becomes zero. That value is simpy ",r.createElement("i",null,"-x/y"),", because ",r.createElement("i",null,"-x/y * y = -x"),". Done:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/585fa88864a98008c15225bdbeb0eb26a4653dab.svg",width:"140rem",height:"70rem"}),r.createElement("p",null,"Now, running this on all our points generates a new set of coordinates, let's call those V, which now have point 1 on (0,0) and point 2 on (0, some-value), and we wanted it at (0,1), so we need to ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Scaling_%28geometry%29"},"do some scaling")," to make sure it ends up at (0,1). Additionally, we want point 3 to end up on (1,1), so we can also scale x to make sure its x-coordinate will be 1 after we run the transform. That means we'll be x-scaling by 1/point3",r.createElement("sub",null,"x"),", and y-scaling by point2",r.createElement("sub",null,"y"),". This is really easy:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/bf9c60b59e6247de3fece63638a8333bdcd068a4.svg",width:"144.2rem",height:"74.19999999999999rem"}),r.createElement("p",null,"Then, finally, this generates a new set of coordinates, let's call those W, of which point 1 lies on (0,0), point 2 lies on (0,1), and point three lies on (1, ...) so all that's left is to make sure point 3 ends up at (1,1) - but we can't scale! Point 2 is already in the right place, and y-scaling would move it out of (0,1) again, so our only option is to y-shear point three, just like how we x-sheared point 2 earlier. In this case, we do the same trick, but with ",r.createElement("code",null,"y/x")," rather than ",r.createElement("code",null,"x/y")," because we're not x-shearing but y-shearing. Additionally, we don't actually want to end up at zero (which is what we did before) so we need to shear towards an offset, in this case 1:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/af412fd7df7faf35973314095ec6bf1cb28a8e34.svg",width:"147rem",height:"68.6rem"}),r.createElement("p",null,'And this generates our final set of four coordinates. Of these, we already know that points 1 through 3 are (0,0), (0,1) and (1,1), and only the last coordinate is "free". In fact, given any four starting coordinates, the resulting "transformation mapped" coordinate will be:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/66e084e9ee396b8cc40de3d0df9c4658dcd10e14.svg",width:"477.4rem",height:"95.19999999999999rem"}),r.createElement("p",null,"That looks very complex, but notice that every coordinate value is being offset by the initial translation, and a lot of terms in there repeat: it's pretty easy to calculate this fast, since there's so much we can cache and reuse while we compute this mapped coordinate!"),r.createElement("p",null,"First, let's just do that translation step as a \"preprocessing\" operation so we don't have to subtract the values all the time. What does that leave?"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d2dc58a4a6951ff27e5b83fb9be239e2fbe0f7ce.svg",width:"371rem",height:"61.599999999999994rem"}),r.createElement("p",null,"Suddenly things look a lot simpler: the mapped x is fairly straight forward to compute, and we see that the mapped y actually contains the mapped x in its entirety, so we'll have that part already available when we need to evaluate it. In fact, let's pull out all those common factors to see just how simple this is:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ebaea590e50dfce555e8ad2c63682fe9e6285f06.svg",width:"428.4rem",height:"42rem"}),r.createElement("p",null,"That's kind of super-simple to write out in code, I think you'll agree. Coding math tends to be easier than the formulae initially make it look!"),r.createElement("div",{className:"note"},r.createElement("h3",{id:"how-do-you-track-all-that-"},"How do you track all that?"),r.createElement("p",null,"Doing maths can be a pain, so whenever possible, I like to make computers do the work for me. Especially for things like this, I simply use ",r.createElement("a",{href:"http://www.wolfram.com/mathematica"},"Mathematica"),". Tracking all this math by hand is insane, and we invented computers, literally, to do this for us. I have no reason to use pen and paper when I can write out what I want to do in a program, and have the program do the math for me. And real math, too, with symbols, not with numbers. In fact, ",r.createElement("a",{href:"http://pomax.github.io/gh-weblog/downloads/canonical-curve.nb"},"here's")," the Mathematica notebook if you want to see how this works for yourself."),r.createElement("p",null,"Now, I know, you're thinking \"but Mathematica is super expensive!\" and that's true, it's ",r.createElement("a",{href:"http://www.wolfram.com/mathematica-home-edition"},"$295 for home use"),", but it's ",r.createElement("strong",null,"also")," ",r.createElement("a",{href:"http://www.wolfram.com/raspberry-pi"},"free when you buy a $35 raspberry pi"),". Obviously, I bought a raspberry pi, and I encourage you to do the same. With that, as long as you know what you want to ",r.createElement("em",null,"do"),", Mathematica can just do it for you. And we don't have to be geniusses to work out what the maths looks like. That's what we have computers for.")),r.createElement("p",null,"So, let's write up a sketch that'll show us the canonical form for any curve drawn in blue, overlaid on our canonical map, so that we can immediately tell which features our curve must have, based on where the fourth coordinate is located on the map:"),r.createElement(i,{preset:"simple",title:"A cubic curve mapped to canonical form",setup:e.setup,draw:e.draw}))}},arclength:{locale:"en-GB",title:"Arc length",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"arclength",title:"Arc length",number:"21"}),r.createElement("p",null,"How long is a Bézier curve? As it turns out, that's not actually an easy question, because the answer requires maths that —much like root finding— cannot generally be solved the traditional way. If we have a parametric curve with ",r.createElement("em",null,"f",r.createElement("sub",null,"x"),"(t)")," and ",r.createElement("em",null,"f",r.createElement("sub",null,"y"),"(t)"),", then the length of the curve, measured from start point to some point ",r.createElement("em",null,"t = z"),", is computed using the following seemingly straight forward (if a bit overwhelming) formula:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/16e3f81dfc12c526ca53b477b2aa67ef7b56bfe2.svg",width:"147rem",height:"35rem"}),r.createElement("p",null,"or, more commonly written using Leibnitz notation as:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/8e2857c32b23969bca67b0ead318493a3e61dc4a.svg",width:"257.59999999999997rem",height:"36.4rem"}),r.createElement("p",null,"This formula says that the length of a parametric curve is in fact equal to the ",r.createElement("strong",null,"area")," underneath a function that looks a remarkable amount like Pythagoras' rule for computing the diagonal of a straight angled triangle. This sounds pretty simple, right? Sadly, it's far from simple... cutting straight to after the chase is over: for quadratic curves, this formula generates an ",r.createElement("a",{href:"http://www.wolframalpha.com/input/?i=antiderivative+for+sqrt%28%282*%281-t%29*t*B+%2B+t%5E2*C%29%27%5E2+%2B+%282*%281-t%29*t*E%29%27%5E2%29&incParTime=true"},"unwieldy computation"),", and we're simply not going to implement things that way. For cubic Bézier curves, things get even more fun, because there is no \"closed form\" solution, meaning that due to the way calculus works, there is no generic formula that allows you to calculate the arc length. Let me just repeat this, because it's fairly crucial: ",r.createElement("strong",null,r.createElement("em",null,'for cubic and higher Bézier curves, there is no way to solve this function if you want to use it "for all possible coordinates"')),"."),r.createElement("p",null,"Seriously: ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Abel%E2%80%93Ruffini_theorem"},"It cannot be done"),"."),r.createElement("p",null,"So we turn to numerical approaches again. The method we'll look at here is the ",r.createElement("a",{href:"http://www.youtube.com/watch?v=unWguclP-Ds&feature=BFa&list=PLC8FC40C714F5E60F&index=1"},"Gauss quadrature"),". This approximation is a really neat trick, because for any ",r.createElement("em",null,"n",r.createElement("sup",null,"th"))," degree polynomial it finds approximated values for an integral really efficiently. Explaining this procedure in length is way beyond the scope of this page, so if you're interested in finding out why it works, I can recommend the University of South Florida video lecture on the procedure, linked in this very paragraph. The general solution we're looking for is the following:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e6a8d7d5f1742bb926c0c992d2b89c71090edbf4.svg",width:"576.8rem",height:"74.19999999999999rem"}),r.createElement("p",null,'In plain text: an integral function can always be treated as the sum of an (infinite) number of (infinitely thin) rectangular strips sitting "under" the function\'s plotted graph. To illustrate this idea, the following graph shows the integral for a sinoid function. The more strips we use (and of course the more we use, the thinner they get) the closer we get to the true area under the curve, and thus the better the approximation:'),r.createElement("div",{className:"figure"},r.createElement(i,{inline:!0,static:!0,preset:"empty",title:"A function's approximated integral",setup:e.setup,draw:e.drawCoarseIntegral}),r.createElement(i,{inline:!0,static:!0,preset:"empty",title:"A better approximation",setup:e.setup,draw:e.drawFineIntegral}),r.createElement(i,{inline:!0,static:!0,preset:"empty",title:"An even better approximation",setup:e.setup,draw:e.drawSuperFineIntegral})),r.createElement("p",null,'Now, infinitely many terms to sum and infinitely thin rectangles are not something that computers can work with, so instead we\'re going to approximate the infinite summation by using a sum of a finite number of "just thin" rectangular strips. As long as we use a high enough number of thin enough rectangular strips, this will give us an approximation that is pretty close to what the real value is.'),r.createElement("p",null,"So, the trick is to come up with useful rectangular strips. A naive way is to simply create ",r.createElement("em",null,"n")," strips, all with the same width, but there is a far better way using special values for ",r.createElement("em",null,"C")," and ",r.createElement("em",null,"f(t)")," depending on the value of ",r.createElement("em",null,"n"),", which indicates how many strips we'll use, and it's called the Legendre-Gauss quadrature."),r.createElement("p",null,"This approach uses strips that are ",r.createElement("em",null,"not")," spaced evenly, but instead spaces them in a special way that works remarkably well. If you look at the earlier sinoid graphic, you could imagine that we could probably get a result similar to the one with 99 strips if we used fewer strips, but spaced them so that the steeper the curve is, the thinner we make the strip, and conversely, the flatter the curve is (especially near the tops of the function), the wider we make the strip. That's akin to how the Legendre values work."),r.createElement("div",{className:"note"},r.createElement("p",null,"Note that one requirement for the approach we'll use is that the integral must run from -1 to 1. That's no good, because we're dealing with Bézier curves, and the length of a section of curve applies to values which run from 0 to \"some value smaller than or equal to 1\" (let's call that value ",r.createElement("em",null,"z"),"). Thankfully, we can quite easily transform any integral interval to any other integral interval, by shifting and scaling the inputs. Doing so, we get the following:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/631e6396082d9621472546b87c2e27065990d568.svg",width:"358.4rem",height:"75.6rem"}),r.createElement("p",null,"That may look a bit more complicated, but the fraction involving ",r.createElement("em",null,"z")," is a fixed number, so the summation, and the evaluation of the ",r.createElement("em",null,"f(t)")," values are still pretty simple."),r.createElement("p",null,"So, what do we need to perform this calculation? For one, we'll need an explicit formula for ",r.createElement("em",null,"f(t)"),", because that derivative notation is handy on paper, but not when we have to implement it. We'll also need to know what these ",r.createElement("em",null,"C",r.createElement("sub",null,"i"))," and ",r.createElement("em",null,"t",r.createElement("sub",null,"i"))," values should be. Luckily, that's less work because there are actually many tables available that give these values, for any ",r.createElement("em",null,"n"),", so if we want to approximate our integral with only two terms (which is a bit low, really) then ",r.createElement("a",{href:"legendre-gauss.html"},"these tables")," would tell us that for ",r.createElement("em",null,"n=2")," we must use the following values:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/6dc4299695f03c27c362e7faf47ae4474794809e.svg",width:"65.8rem",height:"98rem"}),r.createElement("p",null,"Which means that in order for us to approximate the integral, we must plug these values into the approximate function, which gives us:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/fe54606651e308caf83a65e53bc4d6104f8a4ee1.svg",width:"499.79999999999995rem",height:"46.199999999999996rem"}),r.createElement("p",null,"We can program that pretty easily, provided we have that ",r.createElement("em",null,"f(t)")," available, which we do, as we know the full description for the Bézier curve functions B",r.createElement("sub",null,"x"),"(t) and B",r.createElement("sub",null,"y"),"(t).")),r.createElement("p",null,"If we use the Legendre-Gauss values for our ",r.createElement("em",null,"C")," values (thickness for each strip) and ",r.createElement("em",null,"t")," values (location of each strip), we can determine the approximate length of a Bézier curve by computing the Legendre-Gauss sum. The following graphic shows a cubic curve, with its computed lengths; Go ahead and change the curve, to see how its length changes. One thing worth trying is to see if you can make a straight line, and see if the length matches what you'd expect. What if you form a line with the control points on the outside, and the start/end points on the inside?"),r.createElement(i,{preset:"simple",title:"Arc length for a Bézier curve",setup:e.setupCurve,draw:e.drawCurve}))}},arclengthapprox:{locale:"en-GB",title:"Approximated arc length",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"arclengthapprox",title:"Approximated arc length",number:"22"}),r.createElement("p",null,"Sometimes, we don't actually need the precision of a true arc length, and we can get away with simply computing the approximate arc length instead. The by far fastest way to do this is to flatten the curve and then simply calculate the linear distance from point to point. This will come with an error, but this can be made arbitrarily small by increasing the segment count."),r.createElement("p",null,"If we combine the work done in the previous sections on curve flattening and arc length computation, we can implement these with minimal effort:"),r.createElement(i,{preset:"twopanel",title:"Approximate quadratic curve arc length",setup:e.setupQuadratic,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement(i,{preset:"twopanel",title:"Approximate cubic curve arc length",setup:e.setupCubic,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"Try clicking on the sketch and using your up and down arrow keys to lower the number of segments for both the quadratic and cubic curve. You may notice that the error in length is actually pretty significant, even if the percentage is fairly low: if the number of segments used yields an error of 0.1% or higher, the flattened curve already looks fairly obviously flattened. And of course, the longer the curve, the more significant the error will be."))}},tracing:{locale:"en-GB",title:"Tracing a curve at fixed distance intervals",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"tracing",title:"Tracing a curve at fixed distance intervals",number:"23"}),r.createElement("p",null,"Say you want to draw a curve with a dashed line, rather than a solid line, or you want to move something along the curve at fixed distance intervals over time, like a train along a track, and you want to use Bézier curves."),r.createElement("p",null,"Now you have a problem."),r.createElement("p",null,"The reason you have a problem is that Bézier curves are parametric functions with non-linear behaviour, whereas moving a train along a track is about as close to a practical example of linear behaviour as you can get. The problem we're faced with is that we can't just pick ",r.createElement("em",null,"t"),' values at some fixed interval and expect the Bézier functions to generate points that are spaced a fixed distance apart. In fact, let\'s look at the relation between "distance long a curve" and "',r.createElement("em",null,"t"),' value", by plotting them against one another.'),r.createElement("p",null,"The following graphic shows a particularly illustrative curve, and it's length-to-t plot. For linear traversal, this line needs to be straight, running from (0,0) to (length,1). This is, it's safe to say, not what we'll see, we'll see something wobbly instead. To make matters even worse, the length-to-",r.createElement("em",null,"t")," function is also of a much higher order than our curve is: while the curve we're using for this exercise is a cubic curve, which can switch concave/convex form once at best, the plot shows that the distance function along the curve is able to switch forms three times (to see this, try creating an S curve with the start/end close together, but the control points far apart)."),r.createElement(i,{preset:"twopanel",title:"The t-for-distance function",setup:e.setup,draw:e.plotOnly}),r.createElement("p",null,"We see a function that might be invertible, but we won't be able to do so, symbolically. You may remember from the section on arc length that we cannot actually compute the true arc length function as an expression of ",r.createElement("em",null,"t"),", which means we also can't compute the true inverted function that gives ",r.createElement("em",null,"t")," as an expression of length. So how do we fix this?"),r.createElement("p",null,"One way is to do what the graphic does: simply run through the curve, determine its ",r.createElement("em",null,"t"),"-for-length values as a set of discrete values at some high resolution (the graphic uses 100 discrete points), and then use those as a basis for finding an appropriate ",r.createElement("em",null,"t")," value, given a distance along the curve. This works quite well, actually, and is fairly fast."),r.createElement("p",null,"We can use some colour to show the difference between distance-based and time based intervals: the following graph is similar to the previous one, except it segments the curve in terms of equal-distance intervals. This shows as regular colour intervals going down the graph, but the mapping to ",r.createElement("em",null,"t")," values is not linear, so there will be (highly) irregular intervals along the horizontal axis. It also shows the curve in an alternating colouring based on the t-for-distance values we find our LUT:"),r.createElement(i,{ +preset:"threepanel",title:"Fixed-interval coloring a curve",setup:e.setup,draw:e.drawColoured,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"Use your up and down arrow keys to increase or decrease the number of equidistant segments used to colour the curve."),r.createElement("p",null,'However, are there better ways? One such way is discussed in "',r.createElement("a",{href:"http://www.geometrictools.com/Documentation/MovingAlongCurveSpecifiedSpeed.pdf"},"Moving Along a Curve with Specified Speed"),"\" by David Eberly of Geometric Tools, LLC, but basically because we have no explicit length function (or rather, one we don't have to constantly compute for different intervals), you may simply be better off with a traditional lookup table (LUT)."))}},intersections:{locale:"en-GB",title:"Intersections",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"intersections",title:"Intersections",number:"24"}),r.createElement("p",null,"Let's look at some more things we will want to do with Bézier curves. Almost immediately after figuring out how to get bounding boxes to work, people tend to run into the problem that even though the minimal bounding box (based on rotation) is tight, it's not sufficient to perform true collision detection. It's a good first step to make sure there ",r.createElement("em",null,"might")," be a collision (if there is no bounding box overlap, there can't be one), but in order to do real collision detection we need to know whether or not there's an intersection on the actual curve."),r.createElement("p",null,"We'll do this in steps, because it's a bit of a journey to get to curve/curve intersection checking. First, let's start simple, by implementing a line-line intersection checker. While we can solve this the traditional calculus way (determine the functions for both lines, then compute the intersection by equating them and solving for two unknowns), linear algebra actually offers a nicer solution."),r.createElement("h3",{id:"line-line-intersections"},"Line-line intersections"),r.createElement("p",null,"if we have two line segments with two coordinates each, segments A-B and C-D, we can find the intersection of the lines these segments are an intervals on by linear algebra, using the procedure outlined in this ",r.createElement("a",{href:"http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=geometry2#line_line_intersection"},"top coder")," article. Of course, we need to make sure that the intersection isn't just on the lines our line segments lie on, but also on our line segments themselves, so after we find the intersection we need to verify it lies without the bounds of our original line segments."),r.createElement("p",null,"The following graphic implements this intersection detection, showing a red point for an intersection on the lines our segments lie on (thus being a virtual intersection point), and a green point for an intersection that lies on both segments (being a real intersection point)."),r.createElement(i,{preset:"simple",title:"Line/line intersections",setup:e.setupLines,draw:e.drawLineIntersection}),r.createElement("div",{className:"howtocode"},r.createElement("h3",{id:"implementing-line-line-intersections"},"Implementing line-line intersections"),r.createElement("p",null,"Let's have a look at how to implement a line-line intersection checking function. The basics are covered in the article mentioned above, but sometimes you need more function signatures, because you might not want to call your function with eight distinct parameters. Maybe you're using point structs or the line. Let's get coding:"),r.createElement("pre",null,"lli8 = function(x1,y1,x2,y2,x3,y3,x4,y4):\n var nx=(x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4),\n ny=(x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4),\n d=(x1-x2)*(y3-y4)-(y1-y2)*(x3-x4);\n if d=0:\n return false\n return point(nx/d, ny/d)\n\nlli4 = function(p1, p2, p3, p4):\n var x1 = p1.x, y1 = p1.y,\n x2 = p2.x, y2 = p2.y,\n x3 = p3.x, y3 = p3.y,\n x4 = p4.x, y4 = p4.y;\n return lli8(x1,y1,x2,y2,x3,y3,x4,y4)\n\nlli = function(line1, line2):\n return lli4(line1.p1, line1.p2, line2.p1, line2.p2)\n")),r.createElement("h3",{id:"what-about-curve-line-intersections-"},"What about curve-line intersections?"),r.createElement("p",null,"Curve/line intersection is more work, but we've already seen the techniques we need to use in order to perform it: first we translate/rotate both the line and curve together, in such a way that the line coincides with the x-axis. This will position the curve in a way that makes it cross the line at points where its y-function is zero. By doing this, the problem of finding intersections between a curve and a line has now become the problem of performing root finding on our translated/rotated curve, as we already covered in the section on finding extremities."),r.createElement(i,{preset:"simple",title:"Quadratic curve/line intersections",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"simple",title:"Cubic curve/line intersections",setup:e.setupCubic,draw:e.draw}),r.createElement("p",null,"Curve/curve intersection, however, is more complicated. Since we have no straight line to align to, we can't simply align one of the curves and be left with a simple procedure. Instead, we'll need to apply two techniques we've not covered yet: de Casteljau's algorithm, and curve splitting."))}},curveintersection:{locale:"en-GB",title:"Curve/curve intersection",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"curveintersection",title:"Curve/curve intersection",number:"25"}),r.createElement("p",null,'Using de Casteljau\'s algorithm to split the curve we can now implement curve/curve intersection finding using a "divide and conquer" technique:'),r.createElement("ul",null,r.createElement("li",null,"Take two curves ",r.createElement("em",null,"C",r.createElement("sub",null,"1"))," and ",r.createElement("em",null,"C",r.createElement("sub",null,"2")),", and treat them as a pair."),r.createElement("li",null,"If their bounding boxes overlap, split up each curve into two sub-curves"),r.createElement("li",null,"With ",r.createElement("em",null,"C",r.createElement("sub",null,"1.1")),", ",r.createElement("em",null,"C",r.createElement("sub",null,"1.2")),", ",r.createElement("em",null,"C",r.createElement("sub",null,"2.1"))," and ",r.createElement("em",null,"C",r.createElement("sub",null,"2.2")),", form four new pairs (",r.createElement("em",null,"C",r.createElement("sub",null,"1.1")),",",r.createElement("em",null,"C",r.createElement("sub",null,"2.1")),"), (",r.createElement("em",null,"C",r.createElement("sub",null,"1.1")),", ",r.createElement("em",null,"C",r.createElement("sub",null,"2.2")),"), (",r.createElement("em",null,"C",r.createElement("sub",null,"1.2")),",",r.createElement("em",null,"C",r.createElement("sub",null,"2.1")),"), and (",r.createElement("em",null,"C",r.createElement("sub",null,"1.2")),",",r.createElement("em",null,"C",r.createElement("sub",null,"2.2")),")."),r.createElement("li",null,"For each pair, check whether their bounding boxes overlap.",r.createElement("ul",null,r.createElement("li",null,"If their bounding boxes do not overlap, discard the pair, as there is no intersection between this pair of curves."),r.createElement("li",null,"If there ",r.createElement("em",null,"is")," overlap, rerun all steps for this pair."))),r.createElement("li",null,"Once the sub-curves we form are so small that they effectively occupy sub-pixel areas, we consider an intersection found.")),r.createElement("p",null,'This algorithm will start with a single pair, "balloon" until it runs in parallel for a large number of potential sub-pairs, and then taper back down as it homes in on intersection coordinates, ending up with as many pairs as there are intersections.'),r.createElement("p",null,"The following graphic applies this algorithm to a pair of cubic curves, one step at a time, so you can see the algorithm in action. Click the button to run a single step in the algorithm, after setting up your curves in some creative arrangement. The algorithm resets once it's found a solution, so you can try this with lots of different curves (can you find the configuration that yields the maximum number of intersections between two cubic curves? Nine intersections!)"),r.createElement(i,{preset:"clipping",title:"Curve/curve intersections",setup:e.setup,draw:e.draw},"\\t",r.createElement("button",{onClick:e.stepUp},"advance one step")),r.createElement("p",null,"Self-intersection is dealt with in the same way, except we turn a curve into two or more curves first based on the inflection points. We then form all possible curve pairs with the resultant segments, and run exactly the same algorithm. All non-overlapping curve pairs will be removed after the first iteration, and the remaining steps home in on the curve's self-intersection points."))}},abc:{locale:"en-GB",title:"The projection identity",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"abc",title:"The projection identity",number:"26"}),r.createElement("p",null,"De Casteljau's algorithm is the pivotal algorithm when it comes to Bézier curves. You can use it not just to split curves, but also to draw them efficiently (especially for high-order Bézier curves), as well as to come up with curves based on three points and a tangent. Particularly this last thing is really useful because it lets us \"mould\" a curve, by picking it up at some point, and dragging that point around to change the curve's shape."),r.createElement("p",null,"How does that work? Succinctly: we run de Casteljau's algorithm in reverse!"),r.createElement("p",null,"In order to run de Casteljau's algorithm in reverse, we need a few basic things: a start and end point, a point on the curve that want to be moving around, which has an associated ",r.createElement("em",null,"t"),' value, and a point we\'ve not explicitly talked about before, and as far as I know has no explicit name, but lives one iteration higher in the de Casteljau process then our on-curve point does. I like to call it "A" for reasons that will become obvious.'),r.createElement("p",null,'So let\'s use graphics instead of text to see where this "A" is, because text only gets us so far: in the following graphic, click anywhere on the curves to see the identity information that we\'ll be using to run de Casteljau in reverse (you can manipulate the curve even after picking a point. Note the "ratio" value when you do so: does it change?):'),r.createElement("div",{className:"figure"},r.createElement(i,{inline:!0,preset:"abc",title:"Projections in a quadratic Bézier curve",setup:e.setupQuadratic,draw:e.draw,onClick:e.onClick}),r.createElement(i,{inline:!0,preset:"abc",title:"Projections in a cubic Bézier curve",setup:e.setupCubic,draw:e.draw,onClick:e.onClick})),r.createElement("p",null,"Clicking anywhere on the curves shows us three things:"),r.createElement("ol",null,r.createElement("li",null,"our on-curve point; let's call that ",r.createElement("b",null,"B"),","),r.createElement("li",null,"a point at the tip of B's \"hat\", on de Casteljau step up; let's call that ",r.createElement("b",null,"A"),", and"),r.createElement("li",null,"a point that we get by projecting B onto the start--end baseline; let's call that ",r.createElement("b",null,"C"),".")),r.createElement("p",null,"These three values ABC hide an important identity formula for quadratic and cubic Bézier curves: for any point on the curve with some ",r.createElement("em",null,"t")," value, the ratio distance of C along baseline is fixed: if some ",r.createElement("em",null,"t")," value sets up a C that is 20% away from the start and 80% away from the end, then it doesn't matter where the start, end, or control points are: for that ",r.createElement("em",null,"t")," value, C will ",r.createElement("em",null,"always")," lie at 20% from the start and 80% from the end point. Go ahead, pick an on-curve point in either graphic and then move all the other points around: if you only move the control points, start and end won't move, and so neither will C, and if you move either start or end point, C will move but its relative position will not change. The following function stays true:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/f48f095d9c37c079ff6a5f71b3047397aa7dfc6b.svg",width:"207.2rem",height:"16.799999999999997rem"}),r.createElement("p",null,"So that just leaves finding A."),r.createElement("div",{className:"note"},r.createElement("p",null,"While that relation is fixed, the function ",r.createElement("em",null,"u(t)")," differs depending on whether we're working with quadratic or cubic curves:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/cb35e42bf53bfc2b96f959e78256da01f8b91dbc.svg",width:"207.2rem",height:"91rem"}),r.createElement("p",null,"So, if we know the start and end coordinates, and we know the ",r.createElement("em",null,"t")," value, we know C:"),r.createElement("div",{className:"figure"},r.createElement(i,{inline:!0,preset:"abc",title:"Quadratic value of C for t",draw:e.drawQCT,onMouseMove:e.setCT}),r.createElement(i,{inline:!0,preset:"abc",title:"Cubic value of C for t",draw:e.drawCCT,onMouseMove:e.setCT})),r.createElement("p",null,"Mouse-over the graphs to see the expression for C, given the ",r.createElement("em",null,"t")," value at the mouse pointer.")),r.createElement("p",null,"There's also another important bit of information that is inherent to the ABC values: while the distances between A and B, and B and C, are dynamic (based on where we put B), the ",r.createElement("em",null,"ratio")," between the two distances is stable: given some ",r.createElement("em",null,"t")," value, the following always holds:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/6cb3e94fe9164128a25570a32abed15baa726f17.svg",width:"263.2rem",height:"40.599999999999994rem"}),r.createElement("p",null,"This leads to a pretty powerful bit of knowledge: merely by knowing the ",r.createElement("em",null,"t")," value of some on curve point, we know where C has to be (as per the above note), and because we know B and C, and thus have the distance between them, we know where A has to be:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1dffb79b42799c95c899e689b074361f662ec807.svg",width:"228.2rem",height:"39.199999999999996rem"}),r.createElement("p",null,"And that's it, all values found."),r.createElement("div",{className:"note"},r.createElement("p",null,"Much like the ",r.createElement("em",null,"u(t)")," function in the above note, the ",r.createElement("em",null,"ratio(t)")," function depends on whether we're looking at quadratic or cubic curves. Their form is intrinsically related to the ",r.createElement("em",null,"u(t)")," function in that they both come rolling out of the same function evalution, explained over on ",r.createElement("a",{href:"http://mathoverflow.net/questions/122257/finding-the-formula-for-Bézier-curve-ratios-hull-point-point-baseline"},"MathOverflow"),' by Boris Zbarsky and myself. The ratio functions are the "s(t)" functions from the answers there, while the "u(t)" functions have the same name both here and on MathOverflow.'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7ef64890f95db9e48258edb46a3d52d5ed143155.svg",width:"257.59999999999997rem",height:"43.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5f2bb71795c615637d632da70b722938cb103b03.svg",width:"233.79999999999998rem",height:"43.4rem"}),r.createElement("p",null,'Unfortunately, this trick only works for quadratic and cubic curves. Once we hit higher order curves, things become a lot less predictable; the "fixed point ',r.createElement("em",null,"C"),'" is no longer fixed, moving around as we move the control points, and projections of ',r.createElement("em",null,"B")," onto the line between start and end may actually lie on that line before the start, or after the end, and there are no simple ratios that we can exploit.")),r.createElement("p",null,"So: if we know B and its corresponding ",r.createElement("em",null,"t"),' value, then we know all the ABC values, which —together with a start and end coordinate— gives us the necessary information to reconstruct a curve\'s "de Casteljau skeleton", which means that two points and a value between 0 and 1, we can come up with a curve. And that opens up possibilities: curve manipulation by dragging an on-curve point, curve fitting of "a bunch of coordinates", these are useful things, and we\'ll look at both in the next sections.'))}},moulding:{locale:"en-GB",title:"Manipulating a curve",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"moulding",title:"Manipulating a curve",number:"27"}),r.createElement("p",null,'Armed with knowledge of the "ABC" relation, we can now update a curve interactively, by letting people click anywhere on the curve, find the ',r.createElement("em",null,"t"),'-value matching that coordinate, and then letting them drag that point around. With every drag update we\'ll have a new point "B", which we can combine with the fixed point "C" to find our new point A. Once we have those, we can reconstruct the de Casteljau skeleton and thus construct a new curve with the same start/end points as the original curve, passing through the user-selected point B, with correct new control points.'),r.createElement(i,{preset:"moulding",title:"Moulding a quadratic Bézier curve",setup:e.setupQuadratic,draw:e.drawMould,onClick:e.placeMouldPoint,onMouseDown:e.markQB,onMouseDrag:e.dragQB,onMouseUp:e.saveCurve}),r.createElement("p",null,r.createElement("strong",null,"Click-dragging the curve itself")," shows what we're using to compute the new coordinates: while dragging you will see the original points B and its corresponding ",r.createElement("i",null,"t"),"-value, the original point C for that ",r.createElement("i",null,"t"),"-value, as well as the new point B' based on the mouse cursor. Since we know the ",r.createElement("i",null,"t"),"-value for this configuration, we can compute the ABC ratio for this configuration, and we know that our new point A' should like at a distance:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/e361e1235c94bbe87e95834c7fcfb6ab96e028b9.svg",width:"226.79999999999998rem",height:"37.8rem"}),r.createElement("p",null,"For quadratic curves, this means we're done, since the new point A' is equivalent to the new quadratic control point. For cubic curves, we need to do a little more work:"),r.createElement(i,{preset:"moulding",title:"Moulding a cubic Bézier curve",setup:e.setupCubic,draw:e.drawMould,onClick:e.placeMouldPoint,onMouseDown:e.markCB,onMouseDrag:e.dragCB,onMouseUp:e.saveCurve}),r.createElement("p",null,"To help understand what's going on, the cubic graphic shows the full de Casteljau construction \"hull\" when repositioning point B. We compute A` in exactly the same way as before, but we also record the final strut line that forms B in the original curve. Given A', B', and the endpoints e1 and e2 of the strut line relative to B', we can now compute where the new control points should be. Remember that B' lies on line e1--e2 at a distance ",r.createElement("i",null,"t"),", because that's how Bézier curves work. In the same manner, we know the distance A--e1 is only line-interval [0,t] of the full segment, and A--e2 is only line-interval [t,1], so constructing the new control points is fairly easy."),r.createElement("p",null,"First, we construct the one-level-of-de-Casteljau-up points:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1833383a4800c495451abcacc2ada34e5601995d.svg",width:"140rem",height:"78.39999999999999rem"}),r.createElement("p",null,"And then we can compute the new control points:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d53cad094fddaacbb047c9d7c465a5011e3bfbfd.svg",width:"163.79999999999998rem",height:"78.39999999999999rem"}),r.createElement("p",null,"And that's cubic curve manipulation."))}},pointcurves:{locale:"en-GB",title:"Creating a curve from three points",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"pointcurves",title:"Creating a curve from three points",number:"28"}),r.createElement("p",null,"Given the preceding section on curve manipulation, we can also generate quadratic and cubic curves from any three points. However, unlike circle-fitting, which requires just three points, Bézier curve fitting requires three points, as well as a ",r.createElement("em",null,"t")," value, so we can figure out where point 'C' needs to be."),r.createElement("p",null,"The following graphic lets you place three points, and will use the preceding sections on the ABC ratio and curve construction to form a quadratic curve through them. You can move the points you've placed around by click-dragging, or try a new curve by drawing new points with pure clicks. (There's some freedom here, so for illustrative purposes we clamped ",r.createElement("em",null,"t")," to simply be 0.5, lets us bypass some maths, since a ",r.createElement("em",null,"t")," value of 0.5 always puts C in the middle of the start--end line segment)"),r.createElement(i,{preset:"generate",title:"Fitting a quadratic Bézier curve",setup:e.setup,draw:e.drawQuadratic,onClick:e.onClick}),r.createElement("p",null,'For cubic curves we also need some values to construct the "de Casteljau line through B" with, and that gives us quite a bit of choice. Since we\'ve clamped ',r.createElement("em",null,"t"),' to 0.5, we\'ll set up a line through B parallel to the line start--end, with a length that is proportional to the length of the line B--C: the further away from the baseline B is, the wider its construction line will be, and so the more "bulby" the curve will look. This still gives us some freedom in terms of exactly how to scale the length of the construction line as we move B closer or further away from the baseline, so I simply picked some values that sort-of-kind-of look right in that if a circle through (start,B,end) forms a perfect hemisphere, the cubic curve constructed forms something close to a hemisphere, too, and if the points lie on a line, then the curve constructed has the control points very close to B, while still lying between B and the correct curve end point:'),r.createElement(i,{preset:"generate",title:"Fitting a cubic Bézier curve",setup:e.setup,draw:e.drawCubic,onClick:e.onClick}),r.createElement("p",null,'In each graphic, the blue parts are the values that we "just have" simply by setting up our three points, combined with our decision on which ',r.createElement("em",null,"t")," value to use (and construction line orientation and length for cubic curves). There are of course many ways to determine a combination of ",r.createElement("em",null,"t"),' and tangent values that lead to a more "æsthetic" curve, but this will be left as an exercise to the reader, since there are many, and æsthetics are often quite personal.'))}},catmullconv:{locale:"en-GB",title:"Bézier curves and Catmull-Rom curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"catmullconv",title:"Bézier curves and Catmull-Rom curves",number:"29"}),r.createElement("p",null,"Taking an excursion to different splines, the other common design curve is the ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull.E2.80.93Rom_spline"},"Catmull-Rom spline"),". Now, a Catmull-Rom spline is a form of cubic Hermite spline, and as it so happens the cubic Bézier curve is also a cubic Hermite spline, so maybe... maybe we can convert one into the other, and back, with some simple substitutions?"),r.createElement("p",null,'Unlike Bézier curves, Catmull-Rom splines pass through each point used to define the curve, except the first and last, which makes sense if you read the "natural language" descriptionfor how a Catmull-Rom spline works: a Catmull-Rom spline is a curve that, at each point P',r.createElement("sub",null,"x"),", has a tangent along the line P",r.createElement("sub",null,"x-1")," to P",r.createElement("sub",null,"x+1"),". The curve runs from points P",r.createElement("sub",null,"2")," to P",r.createElement("sub",null,"n-1"),', and has a "tension" that determines how fast the curve passes through each point. The lower the tension, the faster the curve goes through each point, and the bigger its local tangent is.'),r.createElement("p",null,"I'll be showing the conversion to and from Catmull-Rom curves for the tension that the Processing language uses for its Catmull-Rom algorithm."),r.createElement("p",null,"We start with showing the Catmull-Rom matrix form:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5fc1c44e623f2a9fbeefdaa204557479e3debf5a.svg",width:"429.79999999999995rem",height:"78.39999999999999rem"}),r.createElement("p",null,"However, there's something funny going on here: the coordinate column matrix looks weird. The reason is that Catmull-Rom curves are actually curve segments that are described by two points, and two tangents; the curve leaves a point V1 (if we have four coordinates instead, this is coordinate 2), arriving at a point V2 (coordinate 3), with the curve departing V1 with a tangent vector V'1 (equal to the tangent from coordinate 1 to coordinate 3) and arriving at V2 with tangent vector V'2 (equal to the tangent from coordinate 2 to coordinate 4). So if we want to express this as a matrix form based on four coordinates, we get this representation instead:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/40b9ca9b5755a4be49517ddfa630fef7b8e23067.svg",width:"406rem",height:"86.8rem"}),r.createElement("div",{className:"note"},r.createElement("h2",{id:"where-did-that-2-come-from-"},"Where did that 2 come from?"),r.createElement("p",null,"Catmull-Rom splines are based on the concept of tension: the higher the tensions, the shorter the tangents at the departure and arrival points. The basic Catmull-Rom curve arrives and departs with tangents equal to half the distance between the two adjacent points, so that's where that 2 came from."),r.createElement("p",null,'However, the "real" matrix is this:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7bf9b5e971866babedd991ccdde5c4ab104297e5.svg",width:"351.4rem",height:"88.19999999999999rem"}),r.createElement("p",null,"This bakes in the tension factor τ explicitly.")),r.createElement("p",null,'Plugging this into the "two coordinates and two tangent vectors" matrix form, we get:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/4818f8797c35f23c2b9883aa986b1129b2fa151a.svg",width:"299.59999999999997rem",height:"78.39999999999999rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/08f77989369f664cbc0fb7526791efd4c5299d70.svg",width:"499.79999999999995rem",height:"77rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c7ae769c5370469b16523bab6f34abf0dd6749be.svg",width:"414.4rem",height:"77rem"}),r.createElement("p",null,"So let's find out which transformation matrix we need in order to convert from Catmull-Rom to Bézier:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/7250f1c57e2bd66ec4349e4e88db4d5d74401a06.svg",width:"730.8rem",height:"77rem"}),r.createElement("p",null,"The difference is somewhere in the actual hermite matrix, since the ",r.createElement("em",null,"t")," and coordinate values are identical, so let's solve that matrix equasion:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/8a42b24fca3aaf6b8ec08e84b7e91c43e26e8acf.svg",width:"418.59999999999997rem",height:"75.6rem"}),r.createElement("p",null,"We left-multiply both sides by the inverse of the Bézier matrix, to get rid of the Bézier matrix on the right side of the equals sign:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e111d6e846f4d7204dec484005f74993e66c6c9.svg",width:"841.4rem",height:"84rem"}),r.createElement("p",null,"Which gives us:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/f94b80113772d90a4fbc93d4495cb5767e5c8123.svg",width:"183.39999999999998rem",height:"75.6rem"}),r.createElement("p",null,"Multiplying this ",r.createElement("strong",null,r.createElement("em",null,"A"))," with our coordinates will give us a proper Bézier matrix expression again:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/d088274e440ceeac2916a0f32176682d776c1c57.svg",width:"448rem",height:"77rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/9e68f80b270d3445d9f9cb28ff2c5aed219aa9d2.svg",width:"365.4rem",height:"85.39999999999999rem"}),r.createElement("p",null,"So a Catmull-Rom to Bézier conversion, based on coordinates, requires turning the Catmull-Rom coordinates on the left into the Bézier coordinates on the right (with τ being our tension factor):"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/92a34d777899da97f1907e6b093db28872f02c3a.svg",width:"261.8rem",height:"89.6rem"}),r.createElement("p",null,"And the other way around, a Bézier to Catmull-Rom conversion requires turning the Bézier coordinates on the left this time into the Catmull-Rom coordinates on the right. Note that there is no tension this time, because Bézier curves don't have any. Converting from Bézier to Catmull-Rom is simply a default-tension Catmull-Rom curve:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ee3d3d219a18596dc403c0392d44bc585d738e6c.svg",width:"309.4rem",height:"81.19999999999999rem"}),r.createElement("p",null,"Done. We can now draw the curves we want using either Bézier curves or Catmull-Rom splines, the choice mostly being which drawing algorithms we have natively available."))}},catmullmoulding:{locale:"en-GB",title:"Creating a Catmull-Rom curve from three points",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"catmullmoulding",title:"Creating a Catmull-Rom curve from three points",number:"30"}),r.createElement("p",null,"Now, we saw how to fit a Bézier curve to three points, but if Catmull-Rom curves go through points, why can't we just use those to do curve fitting, instead?"),r.createElement("p",null,"As a matter of fact, we can, but there's a difference between the kind of curve fitting we did in the previous section, and the kind of curve fitting that we can do with Catmull-Rom curves. In the previous section we came up with a single curve that goes through three points. There was a decent amount of maths and computation involved, and the end result was three or four coordinates that described a single curve, depending on whether we were fitting a quadratic or cubic curve."),r.createElement("p",null,"Using Catmull-Rom curves, we need virtually no computation, but even though we end up with one Catmull-Rom curve of ",r.createElement("i",null,"n")," points, in order to draw the equivalent curve using cubic Bézier curves we need a massive ",r.createElement("i",null,"3n-2")," points (and that's without double-counting points that are shared by consecutive cubic curves)."),r.createElement("p",null,'In the following graphic, on the left we see three points that we want to draw a Catmull-Rom curve through (which we can move around freely, by the way), with in the second panel some of the "interesting" Catmull-Rom information: in black there\'s the baseline start--end, which will act as tangent orientation for the curve at point p2. We also see a virtual point p0 and p4, which are initially just point p2 reflected over the baseline. However, by using the up and down cursor key we can offset these points parallel to the baseline. Why would we want to do this? Because the line p0--p2 acts as departure tangent at p1, and the line p2--p4 acts as arrival tangent at p3. Play around with the graphic a bit to get an idea of what all of that meant:'),r.createElement(i,{ +preset:"threepanel",title:"Catmull-Rom curve fitting",setup:e.setup,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"As should be obvious by now, Catmull-Rom curves are great for \"fitting a curvature to some points\", but if we want to convert that curve to Bézier form we're going to end up with a lot of separate (but visually joined) Bézier curves. Depending on what we want to do, that'll be either unnecessary work, or exactly what we want: which it is depends entirely on you."))}},polybezier:{locale:"en-GB",title:"Forming poly-Bézier curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"polybezier",title:"Forming poly-Bézier curves",number:"31"}),r.createElement("p",null,"Much like lines can be chained together to form polygons, Bézier curves can be chained together to form poly-Béziers, and the only trick required is to make sure that:"),r.createElement("ol",null,r.createElement("li",null,"the end point of each section is the starting point of the following section, and"),r.createElement("li",null,"the derivatives across that dual point line up.")),r.createElement("p",null,"Unless, of course, you want discontinuities; then you don't even need 2."),r.createElement("p",null,"We'll cover three forms of poly-Bézier curves in this section. First, we'll look at the kind that just follows point 1. where the end point of a segment is the same point as the start point of the next segment. This leads to poly-Béziers that are pretty hard to work with, but they're the easiest to implement:"),r.createElement(i,{preset:"poly",title:"Unlinked quadratic poly-Bézier",setup:e.setupQuadratic,draw:e.draw}),r.createElement(i,{preset:"poly",title:"Unlinked cubic poly-Bézier",setup:e.setupCubic,draw:e.draw}),r.createElement("p",null,'Dragging the control points around only affects the curve segments that the control point belongs to, and moving an on-curve point leaves the control points where they are, which is not the most useful for practical modelling purposes. So, let\'s add in the logic we need to make things a little better. We\'ll start by linking up control points by ensuring that the "incoming" derivative at an on-curve point is the same as it\'s "outgoing" derivative:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/37740bb1a0b7b1ff48bf3454e52295fc717cacbb.svg",width:"130.2rem",height:"18.2rem"}),r.createElement("p",null,"We can effect this quite easily, because we know that the vector from a curve's last control point to its last on-curve point is equal to the derivative vector. If we want to ensure that the first control point of the next curve matches that, all we have to do is mirror that last control point through the last on-curve point. And mirroring any point A through any point B is really simple:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ce6e3939608c4ed0598107b06543c2301b91bb7f.svg",width:"319.2rem",height:"42rem"}),r.createElement("p",null,"So let's implement that and see what it gets us. The following two graphics show a quadratic and a cubic poly-Bézier curve again, but this time moving the control points around moves others, too. However, you might see something unexpected going on for quadratic curves..."),r.createElement(i,{preset:"poly",title:"Loosely connected quadratic poly-Bézier",setup:e.setupQuadratic,draw:e.draw,onMouseMove:e.linkDerivatives}),r.createElement(i,{preset:"poly",title:"Loosely connected cubic poly-Bézier",setup:e.setupCubic,draw:e.draw,onMouseMove:e.linkDerivatives}),r.createElement("p",null,"As you can see, quadratic curves are particularly ill-suited for poly-Bézier curves, as all the control points are effectively linked. Move one of them, and you move all of them. Not only that, but if we move the on-curve points, it's possible to get a situation where a control point's positions is different depending on whether it's the reflection of its left or right neighbouring control point: we can't even form a proper rule-conforming curve! This means that we cannot use quadratic poly-Béziers for anything other than really, really simple shapes. And even then, they're probably the wrong choice. Cubic curves are pretty decent, but the fact that the derivatives are linked means we can't manipulate curves as well as we might if we relaxed the constraints a little."),r.createElement("p",null,"So: let's relax the requirement a little."),r.createElement("p",null,"We can change the constraint so that we still preserve the ",r.createElement("em",null,"angle")," of the derivatives across sections (so transitions from one section to the next will still look natural), but give up the requirement that they should also have the same ",r.createElement("em",null,"vector length"),". Doing so will give us a much more useful kind of poly-Bézier curve:"),r.createElement(i,{preset:"poly",title:"Loosely connected quadratic poly-Bézier",setup:e.setupQuadratic,draw:e.draw,onMouseMove:e.linkDirection}),r.createElement(i,{preset:"poly",title:"Loosely connected cubic poly-Bézier",setup:e.setupCubic,draw:e.draw,onMouseMove:e.linkDirection}),r.createElement("p",null,"Cubic curves are now better behaved when it comes to dragging control points around, but the quadratic poly-Bézier still has the problem that moving one control points will move the control points and may ending up defining \"the next\" control point in a way that doesn't work. Quadratic curves really aren't very useful to work with..."),r.createElement("p",null,"Finally, we also want to make sure that moving the on-curve coordinates preserves the relative positions of the associated control points. With that, we get to the kind of curve control that you might be familiar with from applications like Photoshop, Inkscape, Blender, etc."),r.createElement(i,{preset:"poly",title:"Loosely connected quadratic poly-Bézier",setup:e.setupQuadratic,draw:e.draw,onMouseDown:e.bufferPoints,onMouseMove:e.modelCurve}),r.createElement(i,{preset:"poly",title:"Loosely connected cubic poly-Bézier",setup:e.setupCubic,draw:e.draw,onMouseDown:e.bufferPoints,onMouseMove:e.modelCurve}),r.createElement("p",null,'Again, we see that cubic curves are now rather nice to work with, but quadratic curves have a new, very serious problem: we can move an on-curve point in such a way that we can\'t compute what needs to "happen next". Move the top point down, below the left and right points, for instance. There is no way to preserve correct control points without a kink at the bottom point. Quadratic curves: just not that good...'),r.createElement("p",null,'A final improvement is to offer fine-level control over which points behave which, so that you can have "kinks" or individually controlled segments when you need them, with nicely well-behaved curves for the rest of the path. Implementing that, is left as an excercise for the reader.'))}},shapes:{locale:"en-GB",title:"Boolean shape operations",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"shapes",title:"Boolean shape operations",number:"32"}),r.createElement("p",null,"We can apply the topics covered so far in this primer to effect boolean shape operations: getting the union, intersection, or exclusion, between two or more shapes that involve Bézier curves. For simplicity (well.. sort of, more homogeneity), we'll be looking at Poly-Bézier shapes only, but a shape that consists of a mix of lines and Bézier curves is technically a simplification (although it does mean we need to write a definition for the class of shapes that mix lines and Bézier curves. Since poly-Bézier curves are a superset, we'll be using those in the following examples)"),r.createElement("p",null,"The procedure for performing boolean operations consists, broadly, of four steps:"),r.createElement("ol",null,r.createElement("li",null,"Find the intersection points between both shapes,"),r.createElement("li",null,"cut up the shapes into multiple sections between these intersections,"),r.createElement("li",null,"discard any section that isn't part of the desired operation's resultant shape, and"),r.createElement("li",null,"link up the remaining sections to form the new shape.")),r.createElement("p",null,"Finding all intersections between two poly-Bézier curves, or any poly-line-section shape, is similar to the iterative algorithm discussed in the section on curve/curve intersection. For each segment in the poly-Bézier curve we check whether its bounding box overlaps with any of the segment bounding boxes in the other poly-Bézier curve. If so, we run normal intersection detection."),r.createElement("p",null,"After we found all intersection points, we split up our poly-Bézier curves, making sure to record which of the newly formed poly-Bézier curves might potentially link up at the points we split the originals up at. This will let us quickly glue poly-Bézier curves back together after the next step."),r.createElement("p",null,"Once we have all the new poly-Bézier curves, we run the first step of the desired boolean operation."),r.createElement("ul",null,r.createElement("li",null,'Union: discard all poly-Bézier curves that lie "inside" our union of our shapes. E.g. if we want the union of two overlapping circles, the resulting shape is the outline.'),r.createElement("li",null,'Intersection: discard all poly-Bézier curves that lie "outside" the intersection of the two shapes. E.g. if we want the intersection of two overlapping circles, the resulting shape is the tapered ellipse where they overlap.'),r.createElement("li",null,"Exclusion: none of the sections are discarded, but we will need to link the shapes back up in a special way. Flip any section that would qualify for removal under UNION rules.")),r.createElement("table",{className:"sketch"},r.createElement("tbody",null,r.createElement("tr",null,r.createElement("td",{className:"labeled-image"},r.createElement("img",{src:"images/op_base.gif",height:"169px"}),"Two overlapping shapes."),r.createElement("td",{className:"labeled-image"},r.createElement("img",{src:"images/op_union.gif",height:"169px"}),"The unified region."),r.createElement("td",{className:"labeled-image"},r.createElement("img",{src:"images/op_intersection.gif",height:"169px"}),"Their intersection."),r.createElement("td",{className:"labeled-image"},r.createElement("img",{src:"images/op_exclusion.gif",height:"169px"}),"Their exclusion regions.")))),r.createElement("p",null,'The main complication in the outlined procedure here is determining how sections qualify in terms of being "inside" and "outside" of our shapes. For this, we need to be able to perform point-in-shape detection, for which we\'ll use a classic algorithm: getting the "crossing number" by using ray casting, and then testing for "insidedness" by applying the ',r.createElement("a",{href:"http://folk.uio.no/bjornw/doc/bifrost-ref/bifrost-ref-12.html"},"even-odd rule"),': For any point and any shape, we can cast a ray from our point, to some point that we know lies outside of the shape (such as a corner of our drawing surface). We then count how many times that line crosses our shape (remember that we can perform line/curve intersection detection quite easily). If the number of times it crosses the shape\'s outline is even, the point did not actually lie inside our shape. If the number of intersections is odd, our point did lie inside out shape. With that knowledge, we can decide whether to treat a section that such a point lies on "needs removal" (under union rules), "needs preserving" (under intersection rules), or "needs flipping" (under exclusion rules).'),r.createElement("p",null,"These operations are expensive, and implementing your own code for this is generally a bad idea if there is already a geometry package available for your language of choice. In this case, for JavaScript the most excellent ",r.createElement("a",{href:"http://paperjs.org"},"Paper.js")," already comes with all the code in place to perform efficient boolean shape operations, so rather that implement an inferior version here, I can strongly recommend the Paper.js library if you intend to do any boolean shape work."),r.createElement("p",null,"The following graphic shows Paper.js doing its thing for two shapes: one static, and one that is linked to your mouse pointer. If you move the mouse around, you'll see how the shape intersections are resolved. The base shapes are outlined in blue, and the boolean result is coloured red."),r.createElement(i,{preset:"simple",title:"Boolean shape operations with Paper.js",paperjs:!0,setup:e.setup,draw:e.draw,onMouseMove:e.onMouseMove},r.createElement("br",null),e.modes.map(function(t){var n=e.state.mode===t?"selected":null;return r.createElement("button",{className:n,key:t,onClick:function(){return e.setMode(t)}},t)})))}},projections:{locale:"en-GB",title:"Projecting a point onto a Bézier curve",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"projections",title:"Projecting a point onto a Bézier curve",number:"33"}),r.createElement("p",null,"Say we have a Bézier curve and some point, not on the curve, of which we want to know which ",r.createElement("code",null,"t")," value on the curve gives us an on-curve point closest to our off-curve point. Or: say we want to find the projection of a random point onto a curve. How do we do that?"),r.createElement("p",null,"If the Bézier curve is of low enough order, we might be able to ",r.createElement("a",{href:"http://jazzros.blogspot.ca/2011/03/projecting-point-on-bezier-curve.html"},"work out the maths for how to do this"),", and get a perfect ",r.createElement("code",null,"t")," value back, but in general this is an incredibly hard problem and the easiest solution is, really, a numerical approach again. We'll be finding our ideal ",r.createElement("code",null,"t")," value using a ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Binary_search_algorithm"},"binary search"),". First, we do a coarse distance-check based on ",r.createElement("code",null,"t"),' values associated with the curve\'s "to draw" coordinates (using a lookup table, or LUT). This is pretty fast. Then we run this algorithm:'),r.createElement("ol",null,r.createElement("li",null,"with the ",r.createElement("code",null,"t")," value we found, start with some small interval around ",r.createElement("code",null,"t")," (1/length_of_LUT on either side is a reasonable start),"),r.createElement("li",null,"if the distance to ",r.createElement("code",null,"t ± interval/2")," is larger than the distance to ",r.createElement("code",null,"t"),", try again with the interval reduced to half its original length."),r.createElement("li",null,"if the distance to ",r.createElement("code",null,"t ± interval/2")," is smaller than the distance to ",r.createElement("code",null,"t"),", replace ",r.createElement("code",null,"t")," with the smaller-distance value."),r.createElement("li",null,"after reducing the interval, or changing ",r.createElement("code",null,"t"),", go back to step 1.")),r.createElement("p",null,"We keep repeating this process until the interval is small enough to claim the difference in precision found is irrelevant for the purpose we're trying to find ",r.createElement("code",null,"t")," for. In this case, I'm arbitrarily fixing it at 0.0001."),r.createElement("p",null,'The following graphic demonstrates the result of this procedure.Simply move the cursor around, and if it does not lie on top of the curve, you will see a line that projects the cursor onto the curve based on an iteratively found "ideal" ',r.createElement("code",null,"t")," value."),r.createElement(i,{preset:"simple",title:"Projecting a point onto a Bézier curve",setup:e.setup,draw:e.draw,onMouseMove:e.onMouseMove}))}},offsetting:{locale:"en-GB",title:"Curve offsetting",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"offsetting",title:"Curve offsetting",number:"34"}),r.createElement("p",null,"Perhaps you are like me, and you've been writing various small programs that use Bézier curves in some way or another, and at some point you make the step to implementing path extrusion. But you don't want to do it pixel based, you want to stay in the vector world. You find that extruding lines is relatively easy, and tracing outlines is coming along nicely (although junction caps and fillets are a bit of a hassle), and then decide to do things properly and add Bézier curves to the mix. Now you have a problem."),r.createElement("p",null,"Unlike lines, you can't simply extrude a Bézier curve by taking a copy and moving it around, because of the curvatures; rather than a uniform thickness you get an extrusion that looks too thin in places, if you're lucky, but more likely will self-intersect. The trick, then, is to scale the curve, rather than simply copying it. But how do you scale a Bézier curve?"),r.createElement("p",null,"Bottom line: ",r.createElement("strong",null,"you can't"),". So you cheat. We're not going to do true curve scaling, or rather curve offsetting, because that's impossible. Instead we're going to try to generate 'looks good enough' offset curves."),r.createElement("div",{className:"note"},r.createElement("h3",{id:"-what-do-you-mean-you-can-t-prove-it-"},'"What do you mean, you can\'t. Prove it."'),r.createElement("p",null,'First off, when I say "you can\'t" what I really mean is "you can\'t offset a Bézier curve with another Bézier curve". not even by using a really high order curve. You can find the function that describes the offset curve, but it won\'t be a polynomial, and as such it cannot be represented as a Bézier curve, which ',r.createElement("strong",null,"has")," to be a polynomial. Let's look at why this is:"),r.createElement("p",null,"From a mathematical point of view, an offset curve ",r.createElement("code",null,"O(t)")," is a curve such that, given our original curve ",r.createElement("code",null,"B(t)"),", any point on ",r.createElement("code",null,"O(t)")," is a fixed distance ",r.createElement("code",null,"d")," away from coordinate ",r.createElement("code",null,"B(t)"),". So let's math that:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3aff5cef0028337bbb48ae64ad30000c4d5e238f.svg",width:"113.39999999999999rem",height:"16.799999999999997rem"}),r.createElement("p",null,"However, we're working in 2D, and ",r.createElement("code",null,"d")," is a single value, so we want to turn it into a vector. If we want a point distance ",r.createElement("code",null,"d"),' "away" from the curve ',r.createElement("code",null,"B(t)")," then what we really mean is that we want a point at ",r.createElement("code",null,"d"),' times the "normal vector" from point ',r.createElement("code",null,"B(t)"),', where the "normal" is a vector that runs perpendicular ("at a right angle") to the tangent at ',r.createElement("code",null,"B(t)"),". Easy enough:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/2cf48e2f8525258a3fa0fe4f10ec2acef67104b3.svg",width:"158.2rem",height:"16.799999999999997rem"}),r.createElement("p",null,"Now this still isn't very useful unless we know what the formula for ",r.createElement("code",null,"N(t)")," is, so let's find out. ",r.createElement("code",null,"N(t)")," runs perpendicular to the original curve tangent, and we know that the tangent is simply ",r.createElement("code",null,"B'(t)"),", so we could just rotate that 90 degrees and be done with it. However, we need to ensure that ",r.createElement("code",null,"N(t)")," has the same magnitude for every ",r.createElement("code",null,"t"),", or the offset curve won't be at a uniform distance, thus not being an offset curve at all. The easiest way to guarantee this is to make sure ",r.createElement("code",null,"N(t)")," always has length 1, which we can achieve by dividing ",r.createElement("code",null,"B'(t)")," by its magnitude:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/4941ecbff4c50732ba66fec53307456fc605f032.svg",width:"125.99999999999999rem",height:"42rem"}),r.createElement("p",null,"Determining the length requires computing an arc length, and this is where things get Tricky with a capital T. First off, to compute arc length from some start ",r.createElement("code",null,"a")," to end ",r.createElement("code",null,"b"),', we must use the formula we saw earlier. Noting that "length" is usually denoted with double vertical bars:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/f6d8c2965b02363e092acb00bbc1398cfbb170a4.svg",width:"177.79999999999998rem",height:"37.8rem"}),r.createElement("p",null,"So if we want the length of the tangent, we plug in ",r.createElement("code",null,"B'(t)"),", with ",r.createElement("code",null,"t = 0")," as start and",r.createElement("code",null,"t = 1")," as end:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1f024282044316a9e4b3de2c855d2ceb96aff056.svg",width:"219.79999999999998rem",height:"37.8rem"}),r.createElement("p",null,"And that's where things go wrong. It doesn't even really matter what the second derivative for ",r.createElement("code",null,"B(t)")," is, that square root is screwing everything up, because it turns our nice polynomials into things that are no longer polynomials."),r.createElement("p",null,"There is a small class of polynomials where the square root is also a polynomial, but they're utterly useless to us: any polynomial with unweighted binomial coefficients has a square root that is also a polynomial. Now, you might think that Bézier curves are just fine because they do, but they don't; remember that only the ",r.createElement("strong",null,"base")," function has binomial coefficients. That's before we factor in our coordinates, which turn it into a non-binomial polygon. The only way to make sure the functions stay binomial is to make all our coordinates have the same value. And that's not a curve, that's a point. We can already create offset curves for points, we call them circles, and they have much simpler functions than Bézier curves."),r.createElement("p",null,"So, since the tangent length isn't a polynomial, the normalised tangent won't be a polynomial either, which means ",r.createElement("code",null,"N(t)")," won't be a polynomial, which means that ",r.createElement("code",null,"d")," times ",r.createElement("code",null,"N(t)")," won't be a polynomial, which means that, ultimately, ",r.createElement("code",null,"O(t)")," won't be a polynomial, which means that even if we can determine the function for ",r.createElement("code",null,"O(t)")," just fine (and that's far from trivial!), it simply cannot be represented as a Bézier curve."),r.createElement("p",null,"And that's one reason why Bézier curves are tricky: there are actually a ",r.createElement("code",null,"lot")," of curves that cannot be represent as a Bézier curve at all. They can't even model their own offset curves. They're weird that way. So how do all those other programs do it? Well, much like we're about to do, they cheat. We're going to approximate an offset curve in a way that will look relatively close to what the real offset curve would look like, if we could compute it.")),r.createElement("p",null,'So, you cannot offset a Bézier curve perfectly with another Bézier curve, no matter how high-order you make that other Bézier curve. However, we can chop up a curve into "safe" sub-curves (where safe means that all the control points are always on a single side of the baseline, and the midpoint of the curve at ',r.createElement("code",null,"t=0.5")," is roughly in the centre of the polygon defined by the curve coordinates) and then point-scale each sub-curve with respect to its scaling origin (which is the intersection of the point normals at the start and end points)."),r.createElement("p",null,"A good way to do this reduction is to first find the curve's extreme points, as explained in the earlier section on curve extremities, and use these as initial splitting points. After this initial split, we can check each individual segment to see if it's \"safe enough\" based on where the center of the curve is. If the on-curve point for ",r.createElement("code",null,"t=0.5")," is too far off from the center, we simply split the segment down the middle. Generally this is more than enough to end up with safe segments."),r.createElement("p",null,"The following graphics show off curve offsetting, and you can use your up and down arrow keys to control the distance at which the curve gets offset. The curve first gets reduced to safe segments, each of which is then offset at the desired distance. Especially for simple curves, particularly easily set up for quadratic curves, no reduction is necessary, but the more twisty the curve gets, the more the curve needs to be reduced in order to get segments that can safely be scaled."),r.createElement(i,{preset:"simple",title:"Offsetting a quadratic Bézier curve",setup:e.setupQuadratic,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement(i,{preset:"simple",title:"Offsetting a cubic Bézier curve",setup:e.setupCubic,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"You may notice that this may still lead to small 'jumps' in the sub-curves when moving the curve around. This is caused by the fact that we're still performing a naive form of offsetting, moving the control points the same distance as the start and end points. If the curve is large enough, this may still lead to incorrect offsets."))}},graduatedoffset:{locale:"en-GB",title:"Graduated curve offsetting",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"graduatedoffset",title:"Graduated curve offsetting",number:"35"}),r.createElement("p",null,"What if we want to do graduated offsetting, starting at some distance ",r.createElement("code",null,"s")," but ending at some other distance ",r.createElement("code",null,"e"),'? well, if we can compute the length of a curve (which we can if we use the Legendre-Gauss quadrature approach) then we can also determine how far "along the line" any point on the curve is. With that knowledge, we can offset a curve so that its offset curve is not uniformly wide, but graduated between with two different offset widths at the start and end.'),r.createElement("p",null,'Like normal offsetting we cut up our curve in sub-curves, and then check at which distance along the original curve each sub-curve starts and ends, as well as to which point on the curve each of the control points map. This gives us the distance-along-the-curve for each interesting point in the sub-curve. If we call the total length of all sub-curves seen prior to seeing "the current" sub-curve ',r.createElement("code",null,"S")," (and if the current sub-curve is the first one, ",r.createElement("code",null,"S")," is zero), and we call the full length of our original curve ",r.createElement("code",null,"L"),", then we get the following graduation values:"),r.createElement("ul",null,r.createElement("li",null,"start: map ",r.createElement("code",null,"S")," from interval (",r.createElement("code",null,"0,L"),") to interval ",r.createElement("code",null,"(s,e)")),r.createElement("li",null,"c1: ",r.createElement("code",null,"map(<strong>S+d1</strong>, 0,L, s,e)"),", d1 = distance along curve to projection of c1"),r.createElement("li",null,"c2: ",r.createElement("code",null,"map(<strong>S+d2</strong>, 0,L, s,e)"),", d2 = distance along curve to projection of c2"),r.createElement("li",null,"..."),r.createElement("li",null,"end: ",r.createElement("code",null,"map(<strong>S+length(subcurve)</strong>, 0,L, s,e)"))),r.createElement("p",null,"At each of the relevant points (start, end, and the projections of the control points onto the curve) we know the curve's normal, so offsetting is simply a matter of taking our original point, and moving it along the normal vector by the offset distance for each point. Doing so will give us the following result (these have with a starting width of 0, and an end width of 40 pixels, but can be controlled with your up and down arrow keys):"),r.createElement(i,{preset:"simple",title:"Offsetting a quadratic Bézier curve",setup:e.setupQuadratic,draw:e.draw,onKeyDown:e.props.onKeyDown}),r.createElement(i,{preset:"simple",title:"Offsetting a cubic Bézier curve",setup:e.setupCubic,draw:e.draw,onKeyDown:e.props.onKeyDown}))}},circles:{locale:"en-GB",title:"Circles and quadratic Bézier curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"circles",title:"Circles and quadratic Bézier curves",number:"36"}),r.createElement("p",null,"Circles and Bézier curves are very different beasts, and circles are infinitely easier to work with than Bézier curves. Their formula is much simpler, and they can be drawn more efficiently. But, sometimes you don't have the luxury of using circles, or ellipses, or arcs. Sometimes, all you have are Bézier curves. For instance, if you're doing font design, fonts have no concept of geometric shapes, they only know straight lines, and Bézier curves. OpenType fonts with TrueType outlines only know quadratic Bézier curves, and OpenType fonts with Type 2 outlines only know cubic Bézier curves. So how do you draw a circle, or an ellipse, or an arc?"),r.createElement("p",null,"You approximate."),r.createElement("p",null,"We already know that Bézier curves cannot model all curves that we can think of, and this includes perfect circles, as well as ellipses, and their arc counterparts. However, we can certainly approximate them to a degree that is visually acceptable. Quadratic and cubic curves offer us different curvature control, so in order to approximate a circle we will first need to figure out what the error is if we try to approximate arcs of increasing degree with quadratic and cubic curves, and where the coordinates even lie."),r.createElement("p",null,"Since arcs are mid-point-symmetrical, we need the control points to set up a symmetrical curve. For quadratic curves this means that the control point will be somewhere on a line that intersects the baseline at a right angle. And we don't get any choice on where that will be, since the derivatives at the start and end point have to line up, so our control point will lie at the intersection of the tangents at the start and end point."),r.createElement("p",null,"First, let's try to fit the quadratic curve onto a circular arc. In the following sketch you can move the mouse around over a unit circle, to see how well, or poorly, a quadratic curve can approximate the arc from (1,0) to where your mouse cursor is:"),r.createElement(i,{preset:"arcfitting",title:"Quadratic Bézier arc approximation",setup:e.setup,draw:e.draw,onMouseMove:e.onMouseMove}),r.createElement("p",null,"As you can see, things go horribly wrong quite quickly; even trying to approximate a quarter circle using a quadratic curve is a bad idea. An eighth of a turns might look okay, but how okay is okay? Let's apply some maths and find out. What we're interested in is how far off our on-curve coordinates are with respect to a circular arc, given a specific start and end angle. We'll be looking at how much space there is between the circular arc, and the quadratic curve's midpoint."),r.createElement("p",null,"We start out with our start and end point, and for convenience we will place them on a unit circle (a circle around 0,0 with radius 1), at some angle ",r.createElement("em",null,"φ"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ef34ab8f466ed3294895135a346b55ada05d779d.svg",width:"183.39999999999998rem",height:"42rem"}),r.createElement("p",null,"What we want to find is the intersection of the tangents, so we want a point C such that:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/5660e8512b07dbac7fcf04633de8002fa25aa962.svg",width:"298.2rem",height:"42rem"}),r.createElement("p",null,"i.e. we want a point that lies on the vertical line through S (at some distance ",r.createElement("em",null,"a")," from S) and also lies on the tangent line through E (at some distance ",r.createElement("em",null,"b")," from E). Solving this gives us:"),r.createElement("img",{ +className:"LaTeX SVG",src:"images/latex/d16e7a1c1e9686e1afb82f4ffcec07078d264565.svg",width:"229.6rem",height:"42rem"}),r.createElement("p",null,"First we solve for ",r.createElement("em",null,"b"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3128b31a874166ebe4479d3002d70f280de375a1.svg",width:"588rem",height:"18.2rem"}),r.createElement("p",null,"which yields:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/02b158f9ef2191b970dc2fe69c0903eba2b1f8b5.svg",width:"106.39999999999999rem",height:"40.599999999999994rem"}),r.createElement("p",null,"which we can then substitute in the expression for ",r.createElement("em",null,"a"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3bd9c2d6740ff530aabcbe60252742032af816e9.svg",width:"242.2rem",height:"204.39999999999998rem"}),r.createElement("p",null,"A quick check shows that plugging these values for ",r.createElement("em",null,"a")," and ",r.createElement("em",null,"b")," into the expressions for C",r.createElement("sub",null,"x")," and C",r.createElement("sub",null,"y"),' give the same x/y coordinates for both "',r.createElement("em",null,"a"),' away from A" and "',r.createElement("em",null,"b")," away from B\", so let's continue: now that we know the coordinate values for C, we know where our on-curve point T for ",r.createElement("em",null,"t=0.5")," (or angle φ/2) is, because we can just evaluate the Bézier polynomial, and we know where the circle arc's actual point P is for angle φ/2:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b80423188012451e0400f473c19729eb2bad654.svg",width:"197.39999999999998rem",height:"33.599999999999994rem"}),r.createElement("p",null,"We compute T, observing that if ",r.createElement("em",null,"t=0.5"),", the polynomial values (1-t)², 2(1-t)t, and t² are 0.25, 0.5, and 0.25 respectively:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/bc50559ff8bd9062694a449aae5f6f85f91de909.svg",width:"264.59999999999997rem",height:"36.4rem"}),r.createElement("p",null,"Which, worked out for the x and y components, gives:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c7fca7664a3acb855eeaaf412aa2331202f41097.svg",width:"428.4rem",height:"81.19999999999999rem"}),r.createElement("p",null,"And the distance between these two is the standard Euclidean distance:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3251cd91a1cffc27a1695ece4c13cc651d7007fb.svg",width:"418.59999999999997rem",height:"161rem"}),r.createElement("p",null,"So, what does this distance function look like when we plot it for a number of ranges for the angle φ, such as a half circle, quarter circle and eighth circle?"),r.createElement("table",null,r.createElement("tbody",null,r.createElement("tr",null,r.createElement("td",null,r.createElement("img",{src:"images/arc-q-pi.gif",height:"190px"}),"plotted for 0 ≤ φ ≤ π:"),r.createElement("td",null,r.createElement("img",{src:"images/arc-q-pi2.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ ½π:"),r.createElement("td",null,e.props.showhref?"http://www.wolframalpha.com/input/?i=plot+sqrt%28%281%2F4+*+%28sin%28x%29+%2B+2tan%28x%2F2%29%29+-+sin%28x%2F2%29%29%5E2+%2B+%282sin%5E4%28x%2F4%29%29%5E2%29+for+0+%3C%3D+x+%3C%3D+pi%2F4":null,r.createElement("img",{src:"images/arc-q-pi4.gif",height:"174px"}),"plotted for 0 ≤ φ ≤ ¼π:")))),r.createElement("p",null,"We now see why the eighth circle arc looks decent, but the quarter circle arc doesn't: an error of roughly 0.06 at ",r.createElement("em",null,"t=0.5")," means we're 6% off the mark... we will already be off by one pixel on a circle with pixel radius 17. Any decent sized quarter circle arc, say with radius 100px, will be way off if approximated by a quadratic curve! For the eighth circle arc, however, the error is only roughly 0.003, or 0.3%, which explains why it looks so close to the actual eighth circle arc. In fact, if we want a truly tiny error, like 0.001, we'll have to contend with an angle of (rounded) 0.593667, which equates to roughly 34 degrees. We'd need 11 quadratic curves to form a full circle with that precision! (technically, 10 and ten seventeenth, but we can't do partial curves, so we have to round up). That's a whole lot of curves just to get a shape that can be drawn using a simple function!"),r.createElement("p",null,"In fact, let's flip the function around, so that if we plug in the precision error, labelled ε, we get back the maximum angle for that precision:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/61a938fa10b77e8c41c3c064ed39bd1145d6bbcc.svg",width:"259rem",height:"56rem"}),r.createElement("p",null,"And frankly, things are starting to look a bit ridiculous at this point, we're doing way more maths than we've ever done, but thankfully this is as far as we need the maths to take us: If we plug in the precisions 0.1, 0.01, 0.001 and 0.0001 we get the radians values 1.748, 1.038, 0.594 and 0.3356; in degrees, that means we can cover roughly 100 degrees (requiring four curves), 59.5 degrees (requiring six curves), 34 degrees (requiring 11 curves), and 19.2 degrees (requiring a whopping nineteen curves)."),r.createElement("p",null,"The bottom line? ",r.createElement("strong",null,"Quadratic curves are kind of lousy")," if you want circular (or elliptical, which are circles that have been squashed in one dimension) curves. We can do better, even if it's just by raising the order of our curve once. So let's try the same thing for cubic curves."))}},circles_cubic:{locale:"en-GB",title:"Circles and cubic Bézier curves",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"circles_cubic",title:"Circles and cubic Bézier curves",number:"37"}),r.createElement("p",null,"In the previous section we tried to approximate a circular arc with a quadratic curve, and it mostly made us unhappy. Cubic curves are much better suited to this task, so what do we need to do?"),r.createElement("p",null,'For cubic curves, we basically want the curve to pass through three points on the circle: the start point, the mid point at "angle/2", and the end point at "angle". We then also need to make sure the control points are such that the start and end tangent lines line up with the circle\'s tangent lines at the start and end point.'),r.createElement("p",null,'The first thing we can do is "guess" what the curve should look like, based on the previously outlined curve-through-three-points procedure. This will give use a curve with correct start, mid and end points, but possibly incorrect derivatives at the start and end, because the control points might not be in the right spot. We can then slide the control points along the lines that connect them to their respective end point, until they effect the corrected derivative at the start and end points. However, if you look back at the section on fitting curves through three points, the rules used were such that they optimized for a near perfect hemisphere, so using the same guess won\'t be all that useful: guessing the solution based on knowing the solution is not really guessing.'),r.createElement("p",null,'So have a graphical look at a "bad" guess versus the true fit, where we\'ll be using the bad guess and the description in the second paragraph to derive the maths for the true fit:'),r.createElement(i,{preset:"arcfitting",title:"Cubic Bézier arc approximation",setup:e.setup,draw:e.draw,onMouseMove:e.onMouseMove}),r.createElement("p",null,'We see two curves here; in blue, our "guessed" curve and its control points, and in grey/black, the true curve fit, with proper control points that were shifted in, along line between our guessed control points, such that the derivatives at the start and end points are correct.'),r.createElement("p",null,'We can already seethat cubic curves are a lot better than quadratic curves, and don\'t look all that wrong until we go well past a quarter circle; ⅜th starts to hint at problems, and half a circle has an obvious "gap" between the real circle and the cubic approximation. Anything past that just looks plain ridiculous... but quarter curves actually look pretty okay!'),r.createElement("p",null,'So, maths time again: how okay is "okay"? Let\'s apply some more maths to find out.'),r.createElement("p",null,"Unlike for the quadratic curve, we can't use ",r.createElement("i",null,"t=0.5")," as our reference point because by its very nature it's one of the three points that are actually guaranteed to lie on the circular curve. Instead, we need a different ",r.createElement("i",null,"t")," value. If we run some analysis on the curve we find that the actual ",r.createElement("i",null,"t"),' value at which the curve is furthest from what it should be is 0.211325 (rounded), but we don\'t know "why", since finding this value involves root-finding, and is nearly impossible to do symbolically without pages and pages of math just to express one of the possible solutions.'),r.createElement("p",null,"So instead of walking you through the derivation for that value, let's simply take that ",r.createElement("i",null,"t")," value and see what the error is for circular arcs with an angle ranging from 0 to 2π:"),r.createElement("table",null,r.createElement("tbody",null,r.createElement("tr",null,r.createElement("td",null,r.createElement("img",{src:"images/arc-c-2pi.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ 2π:"),r.createElement("td",null,r.createElement("img",{src:"images/arc-c-pi.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ π:"),r.createElement("td",null,r.createElement("img",{src:"images/arc-c-pi2.gif",height:"187px"}),"plotted for 0 ≤ φ ≤ ½π:")))),r.createElement("p",null,"We see that cubic Bézier curves are much better when it comes to approximating circular arcs, with an error of less than 0.027 at the two \"bulge\" points for a quarter circle (which had an error of 0.06 for quadratic curves at the mid point), and an error near 0.001 for an eighth of a circle, so we're getting less than half the error for a quarter circle, or: at a slightly lower error, we're getting twice the arc. This makes cubic curves quite useful!"),r.createElement("p",null,'In fact, the precision of a cubic curve at a quarter circle is considered "good enough" by so many people that it\'s generally considered "just fine" to use four cubic Bézier curves to fake a full circle when no circle primitives are available; generally, people won\'t notice that it\'s not a real circle unless you also happen to overlay an actual circle, so that the difference becomes obvious.'),r.createElement("p",null,'So with the error analysis out of the way, how do we actually compute the coordinates needed to get that "true fit" cubic curve? The first observation is that we already know the start and end points, because they\'re the same as for the quadratic attempt:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ef34ab8f466ed3294895135a346b55ada05d779d.svg",width:"183.39999999999998rem",height:"42rem"}),r.createElement("p",null,"But we now need to find two control points, rather than one. If we want the derivatives at the start and end point to match the circle, then the first control point can only lie somewhere on the vertical line through S, and the second control point can only lie somewhere on the line tangent to point E, which means:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/4df65dae78bc5a0e6c5f23a2faae9a9d7a8b39b3.svg",width:"118.99999999999999rem",height:"42rem"}),r.createElement("p",null,'where "a" is some scaling factor, and:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/cb32f8f9c3ae2b264a48003c237a798d02dc8935.svg",width:"170.79999999999998rem",height:"42rem"}),r.createElement("p",null,'where "b" is also some scaling factor.'),r.createElement("p",null,"Starting with this information, we slowly maths our way to success, but I won't lie: the maths for this is pretty trig-heavy, and it's easy to get lost if you remember (or know!) some of the core trigonoetric identities, so if you just want to see the final result just skip past the next section!"),r.createElement("div",{className:"note"},r.createElement("h2",{id:"let-s-do-this-thing-"},"Let's do this thing."),r.createElement("p",null,"Unlike for the quadratic case, we need some more information in order to compute ",r.createElement("i",null,"a")," and ",r.createElement("i",null,"b"),", since they're no longer dependent variables. First, we observe that the curve is symmetrical, so whatever values we end up finding for C",r.createElement("sub",null,"1")," will apply to C",r.createElement("sub",null,"2")," as well (rotated along its tangent), so we'll focus on finding the location of C",r.createElement("sub",null,"1")," only. So here's where we do something that you might not expect: we're going to ignore for a moment, because we're going to have a much easier time if we just solve this problem with geometry first, then move to calculus to solve a much simpler problem."),r.createElement("p",null,"If we look at the triangle that is formed between our starting point, or initial guess C",r.createElement("sub",null,"1")," and our real C",r.createElement("sub",null,"1"),", there's something funny going on: if we treat the line ","{","start,guess","}"," as our opposite side, the line ","{","guess,real","}"," as our adjacent side, with ","{","start,real","}"," our hypothenuse, then the angle for the corner hypothenuse/adjacent is half that of the arc we're covering. Try it: if you place the end point at a quarter circle (pi/2, or 90 degrees), the angle in our triangle is half a quarter (pi/4, or 45 degrees). With that knowledge, and a knowledge of what the length of any of our lines segments are (as a function), we can determine where our control points are, and thus have everything we need to find the error distance function. Of the three lines, the one we can easiest determine is ","{","start,guess","}",", so let's find out what the guessed control point is. Again geometrically, because we have the benefit of an on-curve ",r.createElement("i",null,"t=0.5")," value."),r.createElement("p",null,"The distance from our guessed point to the start point is exactly the same as the projection distance we looked at earlier. Using ",r.createElement("i",null,"t=0.5"),' as our point "B" in the "A,B,C" projection, then we know the length of the line segment ',"{","C,A","}",", since it's d",r.createElement("sub",null,"1")," = ","{","A,B","}"," + d",r.createElement("sub",null,"2")," = ","{","B,C","}",":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/b15a274c1e0a6aeeaf517b5d2c8ee0a7997dd617.svg",width:"417.2rem",height:"42rem"}),r.createElement("p",null,"So that just leaves us to find the distance from ",r.createElement("i",null,"t=0.5")," to the baseline for an arbitrary angle φ, which is the distance from the centre of the circle to our ",r.createElement("i",null,"t=0.5")," point, minus the distance from the centre to the line that runs from start point to end point. The first is the same as the point P we found for the quadratic curve:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b80423188012451e0400f473c19729eb2bad654.svg",width:"197.39999999999998rem",height:"33.599999999999994rem"}),r.createElement("p",null,"And the distance from the origin to the line start/end is another application of angles, since the triangle ","{","origin,start,C","}"," has known angles, and two known sides. We can find the length of the line ","{","origin,C","}",", which lets us trivially compute the coordinate for C:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/9be55fb38d5d30bbc6c7140afb1c7bc097bc044e.svg",width:"274.4rem",height:"70rem"}),r.createElement("p",null,"With the coordinate C, and knowledge of coordinate B, we can determine coordinate A, and get a vector that is identical to the vector ","{","start,guess","}",":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/262f2eca63105779f30a0a5445cf76f60786039a.svg",width:"417.2rem",height:"50.4rem"}),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e83ebbac13a84ef6036bf4be57b3d1b6cb316f8.svg",width:"221.2rem",height:"49rem"}),r.createElement("p",null,"Which means we can now determine the distance ","{","start,guessed","}",", which is the same as the distance ","{","C,A","}",", and use that to determine the vertical distance from our start point to our C",r.createElement("sub",null,"1"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c87e454fb11ef7f15c7386e83ca1ce41a004d8a7.svg",width:"264.59999999999997rem",height:"58.8rem"}),r.createElement("p",null,"And after this tedious detour to find the coordinate for C",r.createElement("sub",null,"1"),", we can find C",r.createElement("sub",null,"2")," fairly simply, since it's lies at distance -C",r.createElement("sub",null,"1y")," along the end point's tangent:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/25f027074b6af8ca7b640e27636e3bf89c28afdb.svg",width:"550.1999999999999rem",height:"82.6rem"}),r.createElement("p",null,"And that's it, we have all four points now for an approximation of an arbitrary circular arc with angle φ.")),r.createElement("p",null,"So, to recap, given an angle φ, the new control coordinates are:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c4d82e44d1c67dda8ba26aa6da0f406d05eba618.svg",width:"215.6rem",height:"42rem"}),r.createElement("p",null,"and"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3a4b1ee00eebb7697e5513ef9df673928913252e.svg",width:"337.4rem",height:"42rem"}),r.createElement("p",null,'And, because the "quarter curve" special case comes up so incredibly often, let\'s look at what these new control points mean for the curve coordinates of a quarter curve, by simply filling in φ = π/2:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/63e0936b4849d4cdbb9a2e0909181259be951e4d.svg",width:"432.59999999999997rem",height:"35rem"}),r.createElement("p",null,"Which, in decimal values, rounded to six significant digits, is:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/fd12e65204a31319b66355c6ff99e6b3d9603b05.svg",width:"432.59999999999997rem",height:"16.799999999999997rem"}),r.createElement("p",null,"Of course, this is for a circle with radius 1, so if you have a different radius circle, simply multiply the coordinate by the radius you need. And then finally, forming a full curve is now a simple a matter of mirroring these coordinates about the origin:"),r.createElement(i,{preset:"simple",title:"Cubic Bézier circle approximation",draw:e.drawCircle,static:!0}))}},arcapproximation:{locale:"en-GB",title:"Approximating Bézier curves with circular arcs",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"arcapproximation",title:"Approximating Bézier curves with circular arcs",number:"38"}),r.createElement("p",null,"Let's look at doing the exact opposite of the previous section: rather than approximating circular arc using Bézier curves, let's approximate Bézier curves using circular arcs."),r.createElement("p",null,"We already saw in the section on circle approximation that this will never yield a perfect equivalent, but sometimes you need circular arcs, such as when you're working with fabrication machinery, or simple vector languages that understand lines and circles, but not much else."),r.createElement("p",null,'The approach is fairly simple: pick a starting point on the curve, and pick two points that are further along the curve. Determine the circle that goes through those three points, and see if it fits the part of the curve we\'re trying to approximate. Decent fit? Try spacing the points further apart. Bad fit? Try spacing the points closer together. Keep doing this until you\'ve found the "good approximation/bad approximation" boundary, record the "good" arc, and then move the starting point up to overlap the end point we previously found. Rinse and repeat until we\'ve covered the entire curve.'),r.createElement("p",null,"So: step 1, how do we find a circle through three points? That part is actually really simple. You may remember (if you ever learned it!) that a line between two points on a circle is called a ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Chord_%28geometry%29"},"chord"),", and one property of chords is that the line from the center of any chord, perpendicular to that chord, passes through the center of the circle."),r.createElement("p",null,"So: if we have have three points, we have three (different) chords, and consequently, three (different) lines that go from those chords through the center of the circle. So we find the centers of the chords, find the perpendicular lines, find the intersection of those lines, and thus find the center of the circle."),r.createElement("p",null,"The following graphic shows this procedure with a different colour for each chord and its associated perpendicular through the center. You can move the points around as much as you like, those lines will always meet!"),r.createElement(i,{preset:"simple",title:"Finding a circle through three points",setup:e.setupCircle,draw:e.drawCircle}),r.createElement("p",null,"So, with the procedure on how to find a circle through three points, finding the arc through those points is straight-forward: pick one of the three points as start point, pick another as an end point, and the arc has to necessarily go from the start point, over the remaining point, to the end point."),r.createElement("p",null,"So how can we convert a Bezier curve into a (sequence of) circular arc(s)?"),r.createElement("ul",null,r.createElement("li",null,"Start at ",r.createElement("em",null,"t=0")),r.createElement("li",null,"Pick two points further down the curve at some value ",r.createElement("em",null,"m = t + n")," and ",r.createElement("em",null,"e = t + 2n")),r.createElement("li",null,"Find the arc that these points define"),r.createElement("li",null,"Determine how close the found arc is to the curve:",r.createElement("ul",null,r.createElement("li",null,"Pick two additional points ",r.createElement("em",null,"e1 = t + n/2")," and ",r.createElement("em",null,"e2 = t + n + n/2"),"."),r.createElement("li",null,"These points, if the arc is a good approximation of the curve interval chosen, should lie ",r.createElement("em",null,"on")," the circle, so their distance to the center of the circle should be the same as the distance from any of the three other points to the center."),r.createElement("li",null,"For point points, determine the (absolute) error between the radius of the circle, and the",r.createElement("em",null,"actual")," distance from the center of the circle to the point on the curve."),r.createElement("li",null,"If this error is too high, we consider the arc bad, and try a smaller interval.")))),r.createElement("p",null,"The result of this is shown in the next graphic: we start at a guaranteed failure: s=0, e=1. That's the entire curve. The midpoint is simply at ",r.createElement("em",null,"t=0.5"),", and then we start performing a ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Binary_search_algorithm"},"Binary Search"),"."),r.createElement("ol",null,r.createElement("li",null,"We start with ",1),r.createElement("li",null,"That'll fail, so we retry with the interval halved: ",.5,r.createElement("ul",null,r.createElement("li",null,"If that arc's good, we move back up by half distance: ",.75,"."),r.createElement("li",null,"However, if the arc was still bad, we move ",r.createElement("em",null,"down")," by half the distance: ",.25,"."))),r.createElement("li",null,"We keep doing this over and over until we have two arcs found in sequence of which the first arc is good, and the second arc is bad. When we find that pair, we've found the boundary between a good approximation and a bad approximation, and we pick the former.")),r.createElement("p",null,"The following graphic shows the result of this approach, with a default error threshold of 0.5, meaning that if an arc is off by a ",r.createElement("em",null,"combined")," half pixel over both verification points, then we treat the arc as bad. This is an extremely simple error policy, but already works really well. Note that the graphic is still interactive, and you can use your up and down arrow keys keys to increase or decrease the error threshold, to see what the effect of a smaller or larger error threshold is."),r.createElement(i,{preset:"simple",title:"Arc approximation of a Bézier curve",setup:e.setupCubic,draw:e.drawSingleArc,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,"With that in place, all that's left now is to \"restart\" the procedure by treating the found arc's end point as the new to-be-determined arc's starting point, and using points further down the curve. We keep trying this until the found end point is for ",r.createElement("em",null,"t=1"),", at which point we are done. Again, the following graphic allows for up and down arrow key input to increase or decrease the error threshold, so you can see how picking a different threshold changes the number of arcs that are necessary to reasonably approximate a curve:"),r.createElement(i,{preset:"simple",title:"Arc approximation of a Bézier curve",setup:e.setupCubic,draw:e.drawArcs,onKeyDown:e.props.onKeyDown}),r.createElement("p",null,'So... what is this good for? Obviously, If you\'re working with technologies that can\'t do curves, but can do lines and circles, then the answer is pretty straight-forward, but what else? There are some reasons why you might need this technique: using circular arcs means you can determine whether a coordinate lies "on" your curve really easily: simply compute the distance to each circular arc center, and if any of those are close to the arc radii, at an angle betwee the arc start and end: bingo, this point can be treated as lying "on the curve". Another benefit is that this approximation is "linear": you can almost trivially travel along the arcs at fixed speed. You can also trivially compute the arc length of the approximated curve (it\'s a bit like curve flattening). The only thing to bear in mind is that this is a lossy equivalence: things that you compute based on the approximation are guaranteed "off" by some small value, and depending on how much precision you need, arc approximation is either going to be super useful, or completely useless. It\'s up to you to decide which, based on your application!'))}},bsplines:{locale:"en-GB",title:"B-Splines",getContent:function(e){return r.createElement("section",null,r.createElement(a,{name:"bsplines",title:"B-Splines",number:"39"}),r.createElement("p",null,"No discussion on Bézier curves is complete without also giving mention of that other beast in the curve design space: B-Splines. Easily confused to mean Bézier splines, that's not actually what they are; they are \"basis function\" splines, which makes a lot of difference, which we'll be looking at in this section. We're not going to dive as deep into B-Splines as we have for Bézier curves (that would be an entire primer on its own) but we'll be looking at how B-Splines work, what kind of maths is involved in computing them, and how to draw them based on a number of parameters that you can pick for individual B-Splines."),r.createElement("p",null,"First off: B-Splines are ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Piecewise"},"piecewise polynomial interpolation curves"),', where the "single curve" is built by performing polynomial interpolation over a set of points, using a sliding window of a fixed number of points. For instance, a "cubic" B-Spline defined by twelve points will have its curve built by evaluating the polynomial interpolation of four points, and the curve can be treated as a lot of different sections, each controlled by four points at a time, such that the full curve consists of smoothly connected sections defined by points ',"{","1,2,3,4","}",", ","{","2,3,4,5","}",", ..., ","{","8,9,10,11","}",", and finally ","{","9,10,11,12","}",", for eight sections."),r.createElement("p",null,"What do they look like? They look like this! .. okay that's an empty graph, but simply click to place some point, with the stipulation that you need at least four point to see any curve. More than four points simply draws a longer B-Spline curve:"),r.createElement(o,{sketch:e.basicSketch}),r.createElement("p",null,"The important part to notice here is that we are ",r.createElement("strong",null,"not"),' doing the same thing with B-Splines that we do for poly-Béziers or Catmull-Rom curves: both of the latter simply define new sections as literally "new sections based on new points", so a 12 point cubic poly-Bézier curve is actually impossible, because we start with a four point curve, and then add three more points for each section that follows, so we can only have 4, 7, 10, 13, 16, etc point Poly-Béziers. Similarly, while Catmull-Rom curves can grow by adding single points, this addition of a single point introduces three implicit Bézier points. Cubic B-Splines, on the other hand, are smooth interpolations of ',r.createElement("em",null,"each possible curve involving four consecutive points"),", such that at any point along the curve except for our start and end points, our on-curve coordinate is defined by four control points."),r.createElement("p",null,"Consider the difference to be this:"),r.createElement("ul",null,r.createElement("li",null,"for Bézier curves, the curve is defined as an interpolation of points, but:"),r.createElement("li",null,"for B-Splines, the curve is defined as an interpolation of ",r.createElement("em",null,"curves"),".")),r.createElement("p",null,"In order to make this interpolation of curves work, the maths is necessarily more complex than the maths for Bézier curves, so let's have a look at how things work."),r.createElement("h2",{id:"how-to-compute-a-b-spline-curve-some-maths"},"How to compute a B-Spline curve: some maths"),r.createElement("p",null,"Given a B-Spline of degree ",r.createElement("code",null,"d")," and thus order ",r.createElement("code",null,"k=d+1")," (so a quadratic B-Spline is degree 2 and order 3, a cubic B-Spline is degree 3 and order 4, etc) and ",r.createElement("code",null,"n")," control points ",r.createElement("code",null,"P<sub>0</sub>")," through ",r.createElement("code",null,"P<sub>n-1</sub>"),", we can compute a point on the curve for some value ",r.createElement("code",null,"t")," in the interval [0,1] (where 0 is the start of the curve, and 1 the end, just like for Bézier curves), by evaluting the following function:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/329da80e737b0005f4dbe4c84ff868bde5dfaee0.svg",width:"177.79999999999998rem",height:"43.4rem"}),r.createElement("p",null,'Which, honestly, doesn\'t tell us all that much. All we can see is that a point on a B-Spline curve is defined as "a mix of all the control points, weighted somehow", where the weighting is achieved through the ',r.createElement("em",null,"N(...)")," function, subscipted with an obvious parameter ",r.createElement("code",null,"i"),", which comes from our summation, and some magical parameter ",r.createElement("code",null,"k"),". So we need to know two things: 1. what does N(t) do, and 2. what is that ",r.createElement("code",null,"k"),"? Let's cover both, in reverse order."),r.createElement("p",null,"The parameter ",r.createElement("code",null,"k"),' represents the "knot interval" over which a section of curve is defined. As we learned earlier, a B-Spline curve is itself an interpoliation of curves, and we can treat each transition where a control point starts or tops influencing the total curvature as a "knot on the curve". Doing so for a degree ',r.createElement("code",null,"d")," B-Spline with ",r.createElement("code",null,"n")," control point gives us ",r.createElement("code",null,"d + n + 1")," knots, defining ",r.createElement("code",null,"d + n")," intervals along the curve, and it is these intervals that the above ",r.createElement("code",null,"k")," subscript to the N() function applies to."),r.createElement("p",null,"Then the N() function itself. What does it look like?"),r.createElement("img",{ +className:"LaTeX SVG",src:"images/latex/c10575fb591062784484357356796a4c0be4f83e.svg",width:"588rem",height:"44.8rem"}),r.createElement("p",null,"So this is where we see the interpolation: N(t) for an (i,k) pair (that is, for a step in the above summation, on a specific knot interval) is a mix between N(t) for (i,k-1) and N(t) for (i+1,k-1), so we see that this is a recursive iteration where ",r.createElement("code",null,"i")," goes up, and ",r.createElement("code",null,"k")," goes down, so it seem reasonable to expect that this recursion has to stop at some point; obviously, it does, and specifically it does so for the following ",r.createElement("code",null,"i"),"/",r.createElement("code",null,"k")," values:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/6664a4fc5832059bbc68eaa8068a4b2577e1d96a.svg",width:"251.99999999999997rem",height:"42rem"}),r.createElement("p",null,"And this function finally has a straight up evaluation: if a ",r.createElement("code",null,"t")," value lies within a knot-specific interval once we reach a ",r.createElement("code",null,"k=1"),' value, it "counts", otherwise it doesn\'t. We did cheat a little, though, because for all these values we need to scale our ',r.createElement("code",null,"t")," value first, so that it lies in the interval bounded by ",r.createElement("code",null,"knots[d]")," and ",r.createElement("code",null,"knots[n]"),", which are the start point and end point where curvature is controlled by exactly ",r.createElement("code",null,"order")," control points. For instance, for degree 3 (=order 4) and 7 control points, with knot vector [1,2,3,4,5,6,7,8,9,10,11], we map ",r.createElement("code",null,"t")," from [the interval 0,1] to the interval [4,8], and then use that value in the functions above, instead."),r.createElement("h2",{id:"can-we-simplify-that-"},"Can we simplify that?"),r.createElement("p",null,"We can, yes."),r.createElement("p",null,"People far smarter than us have looked at this work, and two in particular — ",r.createElement("a",{href:"http://www.npl.co.uk/people/maurice-cox"},"Maurice Cox")," and ",r.createElement("a",{href:"https://en.wikipedia.org/wiki/Carl_R._de_Boor"},"Carl de Boor")," — came to a mathematically pleasing solution: to compute a point P(t), we can compute this point by evaluating ",r.createElement("em",null,"d(t)")," on a curve section between knots ",r.createElement("em",null,"i")," and ",r.createElement("em",null,"i+1"),":"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3780a420cd9b1bc59bec2c49bbd29f5e58497a3c.svg",width:"295.4rem",height:"22.4rem"}),r.createElement("p",null,"This is another recursive function, with ",r.createElement("em",null,"k")," values decreasing from the curve order to 1, and the value ",r.createElement("em",null,"α")," (alpha) defined by:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ba3b25cd54993b4601d8f415bc4cde73af4fc460.svg",width:"267.4rem",height:"40.599999999999994rem"}),r.createElement("p",null,'That looks complicated, but it\'s not. Computing alpha is just a fraction involving known, plain numbers and once we have our alpha value, computing (1-alpha) is literally just "computing one minus alpha". Computing this d() function is thus simply a matter of "computing simple arithmetics but with recursion", which might be computationally expensive because we\'re doing "a lot of" steps, but is also computationally cheap because each step only involves very simple maths. Of course as before the recursion has to stop:'),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/1405067abebab73574934e3e69d7a7158106c744.svg",width:"387.79999999999995rem",height:"42rem"}),r.createElement("p",null,"So, we see two stopping conditions: either ",r.createElement("code",null,"i")," becomes 0, in which case d() is zero, or ",r.createElement("code",null,"k"),' becomes zero, in which case we get the same "either 1 or 0" that we saw in the N() function above.'),r.createElement("p",null,"Thanks to Cox and de Boor, we can compute points on a B-Spline pretty easily: we just need to compute a triangle of interconnected values. For instance, d() for i=3, k=3 yields the following triangle:"),r.createElement("img",{className:"LaTeX SVG",src:"images/latex/a0a1069b001c75a1fab7f40ffa8bc403e1408f0d.svg",width:"438.2rem",height:"242.2rem"}),r.createElement("p",null,"That is, we compute d(3,3) as a mixture of d(2,3) and d(2,2): d(3,3) = a(3,3) x d(2,3) + (1-a(3,3)) x d(2,2)... and we simply keep expanding our triangle until we reach the terminating function parameters. Done deal!"),r.createElement("p",null,"One thing we need to keep in mind is that we're working with a spline that is contrained by its control points, so even though the ",r.createElement("code",null,"d(..., k)")," values are zero or one at the lowest level, they are really \"zero or one, times their respective control point\", so in the next section you'll see the algorithm for running through the computation in a way that starts with a copy of the control point vector and then works its way up to that single point: that's pretty essential!"),r.createElement("p",null,'If we run this computation "down", starting at d(3,3), then without special code in place we would be computing quite a few terms multiple times at each step. On the other hand, we can also start with that last "column", we can generate the terminating d() values first, then compute the a() constants, perform our multiplcations, generate the previous step\'s d() values, compute their a() constants, do the multiplications, etc. until we end up all the way back at the top. If we run our computation this way, we don\'t need any explicit caching, we can just "recycle" the list of numbers we start with and simply update them as we move up the triangle. So, let\'s implement that!'),r.createElement("h2",{id:"cool-cool-but-i-don-t-know-what-to-do-with-that-information"},"Cool, cool... but I don't know what to do with that information"),r.createElement("p",null,"I know, this is pretty mathy, so let's have a look at what happens when we change parameters here. We can't change the maths for the interpolation functions, so that gives us only one way to control what happens here: the knot vector itself. As such, let's look at the graph that shows the interpolation functions for a cubic B-Spline with seven points with a uniform knot vector (so we see seven identical functions), representing how much each point (represented by one function each) influences the total curvature, given our knot values. And, because exploration is the key to discovery, let's make the knot vector a thing we can actually manipulate. Normally a proper knot vector has a constraint that any value is strictly equal to, or larger than the previous ones, but screw it this is programming, let's ignore that hard restriction and just mess with the knots however we like."),r.createElement("div",{className:"two-column"},r.createElement(s,{ref:"interpolation-graph"}),r.createElement(o,{sketch:e.interpolationGraph,controller:function(t,n){return e.bindKnots(t,n,"interpolation-graph")}})),r.createElement("p",null,"Changing the values in the knot vector changes how much each point influences the total curvature (with some clever knot value manipulation, we can even make the influence of certain points disappear entirely!), so we can see that while the control points define the hull inside of which we're going to be drawing a curve, it is actually the knot vector that determines the actual ",r.createElement("em",null,"shape")," of the curve inside that hull."),r.createElement("p",null,"After reading the rest of this section you may want to come back here to try some specific knot vectors, and see if the resulting interpolation landscape makes sense given what you will now think should happen!"),r.createElement("h2",{id:"running-the-computation"},"Running the computation"),r.createElement("p",null,"Unlike the de Casteljau algorithm, where the ",r.createElement("code",null,"t")," value stays the same at every iteration, for B-Splines that is not the case, and so we end having to (for each point we evaluate) run a fairly involving bit of recursive computation. The algorithm is discussed on ",r.createElement("a",{href:"http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/de-Boor.html"},"this Michigan Tech")," page, but an easier to read version is implemented by ",r.createElement("a",{href:"https://github.com/thibauts/b-spline/blob/master/index.js#L59-L71"},"b-spline.js"),", so we'll look at its code."),r.createElement("p",null,"Given an input value ",r.createElement("code",null,"t"),", we first map the input to a value from the domain [0,1] to the domain [knots[degree], knots[knots.length - 1 - degree]. Then, we find the section number ",r.createElement("code",null,"s")," that this mapped ",r.createElement("code",null,"t")," value lies on:"),r.createElement("pre",null,"for(s=domain[0]; s < domain[1]; s++) {\n if(knots[s] <= t && t <= knots[s+1]) break;\n}\n"),r.createElement("p",null,"after running this code, ",r.createElement("code",null,"s")," is the index for the section the point will lie on. We then run the algorithm mentioned on the MU page (updated to use this description's variable names):"),r.createElement("pre",null,"let v = copy of control points\n\nfor(let L = 1; L <= order; L++) {\n for(let i=s; i > s + L - order; i--) {\n let numerator = t - knots[i]\n let denominator = knots[i - L + order] - knots[i]\n let alpha = numerator / denominator\n let v[i] = alpha * v[i] + (1-alpha) * v[i-1]\n }\n}\n"),r.createElement("p",null,'(A nice bit of behaviour in this code is that we work the interpolation "backwards", starting at ',r.createElement("code",null,"i=s")," at each level of the interpolation, and we stop when ",r.createElement("code",null,"i = s - order + level"),", so we always end up with a value for ",r.createElement("code",null,"i")," such that those ",r.createElement("code",null,"v[i-1]")," don't try to use an array index that doesn't exist)"),r.createElement("h2",{id:"open-vs-closed-paths"},"Open vs. closed paths"),r.createElement("p",null,"Much like poly-Béziers, B-Splines can be either open, running from the first point to the last point, or closed, where the first and last point are ",r.createElement("em",null,"the same point"),". However, because B-Splines are an interpolation of curves, not just point, we can't simply make the first and last point the same, we need to link a few point point: for an order ",r.createElement("code",null,"d")," B-Spline, we need to make the last ",r.createElement("code",null,"d")," point the same as the first ",r.createElement("code",null,"d")," points. And the easiest way to do this is to simply append ",r.createElement("code",null,"points.splice(0,d)")," to ",r.createElement("code",null,"points"),". Done!"),r.createElement("p",null,'Of course if we want to manipulate these kind of curves we need to make sure to mark them as "closed" so that we know the coordinate for ',r.createElement("code",null,"points[0]")," and ",r.createElement("code",null,"points[n-k]")," etc. are the same coordinate, and manipulating one will equally manipulate the other, but programming generally makes this really easy by storing references to coordinates (or other linked values such as coordinate weights, discussed in the NURBS section) rather than separate coordinate objects."),r.createElement("h2",{id:"manipulating-the-curve-through-the-knot-vector"},"Manipulating the curve through the knot vector"),r.createElement("p",null,"The most important thing to understand when it comes to B-Splines is that they work ",r.createElement("em",null,"because"),' of the concept of a knot vector. As mentioned above, knots represent "where individual control points start/stop influencing the curve", but we never looked at the ',r.createElement("em",null,"values")," that go in the knot vector. If you look back at the N() and a() functions, you see that interpolations are based on intervals in the knot vector, rather than the actual values in the knot vector, and we can exploit this to do some pretty interesting things with clever manipulation of the knot vector. Specifically there are four things we can do that are worth looking at:"),r.createElement("ol",null,r.createElement("li",null,"we can use a uniform knot vector, with equally spaced intervals,"),r.createElement("li",null,"we can use a non-uniform knot vector, without enforcing equally spaced internvals,"),r.createElement("li",null,'we can collapse sequential knots to the same value, locally lowering curve complexity using "null" intervals, and'),r.createElement("li",null,"we can form a special case non-uniform vector, by combining (1) and (3) to for a vector with collapsed start and end knots, with a uniform vector in between.")),r.createElement("h3",{id:"uniform-b-splines"},"Uniform B-Splines"),r.createElement("p",null,"The most straightforward type of B-Spline is the uniform spline. In a uniform spline, the knots are distributed uniformly over the entire curve interval. For instance, if we have a knot vector of length twelve, then a uniform knot vector would be [0,1,2,3,...,9,10,11]. Or [4,5,6,...,13,14,15], which defines ",r.createElement("em",null,"the same intervals"),", or even [0,2,3,...,18,20,22], which also defines ",r.createElement("em",null,"the same intervals"),", just scaled by a constant factor, which becomes normalised during interpolation and so does not contribute to the curvature."),r.createElement("div",{className:"two-column"},r.createElement(s,{ref:"uniform-spline"}),r.createElement(o,{sketch:e.uniformBSpline,controller:function(t,n){return e.bindKnots(t,n,"uniform-spline")}})),r.createElement("p",null,"This is an important point: the intervals that the knot vector defines are ",r.createElement("em",null,"relative")," intervals, so it doesn't matter if every interval is size 1, or size 100 - the relative differences between the intervals is what shapes any particular curve."),r.createElement("p",null,"The problem with uniform knot vectors is that, as we need ",r.createElement("code",null,"order"),' control points before we have any curve with which we can perform interpolation, the curve does not "start" at the first point, nor "ends" at the last point. Instead there are "gaps". We can get rid of these, by being clever about how we apply the following uniformity-breaking approach instead...'),r.createElement("h3",{id:"reducing-local-curve-complexity-by-collapsing-intervals"},"Reducing local curve complexity by collapsing intervals"),r.createElement("p",null,"By collapsing knot intervals by making two or more consecutive knots have the same value, we can reduce the curve complexity in the sections that are affected by the knots involved. This can have drastic effects: for ever interval collapse, the curve order goes down, and curve continuity goes down, to the point where collapsing ",r.createElement("code",null,"order"),' knots creates a situation where all continuity is lost and the curve "kinks".'),r.createElement("div",{className:"two-column"},r.createElement(s,{ref:"center-cut-bspline"}),r.createElement(o,{sketch:e.centerCutBSpline,controller:function(t,n){return e.bindKnots(t,n,"center-cut-bspline")}})),r.createElement("h3",{id:"open-uniform-b-splines"},"Open-Uniform B-Splines"),r.createElement("p",null,"By combining knot interval collapsing at the start and end of the curve, with uniform knots in between, we can overcome the problem of the curve not starting and ending where we'd kind of like it to:"),r.createElement("p",null,"For any curve of degree ",r.createElement("code",null,"D")," with control points ",r.createElement("code",null,"N"),", we can define a knot vector of length ",r.createElement("code",null,"N+D+1")," in which the values ",r.createElement("code",null,"0 ... D+1")," are the same, the values ",r.createElement("code",null,"D+1 ... N+1"),' follow the "uniform" pattern, and the values ',r.createElement("code",null,"N+1 ... N+D+1"),' are the same again. For example, a cubic B-Spline with 7 control points can have a knot vector [0,0,0,0,1,2,3,4,4,4,4], or it might have the "identical" knot vector [0,0,0,0,2,4,6,8,8,8,8], etc. Again, it is the relative differences that determine the curve shape.'),r.createElement("div",{className:"two-column"},r.createElement(s,{ref:"open-uniform-bspline"}),r.createElement(o,{sketch:e.openUniformBSpline,controller:function(t,n){return e.bindKnots(t,n,"open-uniform-bspline")}})),r.createElement("h3",{id:"non-uniform-b-splines"},"Non-uniform B-Splines"),r.createElement("p",null,'This is essentialy the "free form" version of a B-Spline, and also the least interesting to look at, as without any specific reason to pick specific knot intervals, there is nothing particularly interesting going on. There is one constraint to the knot vector, and that is that any value ',r.createElement("code",null,"knots[k+1]")," should be equal to, or greater than ",r.createElement("code",null,"knots[k]"),"."),r.createElement("h2",{id:"one-last-thing-rational-b-splines"},"One last thing: Rational B-Splines"),r.createElement("p",null,'While it is true that this section on B-Splines is running quite long already, there is one more thing we need to talk about, and that\'s "Rational" splines, where the rationality applies to the "ratio", or relative weights, of the control points themselves. By introducing a ratio vector with weights to apply to each control point, we greatly increase our influence over the final curve shape: the more weight a control point carries, the close to that point the spline curve will lie, a bit like turning up the gravity of a control point.'),r.createElement("div",{className:"two-column"},r.createElement(l,{ref:"rational-uniform-bspline-weights"}),r.createElement(o,{scrolling:!0,sketch:e.rationalUniformBSpline,controller:function(t,n,r,i){e.bindWeights(t,r,i,"rational-uniform-bspline-weights")}})),r.createElement("p",null,'Of course this brings us to the final topic that any text on B-Splines must touch on before calling it a day: the NURBS, or Non-Uniform Rational B-Spline (NURBS is not a plural, the capital S actually just stands for "spline", but a lot of people mistakenly treat it as if it is, so now you know better). NURBS are an important type of curve in computer-facilitated design, used a lot in 3D modelling (as NURBS surfaces) as well as in arbitrary-precision 2D design due to the level of control a NURBS curve offers designers.'),r.createElement("p",null,"While a true non-uniform rational B-Spline would be hard to work with, when we talk about NURBS we typically mean the Open-Uniform Rational B-Spline, or OURBS, but that doesn't roll off the tongue nearly as nicely, and so remember that when people talk about NURBS, they typically mean open-uniform, which has the useful property of starting the curve at the first control point, and ending it at the last."),r.createElement("h2",{id:"extending-our-implementation-to-cover-rational-splines"},"Extending our implementation to cover rational splines"),r.createElement("p",null,"The algorithm for working with Rational B-Splines is virtually identical to the regular algorithm, and the extension to work in the control point weights is fairly simple: we extend each control point from a point in its original number of dimensions (2D, 3D, etc) to one dimension higher, scaling the original dimensions by the control point's weight, and then assigning that weight as its value for the extended dimension."),r.createElement("p",null,"For example, a 2D point ",r.createElement("code",null,"(x,y)")," with weight ",r.createElement("code",null,"w")," becomes a 3D point ",r.createElement("code",null,"(w * x, w * y, w)"),"."),r.createElement("p",null,"We then run the same algorithm as before, which will automatically perform weight interpolation in addition to regular coordinate interpolation, because all we've done is pretended we have coordinates in a higher dimension. The algorithm doesn't really care about how many dimensions it needs to interpolate."),r.createElement("p",null,'In order to recover our "real" curve point, we take the final result of the point generation algorithm, and "unweigh" it: we take the final point\'s derived weight ',r.createElement("code",null,"w'")," and divide all the regular coordinate dimensions by it, then throw away the weight information."),r.createElement("p",null,"Based on our previous example, we take the final 3D point ",r.createElement("code",null,"(x', y', w')"),", which we then turn back into a 2D point by computing ",r.createElement("code",null,"(x'/w', y'/w')"),". And that's it, we're done!"))}},comments:{locale:"en-GB",title:"Comments and questions",getContent:function(e){return r.createElement("section",null,r.createElement("script",null,"/* ----------------------------------------------------------------------------- * * * PLEASE DO NOT LOCALISE THIS FILE * * I can't respond to questions that aren't asked in English, so this is one of * the few cases where there is a content.en-GB.md but you shouldn't change it. * * ----------------------------------------------------------------------------- */"),r.createElement("style",null,"#comments ","{","width: calc(960px + 2em), marginTop: 0, borderTop: 1px solid rgba(255, 0, 0, 0.5), paddingTop: 3em","}"),r.createElement(a,{name:"comments",title:"Comments and questions",number:"40"}),r.createElement("p",null,"If you enjoyed this book, or you simply found it useful for something you were trying to get done, and you were wondering how to let me know you appreciated this book, you can always ",r.createElement("a",{href:"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QPRDLNGDANJSW"},"buy me a coffee"),", however much a coffee is where you live. This work has grown over the years, from a small primer to a 70ish print-page-equivalent reader on the subject of Bézier curves, and a lot of coffee went into the making of it. I don't regret a minute I spent on writing it, but I can always do with some more coffee to keep on writing!"),r.createElement("div",{id:"disqus_thread"}),r.createElement("script",{src:"lib/site/disqus.js",async:!0}))}},"locale-switcher":{locale:"en-GB",title:"locale-switcher",getContent:function(e){return r.createElement("section",null,r.createElement("p",null,"Read this in your own language:"),r.createElement("ul",null,r.createElement("li",null,r.createElement("a",{href:"./en-GB"},"English")),r.createElement("li",null,r.createElement("a",{href:"./ja-JP"},"日本語")),r.createElement("li",null,r.createElement("a",{href:"./zh-CN"},"中文"))),r.createElement("p",null,"Don't see your language listed? ",r.createElement("a",{href:"https://github.com/Pomax/BezierInfo-2/wiki/localize"},"Help translate this content!")))}}}},function(e,t,n){e.exports=n(65)},function(e,t,n){!function(){"use strict";var t=n(66),r=function(e){this.curves=[],this._3d=!1,e&&(this.curves=e,this._3d=this.curves[0]._3d)};r.prototype={valueOf:function(){return this.toString()},toString:function(){return t.pointsToString(this.points)},addCurve:function(e){this.curves.push(e),this._3d=this._3d||e._3d},length:function(){return this.curves.map(function(e){return e.length()}).reduce(function(e,t){return e+t})},curve:function(e){return this.curves[e]},bbox:function(){for(var e=this.curves,n=e[0].bbox(),r=1;r<e.length;r++)t.expandbox(n,e[r].bbox());return n},offset:function(e){var t=[];return this.curves.forEach(function(n){t=t.concat(n.offset(e))}),new r(t)}},e.exports=r}()},function(e,t,n){(function(e){var n,r;/** * @license * * chroma.js - JavaScript library for color conversions @@ -32647,219 +63,7 @@ module.exports = __webpack_require__(70); * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ - -(function() { - var Color, DEG2RAD, LAB_CONSTANTS, PI, PITHIRD, RAD2DEG, TWOPI, _guess_formats, _guess_formats_sorted, _input, _interpolators, abs, atan2, bezier, blend, blend_f, brewer, burn, chroma, clip_rgb, cmyk2rgb, colors, cos, css2rgb, darken, dodge, each, floor, hex2rgb, hsi2rgb, hsl2css, hsl2rgb, hsv2rgb, interpolate, interpolate_hsx, interpolate_lab, interpolate_num, interpolate_rgb, lab2lch, lab2rgb, lab_xyz, lch2lab, lch2rgb, lighten, limit, log, luminance_x, m, max, multiply, normal, num2rgb, overlay, pow, rgb2cmyk, rgb2css, rgb2hex, rgb2hsi, rgb2hsl, rgb2hsv, rgb2lab, rgb2lch, rgb2luminance, rgb2num, rgb2temperature, rgb2xyz, rgb_xyz, rnd, root, round, screen, sin, sqrt, temperature2rgb, type, unpack, w3cx11, xyz_lab, xyz_rgb, - slice = [].slice; - - type = (function() { - - /* - for browser-safe type checking+ - ported from jQuery's $.type - */ - var classToType, len, name, o, ref; - classToType = {}; - ref = "Boolean Number String Function Array Date RegExp Undefined Null".split(" "); - for (o = 0, len = ref.length; o < len; o++) { - name = ref[o]; - classToType["[object " + name + "]"] = name.toLowerCase(); - } - return function(obj) { - var strType; - strType = Object.prototype.toString.call(obj); - return classToType[strType] || "object"; - }; - })(); - - limit = function(x, min, max) { - if (min == null) { - min = 0; - } - if (max == null) { - max = 1; - } - if (x < min) { - x = min; - } - if (x > max) { - x = max; - } - return x; - }; - - unpack = function(args) { - if (args.length >= 3) { - return [].slice.call(args); - } else { - return args[0]; - } - }; - - clip_rgb = function(rgb) { - var i; - for (i in rgb) { - if (i < 3) { - if (rgb[i] < 0) { - rgb[i] = 0; - } - if (rgb[i] > 255) { - rgb[i] = 255; - } - } else if (i === 3) { - if (rgb[i] < 0) { - rgb[i] = 0; - } - if (rgb[i] > 1) { - rgb[i] = 1; - } - } - } - return rgb; - }; - - PI = Math.PI, round = Math.round, cos = Math.cos, floor = Math.floor, pow = Math.pow, log = Math.log, sin = Math.sin, sqrt = Math.sqrt, atan2 = Math.atan2, max = Math.max, abs = Math.abs; - - TWOPI = PI * 2; - - PITHIRD = PI / 3; - - DEG2RAD = PI / 180; - - RAD2DEG = 180 / PI; - - chroma = function() { - if (arguments[0] instanceof Color) { - return arguments[0]; - } - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, arguments, function(){}); - }; - - _interpolators = []; - - if ((typeof module !== "undefined" && module !== null) && (module.exports != null)) { - module.exports = chroma; - } - - if (true) { - !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() { - return chroma; - }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - } else { - root = typeof exports !== "undefined" && exports !== null ? exports : this; - root.chroma = chroma; - } - - chroma.version = '1.1.1'; - - - /** - chroma.js - - Copyright (c) 2011-2013, Gregor Aisch - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * The name Gregor Aisch may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - @source: https://github.com/gka/chroma.js - */ - - _input = {}; - - _guess_formats = []; - - _guess_formats_sorted = false; - - Color = (function() { - function Color() { - var arg, args, chk, len, len1, me, mode, o, w; - me = this; - args = []; - for (o = 0, len = arguments.length; o < len; o++) { - arg = arguments[o]; - if (arg != null) { - args.push(arg); - } - } - mode = args[args.length - 1]; - if (_input[mode] != null) { - me._rgb = clip_rgb(_input[mode](unpack(args.slice(0, -1)))); - } else { - if (!_guess_formats_sorted) { - _guess_formats = _guess_formats.sort(function(a, b) { - return b.p - a.p; - }); - _guess_formats_sorted = true; - } - for (w = 0, len1 = _guess_formats.length; w < len1; w++) { - chk = _guess_formats[w]; - mode = chk.test.apply(chk, args); - if (mode) { - break; - } - } - if (mode) { - me._rgb = clip_rgb(_input[mode].apply(_input, args)); - } - } - if (me._rgb == null) { - console.warn('unknown format: ' + args); - } - if (me._rgb == null) { - me._rgb = [0, 0, 0]; - } - if (me._rgb.length === 3) { - me._rgb.push(1); - } - } - - Color.prototype.alpha = function(alpha) { - if (arguments.length) { - this._rgb[3] = alpha; - return this; - } - return this._rgb[3]; - }; - - Color.prototype.toString = function() { - return this.name(); - }; - - return Color; - - })(); - - chroma._input = _input; - - - /** +(function(){var i,a,o,s,l,c,u,h,d,f,p,m,g,v,w,y,b,_,x,E,C,k,S,P,T,M,N,I,L,A,O,B,z,R,D,j,F,q,V,U,W,G,H,X,K,Q,Y,Z,$,J,ee,te,ne,re,ie,ae,oe,se,le,ce,ue,he,de,fe,pe,me,ge,ve,we,ye,be,_e,xe,Ee,Ce,ke,Se,Pe,Te=[].slice;Ee=function(){var e,t,n,r,i;for(e={},i="Boolean Number String Function Array Date RegExp Undefined Null".split(" "),r=0,t=i.length;r<t;r++)n=i[r],e["[object "+n+"]"]=n.toLowerCase();return function(t){var n;return n=Object.prototype.toString.call(t),e[n]||"object"}}(),K=function(e,t,n){return null==t&&(t=0),null==n&&(n=1),e<t&&(e=t),e>n&&(e=n),e},Ce=function(e){return e.length>=3?[].slice.call(e):e[0]},E=function(e){var t;for(t in e)t<3?(e[t]<0&&(e[t]=0),e[t]>255&&(e[t]=255)):3===t&&(e[t]<0&&(e[t]=0),e[t]>1&&(e[t]=1));return e},s=Math.PI,we=Math.round,S=Math.cos,I=Math.floor,re=Math.pow,Q=Math.log,be=Math.sin,_e=Math.sqrt,g=Math.atan2,$=Math.max,m=Math.abs,u=2*s,l=s/3,a=s/180,c=180/s,x=function(){return arguments[0]instanceof i?arguments[0]:function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,arguments,function(){})},p=[],"undefined"!=typeof e&&null!==e&&null!=e.exports&&(e.exports=x),n=[],r=function(){return x}.apply(t,n),!(void 0!==r&&(e.exports=r)),x.version="1.1.1",f={},h=[],d=!1,i=function(){function e(){var e,t,n,r,i,a,o,s,l;for(a=this,t=[],s=0,r=arguments.length;s<r;s++)e=arguments[s],null!=e&&t.push(e);if(o=t[t.length-1],null!=f[o])a._rgb=E(f[o](Ce(t.slice(0,-1))));else{for(d||(h=h.sort(function(e,t){return t.p-e.p}),d=!0),l=0,i=h.length;l<i&&(n=h[l],!(o=n.test.apply(n,t)));l++);o&&(a._rgb=E(f[o].apply(f,t)))}null==a._rgb&&console.warn("unknown format: "+t),null==a._rgb&&(a._rgb=[0,0,0]),3===a._rgb.length&&a._rgb.push(1)}return e.prototype.alpha=function(e){return arguments.length?(this._rgb[3]=e,this):this._rgb[3]},e.prototype.toString=function(){return this.name()},e}(),x._input=f,/** ColorBrewer colors for chroma.js Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The @@ -32877,16882 +81,8 @@ module.exports = __webpack_require__(70); @preserve */ - - chroma.brewer = brewer = { - OrRd: ['#fff7ec', '#fee8c8', '#fdd49e', '#fdbb84', '#fc8d59', '#ef6548', '#d7301f', '#b30000', '#7f0000'], - PuBu: ['#fff7fb', '#ece7f2', '#d0d1e6', '#a6bddb', '#74a9cf', '#3690c0', '#0570b0', '#045a8d', '#023858'], - BuPu: ['#f7fcfd', '#e0ecf4', '#bfd3e6', '#9ebcda', '#8c96c6', '#8c6bb1', '#88419d', '#810f7c', '#4d004b'], - Oranges: ['#fff5eb', '#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c', '#f16913', '#d94801', '#a63603', '#7f2704'], - BuGn: ['#f7fcfd', '#e5f5f9', '#ccece6', '#99d8c9', '#66c2a4', '#41ae76', '#238b45', '#006d2c', '#00441b'], - YlOrBr: ['#ffffe5', '#fff7bc', '#fee391', '#fec44f', '#fe9929', '#ec7014', '#cc4c02', '#993404', '#662506'], - YlGn: ['#ffffe5', '#f7fcb9', '#d9f0a3', '#addd8e', '#78c679', '#41ab5d', '#238443', '#006837', '#004529'], - Reds: ['#fff5f0', '#fee0d2', '#fcbba1', '#fc9272', '#fb6a4a', '#ef3b2c', '#cb181d', '#a50f15', '#67000d'], - RdPu: ['#fff7f3', '#fde0dd', '#fcc5c0', '#fa9fb5', '#f768a1', '#dd3497', '#ae017e', '#7a0177', '#49006a'], - Greens: ['#f7fcf5', '#e5f5e0', '#c7e9c0', '#a1d99b', '#74c476', '#41ab5d', '#238b45', '#006d2c', '#00441b'], - YlGnBu: ['#ffffd9', '#edf8b1', '#c7e9b4', '#7fcdbb', '#41b6c4', '#1d91c0', '#225ea8', '#253494', '#081d58'], - Purples: ['#fcfbfd', '#efedf5', '#dadaeb', '#bcbddc', '#9e9ac8', '#807dba', '#6a51a3', '#54278f', '#3f007d'], - GnBu: ['#f7fcf0', '#e0f3db', '#ccebc5', '#a8ddb5', '#7bccc4', '#4eb3d3', '#2b8cbe', '#0868ac', '#084081'], - Greys: ['#ffffff', '#f0f0f0', '#d9d9d9', '#bdbdbd', '#969696', '#737373', '#525252', '#252525', '#000000'], - YlOrRd: ['#ffffcc', '#ffeda0', '#fed976', '#feb24c', '#fd8d3c', '#fc4e2a', '#e31a1c', '#bd0026', '#800026'], - PuRd: ['#f7f4f9', '#e7e1ef', '#d4b9da', '#c994c7', '#df65b0', '#e7298a', '#ce1256', '#980043', '#67001f'], - Blues: ['#f7fbff', '#deebf7', '#c6dbef', '#9ecae1', '#6baed6', '#4292c6', '#2171b5', '#08519c', '#08306b'], - PuBuGn: ['#fff7fb', '#ece2f0', '#d0d1e6', '#a6bddb', '#67a9cf', '#3690c0', '#02818a', '#016c59', '#014636'], - Spectral: ['#9e0142', '#d53e4f', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2'], - RdYlGn: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#d9ef8b', '#a6d96a', '#66bd63', '#1a9850', '#006837'], - RdBu: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#f7f7f7', '#d1e5f0', '#92c5de', '#4393c3', '#2166ac', '#053061'], - PiYG: ['#8e0152', '#c51b7d', '#de77ae', '#f1b6da', '#fde0ef', '#f7f7f7', '#e6f5d0', '#b8e186', '#7fbc41', '#4d9221', '#276419'], - PRGn: ['#40004b', '#762a83', '#9970ab', '#c2a5cf', '#e7d4e8', '#f7f7f7', '#d9f0d3', '#a6dba0', '#5aae61', '#1b7837', '#00441b'], - RdYlBu: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee090', '#ffffbf', '#e0f3f8', '#abd9e9', '#74add1', '#4575b4', '#313695'], - BrBG: ['#543005', '#8c510a', '#bf812d', '#dfc27d', '#f6e8c3', '#f5f5f5', '#c7eae5', '#80cdc1', '#35978f', '#01665e', '#003c30'], - RdGy: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#ffffff', '#e0e0e0', '#bababa', '#878787', '#4d4d4d', '#1a1a1a'], - PuOr: ['#7f3b08', '#b35806', '#e08214', '#fdb863', '#fee0b6', '#f7f7f7', '#d8daeb', '#b2abd2', '#8073ac', '#542788', '#2d004b'], - Set2: ['#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', '#e5c494', '#b3b3b3'], - Accent: ['#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666'], - Set1: ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', '#a65628', '#f781bf', '#999999'], - Set3: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f'], - Dark2: ['#1b9e77', '#d95f02', '#7570b3', '#e7298a', '#66a61e', '#e6ab02', '#a6761d', '#666666'], - Paired: ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', '#ffff99', '#b15928'], - Pastel2: ['#b3e2cd', '#fdcdac', '#cbd5e8', '#f4cae4', '#e6f5c9', '#fff2ae', '#f1e2cc', '#cccccc'], - Pastel1: ['#fbb4ae', '#b3cde3', '#ccebc5', '#decbe4', '#fed9a6', '#ffffcc', '#e5d8bd', '#fddaec', '#f2f2f2'] - }; - - - /** - X11 color names - - http://www.w3.org/TR/css3-color/#svg-color - */ - - w3cx11 = { - indigo: "#4b0082", - gold: "#ffd700", - hotpink: "#ff69b4", - firebrick: "#b22222", - indianred: "#cd5c5c", - yellow: "#ffff00", - mistyrose: "#ffe4e1", - darkolivegreen: "#556b2f", - olive: "#808000", - darkseagreen: "#8fbc8f", - pink: "#ffc0cb", - tomato: "#ff6347", - lightcoral: "#f08080", - orangered: "#ff4500", - navajowhite: "#ffdead", - lime: "#00ff00", - palegreen: "#98fb98", - darkslategrey: "#2f4f4f", - greenyellow: "#adff2f", - burlywood: "#deb887", - seashell: "#fff5ee", - mediumspringgreen: "#00fa9a", - fuchsia: "#ff00ff", - papayawhip: "#ffefd5", - blanchedalmond: "#ffebcd", - chartreuse: "#7fff00", - dimgray: "#696969", - black: "#000000", - peachpuff: "#ffdab9", - springgreen: "#00ff7f", - aquamarine: "#7fffd4", - white: "#ffffff", - orange: "#ffa500", - lightsalmon: "#ffa07a", - darkslategray: "#2f4f4f", - brown: "#a52a2a", - ivory: "#fffff0", - dodgerblue: "#1e90ff", - peru: "#cd853f", - lawngreen: "#7cfc00", - chocolate: "#d2691e", - crimson: "#dc143c", - forestgreen: "#228b22", - darkgrey: "#a9a9a9", - lightseagreen: "#20b2aa", - cyan: "#00ffff", - mintcream: "#f5fffa", - silver: "#c0c0c0", - antiquewhite: "#faebd7", - mediumorchid: "#ba55d3", - skyblue: "#87ceeb", - gray: "#808080", - darkturquoise: "#00ced1", - goldenrod: "#daa520", - darkgreen: "#006400", - floralwhite: "#fffaf0", - darkviolet: "#9400d3", - darkgray: "#a9a9a9", - moccasin: "#ffe4b5", - saddlebrown: "#8b4513", - grey: "#808080", - darkslateblue: "#483d8b", - lightskyblue: "#87cefa", - lightpink: "#ffb6c1", - mediumvioletred: "#c71585", - slategrey: "#708090", - red: "#ff0000", - deeppink: "#ff1493", - limegreen: "#32cd32", - darkmagenta: "#8b008b", - palegoldenrod: "#eee8aa", - plum: "#dda0dd", - turquoise: "#40e0d0", - lightgrey: "#d3d3d3", - lightgoldenrodyellow: "#fafad2", - darkgoldenrod: "#b8860b", - lavender: "#e6e6fa", - maroon: "#800000", - yellowgreen: "#9acd32", - sandybrown: "#f4a460", - thistle: "#d8bfd8", - violet: "#ee82ee", - navy: "#000080", - magenta: "#ff00ff", - dimgrey: "#696969", - tan: "#d2b48c", - rosybrown: "#bc8f8f", - olivedrab: "#6b8e23", - blue: "#0000ff", - lightblue: "#add8e6", - ghostwhite: "#f8f8ff", - honeydew: "#f0fff0", - cornflowerblue: "#6495ed", - slateblue: "#6a5acd", - linen: "#faf0e6", - darkblue: "#00008b", - powderblue: "#b0e0e6", - seagreen: "#2e8b57", - darkkhaki: "#bdb76b", - snow: "#fffafa", - sienna: "#a0522d", - mediumblue: "#0000cd", - royalblue: "#4169e1", - lightcyan: "#e0ffff", - green: "#008000", - mediumpurple: "#9370db", - midnightblue: "#191970", - cornsilk: "#fff8dc", - paleturquoise: "#afeeee", - bisque: "#ffe4c4", - slategray: "#708090", - darkcyan: "#008b8b", - khaki: "#f0e68c", - wheat: "#f5deb3", - teal: "#008080", - darkorchid: "#9932cc", - deepskyblue: "#00bfff", - salmon: "#fa8072", - darkred: "#8b0000", - steelblue: "#4682b4", - palevioletred: "#db7093", - lightslategray: "#778899", - aliceblue: "#f0f8ff", - lightslategrey: "#778899", - lightgreen: "#90ee90", - orchid: "#da70d6", - gainsboro: "#dcdcdc", - mediumseagreen: "#3cb371", - lightgray: "#d3d3d3", - mediumturquoise: "#48d1cc", - lemonchiffon: "#fffacd", - cadetblue: "#5f9ea0", - lightyellow: "#ffffe0", - lavenderblush: "#fff0f5", - coral: "#ff7f50", - purple: "#800080", - aqua: "#00ffff", - whitesmoke: "#f5f5f5", - mediumslateblue: "#7b68ee", - darkorange: "#ff8c00", - mediumaquamarine: "#66cdaa", - darksalmon: "#e9967a", - beige: "#f5f5dc", - blueviolet: "#8a2be2", - azure: "#f0ffff", - lightsteelblue: "#b0c4de", - oldlace: "#fdf5e6", - rebeccapurple: "#663399" - }; - - chroma.colors = colors = w3cx11; - - lab2rgb = function() { - var a, args, b, g, l, r, x, y, z; - args = unpack(arguments); - l = args[0], a = args[1], b = args[2]; - y = (l + 16) / 116; - x = isNaN(a) ? y : y + a / 500; - z = isNaN(b) ? y : y - b / 200; - y = LAB_CONSTANTS.Yn * lab_xyz(y); - x = LAB_CONSTANTS.Xn * lab_xyz(x); - z = LAB_CONSTANTS.Zn * lab_xyz(z); - r = xyz_rgb(3.2404542 * x - 1.5371385 * y - 0.4985314 * z); - g = xyz_rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z); - b = xyz_rgb(0.0556434 * x - 0.2040259 * y + 1.0572252 * z); - r = limit(r, 0, 255); - g = limit(g, 0, 255); - b = limit(b, 0, 255); - return [r, g, b, args.length > 3 ? args[3] : 1]; - }; - - xyz_rgb = function(r) { - return round(255 * (r <= 0.00304 ? 12.92 * r : 1.055 * pow(r, 1 / 2.4) - 0.055)); - }; - - lab_xyz = function(t) { - if (t > LAB_CONSTANTS.t1) { - return t * t * t; - } else { - return LAB_CONSTANTS.t2 * (t - LAB_CONSTANTS.t0); - } - }; - - LAB_CONSTANTS = { - Kn: 18, - Xn: 0.950470, - Yn: 1, - Zn: 1.088830, - t0: 0.137931034, - t1: 0.206896552, - t2: 0.12841855, - t3: 0.008856452 - }; - - rgb2lab = function() { - var b, g, r, ref, ref1, x, y, z; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - ref1 = rgb2xyz(r, g, b), x = ref1[0], y = ref1[1], z = ref1[2]; - return [116 * y - 16, 500 * (x - y), 200 * (y - z)]; - }; - - rgb_xyz = function(r) { - if ((r /= 255) <= 0.04045) { - return r / 12.92; - } else { - return pow((r + 0.055) / 1.055, 2.4); - } - }; - - xyz_lab = function(t) { - if (t > LAB_CONSTANTS.t3) { - return pow(t, 1 / 3); - } else { - return t / LAB_CONSTANTS.t2 + LAB_CONSTANTS.t0; - } - }; - - rgb2xyz = function() { - var b, g, r, ref, x, y, z; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - r = rgb_xyz(r); - g = rgb_xyz(g); - b = rgb_xyz(b); - x = xyz_lab((0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / LAB_CONSTANTS.Xn); - y = xyz_lab((0.2126729 * r + 0.7151522 * g + 0.0721750 * b) / LAB_CONSTANTS.Yn); - z = xyz_lab((0.0193339 * r + 0.1191920 * g + 0.9503041 * b) / LAB_CONSTANTS.Zn); - return [x, y, z]; - }; - - chroma.lab = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['lab']), function(){}); - }; - - _input.lab = lab2rgb; - - Color.prototype.lab = function() { - return rgb2lab(this._rgb); - }; - - bezier = function(colors) { - var I, I0, I1, c, lab0, lab1, lab2, lab3, ref, ref1, ref2; - colors = (function() { - var len, o, results; - results = []; - for (o = 0, len = colors.length; o < len; o++) { - c = colors[o]; - results.push(chroma(c)); - } - return results; - })(); - if (colors.length === 2) { - ref = (function() { - var len, o, results; - results = []; - for (o = 0, len = colors.length; o < len; o++) { - c = colors[o]; - results.push(c.lab()); - } - return results; - })(), lab0 = ref[0], lab1 = ref[1]; - I = function(t) { - var i, lab; - lab = (function() { - var o, results; - results = []; - for (i = o = 0; o <= 2; i = ++o) { - results.push(lab0[i] + t * (lab1[i] - lab0[i])); - } - return results; - })(); - return chroma.lab.apply(chroma, lab); - }; - } else if (colors.length === 3) { - ref1 = (function() { - var len, o, results; - results = []; - for (o = 0, len = colors.length; o < len; o++) { - c = colors[o]; - results.push(c.lab()); - } - return results; - })(), lab0 = ref1[0], lab1 = ref1[1], lab2 = ref1[2]; - I = function(t) { - var i, lab; - lab = (function() { - var o, results; - results = []; - for (i = o = 0; o <= 2; i = ++o) { - results.push((1 - t) * (1 - t) * lab0[i] + 2 * (1 - t) * t * lab1[i] + t * t * lab2[i]); - } - return results; - })(); - return chroma.lab.apply(chroma, lab); - }; - } else if (colors.length === 4) { - ref2 = (function() { - var len, o, results; - results = []; - for (o = 0, len = colors.length; o < len; o++) { - c = colors[o]; - results.push(c.lab()); - } - return results; - })(), lab0 = ref2[0], lab1 = ref2[1], lab2 = ref2[2], lab3 = ref2[3]; - I = function(t) { - var i, lab; - lab = (function() { - var o, results; - results = []; - for (i = o = 0; o <= 2; i = ++o) { - results.push((1 - t) * (1 - t) * (1 - t) * lab0[i] + 3 * (1 - t) * (1 - t) * t * lab1[i] + 3 * (1 - t) * t * t * lab2[i] + t * t * t * lab3[i]); - } - return results; - })(); - return chroma.lab.apply(chroma, lab); - }; - } else if (colors.length === 5) { - I0 = bezier(colors.slice(0, 3)); - I1 = bezier(colors.slice(2, 5)); - I = function(t) { - if (t < 0.5) { - return I0(t * 2); - } else { - return I1((t - 0.5) * 2); - } - }; - } - return I; - }; - - chroma.bezier = function(colors) { - var f; - f = bezier(colors); - f.scale = function() { - return chroma.scale(f); - }; - return f; - }; - - - /* - chroma.js - - Copyright (c) 2011-2013, Gregor Aisch - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * The name Gregor Aisch may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - @source: https://github.com/gka/chroma.js - */ - - chroma.cubehelix = function(start, rotations, hue, gamma, lightness) { - var dh, dl, f; - if (start == null) { - start = 300; - } - if (rotations == null) { - rotations = -1.5; - } - if (hue == null) { - hue = 1; - } - if (gamma == null) { - gamma = 1; - } - if (lightness == null) { - lightness = [0, 1]; - } - dl = lightness[1] - lightness[0]; - dh = 0; - f = function(fract) { - var a, amp, b, cos_a, g, h, l, r, sin_a; - a = TWOPI * ((start + 120) / 360 + rotations * fract); - l = pow(lightness[0] + dl * fract, gamma); - h = dh !== 0 ? hue[0] + fract * dh : hue; - amp = h * l * (1 - l) / 2; - cos_a = cos(a); - sin_a = sin(a); - r = l + amp * (-0.14861 * cos_a + 1.78277 * sin_a); - g = l + amp * (-0.29227 * cos_a - 0.90649 * sin_a); - b = l + amp * (+1.97294 * cos_a); - return chroma(clip_rgb([r * 255, g * 255, b * 255])); - }; - f.start = function(s) { - if (s == null) { - return start; - } - start = s; - return f; - }; - f.rotations = function(r) { - if (r == null) { - return rotations; - } - rotations = r; - return f; - }; - f.gamma = function(g) { - if (g == null) { - return gamma; - } - gamma = g; - return f; - }; - f.hue = function(h) { - if (h == null) { - return hue; - } - hue = h; - if (type(hue) === 'array') { - dh = hue[1] - hue[0]; - if (dh === 0) { - hue = hue[1]; - } - } else { - dh = 0; - } - return f; - }; - f.lightness = function(h) { - if (h == null) { - return lightness; - } - lightness = h; - if (type(lightness) === 'array') { - dl = lightness[1] - lightness[0]; - if (dl === 0) { - lightness = lightness[1]; - } - } else { - dl = 0; - } - return f; - }; - f.scale = function() { - return chroma.scale(f); - }; - f.hue(hue); - return f; - }; - - chroma.random = function() { - var code, digits, i, o; - digits = '0123456789abcdef'; - code = '#'; - for (i = o = 0; o < 6; i = ++o) { - code += digits.charAt(floor(Math.random() * 16)); - } - return new Color(code); - }; - - chroma.average = function(colors) { - var a, b, c, g, l, len, o, r, rgba; - r = g = b = a = 0; - l = colors.length; - for (o = 0, len = colors.length; o < len; o++) { - c = colors[o]; - rgba = chroma(c).rgba(); - r += rgba[0]; - g += rgba[1]; - b += rgba[2]; - a += rgba[3]; - } - return new Color(r / l, g / l, b / l, a / l); - }; - - _input.rgb = function() { - var k, ref, results, v; - ref = unpack(arguments); - results = []; - for (k in ref) { - v = ref[k]; - results.push(v); - } - return results; - }; - - chroma.rgb = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['rgb']), function(){}); - }; - - Color.prototype.rgb = function() { - return this._rgb.slice(0, 3); - }; - - Color.prototype.rgba = function() { - return this._rgb; - }; - - _guess_formats.push({ - p: 15, - test: function(n) { - var a; - a = unpack(arguments); - if (type(a) === 'array' && a.length === 3) { - return 'rgb'; - } - if (a.length === 4 && type(a[3]) === "number" && a[3] >= 0 && a[3] <= 1) { - return 'rgb'; - } - } - }); - - hex2rgb = function(hex) { - var a, b, g, r, rgb, u; - if (hex.match(/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)) { - if (hex.length === 4 || hex.length === 7) { - hex = hex.substr(1); - } - if (hex.length === 3) { - hex = hex.split(""); - hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; - } - u = parseInt(hex, 16); - r = u >> 16; - g = u >> 8 & 0xFF; - b = u & 0xFF; - return [r, g, b, 1]; - } - if (hex.match(/^#?([A-Fa-f0-9]{8})$/)) { - if (hex.length === 9) { - hex = hex.substr(1); - } - u = parseInt(hex, 16); - r = u >> 24 & 0xFF; - g = u >> 16 & 0xFF; - b = u >> 8 & 0xFF; - a = round((u & 0xFF) / 0xFF * 100) / 100; - return [r, g, b, a]; - } - if ((_input.css != null) && (rgb = _input.css(hex))) { - return rgb; - } - throw "unknown color: " + hex; - }; - - rgb2hex = function(channels, mode) { - var a, b, g, hxa, r, str, u; - if (mode == null) { - mode = 'rgb'; - } - r = channels[0], g = channels[1], b = channels[2], a = channels[3]; - u = r << 16 | g << 8 | b; - str = "000000" + u.toString(16); - str = str.substr(str.length - 6); - hxa = '0' + round(a * 255).toString(16); - hxa = hxa.substr(hxa.length - 2); - return "#" + (function() { - switch (mode.toLowerCase()) { - case 'rgba': - return str + hxa; - case 'argb': - return hxa + str; - default: - return str; - } - })(); - }; - - _input.hex = function(h) { - return hex2rgb(h); - }; - - chroma.hex = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['hex']), function(){}); - }; - - Color.prototype.hex = function(mode) { - if (mode == null) { - mode = 'rgb'; - } - return rgb2hex(this._rgb, mode); - }; - - _guess_formats.push({ - p: 10, - test: function(n) { - if (arguments.length === 1 && type(n) === "string") { - return 'hex'; - } - } - }); - - hsl2rgb = function() { - var args, b, c, g, h, i, l, o, r, ref, s, t1, t2, t3; - args = unpack(arguments); - h = args[0], s = args[1], l = args[2]; - if (s === 0) { - r = g = b = l * 255; - } else { - t3 = [0, 0, 0]; - c = [0, 0, 0]; - t2 = l < 0.5 ? l * (1 + s) : l + s - l * s; - t1 = 2 * l - t2; - h /= 360; - t3[0] = h + 1 / 3; - t3[1] = h; - t3[2] = h - 1 / 3; - for (i = o = 0; o <= 2; i = ++o) { - if (t3[i] < 0) { - t3[i] += 1; - } - if (t3[i] > 1) { - t3[i] -= 1; - } - if (6 * t3[i] < 1) { - c[i] = t1 + (t2 - t1) * 6 * t3[i]; - } else if (2 * t3[i] < 1) { - c[i] = t2; - } else if (3 * t3[i] < 2) { - c[i] = t1 + (t2 - t1) * ((2 / 3) - t3[i]) * 6; - } else { - c[i] = t1; - } - } - ref = [round(c[0] * 255), round(c[1] * 255), round(c[2] * 255)], r = ref[0], g = ref[1], b = ref[2]; - } - if (args.length > 3) { - return [r, g, b, args[3]]; - } else { - return [r, g, b]; - } - }; - - rgb2hsl = function(r, g, b) { - var h, l, min, ref, s; - if (r !== void 0 && r.length >= 3) { - ref = r, r = ref[0], g = ref[1], b = ref[2]; - } - r /= 255; - g /= 255; - b /= 255; - min = Math.min(r, g, b); - max = Math.max(r, g, b); - l = (max + min) / 2; - if (max === min) { - s = 0; - h = Number.NaN; - } else { - s = l < 0.5 ? (max - min) / (max + min) : (max - min) / (2 - max - min); - } - if (r === max) { - h = (g - b) / (max - min); - } else if (g === max) { - h = 2 + (b - r) / (max - min); - } else if (b === max) { - h = 4 + (r - g) / (max - min); - } - h *= 60; - if (h < 0) { - h += 360; - } - return [h, s, l]; - }; - - chroma.hsl = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['hsl']), function(){}); - }; - - _input.hsl = hsl2rgb; - - Color.prototype.hsl = function() { - return rgb2hsl(this._rgb); - }; - - hsv2rgb = function() { - var args, b, f, g, h, i, p, q, r, ref, ref1, ref2, ref3, ref4, ref5, s, t, v; - args = unpack(arguments); - h = args[0], s = args[1], v = args[2]; - v *= 255; - if (s === 0) { - r = g = b = v; - } else { - if (h === 360) { - h = 0; - } - if (h > 360) { - h -= 360; - } - if (h < 0) { - h += 360; - } - h /= 60; - i = floor(h); - f = h - i; - p = v * (1 - s); - q = v * (1 - s * f); - t = v * (1 - s * (1 - f)); - switch (i) { - case 0: - ref = [v, t, p], r = ref[0], g = ref[1], b = ref[2]; - break; - case 1: - ref1 = [q, v, p], r = ref1[0], g = ref1[1], b = ref1[2]; - break; - case 2: - ref2 = [p, v, t], r = ref2[0], g = ref2[1], b = ref2[2]; - break; - case 3: - ref3 = [p, q, v], r = ref3[0], g = ref3[1], b = ref3[2]; - break; - case 4: - ref4 = [t, p, v], r = ref4[0], g = ref4[1], b = ref4[2]; - break; - case 5: - ref5 = [v, p, q], r = ref5[0], g = ref5[1], b = ref5[2]; - } - } - r = round(r); - g = round(g); - b = round(b); - return [r, g, b, args.length > 3 ? args[3] : 1]; - }; - - rgb2hsv = function() { - var b, delta, g, h, min, r, ref, s, v; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - min = Math.min(r, g, b); - max = Math.max(r, g, b); - delta = max - min; - v = max / 255.0; - if (max === 0) { - h = Number.NaN; - s = 0; - } else { - s = delta / max; - if (r === max) { - h = (g - b) / delta; - } - if (g === max) { - h = 2 + (b - r) / delta; - } - if (b === max) { - h = 4 + (r - g) / delta; - } - h *= 60; - if (h < 0) { - h += 360; - } - } - return [h, s, v]; - }; - - chroma.hsv = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['hsv']), function(){}); - }; - - _input.hsv = hsv2rgb; - - Color.prototype.hsv = function() { - return rgb2hsv(this._rgb); - }; - - num2rgb = function(num) { - var b, g, r; - if (type(num) === "number" && num >= 0 && num <= 0xFFFFFF) { - r = num >> 16; - g = (num >> 8) & 0xFF; - b = num & 0xFF; - return [r, g, b, 1]; - } - console.warn("unknown num color: " + num); - return [0, 0, 0, 1]; - }; - - rgb2num = function() { - var b, g, r, ref; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - return (r << 16) + (g << 8) + b; - }; - - chroma.num = function(num) { - return new Color(num, 'num'); - }; - - Color.prototype.num = function(mode) { - if (mode == null) { - mode = 'rgb'; - } - return rgb2num(this._rgb, mode); - }; - - _input.num = num2rgb; - - _guess_formats.push({ - p: 10, - test: function(n) { - if (arguments.length === 1 && type(n) === "number" && n >= 0 && n <= 0xFFFFFF) { - return 'num'; - } - } - }); - - css2rgb = function(css) { - var aa, ab, hsl, i, m, o, rgb, w; - css = css.toLowerCase(); - if ((chroma.colors != null) && chroma.colors[css]) { - return hex2rgb(chroma.colors[css]); - } - if (m = css.match(/rgb\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*\)/)) { - rgb = m.slice(1, 4); - for (i = o = 0; o <= 2; i = ++o) { - rgb[i] = +rgb[i]; - } - rgb[3] = 1; - } else if (m = css.match(/rgba\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*,\s*([01]|[01]?\.\d+)\)/)) { - rgb = m.slice(1, 5); - for (i = w = 0; w <= 3; i = ++w) { - rgb[i] = +rgb[i]; - } - } else if (m = css.match(/rgb\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/)) { - rgb = m.slice(1, 4); - for (i = aa = 0; aa <= 2; i = ++aa) { - rgb[i] = round(rgb[i] * 2.55); - } - rgb[3] = 1; - } else if (m = css.match(/rgba\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/)) { - rgb = m.slice(1, 5); - for (i = ab = 0; ab <= 2; i = ++ab) { - rgb[i] = round(rgb[i] * 2.55); - } - rgb[3] = +rgb[3]; - } else if (m = css.match(/hsl\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/)) { - hsl = m.slice(1, 4); - hsl[1] *= 0.01; - hsl[2] *= 0.01; - rgb = hsl2rgb(hsl); - rgb[3] = 1; - } else if (m = css.match(/hsla\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/)) { - hsl = m.slice(1, 4); - hsl[1] *= 0.01; - hsl[2] *= 0.01; - rgb = hsl2rgb(hsl); - rgb[3] = +m[4]; - } - return rgb; - }; - - rgb2css = function(rgba) { - var mode; - mode = rgba[3] < 1 ? 'rgba' : 'rgb'; - if (mode === 'rgb') { - return mode + '(' + rgba.slice(0, 3).map(round).join(',') + ')'; - } else if (mode === 'rgba') { - return mode + '(' + rgba.slice(0, 3).map(round).join(',') + ',' + rgba[3] + ')'; - } else { - - } - }; - - rnd = function(a) { - return round(a * 100) / 100; - }; - - hsl2css = function(hsl, alpha) { - var mode; - mode = alpha < 1 ? 'hsla' : 'hsl'; - hsl[0] = rnd(hsl[0] || 0); - hsl[1] = rnd(hsl[1] * 100) + '%'; - hsl[2] = rnd(hsl[2] * 100) + '%'; - if (mode === 'hsla') { - hsl[3] = alpha; - } - return mode + '(' + hsl.join(',') + ')'; - }; - - _input.css = function(h) { - return css2rgb(h); - }; - - chroma.css = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['css']), function(){}); - }; - - Color.prototype.css = function(mode) { - if (mode == null) { - mode = 'rgb'; - } - if (mode.slice(0, 3) === 'rgb') { - return rgb2css(this._rgb); - } else if (mode.slice(0, 3) === 'hsl') { - return hsl2css(this.hsl(), this.alpha()); - } - }; - - _input.named = function(name) { - return hex2rgb(w3cx11[name]); - }; - - _guess_formats.push({ - p: 20, - test: function(n) { - if (arguments.length === 1 && (w3cx11[n] != null)) { - return 'named'; - } - } - }); - - Color.prototype.name = function(n) { - var h, k; - if (arguments.length) { - if (w3cx11[n]) { - this._rgb = hex2rgb(w3cx11[n]); - } - this._rgb[3] = 1; - this; - } - h = this.hex(); - for (k in w3cx11) { - if (h === w3cx11[k]) { - return k; - } - } - return h; - }; - - lch2lab = function() { - - /* - Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel. - These formulas were invented by David Dalrymple to obtain maximum contrast without going - out of gamut if the parameters are in the range 0-1. - - A saturation multiplier was added by Gregor Aisch - */ - var c, h, l, ref; - ref = unpack(arguments), l = ref[0], c = ref[1], h = ref[2]; - h = h * DEG2RAD; - return [l, cos(h) * c, sin(h) * c]; - }; - - lch2rgb = function() { - var L, a, args, b, c, g, h, l, r, ref, ref1; - args = unpack(arguments); - l = args[0], c = args[1], h = args[2]; - ref = lch2lab(l, c, h), L = ref[0], a = ref[1], b = ref[2]; - ref1 = lab2rgb(L, a, b), r = ref1[0], g = ref1[1], b = ref1[2]; - return [limit(r, 0, 255), limit(g, 0, 255), limit(b, 0, 255), args.length > 3 ? args[3] : 1]; - }; - - lab2lch = function() { - var a, b, c, h, l, ref; - ref = unpack(arguments), l = ref[0], a = ref[1], b = ref[2]; - c = sqrt(a * a + b * b); - h = (atan2(b, a) * RAD2DEG + 360) % 360; - if (round(c * 10000) === 0) { - h = Number.NaN; - } - return [l, c, h]; - }; - - rgb2lch = function() { - var a, b, g, l, r, ref, ref1; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - ref1 = rgb2lab(r, g, b), l = ref1[0], a = ref1[1], b = ref1[2]; - return lab2lch(l, a, b); - }; - - chroma.lch = function() { - var args; - args = unpack(arguments); - return new Color(args, 'lch'); - }; - - chroma.hcl = function() { - var args; - args = unpack(arguments); - return new Color(args, 'hcl'); - }; - - _input.lch = lch2rgb; - - _input.hcl = function() { - var c, h, l, ref; - ref = unpack(arguments), h = ref[0], c = ref[1], l = ref[2]; - return lch2rgb([l, c, h]); - }; - - Color.prototype.lch = function() { - return rgb2lch(this._rgb); - }; - - Color.prototype.hcl = function() { - return rgb2lch(this._rgb).reverse(); - }; - - rgb2cmyk = function(mode) { - var b, c, f, g, k, m, r, ref, y; - if (mode == null) { - mode = 'rgb'; - } - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - r = r / 255; - g = g / 255; - b = b / 255; - k = 1 - Math.max(r, Math.max(g, b)); - f = k < 1 ? 1 / (1 - k) : 0; - c = (1 - r - k) * f; - m = (1 - g - k) * f; - y = (1 - b - k) * f; - return [c, m, y, k]; - }; - - cmyk2rgb = function() { - var alpha, args, b, c, g, k, m, r, y; - args = unpack(arguments); - c = args[0], m = args[1], y = args[2], k = args[3]; - alpha = args.length > 4 ? args[4] : 1; - if (k === 1) { - return [0, 0, 0, alpha]; - } - r = c >= 1 ? 0 : round(255 * (1 - c) * (1 - k)); - g = m >= 1 ? 0 : round(255 * (1 - m) * (1 - k)); - b = y >= 1 ? 0 : round(255 * (1 - y) * (1 - k)); - return [r, g, b, alpha]; - }; - - _input.cmyk = function() { - return cmyk2rgb(unpack(arguments)); - }; - - chroma.cmyk = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['cmyk']), function(){}); - }; - - Color.prototype.cmyk = function() { - return rgb2cmyk(this._rgb); - }; - - _input.gl = function() { - var i, k, o, rgb, v; - rgb = (function() { - var ref, results; - ref = unpack(arguments); - results = []; - for (k in ref) { - v = ref[k]; - results.push(v); - } - return results; - }).apply(this, arguments); - for (i = o = 0; o <= 2; i = ++o) { - rgb[i] *= 255; - } - return rgb; - }; - - chroma.gl = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['gl']), function(){}); - }; - - Color.prototype.gl = function() { - var rgb; - rgb = this._rgb; - return [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255, rgb[3]]; - }; - - rgb2luminance = function(r, g, b) { - var ref; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - r = luminance_x(r); - g = luminance_x(g); - b = luminance_x(b); - return 0.2126 * r + 0.7152 * g + 0.0722 * b; - }; - - luminance_x = function(x) { - x /= 255; - if (x <= 0.03928) { - return x / 12.92; - } else { - return pow((x + 0.055) / 1.055, 2.4); - } - }; - - _interpolators = []; - - interpolate = function(col1, col2, f, m) { - var interpol, len, o, res; - if (f == null) { - f = 0.5; - } - if (m == null) { - m = 'rgb'; - } - - /* - interpolates between colors - f = 0 --> me - f = 1 --> col - */ - if (type(col1) !== 'object') { - col1 = chroma(col1); - } - if (type(col2) !== 'object') { - col2 = chroma(col2); - } - for (o = 0, len = _interpolators.length; o < len; o++) { - interpol = _interpolators[o]; - if (m === interpol[0]) { - res = interpol[1](col1, col2, f, m); - break; - } - } - if (res == null) { - throw "color mode " + m + " is not supported"; - } - res.alpha(col1.alpha() + f * (col2.alpha() - col1.alpha())); - return res; - }; - - chroma.interpolate = interpolate; - - Color.prototype.interpolate = function(col2, f, m) { - return interpolate(this, col2, f, m); - }; - - chroma.mix = interpolate; - - Color.prototype.mix = Color.prototype.interpolate; - - interpolate_rgb = function(col1, col2, f, m) { - var xyz0, xyz1; - xyz0 = col1._rgb; - xyz1 = col2._rgb; - return new Color(xyz0[0] + f * (xyz1[0] - xyz0[0]), xyz0[1] + f * (xyz1[1] - xyz0[1]), xyz0[2] + f * (xyz1[2] - xyz0[2]), m); - }; - - _interpolators.push(['rgb', interpolate_rgb]); - - Color.prototype.luminance = function(lum, mode) { - var cur_lum, eps, max_iter, test; - if (mode == null) { - mode = 'rgb'; - } - if (!arguments.length) { - return rgb2luminance(this._rgb); - } - if (lum === 0) { - this._rgb = [0, 0, 0, this._rgb[3]]; - } else if (lum === 1) { - this._rgb = [255, 255, 255, this._rgb[3]]; - } else { - eps = 1e-7; - max_iter = 20; - test = function(l, h) { - var lm, m; - m = l.interpolate(h, 0.5, mode); - lm = m.luminance(); - if (Math.abs(lum - lm) < eps || !max_iter--) { - return m; - } - if (lm > lum) { - return test(l, m); - } - return test(m, h); - }; - cur_lum = rgb2luminance(this._rgb); - this._rgb = (cur_lum > lum ? test(chroma('black'), this) : test(this, chroma('white'))).rgba(); - } - return this; - }; - - temperature2rgb = function(kelvin) { - var b, g, r, temp; - temp = kelvin / 100; - if (temp < 66) { - r = 255; - g = -155.25485562709179 - 0.44596950469579133 * (g = temp - 2) + 104.49216199393888 * log(g); - b = temp < 20 ? 0 : -254.76935184120902 + 0.8274096064007395 * (b = temp - 10) + 115.67994401066147 * log(b); - } else { - r = 351.97690566805693 + 0.114206453784165 * (r = temp - 55) - 40.25366309332127 * log(r); - g = 325.4494125711974 + 0.07943456536662342 * (g = temp - 50) - 28.0852963507957 * log(g); - b = 255; - } - return clip_rgb([r, g, b]); - }; - - rgb2temperature = function() { - var b, eps, g, maxTemp, minTemp, r, ref, rgb, temp; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - minTemp = 1000; - maxTemp = 40000; - eps = 0.4; - while (maxTemp - minTemp > eps) { - temp = (maxTemp + minTemp) * 0.5; - rgb = temperature2rgb(temp); - if ((rgb[2] / rgb[0]) >= (b / r)) { - maxTemp = temp; - } else { - minTemp = temp; - } - } - return round(temp); - }; - - chroma.temperature = chroma.kelvin = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['temperature']), function(){}); - }; - - _input.temperature = _input.kelvin = _input.K = temperature2rgb; - - Color.prototype.temperature = function() { - return rgb2temperature(this._rgb); - }; - - Color.prototype.kelvin = Color.prototype.temperature; - - chroma.contrast = function(a, b) { - var l1, l2, ref, ref1; - if ((ref = type(a)) === 'string' || ref === 'number') { - a = new Color(a); - } - if ((ref1 = type(b)) === 'string' || ref1 === 'number') { - b = new Color(b); - } - l1 = a.luminance(); - l2 = b.luminance(); - if (l1 > l2) { - return (l1 + 0.05) / (l2 + 0.05); - } else { - return (l2 + 0.05) / (l1 + 0.05); - } - }; - - Color.prototype.get = function(modechan) { - var channel, i, me, mode, ref, src; - me = this; - ref = modechan.split('.'), mode = ref[0], channel = ref[1]; - src = me[mode](); - if (channel) { - i = mode.indexOf(channel); - if (i > -1) { - return src[i]; - } else { - return console.warn('unknown channel ' + channel + ' in mode ' + mode); - } - } else { - return src; - } - }; - - Color.prototype.set = function(modechan, value) { - var channel, i, me, mode, ref, src; - me = this; - ref = modechan.split('.'), mode = ref[0], channel = ref[1]; - if (channel) { - src = me[mode](); - i = mode.indexOf(channel); - if (i > -1) { - if (type(value) === 'string') { - switch (value.charAt(0)) { - case '+': - src[i] += +value; - break; - case '-': - src[i] += +value; - break; - case '*': - src[i] *= +(value.substr(1)); - break; - case '/': - src[i] /= +(value.substr(1)); - break; - default: - src[i] = +value; - } - } else { - src[i] = value; - } - } else { - console.warn('unknown channel ' + channel + ' in mode ' + mode); - } - } else { - src = value; - } - me._rgb = chroma(src, mode).alpha(me.alpha())._rgb; - return me; - }; - - Color.prototype.darken = function(amount) { - var lab, me; - if (amount == null) { - amount = 1; - } - me = this; - lab = me.lab(); - lab[0] -= LAB_CONSTANTS.Kn * amount; - return chroma.lab(lab).alpha(me.alpha()); - }; - - Color.prototype.brighten = function(amount) { - if (amount == null) { - amount = 1; - } - return this.darken(-amount); - }; - - Color.prototype.darker = Color.prototype.darken; - - Color.prototype.brighter = Color.prototype.brighten; - - Color.prototype.saturate = function(amount) { - var lch, me; - if (amount == null) { - amount = 1; - } - me = this; - lch = me.lch(); - lch[1] += amount * LAB_CONSTANTS.Kn; - if (lch[1] < 0) { - lch[1] = 0; - } - return chroma.lch(lch).alpha(me.alpha()); - }; - - Color.prototype.desaturate = function(amount) { - if (amount == null) { - amount = 1; - } - return this.saturate(-amount); - }; - - Color.prototype.premultiply = function() { - var a, rgb; - rgb = this.rgb(); - a = this.alpha(); - return chroma(rgb[0] * a, rgb[1] * a, rgb[2] * a, a); - }; - - blend = function(bottom, top, mode) { - if (!blend[mode]) { - throw 'unknown blend mode ' + mode; - } - return blend[mode](bottom, top); - }; - - blend_f = function(f) { - return function(bottom, top) { - var c0, c1; - c0 = chroma(top).rgb(); - c1 = chroma(bottom).rgb(); - return chroma(f(c0, c1), 'rgb'); - }; - }; - - each = function(f) { - return function(c0, c1) { - var i, o, out; - out = []; - for (i = o = 0; o <= 3; i = ++o) { - out[i] = f(c0[i], c1[i]); - } - return out; - }; - }; - - normal = function(a, b) { - return a; - }; - - multiply = function(a, b) { - return a * b / 255; - }; - - darken = function(a, b) { - if (a > b) { - return b; - } else { - return a; - } - }; - - lighten = function(a, b) { - if (a > b) { - return a; - } else { - return b; - } - }; - - screen = function(a, b) { - return 255 * (1 - (1 - a / 255) * (1 - b / 255)); - }; - - overlay = function(a, b) { - if (b < 128) { - return 2 * a * b / 255; - } else { - return 255 * (1 - 2 * (1 - a / 255) * (1 - b / 255)); - } - }; - - burn = function(a, b) { - return 255 * (1 - (1 - b / 255) / (a / 255)); - }; - - dodge = function(a, b) { - if (a === 255) { - return 255; - } - a = 255 * (b / 255) / (1 - a / 255); - if (a > 255) { - return 255; - } else { - return a; - } - }; - - blend.normal = blend_f(each(normal)); - - blend.multiply = blend_f(each(multiply)); - - blend.screen = blend_f(each(screen)); - - blend.overlay = blend_f(each(overlay)); - - blend.darken = blend_f(each(darken)); - - blend.lighten = blend_f(each(lighten)); - - blend.dodge = blend_f(each(dodge)); - - blend.burn = blend_f(each(burn)); - - chroma.blend = blend; - - chroma.analyze = function(data) { - var len, o, r, val; - r = { - min: Number.MAX_VALUE, - max: Number.MAX_VALUE * -1, - sum: 0, - values: [], - count: 0 - }; - for (o = 0, len = data.length; o < len; o++) { - val = data[o]; - if ((val != null) && !isNaN(val)) { - r.values.push(val); - r.sum += val; - if (val < r.min) { - r.min = val; - } - if (val > r.max) { - r.max = val; - } - r.count += 1; - } - } - r.domain = [r.min, r.max]; - r.limits = function(mode, num) { - return chroma.limits(r, mode, num); - }; - return r; - }; - - chroma.scale = function(colors, positions) { - var _classes, _colorCache, _colors, _correctLightness, _domain, _fixed, _max, _min, _mode, _nacol, _out, _padding, _pos, _spread, classifyValue, f, getClass, getColor, resetCache, setColors, tmap; - _mode = 'rgb'; - _nacol = chroma('#ccc'); - _spread = 0; - _fixed = false; - _domain = [0, 1]; - _pos = []; - _padding = [0, 0]; - _classes = false; - _colors = []; - _out = false; - _min = 0; - _max = 1; - _correctLightness = false; - _colorCache = {}; - setColors = function(colors) { - var c, col, o, ref, ref1, ref2, w; - if (colors == null) { - colors = ['#fff', '#000']; - } - if ((colors != null) && type(colors) === 'string' && (((ref = chroma.brewer) != null ? ref[colors] : void 0) != null)) { - colors = chroma.brewer[colors]; - } - if (type(colors) === 'array') { - colors = colors.slice(0); - for (c = o = 0, ref1 = colors.length - 1; 0 <= ref1 ? o <= ref1 : o >= ref1; c = 0 <= ref1 ? ++o : --o) { - col = colors[c]; - if (type(col) === "string") { - colors[c] = chroma(col); - } - } - _pos.length = 0; - for (c = w = 0, ref2 = colors.length - 1; 0 <= ref2 ? w <= ref2 : w >= ref2; c = 0 <= ref2 ? ++w : --w) { - _pos.push(c / (colors.length - 1)); - } - } - resetCache(); - return _colors = colors; - }; - getClass = function(value) { - var i, n; - if (_classes != null) { - n = _classes.length - 1; - i = 0; - while (i < n && value >= _classes[i]) { - i++; - } - return i - 1; - } - return 0; - }; - tmap = function(t) { - return t; - }; - classifyValue = function(value) { - var i, maxc, minc, n, val; - val = value; - if (_classes.length > 2) { - n = _classes.length - 1; - i = getClass(value); - minc = _classes[0] + (_classes[1] - _classes[0]) * (0 + _spread * 0.5); - maxc = _classes[n - 1] + (_classes[n] - _classes[n - 1]) * (1 - _spread * 0.5); - val = _min + ((_classes[i] + (_classes[i + 1] - _classes[i]) * 0.5 - minc) / (maxc - minc)) * (_max - _min); - } - return val; - }; - getColor = function(val, bypassMap) { - var c, col, i, k, o, p, ref, t; - if (bypassMap == null) { - bypassMap = false; - } - if (isNaN(val)) { - return _nacol; - } - if (!bypassMap) { - if (_classes && _classes.length > 2) { - c = getClass(val); - t = c / (_classes.length - 2); - t = _padding[0] + (t * (1 - _padding[0] - _padding[1])); - } else if (_max !== _min) { - t = (val - _min) / (_max - _min); - t = _padding[0] + (t * (1 - _padding[0] - _padding[1])); - t = Math.min(1, Math.max(0, t)); - } else { - t = 1; - } - } else { - t = val; - } - if (!bypassMap) { - t = tmap(t); - } - k = Math.floor(t * 10000); - if (_colorCache[k]) { - col = _colorCache[k]; - } else { - if (type(_colors) === 'array') { - for (i = o = 0, ref = _pos.length - 1; 0 <= ref ? o <= ref : o >= ref; i = 0 <= ref ? ++o : --o) { - p = _pos[i]; - if (t <= p) { - col = _colors[i]; - break; - } - if (t >= p && i === _pos.length - 1) { - col = _colors[i]; - break; - } - if (t > p && t < _pos[i + 1]) { - t = (t - p) / (_pos[i + 1] - p); - col = chroma.interpolate(_colors[i], _colors[i + 1], t, _mode); - break; - } - } - } else if (type(_colors) === 'function') { - col = _colors(t); - } - _colorCache[k] = col; - } - return col; - }; - resetCache = function() { - return _colorCache = {}; - }; - setColors(colors); - f = function(v) { - var c; - c = chroma(getColor(v)); - if (_out && c[_out]) { - return c[_out](); - } else { - return c; - } - }; - f.classes = function(classes) { - var d; - if (classes != null) { - if (type(classes) === 'array') { - _classes = classes; - _domain = [classes[0], classes[classes.length - 1]]; - } else { - d = chroma.analyze(_domain); - if (classes === 0) { - _classes = [d.min, d.max]; - } else { - _classes = chroma.limits(d, 'e', classes); - } - } - return f; - } - return _classes; - }; - f.domain = function(domain) { - var c, d, k, len, o, ref, w; - if (!arguments.length) { - return _domain; - } - _min = domain[0]; - _max = domain[domain.length - 1]; - _pos = []; - k = _colors.length; - if (domain.length === k && _min !== _max) { - for (o = 0, len = domain.length; o < len; o++) { - d = domain[o]; - _pos.push((d - _min) / (_max - _min)); - } - } else { - for (c = w = 0, ref = k - 1; 0 <= ref ? w <= ref : w >= ref; c = 0 <= ref ? ++w : --w) { - _pos.push(c / (k - 1)); - } - } - _domain = [_min, _max]; - return f; - }; - f.mode = function(_m) { - if (!arguments.length) { - return _mode; - } - _mode = _m; - resetCache(); - return f; - }; - f.range = function(colors, _pos) { - setColors(colors, _pos); - return f; - }; - f.out = function(_o) { - _out = _o; - return f; - }; - f.spread = function(val) { - if (!arguments.length) { - return _spread; - } - _spread = val; - return f; - }; - f.correctLightness = function(v) { - if (v == null) { - v = true; - } - _correctLightness = v; - resetCache(); - if (_correctLightness) { - tmap = function(t) { - var L0, L1, L_actual, L_diff, L_ideal, max_iter, pol, t0, t1; - L0 = getColor(0, true).lab()[0]; - L1 = getColor(1, true).lab()[0]; - pol = L0 > L1; - L_actual = getColor(t, true).lab()[0]; - L_ideal = L0 + (L1 - L0) * t; - L_diff = L_actual - L_ideal; - t0 = 0; - t1 = 1; - max_iter = 20; - while (Math.abs(L_diff) > 1e-2 && max_iter-- > 0) { - (function() { - if (pol) { - L_diff *= -1; - } - if (L_diff < 0) { - t0 = t; - t += (t1 - t) * 0.5; - } else { - t1 = t; - t += (t0 - t) * 0.5; - } - L_actual = getColor(t, true).lab()[0]; - return L_diff = L_actual - L_ideal; - })(); - } - return t; - }; - } else { - tmap = function(t) { - return t; - }; - } - return f; - }; - f.padding = function(p) { - if (p != null) { - if (type(p) === 'number') { - p = [p, p]; - } - _padding = p; - return f; - } else { - return _padding; - } - }; - f.colors = function() { - var dd, dm, i, numColors, o, out, ref, results, samples, w; - numColors = 0; - out = 'hex'; - if (arguments.length === 1) { - if (type(arguments[0]) === 'string') { - out = arguments[0]; - } else { - numColors = arguments[0]; - } - } - if (arguments.length === 2) { - numColors = arguments[0], out = arguments[1]; - } - if (numColors) { - dm = _domain[0]; - dd = _domain[1] - dm; - return (function() { - results = []; - for (var o = 0; 0 <= numColors ? o < numColors : o > numColors; 0 <= numColors ? o++ : o--){ results.push(o); } - return results; - }).apply(this).map(function(i) { - return f(dm + i / (numColors - 1) * dd)[out](); - }); - } - colors = []; - samples = []; - if (_classes && _classes.length > 2) { - for (i = w = 1, ref = _classes.length; 1 <= ref ? w < ref : w > ref; i = 1 <= ref ? ++w : --w) { - samples.push((_classes[i - 1] + _classes[i]) * 0.5); - } - } else { - samples = _domain; - } - return samples.map(function(v) { - return f(v)[out](); - }); - }; - return f; - }; - - if (chroma.scales == null) { - chroma.scales = {}; - } - - chroma.scales.cool = function() { - return chroma.scale([chroma.hsl(180, 1, .9), chroma.hsl(250, .7, .4)]); - }; - - chroma.scales.hot = function() { - return chroma.scale(['#000', '#f00', '#ff0', '#fff'], [0, .25, .75, 1]).mode('rgb'); - }; - - chroma.analyze = function(data, key, filter) { - var add, k, len, o, r, val, visit; - r = { - min: Number.MAX_VALUE, - max: Number.MAX_VALUE * -1, - sum: 0, - values: [], - count: 0 - }; - if (filter == null) { - filter = function() { - return true; - }; - } - add = function(val) { - if ((val != null) && !isNaN(val)) { - r.values.push(val); - r.sum += val; - if (val < r.min) { - r.min = val; - } - if (val > r.max) { - r.max = val; - } - r.count += 1; - } - }; - visit = function(val, k) { - if (filter(val, k)) { - if ((key != null) && type(key) === 'function') { - return add(key(val)); - } else if ((key != null) && type(key) === 'string' || type(key) === 'number') { - return add(val[key]); - } else { - return add(val); - } - } - }; - if (type(data) === 'array') { - for (o = 0, len = data.length; o < len; o++) { - val = data[o]; - visit(val); - } - } else { - for (k in data) { - val = data[k]; - visit(val, k); - } - } - r.domain = [r.min, r.max]; - r.limits = function(mode, num) { - return chroma.limits(r, mode, num); - }; - return r; - }; - - chroma.limits = function(data, mode, num) { - var aa, ab, ac, ad, ae, af, ag, ah, ai, aj, ak, al, am, assignments, best, centroids, cluster, clusterSizes, dist, i, j, kClusters, limits, max_log, min, min_log, mindist, n, nb_iters, newCentroids, o, p, pb, pr, ref, ref1, ref10, ref11, ref12, ref13, ref14, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, repeat, sum, tmpKMeansBreaks, value, values, w; - if (mode == null) { - mode = 'equal'; - } - if (num == null) { - num = 7; - } - if (type(data) === 'array') { - data = chroma.analyze(data); - } - min = data.min; - max = data.max; - sum = data.sum; - values = data.values.sort(function(a, b) { - return a - b; - }); - limits = []; - if (mode.substr(0, 1) === 'c') { - limits.push(min); - limits.push(max); - } - if (mode.substr(0, 1) === 'e') { - limits.push(min); - for (i = o = 1, ref = num - 1; 1 <= ref ? o <= ref : o >= ref; i = 1 <= ref ? ++o : --o) { - limits.push(min + (i / num) * (max - min)); - } - limits.push(max); - } else if (mode.substr(0, 1) === 'l') { - if (min <= 0) { - throw 'Logarithmic scales are only possible for values > 0'; - } - min_log = Math.LOG10E * log(min); - max_log = Math.LOG10E * log(max); - limits.push(min); - for (i = w = 1, ref1 = num - 1; 1 <= ref1 ? w <= ref1 : w >= ref1; i = 1 <= ref1 ? ++w : --w) { - limits.push(pow(10, min_log + (i / num) * (max_log - min_log))); - } - limits.push(max); - } else if (mode.substr(0, 1) === 'q') { - limits.push(min); - for (i = aa = 1, ref2 = num - 1; 1 <= ref2 ? aa <= ref2 : aa >= ref2; i = 1 <= ref2 ? ++aa : --aa) { - p = values.length * i / num; - pb = floor(p); - if (pb === p) { - limits.push(values[pb]); - } else { - pr = p - pb; - limits.push(values[pb] * pr + values[pb + 1] * (1 - pr)); - } - } - limits.push(max); - } else if (mode.substr(0, 1) === 'k') { - - /* - implementation based on - http://code.google.com/p/figue/source/browse/trunk/figue.js#336 - simplified for 1-d input values - */ - n = values.length; - assignments = new Array(n); - clusterSizes = new Array(num); - repeat = true; - nb_iters = 0; - centroids = null; - centroids = []; - centroids.push(min); - for (i = ab = 1, ref3 = num - 1; 1 <= ref3 ? ab <= ref3 : ab >= ref3; i = 1 <= ref3 ? ++ab : --ab) { - centroids.push(min + (i / num) * (max - min)); - } - centroids.push(max); - while (repeat) { - for (j = ac = 0, ref4 = num - 1; 0 <= ref4 ? ac <= ref4 : ac >= ref4; j = 0 <= ref4 ? ++ac : --ac) { - clusterSizes[j] = 0; - } - for (i = ad = 0, ref5 = n - 1; 0 <= ref5 ? ad <= ref5 : ad >= ref5; i = 0 <= ref5 ? ++ad : --ad) { - value = values[i]; - mindist = Number.MAX_VALUE; - for (j = ae = 0, ref6 = num - 1; 0 <= ref6 ? ae <= ref6 : ae >= ref6; j = 0 <= ref6 ? ++ae : --ae) { - dist = abs(centroids[j] - value); - if (dist < mindist) { - mindist = dist; - best = j; - } - } - clusterSizes[best]++; - assignments[i] = best; - } - newCentroids = new Array(num); - for (j = af = 0, ref7 = num - 1; 0 <= ref7 ? af <= ref7 : af >= ref7; j = 0 <= ref7 ? ++af : --af) { - newCentroids[j] = null; - } - for (i = ag = 0, ref8 = n - 1; 0 <= ref8 ? ag <= ref8 : ag >= ref8; i = 0 <= ref8 ? ++ag : --ag) { - cluster = assignments[i]; - if (newCentroids[cluster] === null) { - newCentroids[cluster] = values[i]; - } else { - newCentroids[cluster] += values[i]; - } - } - for (j = ah = 0, ref9 = num - 1; 0 <= ref9 ? ah <= ref9 : ah >= ref9; j = 0 <= ref9 ? ++ah : --ah) { - newCentroids[j] *= 1 / clusterSizes[j]; - } - repeat = false; - for (j = ai = 0, ref10 = num - 1; 0 <= ref10 ? ai <= ref10 : ai >= ref10; j = 0 <= ref10 ? ++ai : --ai) { - if (newCentroids[j] !== centroids[i]) { - repeat = true; - break; - } - } - centroids = newCentroids; - nb_iters++; - if (nb_iters > 200) { - repeat = false; - } - } - kClusters = {}; - for (j = aj = 0, ref11 = num - 1; 0 <= ref11 ? aj <= ref11 : aj >= ref11; j = 0 <= ref11 ? ++aj : --aj) { - kClusters[j] = []; - } - for (i = ak = 0, ref12 = n - 1; 0 <= ref12 ? ak <= ref12 : ak >= ref12; i = 0 <= ref12 ? ++ak : --ak) { - cluster = assignments[i]; - kClusters[cluster].push(values[i]); - } - tmpKMeansBreaks = []; - for (j = al = 0, ref13 = num - 1; 0 <= ref13 ? al <= ref13 : al >= ref13; j = 0 <= ref13 ? ++al : --al) { - tmpKMeansBreaks.push(kClusters[j][0]); - tmpKMeansBreaks.push(kClusters[j][kClusters[j].length - 1]); - } - tmpKMeansBreaks = tmpKMeansBreaks.sort(function(a, b) { - return a - b; - }); - limits.push(tmpKMeansBreaks[0]); - for (i = am = 1, ref14 = tmpKMeansBreaks.length - 1; am <= ref14; i = am += 2) { - if (!isNaN(tmpKMeansBreaks[i])) { - limits.push(tmpKMeansBreaks[i]); - } - } - } - return limits; - }; - - hsi2rgb = function(h, s, i) { - - /* - borrowed from here: - http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/hsi2rgb.cpp - */ - var args, b, g, r; - args = unpack(arguments); - h = args[0], s = args[1], i = args[2]; - h /= 360; - if (h < 1 / 3) { - b = (1 - s) / 3; - r = (1 + s * cos(TWOPI * h) / cos(PITHIRD - TWOPI * h)) / 3; - g = 1 - (b + r); - } else if (h < 2 / 3) { - h -= 1 / 3; - r = (1 - s) / 3; - g = (1 + s * cos(TWOPI * h) / cos(PITHIRD - TWOPI * h)) / 3; - b = 1 - (r + g); - } else { - h -= 2 / 3; - g = (1 - s) / 3; - b = (1 + s * cos(TWOPI * h) / cos(PITHIRD - TWOPI * h)) / 3; - r = 1 - (g + b); - } - r = limit(i * r * 3); - g = limit(i * g * 3); - b = limit(i * b * 3); - return [r * 255, g * 255, b * 255, args.length > 3 ? args[3] : 1]; - }; - - rgb2hsi = function() { - - /* - borrowed from here: - http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/rgb2hsi.cpp - */ - var b, g, h, i, min, r, ref, s; - ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; - TWOPI = Math.PI * 2; - r /= 255; - g /= 255; - b /= 255; - min = Math.min(r, g, b); - i = (r + g + b) / 3; - s = 1 - min / i; - if (s === 0) { - h = 0; - } else { - h = ((r - g) + (r - b)) / 2; - h /= Math.sqrt((r - g) * (r - g) + (r - b) * (g - b)); - h = Math.acos(h); - if (b > g) { - h = TWOPI - h; - } - h /= TWOPI; - } - return [h * 360, s, i]; - }; - - chroma.hsi = function() { - return (function(func, args, ctor) { - ctor.prototype = func.prototype; - var child = new ctor, result = func.apply(child, args); - return Object(result) === result ? result : child; - })(Color, slice.call(arguments).concat(['hsi']), function(){}); - }; - - _input.hsi = hsi2rgb; - - Color.prototype.hsi = function() { - return rgb2hsi(this._rgb); - }; - - interpolate_hsx = function(col1, col2, f, m) { - var dh, hue, hue0, hue1, lbv, lbv0, lbv1, res, sat, sat0, sat1, xyz0, xyz1; - if (m === 'hsl') { - xyz0 = col1.hsl(); - xyz1 = col2.hsl(); - } else if (m === 'hsv') { - xyz0 = col1.hsv(); - xyz1 = col2.hsv(); - } else if (m === 'hsi') { - xyz0 = col1.hsi(); - xyz1 = col2.hsi(); - } else if (m === 'lch' || m === 'hcl') { - m = 'hcl'; - xyz0 = col1.hcl(); - xyz1 = col2.hcl(); - } - if (m.substr(0, 1) === 'h') { - hue0 = xyz0[0], sat0 = xyz0[1], lbv0 = xyz0[2]; - hue1 = xyz1[0], sat1 = xyz1[1], lbv1 = xyz1[2]; - } - if (!isNaN(hue0) && !isNaN(hue1)) { - if (hue1 > hue0 && hue1 - hue0 > 180) { - dh = hue1 - (hue0 + 360); - } else if (hue1 < hue0 && hue0 - hue1 > 180) { - dh = hue1 + 360 - hue0; - } else { - dh = hue1 - hue0; - } - hue = hue0 + f * dh; - } else if (!isNaN(hue0)) { - hue = hue0; - if ((lbv1 === 1 || lbv1 === 0) && m !== 'hsv') { - sat = sat0; - } - } else if (!isNaN(hue1)) { - hue = hue1; - if ((lbv0 === 1 || lbv0 === 0) && m !== 'hsv') { - sat = sat1; - } - } else { - hue = Number.NaN; - } - if (sat == null) { - sat = sat0 + f * (sat1 - sat0); - } - lbv = lbv0 + f * (lbv1 - lbv0); - return res = chroma[m](hue, sat, lbv); - }; - - _interpolators = _interpolators.concat((function() { - var len, o, ref, results; - ref = ['hsv', 'hsl', 'hsi', 'hcl', 'lch']; - results = []; - for (o = 0, len = ref.length; o < len; o++) { - m = ref[o]; - results.push([m, interpolate_hsx]); - } - return results; - })()); - - interpolate_num = function(col1, col2, f, m) { - var n1, n2; - n1 = col1.num(); - n2 = col2.num(); - return chroma.num(n1 + (n2 - n1) * f, 'num'); - }; - - _interpolators.push(['num', interpolate_num]); - - interpolate_lab = function(col1, col2, f, m) { - var res, xyz0, xyz1; - xyz0 = col1.lab(); - xyz1 = col2.lab(); - return res = new Color(xyz0[0] + f * (xyz1[0] - xyz0[0]), xyz0[1] + f * (xyz1[1] - xyz0[1]), xyz0[2] + f * (xyz1[2] - xyz0[2]), m); - }; - - _interpolators.push(['lab', interpolate_lab]); - -}).call(this); - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(336)(module))) - -/***/ }), -/* 211 */ -/***/ (function(module, exports, __webpack_require__) { - -var pSlice = Array.prototype.slice; -var objectKeys = __webpack_require__(213); -var isArguments = __webpack_require__(212); - -var deepEqual = module.exports = function (actual, expected, opts) { - if (!opts) opts = {}; - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - - } else if (actual instanceof Date && expected instanceof Date) { - return actual.getTime() === expected.getTime(); - - // 7.3. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if (!actual || !expected || typeof actual != 'object' && typeof expected != 'object') { - return opts.strict ? actual === expected : actual == expected; - - // 7.4. For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected, opts); - } -} - -function isUndefinedOrNull(value) { - return value === null || value === undefined; -} - -function isBuffer (x) { - if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false; - if (typeof x.copy !== 'function' || typeof x.slice !== 'function') { - return false; - } - if (x.length > 0 && typeof x[0] !== 'number') return false; - return true; -} - -function objEquiv(a, b, opts) { - var i, key; - if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) - return false; - // an identical 'prototype' property. - if (a.prototype !== b.prototype) return false; - //~~~I've managed to break Object.keys through screwy arguments passing. - // Converting to array solves the problem. - if (isArguments(a)) { - if (!isArguments(b)) { - return false; - } - a = pSlice.call(a); - b = pSlice.call(b); - return deepEqual(a, b, opts); - } - if (isBuffer(a)) { - if (!isBuffer(b)) { - return false; - } - if (a.length !== b.length) return false; - for (i = 0; i < a.length; i++) { - if (a[i] !== b[i]) return false; - } - return true; - } - try { - var ka = objectKeys(a), - kb = objectKeys(b); - } catch (e) {//happens when one is a string literal and the other isn't - return false; - } - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length != kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] != kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!deepEqual(a[key], b[key], opts)) return false; - } - return typeof a === typeof b; -} - - -/***/ }), -/* 212 */ -/***/ (function(module, exports) { - -var supportsArgumentsClass = (function(){ - return Object.prototype.toString.call(arguments) -})() == '[object Arguments]'; - -exports = module.exports = supportsArgumentsClass ? supported : unsupported; - -exports.supported = supported; -function supported(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -}; - -exports.unsupported = unsupported; -function unsupported(object){ - return object && - typeof object == 'object' && - typeof object.length == 'number' && - Object.prototype.hasOwnProperty.call(object, 'callee') && - !Object.prototype.propertyIsEnumerable.call(object, 'callee') || - false; -}; - - -/***/ }), -/* 213 */ -/***/ (function(module, exports) { - -exports = module.exports = typeof Object.keys === 'function' - ? Object.keys : shim; - -exports.shim = shim; -function shim (obj) { - var keys = []; - for (var key in obj) keys.push(key); - return keys; -} - - -/***/ }), -/* 214 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -var _hyphenPattern = /-(.)/g; - -/** - * Camelcases a hyphenated string, for example: - * - * > camelize('background-color') - * < "backgroundColor" - * - * @param {string} string - * @return {string} - */ -function camelize(string) { - return string.replace(_hyphenPattern, function (_, character) { - return character.toUpperCase(); - }); -} - -module.exports = camelize; - -/***/ }), -/* 215 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - - - -var camelize = __webpack_require__(214); - -var msPattern = /^-ms-/; - -/** - * Camelcases a hyphenated CSS property name, for example: - * - * > camelizeStyleName('background-color') - * < "backgroundColor" - * > camelizeStyleName('-moz-transition') - * < "MozTransition" - * > camelizeStyleName('-ms-transition') - * < "msTransition" - * - * As Andi Smith suggests - * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix - * is converted to lowercase `ms`. - * - * @param {string} string - * @return {string} - */ -function camelizeStyleName(string) { - return camelize(string.replace(msPattern, 'ms-')); -} - -module.exports = camelizeStyleName; - -/***/ }), -/* 216 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - -var isTextNode = __webpack_require__(224); - -/*eslint-disable no-bitwise */ - -/** - * Checks if a given DOM node contains or is another DOM node. - */ -function containsNode(outerNode, innerNode) { - if (!outerNode || !innerNode) { - return false; - } else if (outerNode === innerNode) { - return true; - } else if (isTextNode(outerNode)) { - return false; - } else if (isTextNode(innerNode)) { - return containsNode(outerNode, innerNode.parentNode); - } else if ('contains' in outerNode) { - return outerNode.contains(innerNode); - } else if (outerNode.compareDocumentPosition) { - return !!(outerNode.compareDocumentPosition(innerNode) & 16); - } else { - return false; - } -} - -module.exports = containsNode; - -/***/ }), -/* 217 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -var invariant = __webpack_require__(2); - -/** - * Convert array-like objects to arrays. - * - * This API assumes the caller knows the contents of the data type. For less - * well defined inputs use createArrayFromMixed. - * - * @param {object|function|filelist} obj - * @return {array} - */ -function toArray(obj) { - var length = obj.length; - - // Some browsers builtin objects can report typeof 'function' (e.g. NodeList - // in old versions of Safari). - !(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Array-like object expected') : invariant(false) : void 0; - - !(typeof length === 'number') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object needs a length property') : invariant(false) : void 0; - - !(length === 0 || length - 1 in obj) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object should have keys for indices') : invariant(false) : void 0; - - !(typeof obj.callee !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object can\'t be `arguments`. Use rest params ' + '(function(...args) {}) or Array.from() instead.') : invariant(false) : void 0; - - // Old IE doesn't give collections access to hasOwnProperty. Assume inputs - // without method will throw during the slice call and skip straight to the - // fallback. - if (obj.hasOwnProperty) { - try { - return Array.prototype.slice.call(obj); - } catch (e) { - // IE < 9 does not support Array#slice on collections objects - } - } - - // Fall back to copying key by key. This assumes all keys have a value, - // so will not preserve sparsely populated inputs. - var ret = Array(length); - for (var ii = 0; ii < length; ii++) { - ret[ii] = obj[ii]; - } - return ret; -} - -/** - * Perform a heuristic test to determine if an object is "array-like". - * - * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?" - * Joshu replied: "Mu." - * - * This function determines if its argument has "array nature": it returns - * true if the argument is an actual array, an `arguments' object, or an - * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()). - * - * It will return false for other array-like objects like Filelist. - * - * @param {*} obj - * @return {boolean} - */ -function hasArrayNature(obj) { - return ( - // not null/false - !!obj && ( - // arrays are objects, NodeLists are functions in Safari - typeof obj == 'object' || typeof obj == 'function') && - // quacks like an array - 'length' in obj && - // not window - !('setInterval' in obj) && - // no DOM node should be considered an array-like - // a 'select' element has 'length' and 'item' properties on IE8 - typeof obj.nodeType != 'number' && ( - // a real array - Array.isArray(obj) || - // arguments - 'callee' in obj || - // HTMLCollection/NodeList - 'item' in obj) - ); -} - -/** - * Ensure that the argument is an array by wrapping it in an array if it is not. - * Creates a copy of the argument if it is already an array. - * - * This is mostly useful idiomatically: - * - * var createArrayFromMixed = require('createArrayFromMixed'); - * - * function takesOneOrMoreThings(things) { - * things = createArrayFromMixed(things); - * ... - * } - * - * This allows you to treat `things' as an array, but accept scalars in the API. - * - * If you need to convert an array-like object, like `arguments`, into an array - * use toArray instead. - * - * @param {*} obj - * @return {array} - */ -function createArrayFromMixed(obj) { - if (!hasArrayNature(obj)) { - return [obj]; - } else if (Array.isArray(obj)) { - return obj.slice(); - } else { - return toArray(obj); - } -} - -module.exports = createArrayFromMixed; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 218 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -/*eslint-disable fb-www/unsafe-html*/ - -var ExecutionEnvironment = __webpack_require__(8); - -var createArrayFromMixed = __webpack_require__(217); -var getMarkupWrap = __webpack_require__(219); -var invariant = __webpack_require__(2); - -/** - * Dummy container used to render all markup. - */ -var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; - -/** - * Pattern used by `getNodeName`. - */ -var nodeNamePattern = /^\s*<(\w+)/; - -/** - * Extracts the `nodeName` of the first element in a string of markup. - * - * @param {string} markup String of markup. - * @return {?string} Node name of the supplied markup. - */ -function getNodeName(markup) { - var nodeNameMatch = markup.match(nodeNamePattern); - return nodeNameMatch && nodeNameMatch[1].toLowerCase(); -} - -/** - * Creates an array containing the nodes rendered from the supplied markup. The - * optionally supplied `handleScript` function will be invoked once for each - * <script> element that is rendered. If no `handleScript` function is supplied, - * an exception is thrown if any <script> elements are rendered. - * - * @param {string} markup A string of valid HTML markup. - * @param {?function} handleScript Invoked once for each rendered <script>. - * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes. - */ -function createNodesFromMarkup(markup, handleScript) { - var node = dummyNode; - !!!dummyNode ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createNodesFromMarkup dummy not initialized') : invariant(false) : void 0; - var nodeName = getNodeName(markup); - - var wrap = nodeName && getMarkupWrap(nodeName); - if (wrap) { - node.innerHTML = wrap[1] + markup + wrap[2]; - - var wrapDepth = wrap[0]; - while (wrapDepth--) { - node = node.lastChild; - } - } else { - node.innerHTML = markup; - } - - var scripts = node.getElementsByTagName('script'); - if (scripts.length) { - !handleScript ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createNodesFromMarkup(...): Unexpected <script> element rendered.') : invariant(false) : void 0; - createArrayFromMixed(scripts).forEach(handleScript); - } - - var nodes = Array.from(node.childNodes); - while (node.lastChild) { - node.removeChild(node.lastChild); - } - return nodes; -} - -module.exports = createNodesFromMarkup; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 219 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -/*eslint-disable fb-www/unsafe-html */ - -var ExecutionEnvironment = __webpack_require__(8); - -var invariant = __webpack_require__(2); - -/** - * Dummy container used to detect which wraps are necessary. - */ -var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; - -/** - * Some browsers cannot use `innerHTML` to render certain elements standalone, - * so we wrap them, render the wrapped nodes, then extract the desired node. - * - * In IE8, certain elements cannot render alone, so wrap all elements ('*'). - */ - -var shouldWrap = {}; - -var selectWrap = [1, '<select multiple="true">', '</select>']; -var tableWrap = [1, '<table>', '</table>']; -var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>']; - -var svgWrap = [1, '<svg xmlns="http://www.w3.org/2000/svg">', '</svg>']; - -var markupWrap = { - '*': [1, '?<div>', '</div>'], - - 'area': [1, '<map>', '</map>'], - 'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'], - 'legend': [1, '<fieldset>', '</fieldset>'], - 'param': [1, '<object>', '</object>'], - 'tr': [2, '<table><tbody>', '</tbody></table>'], - - 'optgroup': selectWrap, - 'option': selectWrap, - - 'caption': tableWrap, - 'colgroup': tableWrap, - 'tbody': tableWrap, - 'tfoot': tableWrap, - 'thead': tableWrap, - - 'td': trWrap, - 'th': trWrap -}; - -// Initialize the SVG elements since we know they'll always need to be wrapped -// consistently. If they are created inside a <div> they will be initialized in -// the wrong namespace (and will not display). -var svgElements = ['circle', 'clipPath', 'defs', 'ellipse', 'g', 'image', 'line', 'linearGradient', 'mask', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'text', 'tspan']; -svgElements.forEach(function (nodeName) { - markupWrap[nodeName] = svgWrap; - shouldWrap[nodeName] = true; -}); - -/** - * Gets the markup wrap configuration for the supplied `nodeName`. - * - * NOTE: This lazily detects which wraps are necessary for the current browser. - * - * @param {string} nodeName Lowercase `nodeName`. - * @return {?array} Markup wrap configuration, if applicable. - */ -function getMarkupWrap(nodeName) { - !!!dummyNode ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Markup wrapping node not initialized') : invariant(false) : void 0; - if (!markupWrap.hasOwnProperty(nodeName)) { - nodeName = '*'; - } - if (!shouldWrap.hasOwnProperty(nodeName)) { - if (nodeName === '*') { - dummyNode.innerHTML = '<link />'; - } else { - dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>'; - } - shouldWrap[nodeName] = !dummyNode.firstChild; - } - return shouldWrap[nodeName] ? markupWrap[nodeName] : null; -} - -module.exports = getMarkupWrap; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 220 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - - - -/** - * Gets the scroll position of the supplied element or window. - * - * The return values are unbounded, unlike `getScrollPosition`. This means they - * may be negative or exceed the element boundaries (which is possible using - * inertial scrolling). - * - * @param {DOMWindow|DOMElement} scrollable - * @return {object} Map with `x` and `y` keys. - */ - -function getUnboundedScrollPosition(scrollable) { - if (scrollable === window) { - return { - x: window.pageXOffset || document.documentElement.scrollLeft, - y: window.pageYOffset || document.documentElement.scrollTop - }; - } - return { - x: scrollable.scrollLeft, - y: scrollable.scrollTop - }; -} - -module.exports = getUnboundedScrollPosition; - -/***/ }), -/* 221 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -var _uppercasePattern = /([A-Z])/g; - -/** - * Hyphenates a camelcased string, for example: - * - * > hyphenate('backgroundColor') - * < "background-color" - * - * For CSS style names, use `hyphenateStyleName` instead which works properly - * with all vendor prefixes, including `ms`. - * - * @param {string} string - * @return {string} - */ -function hyphenate(string) { - return string.replace(_uppercasePattern, '-$1').toLowerCase(); -} - -module.exports = hyphenate; - -/***/ }), -/* 222 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - - - -var hyphenate = __webpack_require__(221); - -var msPattern = /^ms-/; - -/** - * Hyphenates a camelcased CSS property name, for example: - * - * > hyphenateStyleName('backgroundColor') - * < "background-color" - * > hyphenateStyleName('MozTransition') - * < "-moz-transition" - * > hyphenateStyleName('msTransition') - * < "-ms-transition" - * - * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix - * is converted to `-ms-`. - * - * @param {string} string - * @return {string} - */ -function hyphenateStyleName(string) { - return hyphenate(string).replace(msPattern, '-ms-'); -} - -module.exports = hyphenateStyleName; - -/***/ }), -/* 223 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -/** - * @param {*} object The object to check. - * @return {boolean} Whether or not the object is a DOM node. - */ -function isNode(object) { - return !!(object && (typeof Node === 'function' ? object instanceof Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string')); -} - -module.exports = isNode; - -/***/ }), -/* 224 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -var isNode = __webpack_require__(223); - -/** - * @param {*} object The object to check. - * @return {boolean} Whether or not the object is a DOM text node. - */ -function isTextNode(object) { - return isNode(object) && object.nodeType == 3; -} - -module.exports = isTextNode; - -/***/ }), -/* 225 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - * @typechecks static-only - */ - - - -/** - * Memoizes the return value of a function that accepts one string argument. - */ - -function memoizeStringOnly(callback) { - var cache = {}; - return function (string) { - if (!cache.hasOwnProperty(string)) { - cache[string] = callback.call(this, string); - } - return cache[string]; - }; -} - -module.exports = memoizeStringOnly; - -/***/ }), -/* 226 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - - - -var ExecutionEnvironment = __webpack_require__(8); - -var performance; - -if (ExecutionEnvironment.canUseDOM) { - performance = window.performance || window.msPerformance || window.webkitPerformance; -} - -module.exports = performance || {}; - -/***/ }), -/* 227 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks - */ - -var performance = __webpack_require__(226); - -var performanceNow; - -/** - * Detect if we can use `window.performance.now()` and gracefully fallback to - * `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now - * because of Facebook's testing infrastructure. - */ -if (performance.now) { - performanceNow = function performanceNow() { - return performance.now(); - }; -} else { - performanceNow = function performanceNow() { - return Date.now(); - }; -} - -module.exports = performanceNow; - -/***/ }), -/* 228 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.loopAsync = loopAsync; - -function loopAsync(turns, work, callback) { - var currentTurn = 0; - var isDone = false; - - function done() { - isDone = true; - callback.apply(this, arguments); - } - - function next() { - if (isDone) return; - - if (currentTurn < turns) { - work.call(this, currentTurn++, next, done); - } else { - done.apply(this, arguments); - } - } - - next(); -} - -/***/ }), -/* 229 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/*eslint-disable no-empty */ - - -exports.__esModule = true; -exports.saveState = saveState; -exports.readState = readState; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var KeyPrefix = '@@History/'; -var QuotaExceededError = 'QuotaExceededError'; -var SecurityError = 'SecurityError'; - -function createKey(key) { - return KeyPrefix + key; -} - -function saveState(key, state) { - try { - window.sessionStorage.setItem(createKey(key), JSON.stringify(state)); - } catch (error) { - if (error.name === SecurityError) { - // Blocking cookies in Chrome/Firefox/Safari throws SecurityError on any - // attempt to access window.sessionStorage. - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, '[history] Unable to save state; sessionStorage is not available due to security settings') : undefined; - - return; - } - - if (error.name === QuotaExceededError && window.sessionStorage.length === 0) { - // Safari "private mode" throws QuotaExceededError. - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, '[history] Unable to save state; sessionStorage is not available in Safari private mode') : undefined; - - return; - } - - throw error; - } -} - -function readState(key) { - var json = undefined; - try { - json = window.sessionStorage.getItem(createKey(key)); - } catch (error) { - if (error.name === SecurityError) { - // Blocking cookies in Chrome/Firefox/Safari throws SecurityError on any - // attempt to access window.sessionStorage. - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, '[history] Unable to read state; sessionStorage is not available due to security settings') : undefined; - - return null; - } - } - - if (json) { - try { - return JSON.parse(json); - } catch (error) { - // Ignore invalid JSON. - } - } - - return null; -} -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 230 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _ExecutionEnvironment = __webpack_require__(43); - -var _DOMUtils = __webpack_require__(75); - -var _createHistory = __webpack_require__(76); - -var _createHistory2 = _interopRequireDefault(_createHistory); - -function createDOMHistory(options) { - var history = _createHistory2['default'](_extends({ - getUserConfirmation: _DOMUtils.getUserConfirmation - }, options, { - go: _DOMUtils.go - })); - - function listen(listener) { - !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'DOM history needs a DOM') : _invariant2['default'](false) : undefined; - - return history.listen(listener); - } - - return _extends({}, history, { - listen: listen - }); -} - -exports['default'] = createDOMHistory; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 231 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _Actions = __webpack_require__(29); - -var _ExecutionEnvironment = __webpack_require__(43); - -var _DOMUtils = __webpack_require__(75); - -var _DOMStateStorage = __webpack_require__(229); - -var _createDOMHistory = __webpack_require__(230); - -var _createDOMHistory2 = _interopRequireDefault(_createDOMHistory); - -var _parsePath = __webpack_require__(24); - -var _parsePath2 = _interopRequireDefault(_parsePath); - -function isAbsolutePath(path) { - return typeof path === 'string' && path.charAt(0) === '/'; -} - -function ensureSlash() { - var path = _DOMUtils.getHashPath(); - - if (isAbsolutePath(path)) return true; - - _DOMUtils.replaceHashPath('/' + path); - - return false; -} - -function addQueryStringValueToPath(path, key, value) { - return path + (path.indexOf('?') === -1 ? '?' : '&') + (key + '=' + value); -} - -function stripQueryStringValueFromPath(path, key) { - return path.replace(new RegExp('[?&]?' + key + '=[a-zA-Z0-9]+'), ''); -} - -function getQueryStringValueFromPath(path, key) { - var match = path.match(new RegExp('\\?.*?\\b' + key + '=(.+?)\\b')); - return match && match[1]; -} - -var DefaultQueryKey = '_k'; - -function createHashHistory() { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - - !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Hash history needs a DOM') : _invariant2['default'](false) : undefined; - - var queryKey = options.queryKey; - - if (queryKey === undefined || !!queryKey) queryKey = typeof queryKey === 'string' ? queryKey : DefaultQueryKey; - - function getCurrentLocation() { - var path = _DOMUtils.getHashPath(); - - var key = undefined, - state = undefined; - if (queryKey) { - key = getQueryStringValueFromPath(path, queryKey); - path = stripQueryStringValueFromPath(path, queryKey); - - if (key) { - state = _DOMStateStorage.readState(key); - } else { - state = null; - key = history.createKey(); - _DOMUtils.replaceHashPath(addQueryStringValueToPath(path, queryKey, key)); - } - } else { - key = state = null; - } - - var location = _parsePath2['default'](path); - - return history.createLocation(_extends({}, location, { state: state }), undefined, key); - } - - function startHashChangeListener(_ref) { - var transitionTo = _ref.transitionTo; - - function hashChangeListener() { - if (!ensureSlash()) return; // Always make sure hashes are preceeded with a /. - - transitionTo(getCurrentLocation()); - } - - ensureSlash(); - _DOMUtils.addEventListener(window, 'hashchange', hashChangeListener); - - return function () { - _DOMUtils.removeEventListener(window, 'hashchange', hashChangeListener); - }; - } - - function finishTransition(location) { - var basename = location.basename; - var pathname = location.pathname; - var search = location.search; - var state = location.state; - var action = location.action; - var key = location.key; - - if (action === _Actions.POP) return; // Nothing to do. - - var path = (basename || '') + pathname + search; - - if (queryKey) { - path = addQueryStringValueToPath(path, queryKey, key); - _DOMStateStorage.saveState(key, state); - } else { - // Drop key and state. - location.key = location.state = null; - } - - var currentHash = _DOMUtils.getHashPath(); - - if (action === _Actions.PUSH) { - if (currentHash !== path) { - window.location.hash = path; - } else { - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'You cannot PUSH the same path using hash history') : undefined; - } - } else if (currentHash !== path) { - // REPLACE - _DOMUtils.replaceHashPath(path); - } - } - - var history = _createDOMHistory2['default'](_extends({}, options, { - getCurrentLocation: getCurrentLocation, - finishTransition: finishTransition, - saveState: _DOMStateStorage.saveState - })); - - var listenerCount = 0, - stopHashChangeListener = undefined; - - function listenBefore(listener) { - if (++listenerCount === 1) stopHashChangeListener = startHashChangeListener(history); - - var unlisten = history.listenBefore(listener); - - return function () { - unlisten(); - - if (--listenerCount === 0) stopHashChangeListener(); - }; - } - - function listen(listener) { - if (++listenerCount === 1) stopHashChangeListener = startHashChangeListener(history); - - var unlisten = history.listen(listener); - - return function () { - unlisten(); - - if (--listenerCount === 0) stopHashChangeListener(); - }; - } - - function push(location) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](queryKey || location.state == null, 'You cannot use state without a queryKey it will be dropped') : undefined; - - history.push(location); - } - - function replace(location) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](queryKey || location.state == null, 'You cannot use state without a queryKey it will be dropped') : undefined; - - history.replace(location); - } - - var goIsSupportedWithoutReload = _DOMUtils.supportsGoWithoutReloadUsingHash(); - - function go(n) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](goIsSupportedWithoutReload, 'Hash history go(n) causes a full page reload in this browser') : undefined; - - history.go(n); - } - - function createHref(path) { - return '#' + history.createHref(path); - } - - // deprecated - function registerTransitionHook(hook) { - if (++listenerCount === 1) stopHashChangeListener = startHashChangeListener(history); - - history.registerTransitionHook(hook); - } - - // deprecated - function unregisterTransitionHook(hook) { - history.unregisterTransitionHook(hook); - - if (--listenerCount === 0) stopHashChangeListener(); - } - - // deprecated - function pushState(state, path) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](queryKey || state == null, 'You cannot use state without a queryKey it will be dropped') : undefined; - - history.pushState(state, path); - } - - // deprecated - function replaceState(state, path) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](queryKey || state == null, 'You cannot use state without a queryKey it will be dropped') : undefined; - - history.replaceState(state, path); - } - - return _extends({}, history, { - listenBefore: listenBefore, - listen: listen, - push: push, - replace: replace, - go: go, - createHref: createHref, - - registerTransitionHook: registerTransitionHook, // deprecated - warning is in createHistory - unregisterTransitionHook: unregisterTransitionHook, // deprecated - warning is in createHistory - pushState: pushState, // deprecated - warning is in createHistory - replaceState: replaceState // deprecated - warning is in createHistory - }); -} - -exports['default'] = createHashHistory; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 232 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -//import warning from 'warning' - - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _Actions = __webpack_require__(29); - -var _parsePath = __webpack_require__(24); - -var _parsePath2 = _interopRequireDefault(_parsePath); - -function createLocation() { - var location = arguments.length <= 0 || arguments[0] === undefined ? '/' : arguments[0]; - var action = arguments.length <= 1 || arguments[1] === undefined ? _Actions.POP : arguments[1]; - var key = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2]; - - var _fourthArg = arguments.length <= 3 || arguments[3] === undefined ? null : arguments[3]; - - if (typeof location === 'string') location = _parsePath2['default'](location); - - if (typeof action === 'object') { - //warning( - // false, - // 'The state (2nd) argument to createLocation is deprecated; use a ' + - // 'location descriptor instead' - //) - - location = _extends({}, location, { state: action }); - - action = key || _Actions.POP; - key = _fourthArg; - } - - var pathname = location.pathname || '/'; - var search = location.search || ''; - var hash = location.hash || ''; - var state = location.state || null; - - return { - pathname: pathname, - search: search, - hash: hash, - state: state, - action: action, - key: key - }; -} - -exports['default'] = createLocation; -module.exports = exports['default']; - -/***/ }), -/* 233 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _Actions = __webpack_require__(29); - -var _createHistory = __webpack_require__(76); - -var _createHistory2 = _interopRequireDefault(_createHistory); - -var _parsePath = __webpack_require__(24); - -var _parsePath2 = _interopRequireDefault(_parsePath); - -function createStateStorage(entries) { - return entries.filter(function (entry) { - return entry.state; - }).reduce(function (memo, entry) { - memo[entry.key] = entry.state; - return memo; - }, {}); -} - -function createMemoryHistory() { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - - if (Array.isArray(options)) { - options = { entries: options }; - } else if (typeof options === 'string') { - options = { entries: [options] }; - } - - var history = _createHistory2['default'](_extends({}, options, { - getCurrentLocation: getCurrentLocation, - finishTransition: finishTransition, - saveState: saveState, - go: go - })); - - var _options = options; - var entries = _options.entries; - var current = _options.current; - - if (typeof entries === 'string') { - entries = [entries]; - } else if (!Array.isArray(entries)) { - entries = ['/']; - } - - entries = entries.map(function (entry) { - var key = history.createKey(); - - if (typeof entry === 'string') return { pathname: entry, key: key }; - - if (typeof entry === 'object' && entry) return _extends({}, entry, { key: key }); - - true ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Unable to create history entry from %s', entry) : _invariant2['default'](false) : undefined; - }); - - if (current == null) { - current = entries.length - 1; - } else { - !(current >= 0 && current < entries.length) ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'Current index must be >= 0 and < %s, was %s', entries.length, current) : _invariant2['default'](false) : undefined; - } - - var storage = createStateStorage(entries); - - function saveState(key, state) { - storage[key] = state; - } - - function readState(key) { - return storage[key]; - } - - function getCurrentLocation() { - var entry = entries[current]; - var key = entry.key; - var basename = entry.basename; - var pathname = entry.pathname; - var search = entry.search; - - var path = (basename || '') + pathname + (search || ''); - - var state = undefined; - if (key) { - state = readState(key); - } else { - state = null; - key = history.createKey(); - entry.key = key; - } - - var location = _parsePath2['default'](path); - - return history.createLocation(_extends({}, location, { state: state }), undefined, key); - } - - function canGo(n) { - var index = current + n; - return index >= 0 && index < entries.length; - } - - function go(n) { - if (n) { - if (!canGo(n)) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'Cannot go(%s) there is not enough history', n) : undefined; - return; - } - - current += n; - - var currentLocation = getCurrentLocation(); - - // change action to POP - history.transitionTo(_extends({}, currentLocation, { action: _Actions.POP })); - } - } - - function finishTransition(location) { - switch (location.action) { - case _Actions.PUSH: - current += 1; - - // if we are not on the top of stack - // remove rest and push new - if (current < entries.length) entries.splice(current); - - entries.push(location); - saveState(location.key, location.state); - break; - case _Actions.REPLACE: - entries[current] = location; - saveState(location.key, location.state); - break; - } - } - - return history; -} - -exports['default'] = createMemoryHistory; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 234 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - -var _ExecutionEnvironment = __webpack_require__(43); - -var _runTransitionHook = __webpack_require__(45); - -var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook); - -var _extractPath = __webpack_require__(77); - -var _extractPath2 = _interopRequireDefault(_extractPath); - -var _parsePath = __webpack_require__(24); - -var _parsePath2 = _interopRequireDefault(_parsePath); - -var _deprecate = __webpack_require__(44); - -var _deprecate2 = _interopRequireDefault(_deprecate); - -function useBasename(createHistory) { - return function () { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - var basename = options.basename; - - var historyOptions = _objectWithoutProperties(options, ['basename']); - - var history = createHistory(historyOptions); - - // Automatically use the value of <base href> in HTML - // documents as basename if it's not explicitly given. - if (basename == null && _ExecutionEnvironment.canUseDOM) { - var base = document.getElementsByTagName('base')[0]; - - if (base) basename = _extractPath2['default'](base.href); - } - - function addBasename(location) { - if (basename && location.basename == null) { - if (location.pathname.indexOf(basename) === 0) { - location.pathname = location.pathname.substring(basename.length); - location.basename = basename; - - if (location.pathname === '') location.pathname = '/'; - } else { - location.basename = ''; - } - } - - return location; - } - - function prependBasename(location) { - if (!basename) return location; - - if (typeof location === 'string') location = _parsePath2['default'](location); - - var pname = location.pathname; - var normalizedBasename = basename.slice(-1) === '/' ? basename : basename + '/'; - var normalizedPathname = pname.charAt(0) === '/' ? pname.slice(1) : pname; - var pathname = normalizedBasename + normalizedPathname; - - return _extends({}, location, { - pathname: pathname - }); - } - - // Override all read methods with basename-aware versions. - function listenBefore(hook) { - return history.listenBefore(function (location, callback) { - _runTransitionHook2['default'](hook, addBasename(location), callback); - }); - } - - function listen(listener) { - return history.listen(function (location) { - listener(addBasename(location)); - }); - } - - // Override all write methods with basename-aware versions. - function push(location) { - history.push(prependBasename(location)); - } - - function replace(location) { - history.replace(prependBasename(location)); - } - - function createPath(location) { - return history.createPath(prependBasename(location)); - } - - function createHref(location) { - return history.createHref(prependBasename(location)); - } - - function createLocation() { - return addBasename(history.createLocation.apply(history, arguments)); - } - - // deprecated - function pushState(state, path) { - if (typeof path === 'string') path = _parsePath2['default'](path); - - push(_extends({ state: state }, path)); - } - - // deprecated - function replaceState(state, path) { - if (typeof path === 'string') path = _parsePath2['default'](path); - - replace(_extends({ state: state }, path)); - } - - return _extends({}, history, { - listenBefore: listenBefore, - listen: listen, - push: push, - replace: replace, - createPath: createPath, - createHref: createHref, - createLocation: createLocation, - - pushState: _deprecate2['default'](pushState, 'pushState is deprecated; use push instead'), - replaceState: _deprecate2['default'](replaceState, 'replaceState is deprecated; use replace instead') - }); - }; -} - -exports['default'] = useBasename; -module.exports = exports['default']; - -/***/ }), -/* 235 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _queryString = __webpack_require__(236); - -var _runTransitionHook = __webpack_require__(45); - -var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook); - -var _parsePath = __webpack_require__(24); - -var _parsePath2 = _interopRequireDefault(_parsePath); - -var _deprecate = __webpack_require__(44); - -var _deprecate2 = _interopRequireDefault(_deprecate); - -var SEARCH_BASE_KEY = '$searchBase'; - -function defaultStringifyQuery(query) { - return _queryString.stringify(query).replace(/%20/g, '+'); -} - -var defaultParseQueryString = _queryString.parse; - -function isNestedObject(object) { - for (var p in object) { - if (object.hasOwnProperty(p) && typeof object[p] === 'object' && !Array.isArray(object[p]) && object[p] !== null) return true; - }return false; -} - -/** - * Returns a new createHistory function that may be used to create - * history objects that know how to handle URL queries. - */ -function useQueries(createHistory) { - return function () { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - var stringifyQuery = options.stringifyQuery; - var parseQueryString = options.parseQueryString; - - var historyOptions = _objectWithoutProperties(options, ['stringifyQuery', 'parseQueryString']); - - var history = createHistory(historyOptions); - - if (typeof stringifyQuery !== 'function') stringifyQuery = defaultStringifyQuery; - - if (typeof parseQueryString !== 'function') parseQueryString = defaultParseQueryString; - - function addQuery(location) { - if (location.query == null) { - var search = location.search; - - location.query = parseQueryString(search.substring(1)); - location[SEARCH_BASE_KEY] = { search: search, searchBase: '' }; - } - - // TODO: Instead of all the book-keeping here, this should just strip the - // stringified query from the search. - - return location; - } - - function appendQuery(location, query) { - var _extends2; - - var queryString = undefined; - if (!query || (queryString = stringifyQuery(query)) === '') return location; - - process.env.NODE_ENV !== 'production' ? _warning2['default'](stringifyQuery !== defaultStringifyQuery || !isNestedObject(query), 'useQueries does not stringify nested query objects by default; ' + 'use a custom stringifyQuery function') : undefined; - - if (typeof location === 'string') location = _parsePath2['default'](location); - - var searchBaseSpec = location[SEARCH_BASE_KEY]; - var searchBase = undefined; - if (searchBaseSpec && location.search === searchBaseSpec.search) { - searchBase = searchBaseSpec.searchBase; - } else { - searchBase = location.search || ''; - } - - var search = searchBase + (searchBase ? '&' : '?') + queryString; - - return _extends({}, location, (_extends2 = { - search: search - }, _extends2[SEARCH_BASE_KEY] = { search: search, searchBase: searchBase }, _extends2)); - } - - // Override all read methods with query-aware versions. - function listenBefore(hook) { - return history.listenBefore(function (location, callback) { - _runTransitionHook2['default'](hook, addQuery(location), callback); - }); - } - - function listen(listener) { - return history.listen(function (location) { - listener(addQuery(location)); - }); - } - - // Override all write methods with query-aware versions. - function push(location) { - history.push(appendQuery(location, location.query)); - } - - function replace(location) { - history.replace(appendQuery(location, location.query)); - } - - function createPath(location, query) { - //warning( - // !query, - // 'the query argument to createPath is deprecated; use a location descriptor instead' - //) - return history.createPath(appendQuery(location, query || location.query)); - } - - function createHref(location, query) { - //warning( - // !query, - // 'the query argument to createHref is deprecated; use a location descriptor instead' - //) - return history.createHref(appendQuery(location, query || location.query)); - } - - function createLocation() { - return addQuery(history.createLocation.apply(history, arguments)); - } - - // deprecated - function pushState(state, path, query) { - if (typeof path === 'string') path = _parsePath2['default'](path); - - push(_extends({ state: state }, path, { query: query })); - } - - // deprecated - function replaceState(state, path, query) { - if (typeof path === 'string') path = _parsePath2['default'](path); - - replace(_extends({ state: state }, path, { query: query })); - } - - return _extends({}, history, { - listenBefore: listenBefore, - listen: listen, - push: push, - replace: replace, - createPath: createPath, - createHref: createHref, - createLocation: createLocation, - - pushState: _deprecate2['default'](pushState, 'pushState is deprecated; use push instead'), - replaceState: _deprecate2['default'](replaceState, 'replaceState is deprecated; use replace instead') - }); - }; -} - -exports['default'] = useQueries; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 236 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var strictUriEncode = __webpack_require__(335); - -exports.extract = function (str) { - return str.split('?')[1] || ''; -}; - -exports.parse = function (str) { - if (typeof str !== 'string') { - return {}; - } - - str = str.trim().replace(/^(\?|#|&)/, ''); - - if (!str) { - return {}; - } - - return str.split('&').reduce(function (ret, param) { - var parts = param.replace(/\+/g, ' ').split('='); - // Firefox (pre 40) decodes `%3D` to `=` - // https://github.com/sindresorhus/query-string/pull/37 - var key = parts.shift(); - var val = parts.length > 0 ? parts.join('=') : undefined; - - key = decodeURIComponent(key); - - // missing `=` should be `null`: - // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters - val = val === undefined ? null : decodeURIComponent(val); - - if (!ret.hasOwnProperty(key)) { - ret[key] = val; - } else if (Array.isArray(ret[key])) { - ret[key].push(val); - } else { - ret[key] = [ret[key], val]; - } - - return ret; - }, {}); -}; - -exports.stringify = function (obj) { - return obj ? Object.keys(obj).sort().map(function (key) { - var val = obj[key]; - - if (val === undefined) { - return ''; - } - - if (val === null) { - return key; - } - - if (Array.isArray(val)) { - return val.slice().sort().map(function (val2) { - return strictUriEncode(key) + '=' + strictUriEncode(val2); - }).join('&'); - } - - return strictUriEncode(key) + '=' + strictUriEncode(val); - }).filter(function (x) { - return x.length > 0; - }).join('&') : ''; -}; - - -/***/ }), -/* 237 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = __webpack_require__(251); - - -/***/ }), -/* 238 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ARIADOMPropertyConfig = { - Properties: { - // Global States and Properties - 'aria-current': 0, // state - 'aria-details': 0, - 'aria-disabled': 0, // state - 'aria-hidden': 0, // state - 'aria-invalid': 0, // state - 'aria-keyshortcuts': 0, - 'aria-label': 0, - 'aria-roledescription': 0, - // Widget Attributes - 'aria-autocomplete': 0, - 'aria-checked': 0, - 'aria-expanded': 0, - 'aria-haspopup': 0, - 'aria-level': 0, - 'aria-modal': 0, - 'aria-multiline': 0, - 'aria-multiselectable': 0, - 'aria-orientation': 0, - 'aria-placeholder': 0, - 'aria-pressed': 0, - 'aria-readonly': 0, - 'aria-required': 0, - 'aria-selected': 0, - 'aria-sort': 0, - 'aria-valuemax': 0, - 'aria-valuemin': 0, - 'aria-valuenow': 0, - 'aria-valuetext': 0, - // Live Region Attributes - 'aria-atomic': 0, - 'aria-busy': 0, - 'aria-live': 0, - 'aria-relevant': 0, - // Drag-and-Drop Attributes - 'aria-dropeffect': 0, - 'aria-grabbed': 0, - // Relationship Attributes - 'aria-activedescendant': 0, - 'aria-colcount': 0, - 'aria-colindex': 0, - 'aria-colspan': 0, - 'aria-controls': 0, - 'aria-describedby': 0, - 'aria-errormessage': 0, - 'aria-flowto': 0, - 'aria-labelledby': 0, - 'aria-owns': 0, - 'aria-posinset': 0, - 'aria-rowcount': 0, - 'aria-rowindex': 0, - 'aria-rowspan': 0, - 'aria-setsize': 0 - }, - DOMAttributeNames: {}, - DOMPropertyNames: {} -}; - -module.exports = ARIADOMPropertyConfig; - -/***/ }), -/* 239 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactDOMComponentTree = __webpack_require__(7); - -var focusNode = __webpack_require__(73); - -var AutoFocusUtils = { - focusDOMComponent: function () { - focusNode(ReactDOMComponentTree.getNodeFromInstance(this)); - } -}; - -module.exports = AutoFocusUtils; - -/***/ }), -/* 240 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var EventPropagators = __webpack_require__(31); -var ExecutionEnvironment = __webpack_require__(8); -var FallbackCompositionState = __webpack_require__(246); -var SyntheticCompositionEvent = __webpack_require__(289); -var SyntheticInputEvent = __webpack_require__(292); - -var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space -var START_KEYCODE = 229; - -var canUseCompositionEvent = ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window; - -var documentMode = null; -if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { - documentMode = document.documentMode; -} - -// Webkit offers a very useful `textInput` event that can be used to -// directly represent `beforeInput`. The IE `textinput` event is not as -// useful, so we don't use it. -var canUseTextInputEvent = ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode && !isPresto(); - -// In IE9+, we have access to composition events, but the data supplied -// by the native compositionend event may be incorrect. Japanese ideographic -// spaces, for instance (\u3000) are not recorded correctly. -var useFallbackCompositionData = ExecutionEnvironment.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); - -/** - * Opera <= 12 includes TextEvent in window, but does not fire - * text input events. Rely on keypress instead. - */ -function isPresto() { - var opera = window.opera; - return typeof opera === 'object' && typeof opera.version === 'function' && parseInt(opera.version(), 10) <= 12; -} - -var SPACEBAR_CODE = 32; -var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); - -// Events and their corresponding property names. -var eventTypes = { - beforeInput: { - phasedRegistrationNames: { - bubbled: 'onBeforeInput', - captured: 'onBeforeInputCapture' - }, - dependencies: ['topCompositionEnd', 'topKeyPress', 'topTextInput', 'topPaste'] - }, - compositionEnd: { - phasedRegistrationNames: { - bubbled: 'onCompositionEnd', - captured: 'onCompositionEndCapture' - }, - dependencies: ['topBlur', 'topCompositionEnd', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown'] - }, - compositionStart: { - phasedRegistrationNames: { - bubbled: 'onCompositionStart', - captured: 'onCompositionStartCapture' - }, - dependencies: ['topBlur', 'topCompositionStart', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown'] - }, - compositionUpdate: { - phasedRegistrationNames: { - bubbled: 'onCompositionUpdate', - captured: 'onCompositionUpdateCapture' - }, - dependencies: ['topBlur', 'topCompositionUpdate', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown'] - } -}; - -// Track whether we've ever handled a keypress on the space key. -var hasSpaceKeypress = false; - -/** - * Return whether a native keypress event is assumed to be a command. - * This is required because Firefox fires `keypress` events for key commands - * (cut, copy, select-all, etc.) even though no character is inserted. - */ -function isKeypressCommand(nativeEvent) { - return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && - // ctrlKey && altKey is equivalent to AltGr, and is not a command. - !(nativeEvent.ctrlKey && nativeEvent.altKey); -} - -/** - * Translate native top level events into event types. - * - * @param {string} topLevelType - * @return {object} - */ -function getCompositionEventType(topLevelType) { - switch (topLevelType) { - case 'topCompositionStart': - return eventTypes.compositionStart; - case 'topCompositionEnd': - return eventTypes.compositionEnd; - case 'topCompositionUpdate': - return eventTypes.compositionUpdate; - } -} - -/** - * Does our fallback best-guess model think this event signifies that - * composition has begun? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackCompositionStart(topLevelType, nativeEvent) { - return topLevelType === 'topKeyDown' && nativeEvent.keyCode === START_KEYCODE; -} - -/** - * Does our fallback mode think that this event is the end of composition? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackCompositionEnd(topLevelType, nativeEvent) { - switch (topLevelType) { - case 'topKeyUp': - // Command keys insert or clear IME input. - return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1; - case 'topKeyDown': - // Expect IME keyCode on each keydown. If we get any other - // code we must have exited earlier. - return nativeEvent.keyCode !== START_KEYCODE; - case 'topKeyPress': - case 'topMouseDown': - case 'topBlur': - // Events are not possible without cancelling IME. - return true; - default: - return false; - } -} - -/** - * Google Input Tools provides composition data via a CustomEvent, - * with the `data` property populated in the `detail` object. If this - * is available on the event object, use it. If not, this is a plain - * composition event and we have nothing special to extract. - * - * @param {object} nativeEvent - * @return {?string} - */ -function getDataFromCustomEvent(nativeEvent) { - var detail = nativeEvent.detail; - if (typeof detail === 'object' && 'data' in detail) { - return detail.data; - } - return null; -} - -// Track the current IME composition fallback object, if any. -var currentComposition = null; - -/** - * @return {?object} A SyntheticCompositionEvent. - */ -function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var eventType; - var fallbackData; - - if (canUseCompositionEvent) { - eventType = getCompositionEventType(topLevelType); - } else if (!currentComposition) { - if (isFallbackCompositionStart(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionStart; - } - } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionEnd; - } - - if (!eventType) { - return null; - } - - if (useFallbackCompositionData) { - // The current composition is stored statically and must not be - // overwritten while composition continues. - if (!currentComposition && eventType === eventTypes.compositionStart) { - currentComposition = FallbackCompositionState.getPooled(nativeEventTarget); - } else if (eventType === eventTypes.compositionEnd) { - if (currentComposition) { - fallbackData = currentComposition.getData(); - } - } - } - - var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget); - - if (fallbackData) { - // Inject data generated from fallback path into the synthetic event. - // This matches the property of native CompositionEventInterface. - event.data = fallbackData; - } else { - var customData = getDataFromCustomEvent(nativeEvent); - if (customData !== null) { - event.data = customData; - } - } - - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; -} - -/** - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} nativeEvent Native browser event. - * @return {?string} The string corresponding to this `beforeInput` event. - */ -function getNativeBeforeInputChars(topLevelType, nativeEvent) { - switch (topLevelType) { - case 'topCompositionEnd': - return getDataFromCustomEvent(nativeEvent); - case 'topKeyPress': - /** - * If native `textInput` events are available, our goal is to make - * use of them. However, there is a special case: the spacebar key. - * In Webkit, preventing default on a spacebar `textInput` event - * cancels character insertion, but it *also* causes the browser - * to fall back to its default spacebar behavior of scrolling the - * page. - * - * Tracking at: - * https://code.google.com/p/chromium/issues/detail?id=355103 - * - * To avoid this issue, use the keypress event as if no `textInput` - * event is available. - */ - var which = nativeEvent.which; - if (which !== SPACEBAR_CODE) { - return null; - } - - hasSpaceKeypress = true; - return SPACEBAR_CHAR; - - case 'topTextInput': - // Record the characters to be added to the DOM. - var chars = nativeEvent.data; - - // If it's a spacebar character, assume that we have already handled - // it at the keypress level and bail immediately. Android Chrome - // doesn't give us keycodes, so we need to blacklist it. - if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { - return null; - } - - return chars; - - default: - // For other native event types, do nothing. - return null; - } -} - -/** - * For browsers that do not provide the `textInput` event, extract the - * appropriate string to use for SyntheticInputEvent. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} nativeEvent Native browser event. - * @return {?string} The fallback string for this `beforeInput` event. - */ -function getFallbackBeforeInputChars(topLevelType, nativeEvent) { - // If we are currently composing (IME) and using a fallback to do so, - // try to extract the composed characters from the fallback object. - // If composition event is available, we extract a string only at - // compositionevent, otherwise extract it at fallback events. - if (currentComposition) { - if (topLevelType === 'topCompositionEnd' || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) { - var chars = currentComposition.getData(); - FallbackCompositionState.release(currentComposition); - currentComposition = null; - return chars; - } - return null; - } - - switch (topLevelType) { - case 'topPaste': - // If a paste event occurs after a keypress, throw out the input - // chars. Paste events should not lead to BeforeInput events. - return null; - case 'topKeyPress': - /** - * As of v27, Firefox may fire keypress events even when no character - * will be inserted. A few possibilities: - * - * - `which` is `0`. Arrow keys, Esc key, etc. - * - * - `which` is the pressed key code, but no char is available. - * Ex: 'AltGr + d` in Polish. There is no modified character for - * this key combination and no character is inserted into the - * document, but FF fires the keypress for char code `100` anyway. - * No `input` event will occur. - * - * - `which` is the pressed key code, but a command combination is - * being used. Ex: `Cmd+C`. No character is inserted, and no - * `input` event will occur. - */ - if (nativeEvent.which && !isKeypressCommand(nativeEvent)) { - return String.fromCharCode(nativeEvent.which); - } - return null; - case 'topCompositionEnd': - return useFallbackCompositionData ? null : nativeEvent.data; - default: - return null; - } -} - -/** - * Extract a SyntheticInputEvent for `beforeInput`, based on either native - * `textInput` or fallback behavior. - * - * @return {?object} A SyntheticInputEvent. - */ -function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var chars; - - if (canUseTextInputEvent) { - chars = getNativeBeforeInputChars(topLevelType, nativeEvent); - } else { - chars = getFallbackBeforeInputChars(topLevelType, nativeEvent); - } - - // If no characters are being inserted, no BeforeInput event should - // be fired. - if (!chars) { - return null; - } - - var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget); - - event.data = chars; - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; -} - -/** - * Create an `onBeforeInput` event to match - * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. - * - * This event plugin is based on the native `textInput` event - * available in Chrome, Safari, Opera, and IE. This event fires after - * `onKeyPress` and `onCompositionEnd`, but before `onInput`. - * - * `beforeInput` is spec'd but not implemented in any browsers, and - * the `input` event does not provide any useful information about what has - * actually been added, contrary to the spec. Thus, `textInput` is the best - * available event to identify the characters that have actually been inserted - * into the target node. - * - * This plugin is also responsible for emitting `composition` events, thus - * allowing us to share composition fallback code for both `beforeInput` and - * `composition` event types. - */ -var BeforeInputEventPlugin = { - - eventTypes: eventTypes, - - extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - return [extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget), extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget)]; - } -}; - -module.exports = BeforeInputEventPlugin; - -/***/ }), -/* 241 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var CSSProperty = __webpack_require__(78); -var ExecutionEnvironment = __webpack_require__(8); -var ReactInstrumentation = __webpack_require__(10); - -var camelizeStyleName = __webpack_require__(215); -var dangerousStyleValue = __webpack_require__(299); -var hyphenateStyleName = __webpack_require__(222); -var memoizeStringOnly = __webpack_require__(225); -var warning = __webpack_require__(3); - -var processStyleName = memoizeStringOnly(function (styleName) { - return hyphenateStyleName(styleName); -}); - -var hasShorthandPropertyBug = false; -var styleFloatAccessor = 'cssFloat'; -if (ExecutionEnvironment.canUseDOM) { - var tempStyle = document.createElement('div').style; - try { - // IE8 throws "Invalid argument." if resetting shorthand style properties. - tempStyle.font = ''; - } catch (e) { - hasShorthandPropertyBug = true; - } - // IE8 only supports accessing cssFloat (standard) as styleFloat - if (document.documentElement.style.cssFloat === undefined) { - styleFloatAccessor = 'styleFloat'; - } -} - -if (process.env.NODE_ENV !== 'production') { - // 'msTransform' is correct, but the other prefixes should be capitalized - var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; - - // style values shouldn't contain a semicolon - var badStyleValueWithSemicolonPattern = /;\s*$/; - - var warnedStyleNames = {}; - var warnedStyleValues = {}; - var warnedForNaNValue = false; - - var warnHyphenatedStyleName = function (name, owner) { - if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { - return; - } - - warnedStyleNames[name] = true; - process.env.NODE_ENV !== 'production' ? warning(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName(name), checkRenderMessage(owner)) : void 0; - }; - - var warnBadVendoredStyleName = function (name, owner) { - if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { - return; - } - - warnedStyleNames[name] = true; - process.env.NODE_ENV !== 'production' ? warning(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), checkRenderMessage(owner)) : void 0; - }; - - var warnStyleValueWithSemicolon = function (name, value, owner) { - if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { - return; - } - - warnedStyleValues[value] = true; - process.env.NODE_ENV !== 'production' ? warning(false, 'Style property values shouldn\'t contain a semicolon.%s ' + 'Try "%s: %s" instead.', checkRenderMessage(owner), name, value.replace(badStyleValueWithSemicolonPattern, '')) : void 0; - }; - - var warnStyleValueIsNaN = function (name, value, owner) { - if (warnedForNaNValue) { - return; - } - - warnedForNaNValue = true; - process.env.NODE_ENV !== 'production' ? warning(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, checkRenderMessage(owner)) : void 0; - }; - - var checkRenderMessage = function (owner) { - if (owner) { - var name = owner.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; - }; - - /** - * @param {string} name - * @param {*} value - * @param {ReactDOMComponent} component - */ - var warnValidStyle = function (name, value, component) { - var owner; - if (component) { - owner = component._currentElement._owner; - } - if (name.indexOf('-') > -1) { - warnHyphenatedStyleName(name, owner); - } else if (badVendoredStyleNamePattern.test(name)) { - warnBadVendoredStyleName(name, owner); - } else if (badStyleValueWithSemicolonPattern.test(value)) { - warnStyleValueWithSemicolon(name, value, owner); - } - - if (typeof value === 'number' && isNaN(value)) { - warnStyleValueIsNaN(name, value, owner); - } - }; -} - -/** - * Operations for dealing with CSS properties. - */ -var CSSPropertyOperations = { - - /** - * Serializes a mapping of style properties for use as inline styles: - * - * > createMarkupForStyles({width: '200px', height: 0}) - * "width:200px;height:0;" - * - * Undefined values are ignored so that declarative programming is easier. - * The result should be HTML-escaped before insertion into the DOM. - * - * @param {object} styles - * @param {ReactDOMComponent} component - * @return {?string} - */ - createMarkupForStyles: function (styles, component) { - var serialized = ''; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - var styleValue = styles[styleName]; - if (process.env.NODE_ENV !== 'production') { - warnValidStyle(styleName, styleValue, component); - } - if (styleValue != null) { - serialized += processStyleName(styleName) + ':'; - serialized += dangerousStyleValue(styleName, styleValue, component) + ';'; - } - } - return serialized || null; - }, - - /** - * Sets the value for multiple styles on a node. If a value is specified as - * '' (empty string), the corresponding style property will be unset. - * - * @param {DOMElement} node - * @param {object} styles - * @param {ReactDOMComponent} component - */ - setValueForStyles: function (node, styles, component) { - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: component._debugID, - type: 'update styles', - payload: styles - }); - } - - var style = node.style; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - if (process.env.NODE_ENV !== 'production') { - warnValidStyle(styleName, styles[styleName], component); - } - var styleValue = dangerousStyleValue(styleName, styles[styleName], component); - if (styleName === 'float' || styleName === 'cssFloat') { - styleName = styleFloatAccessor; - } - if (styleValue) { - style[styleName] = styleValue; - } else { - var expansion = hasShorthandPropertyBug && CSSProperty.shorthandPropertyExpansions[styleName]; - if (expansion) { - // Shorthand property that IE8 won't like unsetting, so unset each - // component to placate it - for (var individualStyleName in expansion) { - style[individualStyleName] = ''; - } - } else { - style[styleName] = ''; - } - } - } - } - -}; - -module.exports = CSSPropertyOperations; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 242 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var EventPluginHub = __webpack_require__(30); -var EventPropagators = __webpack_require__(31); -var ExecutionEnvironment = __webpack_require__(8); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactUpdates = __webpack_require__(14); -var SyntheticEvent = __webpack_require__(17); - -var getEventTarget = __webpack_require__(57); -var isEventSupported = __webpack_require__(58); -var isTextInputElement = __webpack_require__(96); - -var eventTypes = { - change: { - phasedRegistrationNames: { - bubbled: 'onChange', - captured: 'onChangeCapture' - }, - dependencies: ['topBlur', 'topChange', 'topClick', 'topFocus', 'topInput', 'topKeyDown', 'topKeyUp', 'topSelectionChange'] - } -}; - -/** - * For IE shims - */ -var activeElement = null; -var activeElementInst = null; -var activeElementValue = null; -var activeElementValueProp = null; - -/** - * SECTION: handle `change` event - */ -function shouldUseChangeEvent(elem) { - var nodeName = elem.nodeName && elem.nodeName.toLowerCase(); - return nodeName === 'select' || nodeName === 'input' && elem.type === 'file'; -} - -var doesChangeEventBubble = false; -if (ExecutionEnvironment.canUseDOM) { - // See `handleChange` comment below - doesChangeEventBubble = isEventSupported('change') && (!document.documentMode || document.documentMode > 8); -} - -function manualDispatchChangeEvent(nativeEvent) { - var event = SyntheticEvent.getPooled(eventTypes.change, activeElementInst, nativeEvent, getEventTarget(nativeEvent)); - EventPropagators.accumulateTwoPhaseDispatches(event); - - // If change and propertychange bubbled, we'd just bind to it like all the - // other events and have it go through ReactBrowserEventEmitter. Since it - // doesn't, we manually listen for the events and so we have to enqueue and - // process the abstract event manually. - // - // Batching is necessary here in order to ensure that all event handlers run - // before the next rerender (including event handlers attached to ancestor - // elements instead of directly on the input). Without this, controlled - // components don't work properly in conjunction with event bubbling because - // the component is rerendered and the value reverted before all the event - // handlers can run. See https://github.com/facebook/react/issues/708. - ReactUpdates.batchedUpdates(runEventInBatch, event); -} - -function runEventInBatch(event) { - EventPluginHub.enqueueEvents(event); - EventPluginHub.processEventQueue(false); -} - -function startWatchingForChangeEventIE8(target, targetInst) { - activeElement = target; - activeElementInst = targetInst; - activeElement.attachEvent('onchange', manualDispatchChangeEvent); -} - -function stopWatchingForChangeEventIE8() { - if (!activeElement) { - return; - } - activeElement.detachEvent('onchange', manualDispatchChangeEvent); - activeElement = null; - activeElementInst = null; -} - -function getTargetInstForChangeEvent(topLevelType, targetInst) { - if (topLevelType === 'topChange') { - return targetInst; - } -} -function handleEventsForChangeEventIE8(topLevelType, target, targetInst) { - if (topLevelType === 'topFocus') { - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForChangeEventIE8(); - startWatchingForChangeEventIE8(target, targetInst); - } else if (topLevelType === 'topBlur') { - stopWatchingForChangeEventIE8(); - } -} - -/** - * SECTION: handle `input` event - */ -var isInputEventSupported = false; -if (ExecutionEnvironment.canUseDOM) { - // IE9 claims to support the input event but fails to trigger it when - // deleting text, so we ignore its input events. - // IE10+ fire input events to often, such when a placeholder - // changes or when an input with a placeholder is focused. - isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 11); -} - -/** - * (For IE <=11) Replacement getter/setter for the `value` property that gets - * set on the active element. - */ -var newValueProp = { - get: function () { - return activeElementValueProp.get.call(this); - }, - set: function (val) { - // Cast to a string so we can do equality checks. - activeElementValue = '' + val; - activeElementValueProp.set.call(this, val); - } -}; - -/** - * (For IE <=11) Starts tracking propertychange events on the passed-in element - * and override the value property so that we can distinguish user events from - * value changes in JS. - */ -function startWatchingForValueChange(target, targetInst) { - activeElement = target; - activeElementInst = targetInst; - activeElementValue = target.value; - activeElementValueProp = Object.getOwnPropertyDescriptor(target.constructor.prototype, 'value'); - - // Not guarded in a canDefineProperty check: IE8 supports defineProperty only - // on DOM elements - Object.defineProperty(activeElement, 'value', newValueProp); - if (activeElement.attachEvent) { - activeElement.attachEvent('onpropertychange', handlePropertyChange); - } else { - activeElement.addEventListener('propertychange', handlePropertyChange, false); - } -} - -/** - * (For IE <=11) Removes the event listeners from the currently-tracked element, - * if any exists. - */ -function stopWatchingForValueChange() { - if (!activeElement) { - return; - } - - // delete restores the original property definition - delete activeElement.value; - - if (activeElement.detachEvent) { - activeElement.detachEvent('onpropertychange', handlePropertyChange); - } else { - activeElement.removeEventListener('propertychange', handlePropertyChange, false); - } - - activeElement = null; - activeElementInst = null; - activeElementValue = null; - activeElementValueProp = null; -} - -/** - * (For IE <=11) Handles a propertychange event, sending a `change` event if - * the value of the active element has changed. - */ -function handlePropertyChange(nativeEvent) { - if (nativeEvent.propertyName !== 'value') { - return; - } - var value = nativeEvent.srcElement.value; - if (value === activeElementValue) { - return; - } - activeElementValue = value; - - manualDispatchChangeEvent(nativeEvent); -} - -/** - * If a `change` event should be fired, returns the target's ID. - */ -function getTargetInstForInputEvent(topLevelType, targetInst) { - if (topLevelType === 'topInput') { - // In modern browsers (i.e., not IE8 or IE9), the input event is exactly - // what we want so fall through here and trigger an abstract event - return targetInst; - } -} - -function handleEventsForInputEventIE(topLevelType, target, targetInst) { - if (topLevelType === 'topFocus') { - // In IE8, we can capture almost all .value changes by adding a - // propertychange handler and looking for events with propertyName - // equal to 'value' - // In IE9-11, propertychange fires for most input events but is buggy and - // doesn't fire when text is deleted, but conveniently, selectionchange - // appears to fire in all of the remaining cases so we catch those and - // forward the event if the value has changed - // In either case, we don't want to call the event handler if the value - // is changed from JS so we redefine a setter for `.value` that updates - // our activeElementValue variable, allowing us to ignore those changes - // - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForValueChange(); - startWatchingForValueChange(target, targetInst); - } else if (topLevelType === 'topBlur') { - stopWatchingForValueChange(); - } -} - -// For IE8 and IE9. -function getTargetInstForInputEventIE(topLevelType, targetInst) { - if (topLevelType === 'topSelectionChange' || topLevelType === 'topKeyUp' || topLevelType === 'topKeyDown') { - // On the selectionchange event, the target is just document which isn't - // helpful for us so just check activeElement instead. - // - // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire - // propertychange on the first input event after setting `value` from a - // script and fires only keydown, keypress, keyup. Catching keyup usually - // gets it and catching keydown lets us fire an event for the first - // keystroke if user does a key repeat (it'll be a little delayed: right - // before the second keystroke). Other input methods (e.g., paste) seem to - // fire selectionchange normally. - if (activeElement && activeElement.value !== activeElementValue) { - activeElementValue = activeElement.value; - return activeElementInst; - } - } -} - -/** - * SECTION: handle `click` event - */ -function shouldUseClickEvent(elem) { - // Use the `click` event to detect changes to checkbox and radio inputs. - // This approach works across all browsers, whereas `change` does not fire - // until `blur` in IE8. - return elem.nodeName && elem.nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio'); -} - -function getTargetInstForClickEvent(topLevelType, targetInst) { - if (topLevelType === 'topClick') { - return targetInst; - } -} - -/** - * This plugin creates an `onChange` event that normalizes change events - * across form elements. This event fires at a time when it's possible to - * change the element's value without seeing a flicker. - * - * Supported elements are: - * - input (see `isTextInputElement`) - * - textarea - * - select - */ -var ChangeEventPlugin = { - - eventTypes: eventTypes, - - extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var targetNode = targetInst ? ReactDOMComponentTree.getNodeFromInstance(targetInst) : window; - - var getTargetInstFunc, handleEventFunc; - if (shouldUseChangeEvent(targetNode)) { - if (doesChangeEventBubble) { - getTargetInstFunc = getTargetInstForChangeEvent; - } else { - handleEventFunc = handleEventsForChangeEventIE8; - } - } else if (isTextInputElement(targetNode)) { - if (isInputEventSupported) { - getTargetInstFunc = getTargetInstForInputEvent; - } else { - getTargetInstFunc = getTargetInstForInputEventIE; - handleEventFunc = handleEventsForInputEventIE; - } - } else if (shouldUseClickEvent(targetNode)) { - getTargetInstFunc = getTargetInstForClickEvent; - } - - if (getTargetInstFunc) { - var inst = getTargetInstFunc(topLevelType, targetInst); - if (inst) { - var event = SyntheticEvent.getPooled(eventTypes.change, inst, nativeEvent, nativeEventTarget); - event.type = 'change'; - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } - } - - if (handleEventFunc) { - handleEventFunc(topLevelType, targetNode, targetInst); - } - } - -}; - -module.exports = ChangeEventPlugin; - -/***/ }), -/* 243 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var DOMLazyTree = __webpack_require__(25); -var ExecutionEnvironment = __webpack_require__(8); - -var createNodesFromMarkup = __webpack_require__(218); -var emptyFunction = __webpack_require__(12); -var invariant = __webpack_require__(2); - -var Danger = { - - /** - * Replaces a node with a string of markup at its current position within its - * parent. The markup must render into a single root node. - * - * @param {DOMElement} oldChild Child node to replace. - * @param {string} markup Markup to render in place of the child node. - * @internal - */ - dangerouslyReplaceNodeWithMarkup: function (oldChild, markup) { - !ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a worker thread. Make sure `window` and `document` are available globally before requiring React when unit testing or use ReactDOMServer.renderToString() for server rendering.') : _prodInvariant('56') : void 0; - !markup ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : _prodInvariant('57') : void 0; - !(oldChild.nodeName !== 'HTML') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the <html> node. This is because browser quirks make this unreliable and/or slow. If you want to render to the root you must use server rendering. See ReactDOMServer.renderToString().') : _prodInvariant('58') : void 0; - - if (typeof markup === 'string') { - var newChild = createNodesFromMarkup(markup, emptyFunction)[0]; - oldChild.parentNode.replaceChild(newChild, oldChild); - } else { - DOMLazyTree.replaceChildWithTree(oldChild, markup); - } - } - -}; - -module.exports = Danger; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 244 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * Module that is injectable into `EventPluginHub`, that specifies a - * deterministic ordering of `EventPlugin`s. A convenient way to reason about - * plugins, without having to package every one of them. This is better than - * having plugins be ordered in the same order that they are injected because - * that ordering would be influenced by the packaging order. - * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that - * preventing default on events is convenient in `SimpleEventPlugin` handlers. - */ - -var DefaultEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'TapEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin']; - -module.exports = DefaultEventPluginOrder; - -/***/ }), -/* 245 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var EventPropagators = __webpack_require__(31); -var ReactDOMComponentTree = __webpack_require__(7); -var SyntheticMouseEvent = __webpack_require__(37); - -var eventTypes = { - mouseEnter: { - registrationName: 'onMouseEnter', - dependencies: ['topMouseOut', 'topMouseOver'] - }, - mouseLeave: { - registrationName: 'onMouseLeave', - dependencies: ['topMouseOut', 'topMouseOver'] - } -}; - -var EnterLeaveEventPlugin = { - - eventTypes: eventTypes, - - /** - * For almost every interaction we care about, there will be both a top-level - * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that - * we do not extract duplicate events. However, moving the mouse into the - * browser from outside will not fire a `mouseout` event. In this case, we use - * the `mouseover` top-level event. - */ - extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - if (topLevelType === 'topMouseOver' && (nativeEvent.relatedTarget || nativeEvent.fromElement)) { - return null; - } - if (topLevelType !== 'topMouseOut' && topLevelType !== 'topMouseOver') { - // Must not be a mouse in or mouse out - ignoring. - return null; - } - - var win; - if (nativeEventTarget.window === nativeEventTarget) { - // `nativeEventTarget` is probably a window object. - win = nativeEventTarget; - } else { - // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. - var doc = nativeEventTarget.ownerDocument; - if (doc) { - win = doc.defaultView || doc.parentWindow; - } else { - win = window; - } - } - - var from; - var to; - if (topLevelType === 'topMouseOut') { - from = targetInst; - var related = nativeEvent.relatedTarget || nativeEvent.toElement; - to = related ? ReactDOMComponentTree.getClosestInstanceFromNode(related) : null; - } else { - // Moving to a node from outside the window. - from = null; - to = targetInst; - } - - if (from === to) { - // Nothing pertains to our managed components. - return null; - } - - var fromNode = from == null ? win : ReactDOMComponentTree.getNodeFromInstance(from); - var toNode = to == null ? win : ReactDOMComponentTree.getNodeFromInstance(to); - - var leave = SyntheticMouseEvent.getPooled(eventTypes.mouseLeave, from, nativeEvent, nativeEventTarget); - leave.type = 'mouseleave'; - leave.target = fromNode; - leave.relatedTarget = toNode; - - var enter = SyntheticMouseEvent.getPooled(eventTypes.mouseEnter, to, nativeEvent, nativeEventTarget); - enter.type = 'mouseenter'; - enter.target = toNode; - enter.relatedTarget = fromNode; - - EventPropagators.accumulateEnterLeaveDispatches(leave, enter, from, to); - - return [leave, enter]; - } - -}; - -module.exports = EnterLeaveEventPlugin; - -/***/ }), -/* 246 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var PooledClass = __webpack_require__(20); - -var getTextContentAccessor = __webpack_require__(94); - -/** - * This helper class stores information about text content of a target node, - * allowing comparison of content before and after a given event. - * - * Identify the node where selection currently begins, then observe - * both its text content and its current position in the DOM. Since the - * browser may natively replace the target node during composition, we can - * use its position to find its replacement. - * - * @param {DOMEventTarget} root - */ -function FallbackCompositionState(root) { - this._root = root; - this._startText = this.getText(); - this._fallbackText = null; -} - -_assign(FallbackCompositionState.prototype, { - destructor: function () { - this._root = null; - this._startText = null; - this._fallbackText = null; - }, - - /** - * Get current text of input. - * - * @return {string} - */ - getText: function () { - if ('value' in this._root) { - return this._root.value; - } - return this._root[getTextContentAccessor()]; - }, - - /** - * Determine the differing substring between the initially stored - * text content and the current content. - * - * @return {string} - */ - getData: function () { - if (this._fallbackText) { - return this._fallbackText; - } - - var start; - var startValue = this._startText; - var startLength = startValue.length; - var end; - var endValue = this.getText(); - var endLength = endValue.length; - - for (start = 0; start < startLength; start++) { - if (startValue[start] !== endValue[start]) { - break; - } - } - - var minEnd = startLength - start; - for (end = 1; end <= minEnd; end++) { - if (startValue[startLength - end] !== endValue[endLength - end]) { - break; - } - } - - var sliceTail = end > 1 ? 1 - end : undefined; - this._fallbackText = endValue.slice(start, sliceTail); - return this._fallbackText; - } -}); - -PooledClass.addPoolingTo(FallbackCompositionState); - -module.exports = FallbackCompositionState; - -/***/ }), -/* 247 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMProperty = __webpack_require__(18); - -var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY; -var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE; -var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE; -var HAS_POSITIVE_NUMERIC_VALUE = DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE; -var HAS_OVERLOADED_BOOLEAN_VALUE = DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE; - -var HTMLDOMPropertyConfig = { - isCustomAttribute: RegExp.prototype.test.bind(new RegExp('^(data|aria)-[' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$')), - Properties: { - /** - * Standard Properties - */ - accept: 0, - acceptCharset: 0, - accessKey: 0, - action: 0, - allowFullScreen: HAS_BOOLEAN_VALUE, - allowTransparency: 0, - alt: 0, - // specifies target context for links with `preload` type - as: 0, - async: HAS_BOOLEAN_VALUE, - autoComplete: 0, - // autoFocus is polyfilled/normalized by AutoFocusUtils - // autoFocus: HAS_BOOLEAN_VALUE, - autoPlay: HAS_BOOLEAN_VALUE, - capture: HAS_BOOLEAN_VALUE, - cellPadding: 0, - cellSpacing: 0, - charSet: 0, - challenge: 0, - checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - cite: 0, - classID: 0, - className: 0, - cols: HAS_POSITIVE_NUMERIC_VALUE, - colSpan: 0, - content: 0, - contentEditable: 0, - contextMenu: 0, - controls: HAS_BOOLEAN_VALUE, - coords: 0, - crossOrigin: 0, - data: 0, // For `<object />` acts as `src`. - dateTime: 0, - 'default': HAS_BOOLEAN_VALUE, - defer: HAS_BOOLEAN_VALUE, - dir: 0, - disabled: HAS_BOOLEAN_VALUE, - download: HAS_OVERLOADED_BOOLEAN_VALUE, - draggable: 0, - encType: 0, - form: 0, - formAction: 0, - formEncType: 0, - formMethod: 0, - formNoValidate: HAS_BOOLEAN_VALUE, - formTarget: 0, - frameBorder: 0, - headers: 0, - height: 0, - hidden: HAS_BOOLEAN_VALUE, - high: 0, - href: 0, - hrefLang: 0, - htmlFor: 0, - httpEquiv: 0, - icon: 0, - id: 0, - inputMode: 0, - integrity: 0, - is: 0, - keyParams: 0, - keyType: 0, - kind: 0, - label: 0, - lang: 0, - list: 0, - loop: HAS_BOOLEAN_VALUE, - low: 0, - manifest: 0, - marginHeight: 0, - marginWidth: 0, - max: 0, - maxLength: 0, - media: 0, - mediaGroup: 0, - method: 0, - min: 0, - minLength: 0, - // Caution; `option.selected` is not updated if `select.multiple` is - // disabled with `removeAttribute`. - multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - name: 0, - nonce: 0, - noValidate: HAS_BOOLEAN_VALUE, - open: HAS_BOOLEAN_VALUE, - optimum: 0, - pattern: 0, - placeholder: 0, - playsInline: HAS_BOOLEAN_VALUE, - poster: 0, - preload: 0, - profile: 0, - radioGroup: 0, - readOnly: HAS_BOOLEAN_VALUE, - referrerPolicy: 0, - rel: 0, - required: HAS_BOOLEAN_VALUE, - reversed: HAS_BOOLEAN_VALUE, - role: 0, - rows: HAS_POSITIVE_NUMERIC_VALUE, - rowSpan: HAS_NUMERIC_VALUE, - sandbox: 0, - scope: 0, - scoped: HAS_BOOLEAN_VALUE, - scrolling: 0, - seamless: HAS_BOOLEAN_VALUE, - selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - shape: 0, - size: HAS_POSITIVE_NUMERIC_VALUE, - sizes: 0, - span: HAS_POSITIVE_NUMERIC_VALUE, - spellCheck: 0, - src: 0, - srcDoc: 0, - srcLang: 0, - srcSet: 0, - start: HAS_NUMERIC_VALUE, - step: 0, - style: 0, - summary: 0, - tabIndex: 0, - target: 0, - title: 0, - // Setting .type throws on non-<input> tags - type: 0, - useMap: 0, - value: 0, - width: 0, - wmode: 0, - wrap: 0, - - /** - * RDFa Properties - */ - about: 0, - datatype: 0, - inlist: 0, - prefix: 0, - // property is also supported for OpenGraph in meta tags. - property: 0, - resource: 0, - 'typeof': 0, - vocab: 0, - - /** - * Non-standard Properties - */ - // autoCapitalize and autoCorrect are supported in Mobile Safari for - // keyboard hints. - autoCapitalize: 0, - autoCorrect: 0, - // autoSave allows WebKit/Blink to persist values of input fields on page reloads - autoSave: 0, - // color is for Safari mask-icon link - color: 0, - // itemProp, itemScope, itemType are for - // Microdata support. See http://schema.org/docs/gs.html - itemProp: 0, - itemScope: HAS_BOOLEAN_VALUE, - itemType: 0, - // itemID and itemRef are for Microdata support as well but - // only specified in the WHATWG spec document. See - // https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api - itemID: 0, - itemRef: 0, - // results show looking glass icon and recent searches on input - // search fields in WebKit/Blink - results: 0, - // IE-only attribute that specifies security restrictions on an iframe - // as an alternative to the sandbox attribute on IE<10 - security: 0, - // IE-only attribute that controls focus behavior - unselectable: 0 - }, - DOMAttributeNames: { - acceptCharset: 'accept-charset', - className: 'class', - htmlFor: 'for', - httpEquiv: 'http-equiv' - }, - DOMPropertyNames: {} -}; - -module.exports = HTMLDOMPropertyConfig; - -/***/ }), -/* 248 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactReconciler = __webpack_require__(26); - -var instantiateReactComponent = __webpack_require__(95); -var KeyEscapeUtils = __webpack_require__(49); -var shouldUpdateReactComponent = __webpack_require__(59); -var traverseAllChildren = __webpack_require__(98); -var warning = __webpack_require__(3); - -var ReactComponentTreeHook; - -if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'test') { - // Temporary hack. - // Inline requires don't work well with Jest: - // https://github.com/facebook/react/issues/7240 - // Remove the inline requires when we don't need them anymore: - // https://github.com/facebook/react/pull/7178 - ReactComponentTreeHook = __webpack_require__(9); -} - -function instantiateChild(childInstances, child, name, selfDebugID) { - // We found a component instance. - var keyUnique = childInstances[name] === undefined; - if (process.env.NODE_ENV !== 'production') { - if (!ReactComponentTreeHook) { - ReactComponentTreeHook = __webpack_require__(9); - } - if (!keyUnique) { - process.env.NODE_ENV !== 'production' ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0; - } - } - if (child != null && keyUnique) { - childInstances[name] = instantiateReactComponent(child, true); - } -} - -/** - * ReactChildReconciler provides helpers for initializing or updating a set of - * children. Its output is suitable for passing it onto ReactMultiChild which - * does diffed reordering and insertion. - */ -var ReactChildReconciler = { - /** - * Generates a "mount image" for each of the supplied children. In the case - * of `ReactDOMComponent`, a mount image is a string of markup. - * - * @param {?object} nestedChildNodes Nested child maps. - * @return {?object} A set of child instances. - * @internal - */ - instantiateChildren: function (nestedChildNodes, transaction, context, selfDebugID // 0 in production and for roots - ) { - if (nestedChildNodes == null) { - return null; - } - var childInstances = {}; - - if (process.env.NODE_ENV !== 'production') { - traverseAllChildren(nestedChildNodes, function (childInsts, child, name) { - return instantiateChild(childInsts, child, name, selfDebugID); - }, childInstances); - } else { - traverseAllChildren(nestedChildNodes, instantiateChild, childInstances); - } - return childInstances; - }, - - /** - * Updates the rendered children and returns a new set of children. - * - * @param {?object} prevChildren Previously initialized set of children. - * @param {?object} nextChildren Flat child element maps. - * @param {ReactReconcileTransaction} transaction - * @param {object} context - * @return {?object} A new set of child instances. - * @internal - */ - updateChildren: function (prevChildren, nextChildren, mountImages, removedNodes, transaction, hostParent, hostContainerInfo, context, selfDebugID // 0 in production and for roots - ) { - // We currently don't have a way to track moves here but if we use iterators - // instead of for..in we can zip the iterators and check if an item has - // moved. - // TODO: If nothing has changed, return the prevChildren object so that we - // can quickly bailout if nothing has changed. - if (!nextChildren && !prevChildren) { - return; - } - var name; - var prevChild; - for (name in nextChildren) { - if (!nextChildren.hasOwnProperty(name)) { - continue; - } - prevChild = prevChildren && prevChildren[name]; - var prevElement = prevChild && prevChild._currentElement; - var nextElement = nextChildren[name]; - if (prevChild != null && shouldUpdateReactComponent(prevElement, nextElement)) { - ReactReconciler.receiveComponent(prevChild, nextElement, transaction, context); - nextChildren[name] = prevChild; - } else { - if (prevChild) { - removedNodes[name] = ReactReconciler.getHostNode(prevChild); - ReactReconciler.unmountComponent(prevChild, false); - } - // The child must be instantiated before it's mounted. - var nextChildInstance = instantiateReactComponent(nextElement, true); - nextChildren[name] = nextChildInstance; - // Creating mount image now ensures refs are resolved in right order - // (see https://github.com/facebook/react/pull/7101 for explanation). - var nextChildMountImage = ReactReconciler.mountComponent(nextChildInstance, transaction, hostParent, hostContainerInfo, context, selfDebugID); - mountImages.push(nextChildMountImage); - } - } - // Unmount children that are no longer present. - for (name in prevChildren) { - if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) { - prevChild = prevChildren[name]; - removedNodes[name] = ReactReconciler.getHostNode(prevChild); - ReactReconciler.unmountComponent(prevChild, false); - } - } - }, - - /** - * Unmounts all rendered children. This should be used to clean up children - * when this component is unmounted. - * - * @param {?object} renderedChildren Previously initialized set of children. - * @internal - */ - unmountChildren: function (renderedChildren, safely) { - for (var name in renderedChildren) { - if (renderedChildren.hasOwnProperty(name)) { - var renderedChild = renderedChildren[name]; - ReactReconciler.unmountComponent(renderedChild, safely); - } - } - } - -}; - -module.exports = ReactChildReconciler; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 249 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMChildrenOperations = __webpack_require__(46); -var ReactDOMIDOperations = __webpack_require__(256); - -/** - * Abstracts away all functionality of the reconciler that requires knowledge of - * the browser context. TODO: These callers should be refactored to avoid the - * need for this injection. - */ -var ReactComponentBrowserEnvironment = { - - processChildrenUpdates: ReactDOMIDOperations.dangerouslyProcessChildrenUpdates, - - replaceNodeWithMarkup: DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup - -}; - -module.exports = ReactComponentBrowserEnvironment; - -/***/ }), -/* 250 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var React = __webpack_require__(27); -var ReactComponentEnvironment = __webpack_require__(51); -var ReactCurrentOwner = __webpack_require__(15); -var ReactErrorUtils = __webpack_require__(52); -var ReactInstanceMap = __webpack_require__(32); -var ReactInstrumentation = __webpack_require__(10); -var ReactNodeTypes = __webpack_require__(88); -var ReactReconciler = __webpack_require__(26); - -if (process.env.NODE_ENV !== 'production') { - var checkReactTypeSpec = __webpack_require__(298); -} - -var emptyObject = __webpack_require__(28); -var invariant = __webpack_require__(2); -var shallowEqual = __webpack_require__(42); -var shouldUpdateReactComponent = __webpack_require__(59); -var warning = __webpack_require__(3); - -var CompositeTypes = { - ImpureClass: 0, - PureClass: 1, - StatelessFunctional: 2 -}; - -function StatelessComponent(Component) {} -StatelessComponent.prototype.render = function () { - var Component = ReactInstanceMap.get(this)._currentElement.type; - var element = Component(this.props, this.context, this.updater); - warnIfInvalidElement(Component, element); - return element; -}; - -function warnIfInvalidElement(Component, element) { - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(element === null || element === false || React.isValidElement(element), '%s(...): A valid React element (or null) must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(!Component.childContextTypes, '%s(...): childContextTypes cannot be defined on a functional component.', Component.displayName || Component.name || 'Component') : void 0; - } -} - -function shouldConstruct(Component) { - return !!(Component.prototype && Component.prototype.isReactComponent); -} - -function isPureComponent(Component) { - return !!(Component.prototype && Component.prototype.isPureReactComponent); -} - -// Separated into a function to contain deoptimizations caused by try/finally. -function measureLifeCyclePerf(fn, debugID, timerType) { - if (debugID === 0) { - // Top-level wrappers (see ReactMount) and empty components (see - // ReactDOMEmptyComponent) are invisible to hooks and devtools. - // Both are implementation details that should go away in the future. - return fn(); - } - - ReactInstrumentation.debugTool.onBeginLifeCycleTimer(debugID, timerType); - try { - return fn(); - } finally { - ReactInstrumentation.debugTool.onEndLifeCycleTimer(debugID, timerType); - } -} - -/** - * ------------------ The Life-Cycle of a Composite Component ------------------ - * - * - constructor: Initialization of state. The instance is now retained. - * - componentWillMount - * - render - * - [children's constructors] - * - [children's componentWillMount and render] - * - [children's componentDidMount] - * - componentDidMount - * - * Update Phases: - * - componentWillReceiveProps (only called if parent updated) - * - shouldComponentUpdate - * - componentWillUpdate - * - render - * - [children's constructors or receive props phases] - * - componentDidUpdate - * - * - componentWillUnmount - * - [children's componentWillUnmount] - * - [children destroyed] - * - (destroyed): The instance is now blank, released by React and ready for GC. - * - * ----------------------------------------------------------------------------- - */ - -/** - * An incrementing ID assigned to each component when it is mounted. This is - * used to enforce the order in which `ReactUpdates` updates dirty components. - * - * @private - */ -var nextMountID = 1; - -/** - * @lends {ReactCompositeComponent.prototype} - */ -var ReactCompositeComponent = { - - /** - * Base constructor for all composite component. - * - * @param {ReactElement} element - * @final - * @internal - */ - construct: function (element) { - this._currentElement = element; - this._rootNodeID = 0; - this._compositeType = null; - this._instance = null; - this._hostParent = null; - this._hostContainerInfo = null; - - // See ReactUpdateQueue - this._updateBatchNumber = null; - this._pendingElement = null; - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - - this._renderedNodeType = null; - this._renderedComponent = null; - this._context = null; - this._mountOrder = 0; - this._topLevelWrapper = null; - - // See ReactUpdates and ReactUpdateQueue. - this._pendingCallbacks = null; - - // ComponentWillUnmount shall only be called once - this._calledComponentWillUnmount = false; - - if (process.env.NODE_ENV !== 'production') { - this._warnedAboutRefsInRender = false; - } - }, - - /** - * Initializes the component, renders markup, and registers event listeners. - * - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {?object} hostParent - * @param {?object} hostContainerInfo - * @param {?object} context - * @return {?string} Rendered markup to be inserted into the DOM. - * @final - * @internal - */ - mountComponent: function (transaction, hostParent, hostContainerInfo, context) { - var _this = this; - - this._context = context; - this._mountOrder = nextMountID++; - this._hostParent = hostParent; - this._hostContainerInfo = hostContainerInfo; - - var publicProps = this._currentElement.props; - var publicContext = this._processContext(context); - - var Component = this._currentElement.type; - - var updateQueue = transaction.getUpdateQueue(); - - // Initialize the public class - var doConstruct = shouldConstruct(Component); - var inst = this._constructComponent(doConstruct, publicProps, publicContext, updateQueue); - var renderedElement; - - // Support functional components - if (!doConstruct && (inst == null || inst.render == null)) { - renderedElement = inst; - warnIfInvalidElement(Component, renderedElement); - !(inst === null || inst === false || React.isValidElement(inst)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component') : _prodInvariant('105', Component.displayName || Component.name || 'Component') : void 0; - inst = new StatelessComponent(Component); - this._compositeType = CompositeTypes.StatelessFunctional; - } else { - if (isPureComponent(Component)) { - this._compositeType = CompositeTypes.PureClass; - } else { - this._compositeType = CompositeTypes.ImpureClass; - } - } - - if (process.env.NODE_ENV !== 'production') { - // This will throw later in _renderValidatedComponent, but add an early - // warning now to help debugging - if (inst.render == null) { - process.env.NODE_ENV !== 'production' ? warning(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', Component.displayName || Component.name || 'Component') : void 0; - } - - var propsMutated = inst.props !== publicProps; - var componentName = Component.displayName || Component.name || 'Component'; - - process.env.NODE_ENV !== 'production' ? warning(inst.props === undefined || !propsMutated, '%s(...): When calling super() in `%s`, make sure to pass ' + 'up the same props that your component\'s constructor was passed.', componentName, componentName) : void 0; - } - - // These should be set up in the constructor, but as a convenience for - // simpler class abstractions, we set them up after the fact. - inst.props = publicProps; - inst.context = publicContext; - inst.refs = emptyObject; - inst.updater = updateQueue; - - this._instance = inst; - - // Store a reference from the instance back to the internal representation - ReactInstanceMap.set(inst, this); - - if (process.env.NODE_ENV !== 'production') { - // Since plain JS classes are defined without any special initialization - // logic, we can not catch common errors early. Therefore, we have to - // catch them here, at initialization time, instead. - process.env.NODE_ENV !== 'production' ? warning(!inst.getInitialState || inst.getInitialState.isReactClassApproved || inst.state, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', this.getName() || 'a component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(!inst.getDefaultProps || inst.getDefaultProps.isReactClassApproved, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', this.getName() || 'a component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(!inst.propTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', this.getName() || 'a component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(!inst.contextTypes, 'contextTypes was defined as an instance property on %s. Use a ' + 'static property to define contextTypes instead.', this.getName() || 'a component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentShouldUpdate !== 'function', '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', this.getName() || 'A component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentDidUnmount !== 'function', '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', this.getName() || 'A component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentWillRecieveProps !== 'function', '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', this.getName() || 'A component') : void 0; - } - - var initialState = inst.state; - if (initialState === undefined) { - inst.state = initialState = null; - } - !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.state: must be set to an object or null', this.getName() || 'ReactCompositeComponent') : _prodInvariant('106', this.getName() || 'ReactCompositeComponent') : void 0; - - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - - var markup; - if (inst.unstable_handleError) { - markup = this.performInitialMountWithErrorHandling(renderedElement, hostParent, hostContainerInfo, transaction, context); - } else { - markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context); - } - - if (inst.componentDidMount) { - if (process.env.NODE_ENV !== 'production') { - transaction.getReactMountReady().enqueue(function () { - measureLifeCyclePerf(function () { - return inst.componentDidMount(); - }, _this._debugID, 'componentDidMount'); - }); - } else { - transaction.getReactMountReady().enqueue(inst.componentDidMount, inst); - } - } - - return markup; - }, - - _constructComponent: function (doConstruct, publicProps, publicContext, updateQueue) { - if (process.env.NODE_ENV !== 'production') { - ReactCurrentOwner.current = this; - try { - return this._constructComponentWithoutOwner(doConstruct, publicProps, publicContext, updateQueue); - } finally { - ReactCurrentOwner.current = null; - } - } else { - return this._constructComponentWithoutOwner(doConstruct, publicProps, publicContext, updateQueue); - } - }, - - _constructComponentWithoutOwner: function (doConstruct, publicProps, publicContext, updateQueue) { - var Component = this._currentElement.type; - - if (doConstruct) { - if (process.env.NODE_ENV !== 'production') { - return measureLifeCyclePerf(function () { - return new Component(publicProps, publicContext, updateQueue); - }, this._debugID, 'ctor'); - } else { - return new Component(publicProps, publicContext, updateQueue); - } - } - - // This can still be an instance in case of factory components - // but we'll count this as time spent rendering as the more common case. - if (process.env.NODE_ENV !== 'production') { - return measureLifeCyclePerf(function () { - return Component(publicProps, publicContext, updateQueue); - }, this._debugID, 'render'); - } else { - return Component(publicProps, publicContext, updateQueue); - } - }, - - performInitialMountWithErrorHandling: function (renderedElement, hostParent, hostContainerInfo, transaction, context) { - var markup; - var checkpoint = transaction.checkpoint(); - try { - markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context); - } catch (e) { - // Roll back to checkpoint, handle error (which may add items to the transaction), and take a new checkpoint - transaction.rollback(checkpoint); - this._instance.unstable_handleError(e); - if (this._pendingStateQueue) { - this._instance.state = this._processPendingState(this._instance.props, this._instance.context); - } - checkpoint = transaction.checkpoint(); - - this._renderedComponent.unmountComponent(true); - transaction.rollback(checkpoint); - - // Try again - we've informed the component about the error, so they can render an error message this time. - // If this throws again, the error will bubble up (and can be caught by a higher error boundary). - markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context); - } - return markup; - }, - - performInitialMount: function (renderedElement, hostParent, hostContainerInfo, transaction, context) { - var inst = this._instance; - - var debugID = 0; - if (process.env.NODE_ENV !== 'production') { - debugID = this._debugID; - } - - if (inst.componentWillMount) { - if (process.env.NODE_ENV !== 'production') { - measureLifeCyclePerf(function () { - return inst.componentWillMount(); - }, debugID, 'componentWillMount'); - } else { - inst.componentWillMount(); - } - // When mounting, calls to `setState` by `componentWillMount` will set - // `this._pendingStateQueue` without triggering a re-render. - if (this._pendingStateQueue) { - inst.state = this._processPendingState(inst.props, inst.context); - } - } - - // If not a stateless component, we now render - if (renderedElement === undefined) { - renderedElement = this._renderValidatedComponent(); - } - - var nodeType = ReactNodeTypes.getType(renderedElement); - this._renderedNodeType = nodeType; - var child = this._instantiateReactComponent(renderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */ - ); - this._renderedComponent = child; - - var markup = ReactReconciler.mountComponent(child, transaction, hostParent, hostContainerInfo, this._processChildContext(context), debugID); - - if (process.env.NODE_ENV !== 'production') { - if (debugID !== 0) { - var childDebugIDs = child._debugID !== 0 ? [child._debugID] : []; - ReactInstrumentation.debugTool.onSetChildren(debugID, childDebugIDs); - } - } - - return markup; - }, - - getHostNode: function () { - return ReactReconciler.getHostNode(this._renderedComponent); - }, - - /** - * Releases any resources allocated by `mountComponent`. - * - * @final - * @internal - */ - unmountComponent: function (safely) { - if (!this._renderedComponent) { - return; - } - - var inst = this._instance; - - if (inst.componentWillUnmount && !inst._calledComponentWillUnmount) { - inst._calledComponentWillUnmount = true; - - if (safely) { - var name = this.getName() + '.componentWillUnmount()'; - ReactErrorUtils.invokeGuardedCallback(name, inst.componentWillUnmount.bind(inst)); - } else { - if (process.env.NODE_ENV !== 'production') { - measureLifeCyclePerf(function () { - return inst.componentWillUnmount(); - }, this._debugID, 'componentWillUnmount'); - } else { - inst.componentWillUnmount(); - } - } - } - - if (this._renderedComponent) { - ReactReconciler.unmountComponent(this._renderedComponent, safely); - this._renderedNodeType = null; - this._renderedComponent = null; - this._instance = null; - } - - // Reset pending fields - // Even if this component is scheduled for another update in ReactUpdates, - // it would still be ignored because these fields are reset. - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - this._pendingCallbacks = null; - this._pendingElement = null; - - // These fields do not really need to be reset since this object is no - // longer accessible. - this._context = null; - this._rootNodeID = 0; - this._topLevelWrapper = null; - - // Delete the reference from the instance to this internal representation - // which allow the internals to be properly cleaned up even if the user - // leaks a reference to the public instance. - ReactInstanceMap.remove(inst); - - // Some existing components rely on inst.props even after they've been - // destroyed (in event handlers). - // TODO: inst.props = null; - // TODO: inst.state = null; - // TODO: inst.context = null; - }, - - /** - * Filters the context object to only contain keys specified in - * `contextTypes` - * - * @param {object} context - * @return {?object} - * @private - */ - _maskContext: function (context) { - var Component = this._currentElement.type; - var contextTypes = Component.contextTypes; - if (!contextTypes) { - return emptyObject; - } - var maskedContext = {}; - for (var contextName in contextTypes) { - maskedContext[contextName] = context[contextName]; - } - return maskedContext; - }, - - /** - * Filters the context object to only contain keys specified in - * `contextTypes`, and asserts that they are valid. - * - * @param {object} context - * @return {?object} - * @private - */ - _processContext: function (context) { - var maskedContext = this._maskContext(context); - if (process.env.NODE_ENV !== 'production') { - var Component = this._currentElement.type; - if (Component.contextTypes) { - this._checkContextTypes(Component.contextTypes, maskedContext, 'context'); - } - } - return maskedContext; - }, - - /** - * @param {object} currentContext - * @return {object} - * @private - */ - _processChildContext: function (currentContext) { - var Component = this._currentElement.type; - var inst = this._instance; - var childContext; - - if (inst.getChildContext) { - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onBeginProcessingChildContext(); - try { - childContext = inst.getChildContext(); - } finally { - ReactInstrumentation.debugTool.onEndProcessingChildContext(); - } - } else { - childContext = inst.getChildContext(); - } - } - - if (childContext) { - !(typeof Component.childContextTypes === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().', this.getName() || 'ReactCompositeComponent') : _prodInvariant('107', this.getName() || 'ReactCompositeComponent') : void 0; - if (process.env.NODE_ENV !== 'production') { - this._checkContextTypes(Component.childContextTypes, childContext, 'childContext'); - } - for (var name in childContext) { - !(name in Component.childContextTypes) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', this.getName() || 'ReactCompositeComponent', name) : _prodInvariant('108', this.getName() || 'ReactCompositeComponent', name) : void 0; - } - return _assign({}, currentContext, childContext); - } - return currentContext; - }, - - /** - * Assert that the context types are valid - * - * @param {object} typeSpecs Map of context field to a ReactPropType - * @param {object} values Runtime values that need to be type-checked - * @param {string} location e.g. "prop", "context", "child context" - * @private - */ - _checkContextTypes: function (typeSpecs, values, location) { - if (process.env.NODE_ENV !== 'production') { - checkReactTypeSpec(typeSpecs, values, location, this.getName(), null, this._debugID); - } - }, - - receiveComponent: function (nextElement, transaction, nextContext) { - var prevElement = this._currentElement; - var prevContext = this._context; - - this._pendingElement = null; - - this.updateComponent(transaction, prevElement, nextElement, prevContext, nextContext); - }, - - /** - * If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate` - * is set, update the component. - * - * @param {ReactReconcileTransaction} transaction - * @internal - */ - performUpdateIfNecessary: function (transaction) { - if (this._pendingElement != null) { - ReactReconciler.receiveComponent(this, this._pendingElement, transaction, this._context); - } else if (this._pendingStateQueue !== null || this._pendingForceUpdate) { - this.updateComponent(transaction, this._currentElement, this._currentElement, this._context, this._context); - } else { - this._updateBatchNumber = null; - } - }, - - /** - * Perform an update to a mounted component. The componentWillReceiveProps and - * shouldComponentUpdate methods are called, then (assuming the update isn't - * skipped) the remaining update lifecycle methods are called and the DOM - * representation is updated. - * - * By default, this implements React's rendering and reconciliation algorithm. - * Sophisticated clients may wish to override this. - * - * @param {ReactReconcileTransaction} transaction - * @param {ReactElement} prevParentElement - * @param {ReactElement} nextParentElement - * @internal - * @overridable - */ - updateComponent: function (transaction, prevParentElement, nextParentElement, prevUnmaskedContext, nextUnmaskedContext) { - var inst = this._instance; - !(inst != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Attempted to update component `%s` that has already been unmounted (or failed to mount).', this.getName() || 'ReactCompositeComponent') : _prodInvariant('136', this.getName() || 'ReactCompositeComponent') : void 0; - - var willReceive = false; - var nextContext; - - // Determine if the context has changed or not - if (this._context === nextUnmaskedContext) { - nextContext = inst.context; - } else { - nextContext = this._processContext(nextUnmaskedContext); - willReceive = true; - } - - var prevProps = prevParentElement.props; - var nextProps = nextParentElement.props; - - // Not a simple state update but a props update - if (prevParentElement !== nextParentElement) { - willReceive = true; - } - - // An update here will schedule an update but immediately set - // _pendingStateQueue which will ensure that any state updates gets - // immediately reconciled instead of waiting for the next batch. - if (willReceive && inst.componentWillReceiveProps) { - if (process.env.NODE_ENV !== 'production') { - measureLifeCyclePerf(function () { - return inst.componentWillReceiveProps(nextProps, nextContext); - }, this._debugID, 'componentWillReceiveProps'); - } else { - inst.componentWillReceiveProps(nextProps, nextContext); - } - } - - var nextState = this._processPendingState(nextProps, nextContext); - var shouldUpdate = true; - - if (!this._pendingForceUpdate) { - if (inst.shouldComponentUpdate) { - if (process.env.NODE_ENV !== 'production') { - shouldUpdate = measureLifeCyclePerf(function () { - return inst.shouldComponentUpdate(nextProps, nextState, nextContext); - }, this._debugID, 'shouldComponentUpdate'); - } else { - shouldUpdate = inst.shouldComponentUpdate(nextProps, nextState, nextContext); - } - } else { - if (this._compositeType === CompositeTypes.PureClass) { - shouldUpdate = !shallowEqual(prevProps, nextProps) || !shallowEqual(inst.state, nextState); - } - } - } - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(shouldUpdate !== undefined, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', this.getName() || 'ReactCompositeComponent') : void 0; - } - - this._updateBatchNumber = null; - if (shouldUpdate) { - this._pendingForceUpdate = false; - // Will set `this.props`, `this.state` and `this.context`. - this._performComponentUpdate(nextParentElement, nextProps, nextState, nextContext, transaction, nextUnmaskedContext); - } else { - // If it's determined that a component should not update, we still want - // to set props and state but we shortcut the rest of the update. - this._currentElement = nextParentElement; - this._context = nextUnmaskedContext; - inst.props = nextProps; - inst.state = nextState; - inst.context = nextContext; - } - }, - - _processPendingState: function (props, context) { - var inst = this._instance; - var queue = this._pendingStateQueue; - var replace = this._pendingReplaceState; - this._pendingReplaceState = false; - this._pendingStateQueue = null; - - if (!queue) { - return inst.state; - } - - if (replace && queue.length === 1) { - return queue[0]; - } - - var nextState = _assign({}, replace ? queue[0] : inst.state); - for (var i = replace ? 1 : 0; i < queue.length; i++) { - var partial = queue[i]; - _assign(nextState, typeof partial === 'function' ? partial.call(inst, nextState, props, context) : partial); - } - - return nextState; - }, - - /** - * Merges new props and state, notifies delegate methods of update and - * performs update. - * - * @param {ReactElement} nextElement Next element - * @param {object} nextProps Next public object to set as properties. - * @param {?object} nextState Next object to set as state. - * @param {?object} nextContext Next public object to set as context. - * @param {ReactReconcileTransaction} transaction - * @param {?object} unmaskedContext - * @private - */ - _performComponentUpdate: function (nextElement, nextProps, nextState, nextContext, transaction, unmaskedContext) { - var _this2 = this; - - var inst = this._instance; - - var hasComponentDidUpdate = Boolean(inst.componentDidUpdate); - var prevProps; - var prevState; - var prevContext; - if (hasComponentDidUpdate) { - prevProps = inst.props; - prevState = inst.state; - prevContext = inst.context; - } - - if (inst.componentWillUpdate) { - if (process.env.NODE_ENV !== 'production') { - measureLifeCyclePerf(function () { - return inst.componentWillUpdate(nextProps, nextState, nextContext); - }, this._debugID, 'componentWillUpdate'); - } else { - inst.componentWillUpdate(nextProps, nextState, nextContext); - } - } - - this._currentElement = nextElement; - this._context = unmaskedContext; - inst.props = nextProps; - inst.state = nextState; - inst.context = nextContext; - - this._updateRenderedComponent(transaction, unmaskedContext); - - if (hasComponentDidUpdate) { - if (process.env.NODE_ENV !== 'production') { - transaction.getReactMountReady().enqueue(function () { - measureLifeCyclePerf(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), _this2._debugID, 'componentDidUpdate'); - }); - } else { - transaction.getReactMountReady().enqueue(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), inst); - } - } - }, - - /** - * Call the component's `render` method and update the DOM accordingly. - * - * @param {ReactReconcileTransaction} transaction - * @internal - */ - _updateRenderedComponent: function (transaction, context) { - var prevComponentInstance = this._renderedComponent; - var prevRenderedElement = prevComponentInstance._currentElement; - var nextRenderedElement = this._renderValidatedComponent(); - - var debugID = 0; - if (process.env.NODE_ENV !== 'production') { - debugID = this._debugID; - } - - if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { - ReactReconciler.receiveComponent(prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context)); - } else { - var oldHostNode = ReactReconciler.getHostNode(prevComponentInstance); - ReactReconciler.unmountComponent(prevComponentInstance, false); - - var nodeType = ReactNodeTypes.getType(nextRenderedElement); - this._renderedNodeType = nodeType; - var child = this._instantiateReactComponent(nextRenderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */ - ); - this._renderedComponent = child; - - var nextMarkup = ReactReconciler.mountComponent(child, transaction, this._hostParent, this._hostContainerInfo, this._processChildContext(context), debugID); - - if (process.env.NODE_ENV !== 'production') { - if (debugID !== 0) { - var childDebugIDs = child._debugID !== 0 ? [child._debugID] : []; - ReactInstrumentation.debugTool.onSetChildren(debugID, childDebugIDs); - } - } - - this._replaceNodeWithMarkup(oldHostNode, nextMarkup, prevComponentInstance); - } - }, - - /** - * Overridden in shallow rendering. - * - * @protected - */ - _replaceNodeWithMarkup: function (oldHostNode, nextMarkup, prevInstance) { - ReactComponentEnvironment.replaceNodeWithMarkup(oldHostNode, nextMarkup, prevInstance); - }, - - /** - * @protected - */ - _renderValidatedComponentWithoutOwnerOrContext: function () { - var inst = this._instance; - var renderedElement; - - if (process.env.NODE_ENV !== 'production') { - renderedElement = measureLifeCyclePerf(function () { - return inst.render(); - }, this._debugID, 'render'); - } else { - renderedElement = inst.render(); - } - - if (process.env.NODE_ENV !== 'production') { - // We allow auto-mocks to proceed as if they're returning null. - if (renderedElement === undefined && inst.render._isMockFunction) { - // This is probably bad practice. Consider warning here and - // deprecating this convenience. - renderedElement = null; - } - } - - return renderedElement; - }, - - /** - * @private - */ - _renderValidatedComponent: function () { - var renderedElement; - if (process.env.NODE_ENV !== 'production' || this._compositeType !== CompositeTypes.StatelessFunctional) { - ReactCurrentOwner.current = this; - try { - renderedElement = this._renderValidatedComponentWithoutOwnerOrContext(); - } finally { - ReactCurrentOwner.current = null; - } - } else { - renderedElement = this._renderValidatedComponentWithoutOwnerOrContext(); - } - !( - // TODO: An `isValidNode` function would probably be more appropriate - renderedElement === null || renderedElement === false || React.isValidElement(renderedElement)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.', this.getName() || 'ReactCompositeComponent') : _prodInvariant('109', this.getName() || 'ReactCompositeComponent') : void 0; - - return renderedElement; - }, - - /** - * Lazily allocates the refs object and stores `component` as `ref`. - * - * @param {string} ref Reference name. - * @param {component} component Component to store as `ref`. - * @final - * @private - */ - attachRef: function (ref, component) { - var inst = this.getPublicInstance(); - !(inst != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Stateless function components cannot have refs.') : _prodInvariant('110') : void 0; - var publicComponentInstance = component.getPublicInstance(); - if (process.env.NODE_ENV !== 'production') { - var componentName = component && component.getName ? component.getName() : 'a component'; - process.env.NODE_ENV !== 'production' ? warning(publicComponentInstance != null || component._compositeType !== CompositeTypes.StatelessFunctional, 'Stateless function components cannot be given refs ' + '(See ref "%s" in %s created by %s). ' + 'Attempts to access this ref will fail.', ref, componentName, this.getName()) : void 0; - } - var refs = inst.refs === emptyObject ? inst.refs = {} : inst.refs; - refs[ref] = publicComponentInstance; - }, - - /** - * Detaches a reference name. - * - * @param {string} ref Name to dereference. - * @final - * @private - */ - detachRef: function (ref) { - var refs = this.getPublicInstance().refs; - delete refs[ref]; - }, - - /** - * Get a text description of the component that can be used to identify it - * in error messages. - * @return {string} The name or null. - * @internal - */ - getName: function () { - var type = this._currentElement.type; - var constructor = this._instance && this._instance.constructor; - return type.displayName || constructor && constructor.displayName || type.name || constructor && constructor.name || null; - }, - - /** - * Get the publicly accessible representation of this component - i.e. what - * is exposed by refs and returned by render. Can be null for stateless - * components. - * - * @return {ReactComponent} the public component instance. - * @internal - */ - getPublicInstance: function () { - var inst = this._instance; - if (this._compositeType === CompositeTypes.StatelessFunctional) { - return null; - } - return inst; - }, - - // Stub - _instantiateReactComponent: null - -}; - -module.exports = ReactCompositeComponent; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 251 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/ - - - -var ReactDOMComponentTree = __webpack_require__(7); -var ReactDefaultInjection = __webpack_require__(268); -var ReactMount = __webpack_require__(87); -var ReactReconciler = __webpack_require__(26); -var ReactUpdates = __webpack_require__(14); -var ReactVersion = __webpack_require__(283); - -var findDOMNode = __webpack_require__(300); -var getHostComponentFromComposite = __webpack_require__(93); -var renderSubtreeIntoContainer = __webpack_require__(308); -var warning = __webpack_require__(3); - -ReactDefaultInjection.inject(); - -var ReactDOM = { - findDOMNode: findDOMNode, - render: ReactMount.render, - unmountComponentAtNode: ReactMount.unmountComponentAtNode, - version: ReactVersion, - - /* eslint-disable camelcase */ - unstable_batchedUpdates: ReactUpdates.batchedUpdates, - unstable_renderSubtreeIntoContainer: renderSubtreeIntoContainer -}; - -// Inject the runtime into a devtools global hook regardless of browser. -// Allows for debugging when the hook is injected on the page. -if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') { - __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ - ComponentTree: { - getClosestInstanceFromNode: ReactDOMComponentTree.getClosestInstanceFromNode, - getNodeFromInstance: function (inst) { - // inst is an internal instance (but could be a composite) - if (inst._renderedComponent) { - inst = getHostComponentFromComposite(inst); - } - if (inst) { - return ReactDOMComponentTree.getNodeFromInstance(inst); - } else { - return null; - } - } - }, - Mount: ReactMount, - Reconciler: ReactReconciler - }); -} - -if (process.env.NODE_ENV !== 'production') { - var ExecutionEnvironment = __webpack_require__(8); - if (ExecutionEnvironment.canUseDOM && window.top === window.self) { - - // First check if devtools is not installed - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { - // If we're in Chrome or Firefox, provide a download link if not installed. - if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) { - // Firefox does not have the issue with devtools loaded over file:// - var showFileUrlMessage = window.location.protocol.indexOf('http') === -1 && navigator.userAgent.indexOf('Firefox') === -1; - console.debug('Download the React DevTools ' + (showFileUrlMessage ? 'and use an HTTP server (instead of a file: URL) ' : '') + 'for a better development experience: ' + 'https://fb.me/react-devtools'); - } - } - - var testFunc = function testFn() {}; - process.env.NODE_ENV !== 'production' ? warning((testFunc.name || testFunc.toString()).indexOf('testFn') !== -1, 'It looks like you\'re using a minified copy of the development build ' + 'of React. When deploying React apps to production, make sure to use ' + 'the production build which skips development warnings and is faster. ' + 'See https://fb.me/react-minification for more details.') : void 0; - - // If we're in IE8, check to see if we are in compatibility mode and provide - // information on preventing compatibility mode - var ieCompatibilityMode = document.documentMode && document.documentMode < 8; - - process.env.NODE_ENV !== 'production' ? warning(!ieCompatibilityMode, 'Internet Explorer is running in compatibility mode; please add the ' + 'following tag to your HTML to prevent this from happening: ' + '<meta http-equiv="X-UA-Compatible" content="IE=edge" />') : void 0; - - var expectedFeatures = [ - // shims - Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.trim]; - - for (var i = 0; i < expectedFeatures.length; i++) { - if (!expectedFeatures[i]) { - process.env.NODE_ENV !== 'production' ? warning(false, 'One or more ES5 shims expected by React are not available: ' + 'https://fb.me/react-warning-polyfills') : void 0; - break; - } - } - } -} - -if (process.env.NODE_ENV !== 'production') { - var ReactInstrumentation = __webpack_require__(10); - var ReactDOMUnknownPropertyHook = __webpack_require__(265); - var ReactDOMNullInputValuePropHook = __webpack_require__(259); - var ReactDOMInvalidARIAHook = __webpack_require__(258); - - ReactInstrumentation.debugTool.addHook(ReactDOMUnknownPropertyHook); - ReactInstrumentation.debugTool.addHook(ReactDOMNullInputValuePropHook); - ReactInstrumentation.debugTool.addHook(ReactDOMInvalidARIAHook); -} - -module.exports = ReactDOM; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 252 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -/* global hasOwnProperty:true */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var AutoFocusUtils = __webpack_require__(239); -var CSSPropertyOperations = __webpack_require__(241); -var DOMLazyTree = __webpack_require__(25); -var DOMNamespaces = __webpack_require__(47); -var DOMProperty = __webpack_require__(18); -var DOMPropertyOperations = __webpack_require__(80); -var EventPluginHub = __webpack_require__(30); -var EventPluginRegistry = __webpack_require__(35); -var ReactBrowserEventEmitter = __webpack_require__(36); -var ReactDOMComponentFlags = __webpack_require__(81); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactDOMInput = __webpack_require__(257); -var ReactDOMOption = __webpack_require__(260); -var ReactDOMSelect = __webpack_require__(82); -var ReactDOMTextarea = __webpack_require__(263); -var ReactInstrumentation = __webpack_require__(10); -var ReactMultiChild = __webpack_require__(276); -var ReactServerRenderingTransaction = __webpack_require__(281); - -var emptyFunction = __webpack_require__(12); -var escapeTextContentForBrowser = __webpack_require__(39); -var invariant = __webpack_require__(2); -var isEventSupported = __webpack_require__(58); -var shallowEqual = __webpack_require__(42); -var validateDOMNesting = __webpack_require__(60); -var warning = __webpack_require__(3); - -var Flags = ReactDOMComponentFlags; -var deleteListener = EventPluginHub.deleteListener; -var getNode = ReactDOMComponentTree.getNodeFromInstance; -var listenTo = ReactBrowserEventEmitter.listenTo; -var registrationNameModules = EventPluginRegistry.registrationNameModules; - -// For quickly matching children type, to test if can be treated as content. -var CONTENT_TYPES = { 'string': true, 'number': true }; - -var STYLE = 'style'; -var HTML = '__html'; -var RESERVED_PROPS = { - children: null, - dangerouslySetInnerHTML: null, - suppressContentEditableWarning: null -}; - -// Node type for document fragments (Node.DOCUMENT_FRAGMENT_NODE). -var DOC_FRAGMENT_TYPE = 11; - -function getDeclarationErrorAddendum(internalInstance) { - if (internalInstance) { - var owner = internalInstance._currentElement._owner || null; - if (owner) { - var name = owner.getName(); - if (name) { - return ' This DOM node was rendered by `' + name + '`.'; - } - } - } - return ''; -} - -function friendlyStringify(obj) { - if (typeof obj === 'object') { - if (Array.isArray(obj)) { - return '[' + obj.map(friendlyStringify).join(', ') + ']'; - } else { - var pairs = []; - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - var keyEscaped = /^[a-z$_][\w$_]*$/i.test(key) ? key : JSON.stringify(key); - pairs.push(keyEscaped + ': ' + friendlyStringify(obj[key])); - } - } - return '{' + pairs.join(', ') + '}'; - } - } else if (typeof obj === 'string') { - return JSON.stringify(obj); - } else if (typeof obj === 'function') { - return '[function object]'; - } - // Differs from JSON.stringify in that undefined because undefined and that - // inf and nan don't become null - return String(obj); -} - -var styleMutationWarning = {}; - -function checkAndWarnForMutatedStyle(style1, style2, component) { - if (style1 == null || style2 == null) { - return; - } - if (shallowEqual(style1, style2)) { - return; - } - - var componentName = component._tag; - var owner = component._currentElement._owner; - var ownerName; - if (owner) { - ownerName = owner.getName(); - } - - var hash = ownerName + '|' + componentName; - - if (styleMutationWarning.hasOwnProperty(hash)) { - return; - } - - styleMutationWarning[hash] = true; - - process.env.NODE_ENV !== 'production' ? warning(false, '`%s` was passed a style object that has previously been mutated. ' + 'Mutating `style` is deprecated. Consider cloning it beforehand. Check ' + 'the `render` %s. Previous style: %s. Mutated style: %s.', componentName, owner ? 'of `' + ownerName + '`' : 'using <' + componentName + '>', friendlyStringify(style1), friendlyStringify(style2)) : void 0; -} - -/** - * @param {object} component - * @param {?object} props - */ -function assertValidProps(component, props) { - if (!props) { - return; - } - // Note the use of `==` which checks for null or undefined. - if (voidElementTags[component._tag]) { - !(props.children == null && props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : _prodInvariant('137', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : void 0; - } - if (props.dangerouslySetInnerHTML != null) { - !(props.children == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : _prodInvariant('60') : void 0; - !(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.') : _prodInvariant('61') : void 0; - } - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : void 0; - process.env.NODE_ENV !== 'production' ? warning(props.suppressContentEditableWarning || !props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : void 0; - process.env.NODE_ENV !== 'production' ? warning(props.onFocusIn == null && props.onFocusOut == null, 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.') : void 0; - } - !(props.style == null || typeof props.style === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + \'em\'}} when using JSX.%s', getDeclarationErrorAddendum(component)) : _prodInvariant('62', getDeclarationErrorAddendum(component)) : void 0; -} - -function enqueuePutListener(inst, registrationName, listener, transaction) { - if (transaction instanceof ReactServerRenderingTransaction) { - return; - } - if (process.env.NODE_ENV !== 'production') { - // IE8 has no API for event capturing and the `onScroll` event doesn't - // bubble. - process.env.NODE_ENV !== 'production' ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\'t support the `onScroll` event') : void 0; - } - var containerInfo = inst._hostContainerInfo; - var isDocumentFragment = containerInfo._node && containerInfo._node.nodeType === DOC_FRAGMENT_TYPE; - var doc = isDocumentFragment ? containerInfo._node : containerInfo._ownerDocument; - listenTo(registrationName, doc); - transaction.getReactMountReady().enqueue(putListener, { - inst: inst, - registrationName: registrationName, - listener: listener - }); -} - -function putListener() { - var listenerToPut = this; - EventPluginHub.putListener(listenerToPut.inst, listenerToPut.registrationName, listenerToPut.listener); -} - -function inputPostMount() { - var inst = this; - ReactDOMInput.postMountWrapper(inst); -} - -function textareaPostMount() { - var inst = this; - ReactDOMTextarea.postMountWrapper(inst); -} - -function optionPostMount() { - var inst = this; - ReactDOMOption.postMountWrapper(inst); -} - -var setAndValidateContentChildDev = emptyFunction; -if (process.env.NODE_ENV !== 'production') { - setAndValidateContentChildDev = function (content) { - var hasExistingContent = this._contentDebugID != null; - var debugID = this._debugID; - // This ID represents the inlined child that has no backing instance: - var contentDebugID = -debugID; - - if (content == null) { - if (hasExistingContent) { - ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID); - } - this._contentDebugID = null; - return; - } - - validateDOMNesting(null, String(content), this, this._ancestorInfo); - this._contentDebugID = contentDebugID; - if (hasExistingContent) { - ReactInstrumentation.debugTool.onBeforeUpdateComponent(contentDebugID, content); - ReactInstrumentation.debugTool.onUpdateComponent(contentDebugID); - } else { - ReactInstrumentation.debugTool.onBeforeMountComponent(contentDebugID, content, debugID); - ReactInstrumentation.debugTool.onMountComponent(contentDebugID); - ReactInstrumentation.debugTool.onSetChildren(debugID, [contentDebugID]); - } - }; -} - -// There are so many media events, it makes sense to just -// maintain a list rather than create a `trapBubbledEvent` for each -var mediaEvents = { - topAbort: 'abort', - topCanPlay: 'canplay', - topCanPlayThrough: 'canplaythrough', - topDurationChange: 'durationchange', - topEmptied: 'emptied', - topEncrypted: 'encrypted', - topEnded: 'ended', - topError: 'error', - topLoadedData: 'loadeddata', - topLoadedMetadata: 'loadedmetadata', - topLoadStart: 'loadstart', - topPause: 'pause', - topPlay: 'play', - topPlaying: 'playing', - topProgress: 'progress', - topRateChange: 'ratechange', - topSeeked: 'seeked', - topSeeking: 'seeking', - topStalled: 'stalled', - topSuspend: 'suspend', - topTimeUpdate: 'timeupdate', - topVolumeChange: 'volumechange', - topWaiting: 'waiting' -}; - -function trapBubbledEventsLocal() { - var inst = this; - // If a component renders to null or if another component fatals and causes - // the state of the tree to be corrupted, `node` here can be null. - !inst._rootNodeID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Must be mounted to trap events') : _prodInvariant('63') : void 0; - var node = getNode(inst); - !node ? process.env.NODE_ENV !== 'production' ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : _prodInvariant('64') : void 0; - - switch (inst._tag) { - case 'iframe': - case 'object': - inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topLoad', 'load', node)]; - break; - case 'video': - case 'audio': - - inst._wrapperState.listeners = []; - // Create listener for each media event - for (var event in mediaEvents) { - if (mediaEvents.hasOwnProperty(event)) { - inst._wrapperState.listeners.push(ReactBrowserEventEmitter.trapBubbledEvent(event, mediaEvents[event], node)); - } - } - break; - case 'source': - inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topError', 'error', node)]; - break; - case 'img': - inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topError', 'error', node), ReactBrowserEventEmitter.trapBubbledEvent('topLoad', 'load', node)]; - break; - case 'form': - inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topReset', 'reset', node), ReactBrowserEventEmitter.trapBubbledEvent('topSubmit', 'submit', node)]; - break; - case 'input': - case 'select': - case 'textarea': - inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topInvalid', 'invalid', node)]; - break; - } -} - -function postUpdateSelectWrapper() { - ReactDOMSelect.postUpdateWrapper(this); -} - -// For HTML, certain tags should omit their close tag. We keep a whitelist for -// those special-case tags. - -var omittedCloseTags = { - 'area': true, - 'base': true, - 'br': true, - 'col': true, - 'embed': true, - 'hr': true, - 'img': true, - 'input': true, - 'keygen': true, - 'link': true, - 'meta': true, - 'param': true, - 'source': true, - 'track': true, - 'wbr': true -}; - -var newlineEatingTags = { - 'listing': true, - 'pre': true, - 'textarea': true -}; - -// For HTML, certain tags cannot have children. This has the same purpose as -// `omittedCloseTags` except that `menuitem` should still have its closing tag. - -var voidElementTags = _assign({ - 'menuitem': true -}, omittedCloseTags); - -// We accept any tag to be rendered but since this gets injected into arbitrary -// HTML, we want to make sure that it's a safe tag. -// http://www.w3.org/TR/REC-xml/#NT-Name - -var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset -var validatedTagCache = {}; -var hasOwnProperty = {}.hasOwnProperty; - -function validateDangerousTag(tag) { - if (!hasOwnProperty.call(validatedTagCache, tag)) { - !VALID_TAG_REGEX.test(tag) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Invalid tag: %s', tag) : _prodInvariant('65', tag) : void 0; - validatedTagCache[tag] = true; - } -} - -function isCustomComponent(tagName, props) { - return tagName.indexOf('-') >= 0 || props.is != null; -} - -var globalIdCounter = 1; - -/** - * Creates a new React class that is idempotent and capable of containing other - * React components. It accepts event listeners and DOM properties that are - * valid according to `DOMProperty`. - * - * - Event listeners: `onClick`, `onMouseDown`, etc. - * - DOM properties: `className`, `name`, `title`, etc. - * - * The `style` property functions differently from the DOM API. It accepts an - * object mapping of style properties to values. - * - * @constructor ReactDOMComponent - * @extends ReactMultiChild - */ -function ReactDOMComponent(element) { - var tag = element.type; - validateDangerousTag(tag); - this._currentElement = element; - this._tag = tag.toLowerCase(); - this._namespaceURI = null; - this._renderedChildren = null; - this._previousStyle = null; - this._previousStyleCopy = null; - this._hostNode = null; - this._hostParent = null; - this._rootNodeID = 0; - this._domID = 0; - this._hostContainerInfo = null; - this._wrapperState = null; - this._topLevelWrapper = null; - this._flags = 0; - if (process.env.NODE_ENV !== 'production') { - this._ancestorInfo = null; - setAndValidateContentChildDev.call(this, null); - } -} - -ReactDOMComponent.displayName = 'ReactDOMComponent'; - -ReactDOMComponent.Mixin = { - - /** - * Generates root tag markup then recurses. This method has side effects and - * is not idempotent. - * - * @internal - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {?ReactDOMComponent} the parent component instance - * @param {?object} info about the host container - * @param {object} context - * @return {string} The computed markup. - */ - mountComponent: function (transaction, hostParent, hostContainerInfo, context) { - this._rootNodeID = globalIdCounter++; - this._domID = hostContainerInfo._idCounter++; - this._hostParent = hostParent; - this._hostContainerInfo = hostContainerInfo; - - var props = this._currentElement.props; - - switch (this._tag) { - case 'audio': - case 'form': - case 'iframe': - case 'img': - case 'link': - case 'object': - case 'source': - case 'video': - this._wrapperState = { - listeners: null - }; - transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); - break; - case 'input': - ReactDOMInput.mountWrapper(this, props, hostParent); - props = ReactDOMInput.getHostProps(this, props); - transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); - break; - case 'option': - ReactDOMOption.mountWrapper(this, props, hostParent); - props = ReactDOMOption.getHostProps(this, props); - break; - case 'select': - ReactDOMSelect.mountWrapper(this, props, hostParent); - props = ReactDOMSelect.getHostProps(this, props); - transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); - break; - case 'textarea': - ReactDOMTextarea.mountWrapper(this, props, hostParent); - props = ReactDOMTextarea.getHostProps(this, props); - transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); - break; - } - - assertValidProps(this, props); - - // We create tags in the namespace of their parent container, except HTML - // tags get no namespace. - var namespaceURI; - var parentTag; - if (hostParent != null) { - namespaceURI = hostParent._namespaceURI; - parentTag = hostParent._tag; - } else if (hostContainerInfo._tag) { - namespaceURI = hostContainerInfo._namespaceURI; - parentTag = hostContainerInfo._tag; - } - if (namespaceURI == null || namespaceURI === DOMNamespaces.svg && parentTag === 'foreignobject') { - namespaceURI = DOMNamespaces.html; - } - if (namespaceURI === DOMNamespaces.html) { - if (this._tag === 'svg') { - namespaceURI = DOMNamespaces.svg; - } else if (this._tag === 'math') { - namespaceURI = DOMNamespaces.mathml; - } - } - this._namespaceURI = namespaceURI; - - if (process.env.NODE_ENV !== 'production') { - var parentInfo; - if (hostParent != null) { - parentInfo = hostParent._ancestorInfo; - } else if (hostContainerInfo._tag) { - parentInfo = hostContainerInfo._ancestorInfo; - } - if (parentInfo) { - // parentInfo should always be present except for the top-level - // component when server rendering - validateDOMNesting(this._tag, null, this, parentInfo); - } - this._ancestorInfo = validateDOMNesting.updatedAncestorInfo(parentInfo, this._tag, this); - } - - var mountImage; - if (transaction.useCreateElement) { - var ownerDocument = hostContainerInfo._ownerDocument; - var el; - if (namespaceURI === DOMNamespaces.html) { - if (this._tag === 'script') { - // Create the script via .innerHTML so its "parser-inserted" flag is - // set to true and it does not execute - var div = ownerDocument.createElement('div'); - var type = this._currentElement.type; - div.innerHTML = '<' + type + '></' + type + '>'; - el = div.removeChild(div.firstChild); - } else if (props.is) { - el = ownerDocument.createElement(this._currentElement.type, props.is); - } else { - // Separate else branch instead of using `props.is || undefined` above becuase of a Firefox bug. - // See discussion in https://github.com/facebook/react/pull/6896 - // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240 - el = ownerDocument.createElement(this._currentElement.type); - } - } else { - el = ownerDocument.createElementNS(namespaceURI, this._currentElement.type); - } - ReactDOMComponentTree.precacheNode(this, el); - this._flags |= Flags.hasCachedChildNodes; - if (!this._hostParent) { - DOMPropertyOperations.setAttributeForRoot(el); - } - this._updateDOMProperties(null, props, transaction); - var lazyTree = DOMLazyTree(el); - this._createInitialChildren(transaction, props, context, lazyTree); - mountImage = lazyTree; - } else { - var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction, props); - var tagContent = this._createContentMarkup(transaction, props, context); - if (!tagContent && omittedCloseTags[this._tag]) { - mountImage = tagOpen + '/>'; - } else { - mountImage = tagOpen + '>' + tagContent + '</' + this._currentElement.type + '>'; - } - } - - switch (this._tag) { - case 'input': - transaction.getReactMountReady().enqueue(inputPostMount, this); - if (props.autoFocus) { - transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); - } - break; - case 'textarea': - transaction.getReactMountReady().enqueue(textareaPostMount, this); - if (props.autoFocus) { - transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); - } - break; - case 'select': - if (props.autoFocus) { - transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); - } - break; - case 'button': - if (props.autoFocus) { - transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); - } - break; - case 'option': - transaction.getReactMountReady().enqueue(optionPostMount, this); - break; - } - - return mountImage; - }, - - /** - * Creates markup for the open tag and all attributes. - * - * This method has side effects because events get registered. - * - * Iterating over object properties is faster than iterating over arrays. - * @see http://jsperf.com/obj-vs-arr-iteration - * - * @private - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {object} props - * @return {string} Markup of opening tag. - */ - _createOpenTagMarkupAndPutListeners: function (transaction, props) { - var ret = '<' + this._currentElement.type; - - for (var propKey in props) { - if (!props.hasOwnProperty(propKey)) { - continue; - } - var propValue = props[propKey]; - if (propValue == null) { - continue; - } - if (registrationNameModules.hasOwnProperty(propKey)) { - if (propValue) { - enqueuePutListener(this, propKey, propValue, transaction); - } - } else { - if (propKey === STYLE) { - if (propValue) { - if (process.env.NODE_ENV !== 'production') { - // See `_updateDOMProperties`. style block - this._previousStyle = propValue; - } - propValue = this._previousStyleCopy = _assign({}, props.style); - } - propValue = CSSPropertyOperations.createMarkupForStyles(propValue, this); - } - var markup = null; - if (this._tag != null && isCustomComponent(this._tag, props)) { - if (!RESERVED_PROPS.hasOwnProperty(propKey)) { - markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue); - } - } else { - markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue); - } - if (markup) { - ret += ' ' + markup; - } - } - } - - // For static pages, no need to put React ID and checksum. Saves lots of - // bytes. - if (transaction.renderToStaticMarkup) { - return ret; - } - - if (!this._hostParent) { - ret += ' ' + DOMPropertyOperations.createMarkupForRoot(); - } - ret += ' ' + DOMPropertyOperations.createMarkupForID(this._domID); - return ret; - }, - - /** - * Creates markup for the content between the tags. - * - * @private - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {object} props - * @param {object} context - * @return {string} Content markup. - */ - _createContentMarkup: function (transaction, props, context) { - var ret = ''; - - // Intentional use of != to avoid catching zero/false. - var innerHTML = props.dangerouslySetInnerHTML; - if (innerHTML != null) { - if (innerHTML.__html != null) { - ret = innerHTML.__html; - } - } else { - var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null; - var childrenToUse = contentToUse != null ? null : props.children; - if (contentToUse != null) { - // TODO: Validate that text is allowed as a child of this node - ret = escapeTextContentForBrowser(contentToUse); - if (process.env.NODE_ENV !== 'production') { - setAndValidateContentChildDev.call(this, contentToUse); - } - } else if (childrenToUse != null) { - var mountImages = this.mountChildren(childrenToUse, transaction, context); - ret = mountImages.join(''); - } - } - if (newlineEatingTags[this._tag] && ret.charAt(0) === '\n') { - // text/html ignores the first character in these tags if it's a newline - // Prefer to break application/xml over text/html (for now) by adding - // a newline specifically to get eaten by the parser. (Alternately for - // textareas, replacing "^\n" with "\r\n" doesn't get eaten, and the first - // \r is normalized out by HTMLTextAreaElement#value.) - // See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre> - // See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions> - // See: <http://www.w3.org/TR/html5/syntax.html#newlines> - // See: Parsing of "textarea" "listing" and "pre" elements - // from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody> - return '\n' + ret; - } else { - return ret; - } - }, - - _createInitialChildren: function (transaction, props, context, lazyTree) { - // Intentional use of != to avoid catching zero/false. - var innerHTML = props.dangerouslySetInnerHTML; - if (innerHTML != null) { - if (innerHTML.__html != null) { - DOMLazyTree.queueHTML(lazyTree, innerHTML.__html); - } - } else { - var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null; - var childrenToUse = contentToUse != null ? null : props.children; - // TODO: Validate that text is allowed as a child of this node - if (contentToUse != null) { - // Avoid setting textContent when the text is empty. In IE11 setting - // textContent on a text area will cause the placeholder to not - // show within the textarea until it has been focused and blurred again. - // https://github.com/facebook/react/issues/6731#issuecomment-254874553 - if (contentToUse !== '') { - if (process.env.NODE_ENV !== 'production') { - setAndValidateContentChildDev.call(this, contentToUse); - } - DOMLazyTree.queueText(lazyTree, contentToUse); - } - } else if (childrenToUse != null) { - var mountImages = this.mountChildren(childrenToUse, transaction, context); - for (var i = 0; i < mountImages.length; i++) { - DOMLazyTree.queueChild(lazyTree, mountImages[i]); - } - } - } - }, - - /** - * Receives a next element and updates the component. - * - * @internal - * @param {ReactElement} nextElement - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {object} context - */ - receiveComponent: function (nextElement, transaction, context) { - var prevElement = this._currentElement; - this._currentElement = nextElement; - this.updateComponent(transaction, prevElement, nextElement, context); - }, - - /** - * Updates a DOM component after it has already been allocated and - * attached to the DOM. Reconciles the root DOM node, then recurses. - * - * @param {ReactReconcileTransaction} transaction - * @param {ReactElement} prevElement - * @param {ReactElement} nextElement - * @internal - * @overridable - */ - updateComponent: function (transaction, prevElement, nextElement, context) { - var lastProps = prevElement.props; - var nextProps = this._currentElement.props; - - switch (this._tag) { - case 'input': - lastProps = ReactDOMInput.getHostProps(this, lastProps); - nextProps = ReactDOMInput.getHostProps(this, nextProps); - break; - case 'option': - lastProps = ReactDOMOption.getHostProps(this, lastProps); - nextProps = ReactDOMOption.getHostProps(this, nextProps); - break; - case 'select': - lastProps = ReactDOMSelect.getHostProps(this, lastProps); - nextProps = ReactDOMSelect.getHostProps(this, nextProps); - break; - case 'textarea': - lastProps = ReactDOMTextarea.getHostProps(this, lastProps); - nextProps = ReactDOMTextarea.getHostProps(this, nextProps); - break; - } - - assertValidProps(this, nextProps); - this._updateDOMProperties(lastProps, nextProps, transaction); - this._updateDOMChildren(lastProps, nextProps, transaction, context); - - switch (this._tag) { - case 'input': - // Update the wrapper around inputs *after* updating props. This has to - // happen after `_updateDOMProperties`. Otherwise HTML5 input validations - // raise warnings and prevent the new value from being assigned. - ReactDOMInput.updateWrapper(this); - break; - case 'textarea': - ReactDOMTextarea.updateWrapper(this); - break; - case 'select': - // <select> value update needs to occur after <option> children - // reconciliation - transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this); - break; - } - }, - - /** - * Reconciles the properties by detecting differences in property values and - * updating the DOM as necessary. This function is probably the single most - * critical path for performance optimization. - * - * TODO: Benchmark whether checking for changed values in memory actually - * improves performance (especially statically positioned elements). - * TODO: Benchmark the effects of putting this at the top since 99% of props - * do not change for a given reconciliation. - * TODO: Benchmark areas that can be improved with caching. - * - * @private - * @param {object} lastProps - * @param {object} nextProps - * @param {?DOMElement} node - */ - _updateDOMProperties: function (lastProps, nextProps, transaction) { - var propKey; - var styleName; - var styleUpdates; - for (propKey in lastProps) { - if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) { - continue; - } - if (propKey === STYLE) { - var lastStyle = this._previousStyleCopy; - for (styleName in lastStyle) { - if (lastStyle.hasOwnProperty(styleName)) { - styleUpdates = styleUpdates || {}; - styleUpdates[styleName] = ''; - } - } - this._previousStyleCopy = null; - } else if (registrationNameModules.hasOwnProperty(propKey)) { - if (lastProps[propKey]) { - // Only call deleteListener if there was a listener previously or - // else willDeleteListener gets called when there wasn't actually a - // listener (e.g., onClick={null}) - deleteListener(this, propKey); - } - } else if (isCustomComponent(this._tag, lastProps)) { - if (!RESERVED_PROPS.hasOwnProperty(propKey)) { - DOMPropertyOperations.deleteValueForAttribute(getNode(this), propKey); - } - } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) { - DOMPropertyOperations.deleteValueForProperty(getNode(this), propKey); - } - } - for (propKey in nextProps) { - var nextProp = nextProps[propKey]; - var lastProp = propKey === STYLE ? this._previousStyleCopy : lastProps != null ? lastProps[propKey] : undefined; - if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) { - continue; - } - if (propKey === STYLE) { - if (nextProp) { - if (process.env.NODE_ENV !== 'production') { - checkAndWarnForMutatedStyle(this._previousStyleCopy, this._previousStyle, this); - this._previousStyle = nextProp; - } - nextProp = this._previousStyleCopy = _assign({}, nextProp); - } else { - this._previousStyleCopy = null; - } - if (lastProp) { - // Unset styles on `lastProp` but not on `nextProp`. - for (styleName in lastProp) { - if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) { - styleUpdates = styleUpdates || {}; - styleUpdates[styleName] = ''; - } - } - // Update styles that changed since `lastProp`. - for (styleName in nextProp) { - if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) { - styleUpdates = styleUpdates || {}; - styleUpdates[styleName] = nextProp[styleName]; - } - } - } else { - // Relies on `updateStylesByID` not mutating `styleUpdates`. - styleUpdates = nextProp; - } - } else if (registrationNameModules.hasOwnProperty(propKey)) { - if (nextProp) { - enqueuePutListener(this, propKey, nextProp, transaction); - } else if (lastProp) { - deleteListener(this, propKey); - } - } else if (isCustomComponent(this._tag, nextProps)) { - if (!RESERVED_PROPS.hasOwnProperty(propKey)) { - DOMPropertyOperations.setValueForAttribute(getNode(this), propKey, nextProp); - } - } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) { - var node = getNode(this); - // If we're updating to null or undefined, we should remove the property - // from the DOM node instead of inadvertently setting to a string. This - // brings us in line with the same behavior we have on initial render. - if (nextProp != null) { - DOMPropertyOperations.setValueForProperty(node, propKey, nextProp); - } else { - DOMPropertyOperations.deleteValueForProperty(node, propKey); - } - } - } - if (styleUpdates) { - CSSPropertyOperations.setValueForStyles(getNode(this), styleUpdates, this); - } - }, - - /** - * Reconciles the children with the various properties that affect the - * children content. - * - * @param {object} lastProps - * @param {object} nextProps - * @param {ReactReconcileTransaction} transaction - * @param {object} context - */ - _updateDOMChildren: function (lastProps, nextProps, transaction, context) { - var lastContent = CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null; - var nextContent = CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null; - - var lastHtml = lastProps.dangerouslySetInnerHTML && lastProps.dangerouslySetInnerHTML.__html; - var nextHtml = nextProps.dangerouslySetInnerHTML && nextProps.dangerouslySetInnerHTML.__html; - - // Note the use of `!=` which checks for null or undefined. - var lastChildren = lastContent != null ? null : lastProps.children; - var nextChildren = nextContent != null ? null : nextProps.children; - - // If we're switching from children to content/html or vice versa, remove - // the old content - var lastHasContentOrHtml = lastContent != null || lastHtml != null; - var nextHasContentOrHtml = nextContent != null || nextHtml != null; - if (lastChildren != null && nextChildren == null) { - this.updateChildren(null, transaction, context); - } else if (lastHasContentOrHtml && !nextHasContentOrHtml) { - this.updateTextContent(''); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onSetChildren(this._debugID, []); - } - } - - if (nextContent != null) { - if (lastContent !== nextContent) { - this.updateTextContent('' + nextContent); - if (process.env.NODE_ENV !== 'production') { - setAndValidateContentChildDev.call(this, nextContent); - } - } - } else if (nextHtml != null) { - if (lastHtml !== nextHtml) { - this.updateMarkup('' + nextHtml); - } - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onSetChildren(this._debugID, []); - } - } else if (nextChildren != null) { - if (process.env.NODE_ENV !== 'production') { - setAndValidateContentChildDev.call(this, null); - } - - this.updateChildren(nextChildren, transaction, context); - } - }, - - getHostNode: function () { - return getNode(this); - }, - - /** - * Destroys all event registrations for this instance. Does not remove from - * the DOM. That must be done by the parent. - * - * @internal - */ - unmountComponent: function (safely) { - switch (this._tag) { - case 'audio': - case 'form': - case 'iframe': - case 'img': - case 'link': - case 'object': - case 'source': - case 'video': - var listeners = this._wrapperState.listeners; - if (listeners) { - for (var i = 0; i < listeners.length; i++) { - listeners[i].remove(); - } - } - break; - case 'html': - case 'head': - case 'body': - /** - * Components like <html> <head> and <body> can't be removed or added - * easily in a cross-browser way, however it's valuable to be able to - * take advantage of React's reconciliation for styling and <title> - * management. So we just document it and throw in dangerous cases. - */ - true ? process.env.NODE_ENV !== 'production' ? invariant(false, '<%s> tried to unmount. Because of cross-browser quirks it is impossible to unmount some top-level components (eg <html>, <head>, and <body>) reliably and efficiently. To fix this, have a single top-level component that never unmounts render these elements.', this._tag) : _prodInvariant('66', this._tag) : void 0; - break; - } - - this.unmountChildren(safely); - ReactDOMComponentTree.uncacheNode(this); - EventPluginHub.deleteAllListeners(this); - this._rootNodeID = 0; - this._domID = 0; - this._wrapperState = null; - - if (process.env.NODE_ENV !== 'production') { - setAndValidateContentChildDev.call(this, null); - } - }, - - getPublicInstance: function () { - return getNode(this); - } - -}; - -_assign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild.Mixin); - -module.exports = ReactDOMComponent; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 253 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var validateDOMNesting = __webpack_require__(60); - -var DOC_NODE_TYPE = 9; - -function ReactDOMContainerInfo(topLevelWrapper, node) { - var info = { - _topLevelWrapper: topLevelWrapper, - _idCounter: 1, - _ownerDocument: node ? node.nodeType === DOC_NODE_TYPE ? node : node.ownerDocument : null, - _node: node, - _tag: node ? node.nodeName.toLowerCase() : null, - _namespaceURI: node ? node.namespaceURI : null - }; - if (process.env.NODE_ENV !== 'production') { - info._ancestorInfo = node ? validateDOMNesting.updatedAncestorInfo(null, info._tag, null) : null; - } - return info; -} - -module.exports = ReactDOMContainerInfo; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 254 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var DOMLazyTree = __webpack_require__(25); -var ReactDOMComponentTree = __webpack_require__(7); - -var ReactDOMEmptyComponent = function (instantiate) { - // ReactCompositeComponent uses this: - this._currentElement = null; - // ReactDOMComponentTree uses these: - this._hostNode = null; - this._hostParent = null; - this._hostContainerInfo = null; - this._domID = 0; -}; -_assign(ReactDOMEmptyComponent.prototype, { - mountComponent: function (transaction, hostParent, hostContainerInfo, context) { - var domID = hostContainerInfo._idCounter++; - this._domID = domID; - this._hostParent = hostParent; - this._hostContainerInfo = hostContainerInfo; - - var nodeValue = ' react-empty: ' + this._domID + ' '; - if (transaction.useCreateElement) { - var ownerDocument = hostContainerInfo._ownerDocument; - var node = ownerDocument.createComment(nodeValue); - ReactDOMComponentTree.precacheNode(this, node); - return DOMLazyTree(node); - } else { - if (transaction.renderToStaticMarkup) { - // Normally we'd insert a comment node, but since this is a situation - // where React won't take over (static pages), we can simply return - // nothing. - return ''; - } - return '<!--' + nodeValue + '-->'; - } - }, - receiveComponent: function () {}, - getHostNode: function () { - return ReactDOMComponentTree.getNodeFromInstance(this); - }, - unmountComponent: function () { - ReactDOMComponentTree.uncacheNode(this); - } -}); - -module.exports = ReactDOMEmptyComponent; - -/***/ }), -/* 255 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactDOMFeatureFlags = { - useCreateElement: true, - useFiber: false -}; - -module.exports = ReactDOMFeatureFlags; - -/***/ }), -/* 256 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMChildrenOperations = __webpack_require__(46); -var ReactDOMComponentTree = __webpack_require__(7); - -/** - * Operations used to process updates to DOM nodes. - */ -var ReactDOMIDOperations = { - - /** - * Updates a component's children by processing a series of updates. - * - * @param {array<object>} updates List of update configurations. - * @internal - */ - dangerouslyProcessChildrenUpdates: function (parentInst, updates) { - var node = ReactDOMComponentTree.getNodeFromInstance(parentInst); - DOMChildrenOperations.processUpdates(node, updates); - } -}; - -module.exports = ReactDOMIDOperations; - -/***/ }), -/* 257 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var DOMPropertyOperations = __webpack_require__(80); -var LinkedValueUtils = __webpack_require__(50); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactUpdates = __webpack_require__(14); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -var didWarnValueLink = false; -var didWarnCheckedLink = false; -var didWarnValueDefaultValue = false; -var didWarnCheckedDefaultChecked = false; -var didWarnControlledToUncontrolled = false; -var didWarnUncontrolledToControlled = false; - -function forceUpdateIfMounted() { - if (this._rootNodeID) { - // DOM component is still mounted; update - ReactDOMInput.updateWrapper(this); - } -} - -function isControlled(props) { - var usesChecked = props.type === 'checkbox' || props.type === 'radio'; - return usesChecked ? props.checked != null : props.value != null; -} - -/** - * Implements an <input> host component that allows setting these optional - * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. - * - * If `checked` or `value` are not supplied (or null/undefined), user actions - * that affect the checked state or value will trigger updates to the element. - * - * If they are supplied (and not null/undefined), the rendered element will not - * trigger updates to the element. Instead, the props must change in order for - * the rendered element to be updated. - * - * The rendered element will be initialized as unchecked (or `defaultChecked`) - * with an empty value (or `defaultValue`). - * - * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html - */ -var ReactDOMInput = { - getHostProps: function (inst, props) { - var value = LinkedValueUtils.getValue(props); - var checked = LinkedValueUtils.getChecked(props); - - var hostProps = _assign({ - // Make sure we set .type before any other properties (setting .value - // before .type means .value is lost in IE11 and below) - type: undefined, - // Make sure we set .step before .value (setting .value before .step - // means .value is rounded on mount, based upon step precision) - step: undefined, - // Make sure we set .min & .max before .value (to ensure proper order - // in corner cases such as min or max deriving from value, e.g. Issue #7170) - min: undefined, - max: undefined - }, props, { - defaultChecked: undefined, - defaultValue: undefined, - value: value != null ? value : inst._wrapperState.initialValue, - checked: checked != null ? checked : inst._wrapperState.initialChecked, - onChange: inst._wrapperState.onChange - }); - - return hostProps; - }, - - mountWrapper: function (inst, props) { - if (process.env.NODE_ENV !== 'production') { - LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner); - - var owner = inst._currentElement._owner; - - if (props.valueLink !== undefined && !didWarnValueLink) { - process.env.NODE_ENV !== 'production' ? warning(false, '`valueLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0; - didWarnValueLink = true; - } - if (props.checkedLink !== undefined && !didWarnCheckedLink) { - process.env.NODE_ENV !== 'production' ? warning(false, '`checkedLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0; - didWarnCheckedLink = true; - } - if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { - process.env.NODE_ENV !== 'production' ? warning(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; - didWarnCheckedDefaultChecked = true; - } - if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { - process.env.NODE_ENV !== 'production' ? warning(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; - didWarnValueDefaultValue = true; - } - } - - var defaultValue = props.defaultValue; - inst._wrapperState = { - initialChecked: props.checked != null ? props.checked : props.defaultChecked, - initialValue: props.value != null ? props.value : defaultValue, - listeners: null, - onChange: _handleChange.bind(inst) - }; - - if (process.env.NODE_ENV !== 'production') { - inst._wrapperState.controlled = isControlled(props); - } - }, - - updateWrapper: function (inst) { - var props = inst._currentElement.props; - - if (process.env.NODE_ENV !== 'production') { - var controlled = isControlled(props); - var owner = inst._currentElement._owner; - - if (!inst._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) { - process.env.NODE_ENV !== 'production' ? warning(false, '%s is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; - didWarnUncontrolledToControlled = true; - } - if (inst._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) { - process.env.NODE_ENV !== 'production' ? warning(false, '%s is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; - didWarnControlledToUncontrolled = true; - } - } - - // TODO: Shouldn't this be getChecked(props)? - var checked = props.checked; - if (checked != null) { - DOMPropertyOperations.setValueForProperty(ReactDOMComponentTree.getNodeFromInstance(inst), 'checked', checked || false); - } - - var node = ReactDOMComponentTree.getNodeFromInstance(inst); - var value = LinkedValueUtils.getValue(props); - if (value != null) { - - // Cast `value` to a string to ensure the value is set correctly. While - // browsers typically do this as necessary, jsdom doesn't. - var newValue = '' + value; - - // To avoid side effects (such as losing text selection), only set value if changed - if (newValue !== node.value) { - node.value = newValue; - } - } else { - if (props.value == null && props.defaultValue != null) { - // In Chrome, assigning defaultValue to certain input types triggers input validation. - // For number inputs, the display value loses trailing decimal points. For email inputs, - // Chrome raises "The specified value <x> is not a valid email address". - // - // Here we check to see if the defaultValue has actually changed, avoiding these problems - // when the user is inputting text - // - // https://github.com/facebook/react/issues/7253 - if (node.defaultValue !== '' + props.defaultValue) { - node.defaultValue = '' + props.defaultValue; - } - } - if (props.checked == null && props.defaultChecked != null) { - node.defaultChecked = !!props.defaultChecked; - } - } - }, - - postMountWrapper: function (inst) { - var props = inst._currentElement.props; - - // This is in postMount because we need access to the DOM node, which is not - // available until after the component has mounted. - var node = ReactDOMComponentTree.getNodeFromInstance(inst); - - // Detach value from defaultValue. We won't do anything if we're working on - // submit or reset inputs as those values & defaultValues are linked. They - // are not resetable nodes so this operation doesn't matter and actually - // removes browser-default values (eg "Submit Query") when no value is - // provided. - - switch (props.type) { - case 'submit': - case 'reset': - break; - case 'color': - case 'date': - case 'datetime': - case 'datetime-local': - case 'month': - case 'time': - case 'week': - // This fixes the no-show issue on iOS Safari and Android Chrome: - // https://github.com/facebook/react/issues/7233 - node.value = ''; - node.value = node.defaultValue; - break; - default: - node.value = node.value; - break; - } - - // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug - // this is needed to work around a chrome bug where setting defaultChecked - // will sometimes influence the value of checked (even after detachment). - // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416 - // We need to temporarily unset name to avoid disrupting radio button groups. - var name = node.name; - if (name !== '') { - node.name = ''; - } - node.defaultChecked = !node.defaultChecked; - node.defaultChecked = !node.defaultChecked; - if (name !== '') { - node.name = name; - } - } -}; - -function _handleChange(event) { - var props = this._currentElement.props; - - var returnValue = LinkedValueUtils.executeOnChange(props, event); - - // Here we use asap to wait until all updates have propagated, which - // is important when using controlled components within layers: - // https://github.com/facebook/react/issues/1698 - ReactUpdates.asap(forceUpdateIfMounted, this); - - var name = props.name; - if (props.type === 'radio' && name != null) { - var rootNode = ReactDOMComponentTree.getNodeFromInstance(this); - var queryRoot = rootNode; - - while (queryRoot.parentNode) { - queryRoot = queryRoot.parentNode; - } - - // If `rootNode.form` was non-null, then we could try `form.elements`, - // but that sometimes behaves strangely in IE8. We could also try using - // `form.getElementsByName`, but that will only return direct children - // and won't include inputs that use the HTML5 `form=` attribute. Since - // the input might not even be in a form, let's just use the global - // `querySelectorAll` to ensure we don't miss anything. - var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]'); - - for (var i = 0; i < group.length; i++) { - var otherNode = group[i]; - if (otherNode === rootNode || otherNode.form !== rootNode.form) { - continue; - } - // This will throw if radio buttons rendered by different copies of React - // and the same name are rendered into the same form (same as #1939). - // That's probably okay; we don't support it just as we don't support - // mixing React radio buttons with non-React ones. - var otherInstance = ReactDOMComponentTree.getInstanceFromNode(otherNode); - !otherInstance ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : _prodInvariant('90') : void 0; - // If this is a controlled radio button group, forcing the input that - // was previously checked to update will cause it to be come re-checked - // as appropriate. - ReactUpdates.asap(forceUpdateIfMounted, otherInstance); - } - } - - return returnValue; -} - -module.exports = ReactDOMInput; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 258 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMProperty = __webpack_require__(18); -var ReactComponentTreeHook = __webpack_require__(9); - -var warning = __webpack_require__(3); - -var warnedProperties = {}; -var rARIA = new RegExp('^(aria)-[' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$'); - -function validateProperty(tagName, name, debugID) { - if (warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { - return true; - } - - if (rARIA.test(name)) { - var lowerCasedName = name.toLowerCase(); - var standardName = DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null; - - // If this is an aria-* attribute, but is not listed in the known DOM - // DOM properties, then it is an invalid aria-* attribute. - if (standardName == null) { - warnedProperties[name] = true; - return false; - } - // aria-* attributes should be lowercase; suggest the lowercase version. - if (name !== standardName) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Unknown ARIA attribute %s. Did you mean %s?%s', name, standardName, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - warnedProperties[name] = true; - return true; - } - } - - return true; -} - -function warnInvalidARIAProps(debugID, element) { - var invalidProps = []; - - for (var key in element.props) { - var isValid = validateProperty(element.type, key, debugID); - if (!isValid) { - invalidProps.push(key); - } - } - - var unknownPropString = invalidProps.map(function (prop) { - return '`' + prop + '`'; - }).join(', '); - - if (invalidProps.length === 1) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - } else if (invalidProps.length > 1) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - } -} - -function handleElement(debugID, element) { - if (element == null || typeof element.type !== 'string') { - return; - } - if (element.type.indexOf('-') >= 0 || element.props.is) { - return; - } - - warnInvalidARIAProps(debugID, element); -} - -var ReactDOMInvalidARIAHook = { - onBeforeMountComponent: function (debugID, element) { - if (process.env.NODE_ENV !== 'production') { - handleElement(debugID, element); - } - }, - onBeforeUpdateComponent: function (debugID, element) { - if (process.env.NODE_ENV !== 'production') { - handleElement(debugID, element); - } - } -}; - -module.exports = ReactDOMInvalidARIAHook; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 259 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactComponentTreeHook = __webpack_require__(9); - -var warning = __webpack_require__(3); - -var didWarnValueNull = false; - -function handleElement(debugID, element) { - if (element == null) { - return; - } - if (element.type !== 'input' && element.type !== 'textarea' && element.type !== 'select') { - return; - } - if (element.props != null && element.props.value === null && !didWarnValueNull) { - process.env.NODE_ENV !== 'production' ? warning(false, '`value` prop on `%s` should not be null. ' + 'Consider using the empty string to clear the component or `undefined` ' + 'for uncontrolled components.%s', element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - - didWarnValueNull = true; - } -} - -var ReactDOMNullInputValuePropHook = { - onBeforeMountComponent: function (debugID, element) { - handleElement(debugID, element); - }, - onBeforeUpdateComponent: function (debugID, element) { - handleElement(debugID, element); - } -}; - -module.exports = ReactDOMNullInputValuePropHook; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 260 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var React = __webpack_require__(27); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactDOMSelect = __webpack_require__(82); - -var warning = __webpack_require__(3); -var didWarnInvalidOptionChildren = false; - -function flattenChildren(children) { - var content = ''; - - // Flatten children and warn if they aren't strings or numbers; - // invalid types are ignored. - React.Children.forEach(children, function (child) { - if (child == null) { - return; - } - if (typeof child === 'string' || typeof child === 'number') { - content += child; - } else if (!didWarnInvalidOptionChildren) { - didWarnInvalidOptionChildren = true; - process.env.NODE_ENV !== 'production' ? warning(false, 'Only strings and numbers are supported as <option> children.') : void 0; - } - }); - - return content; -} - -/** - * Implements an <option> host component that warns when `selected` is set. - */ -var ReactDOMOption = { - mountWrapper: function (inst, props, hostParent) { - // TODO (yungsters): Remove support for `selected` in <option>. - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.') : void 0; - } - - // Look up whether this option is 'selected' - var selectValue = null; - if (hostParent != null) { - var selectParent = hostParent; - - if (selectParent._tag === 'optgroup') { - selectParent = selectParent._hostParent; - } - - if (selectParent != null && selectParent._tag === 'select') { - selectValue = ReactDOMSelect.getSelectValueContext(selectParent); - } - } - - // If the value is null (e.g., no specified value or after initial mount) - // or missing (e.g., for <datalist>), we don't change props.selected - var selected = null; - if (selectValue != null) { - var value; - if (props.value != null) { - value = props.value + ''; - } else { - value = flattenChildren(props.children); - } - selected = false; - if (Array.isArray(selectValue)) { - // multiple - for (var i = 0; i < selectValue.length; i++) { - if ('' + selectValue[i] === value) { - selected = true; - break; - } - } - } else { - selected = '' + selectValue === value; - } - } - - inst._wrapperState = { selected: selected }; - }, - - postMountWrapper: function (inst) { - // value="" should make a value attribute (#6219) - var props = inst._currentElement.props; - if (props.value != null) { - var node = ReactDOMComponentTree.getNodeFromInstance(inst); - node.setAttribute('value', props.value); - } - }, - - getHostProps: function (inst, props) { - var hostProps = _assign({ selected: undefined, children: undefined }, props); - - // Read state only from initial mount because <select> updates value - // manually; we need the initial state only for server rendering - if (inst._wrapperState.selected != null) { - hostProps.selected = inst._wrapperState.selected; - } - - var content = flattenChildren(props.children); - - if (content) { - hostProps.children = content; - } - - return hostProps; - } - -}; - -module.exports = ReactDOMOption; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 261 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ExecutionEnvironment = __webpack_require__(8); - -var getNodeForCharacterOffset = __webpack_require__(305); -var getTextContentAccessor = __webpack_require__(94); - -/** - * While `isCollapsed` is available on the Selection object and `collapsed` - * is available on the Range object, IE11 sometimes gets them wrong. - * If the anchor/focus nodes and offsets are the same, the range is collapsed. - */ -function isCollapsed(anchorNode, anchorOffset, focusNode, focusOffset) { - return anchorNode === focusNode && anchorOffset === focusOffset; -} - -/** - * Get the appropriate anchor and focus node/offset pairs for IE. - * - * The catch here is that IE's selection API doesn't provide information - * about whether the selection is forward or backward, so we have to - * behave as though it's always forward. - * - * IE text differs from modern selection in that it behaves as though - * block elements end with a new line. This means character offsets will - * differ between the two APIs. - * - * @param {DOMElement} node - * @return {object} - */ -function getIEOffsets(node) { - var selection = document.selection; - var selectedRange = selection.createRange(); - var selectedLength = selectedRange.text.length; - - // Duplicate selection so we can move range without breaking user selection. - var fromStart = selectedRange.duplicate(); - fromStart.moveToElementText(node); - fromStart.setEndPoint('EndToStart', selectedRange); - - var startOffset = fromStart.text.length; - var endOffset = startOffset + selectedLength; - - return { - start: startOffset, - end: endOffset - }; -} - -/** - * @param {DOMElement} node - * @return {?object} - */ -function getModernOffsets(node) { - var selection = window.getSelection && window.getSelection(); - - if (!selection || selection.rangeCount === 0) { - return null; - } - - var anchorNode = selection.anchorNode; - var anchorOffset = selection.anchorOffset; - var focusNode = selection.focusNode; - var focusOffset = selection.focusOffset; - - var currentRange = selection.getRangeAt(0); - - // In Firefox, range.startContainer and range.endContainer can be "anonymous - // divs", e.g. the up/down buttons on an <input type="number">. Anonymous - // divs do not seem to expose properties, triggering a "Permission denied - // error" if any of its properties are accessed. The only seemingly possible - // way to avoid erroring is to access a property that typically works for - // non-anonymous divs and catch any error that may otherwise arise. See - // https://bugzilla.mozilla.org/show_bug.cgi?id=208427 - try { - /* eslint-disable no-unused-expressions */ - currentRange.startContainer.nodeType; - currentRange.endContainer.nodeType; - /* eslint-enable no-unused-expressions */ - } catch (e) { - return null; - } - - // If the node and offset values are the same, the selection is collapsed. - // `Selection.isCollapsed` is available natively, but IE sometimes gets - // this value wrong. - var isSelectionCollapsed = isCollapsed(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset); - - var rangeLength = isSelectionCollapsed ? 0 : currentRange.toString().length; - - var tempRange = currentRange.cloneRange(); - tempRange.selectNodeContents(node); - tempRange.setEnd(currentRange.startContainer, currentRange.startOffset); - - var isTempRangeCollapsed = isCollapsed(tempRange.startContainer, tempRange.startOffset, tempRange.endContainer, tempRange.endOffset); - - var start = isTempRangeCollapsed ? 0 : tempRange.toString().length; - var end = start + rangeLength; - - // Detect whether the selection is backward. - var detectionRange = document.createRange(); - detectionRange.setStart(anchorNode, anchorOffset); - detectionRange.setEnd(focusNode, focusOffset); - var isBackward = detectionRange.collapsed; - - return { - start: isBackward ? end : start, - end: isBackward ? start : end - }; -} - -/** - * @param {DOMElement|DOMTextNode} node - * @param {object} offsets - */ -function setIEOffsets(node, offsets) { - var range = document.selection.createRange().duplicate(); - var start, end; - - if (offsets.end === undefined) { - start = offsets.start; - end = start; - } else if (offsets.start > offsets.end) { - start = offsets.end; - end = offsets.start; - } else { - start = offsets.start; - end = offsets.end; - } - - range.moveToElementText(node); - range.moveStart('character', start); - range.setEndPoint('EndToStart', range); - range.moveEnd('character', end - start); - range.select(); -} - -/** - * In modern non-IE browsers, we can support both forward and backward - * selections. - * - * Note: IE10+ supports the Selection object, but it does not support - * the `extend` method, which means that even in modern IE, it's not possible - * to programmatically create a backward selection. Thus, for all IE - * versions, we use the old IE API to create our selections. - * - * @param {DOMElement|DOMTextNode} node - * @param {object} offsets - */ -function setModernOffsets(node, offsets) { - if (!window.getSelection) { - return; - } - - var selection = window.getSelection(); - var length = node[getTextContentAccessor()].length; - var start = Math.min(offsets.start, length); - var end = offsets.end === undefined ? start : Math.min(offsets.end, length); - - // IE 11 uses modern selection, but doesn't support the extend method. - // Flip backward selections, so we can set with a single range. - if (!selection.extend && start > end) { - var temp = end; - end = start; - start = temp; - } - - var startMarker = getNodeForCharacterOffset(node, start); - var endMarker = getNodeForCharacterOffset(node, end); - - if (startMarker && endMarker) { - var range = document.createRange(); - range.setStart(startMarker.node, startMarker.offset); - selection.removeAllRanges(); - - if (start > end) { - selection.addRange(range); - selection.extend(endMarker.node, endMarker.offset); - } else { - range.setEnd(endMarker.node, endMarker.offset); - selection.addRange(range); - } - } -} - -var useIEOffsets = ExecutionEnvironment.canUseDOM && 'selection' in document && !('getSelection' in window); - -var ReactDOMSelection = { - /** - * @param {DOMElement} node - */ - getOffsets: useIEOffsets ? getIEOffsets : getModernOffsets, - - /** - * @param {DOMElement|DOMTextNode} node - * @param {object} offsets - */ - setOffsets: useIEOffsets ? setIEOffsets : setModernOffsets -}; - -module.exports = ReactDOMSelection; - -/***/ }), -/* 262 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var DOMChildrenOperations = __webpack_require__(46); -var DOMLazyTree = __webpack_require__(25); -var ReactDOMComponentTree = __webpack_require__(7); - -var escapeTextContentForBrowser = __webpack_require__(39); -var invariant = __webpack_require__(2); -var validateDOMNesting = __webpack_require__(60); - -/** - * Text nodes violate a couple assumptions that React makes about components: - * - * - When mounting text into the DOM, adjacent text nodes are merged. - * - Text nodes cannot be assigned a React root ID. - * - * This component is used to wrap strings between comment nodes so that they - * can undergo the same reconciliation that is applied to elements. - * - * TODO: Investigate representing React components in the DOM with text nodes. - * - * @class ReactDOMTextComponent - * @extends ReactComponent - * @internal - */ -var ReactDOMTextComponent = function (text) { - // TODO: This is really a ReactText (ReactNode), not a ReactElement - this._currentElement = text; - this._stringText = '' + text; - // ReactDOMComponentTree uses these: - this._hostNode = null; - this._hostParent = null; - - // Properties - this._domID = 0; - this._mountIndex = 0; - this._closingComment = null; - this._commentNodes = null; -}; - -_assign(ReactDOMTextComponent.prototype, { - - /** - * Creates the markup for this text node. This node is not intended to have - * any features besides containing text content. - * - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {string} Markup for this text node. - * @internal - */ - mountComponent: function (transaction, hostParent, hostContainerInfo, context) { - if (process.env.NODE_ENV !== 'production') { - var parentInfo; - if (hostParent != null) { - parentInfo = hostParent._ancestorInfo; - } else if (hostContainerInfo != null) { - parentInfo = hostContainerInfo._ancestorInfo; - } - if (parentInfo) { - // parentInfo should always be present except for the top-level - // component when server rendering - validateDOMNesting(null, this._stringText, this, parentInfo); - } - } - - var domID = hostContainerInfo._idCounter++; - var openingValue = ' react-text: ' + domID + ' '; - var closingValue = ' /react-text '; - this._domID = domID; - this._hostParent = hostParent; - if (transaction.useCreateElement) { - var ownerDocument = hostContainerInfo._ownerDocument; - var openingComment = ownerDocument.createComment(openingValue); - var closingComment = ownerDocument.createComment(closingValue); - var lazyTree = DOMLazyTree(ownerDocument.createDocumentFragment()); - DOMLazyTree.queueChild(lazyTree, DOMLazyTree(openingComment)); - if (this._stringText) { - DOMLazyTree.queueChild(lazyTree, DOMLazyTree(ownerDocument.createTextNode(this._stringText))); - } - DOMLazyTree.queueChild(lazyTree, DOMLazyTree(closingComment)); - ReactDOMComponentTree.precacheNode(this, openingComment); - this._closingComment = closingComment; - return lazyTree; - } else { - var escapedText = escapeTextContentForBrowser(this._stringText); - - if (transaction.renderToStaticMarkup) { - // Normally we'd wrap this between comment nodes for the reasons stated - // above, but since this is a situation where React won't take over - // (static pages), we can simply return the text as it is. - return escapedText; - } - - return '<!--' + openingValue + '-->' + escapedText + '<!--' + closingValue + '-->'; - } - }, - - /** - * Updates this component by updating the text content. - * - * @param {ReactText} nextText The next text content - * @param {ReactReconcileTransaction} transaction - * @internal - */ - receiveComponent: function (nextText, transaction) { - if (nextText !== this._currentElement) { - this._currentElement = nextText; - var nextStringText = '' + nextText; - if (nextStringText !== this._stringText) { - // TODO: Save this as pending props and use performUpdateIfNecessary - // and/or updateComponent to do the actual update for consistency with - // other component types? - this._stringText = nextStringText; - var commentNodes = this.getHostNode(); - DOMChildrenOperations.replaceDelimitedText(commentNodes[0], commentNodes[1], nextStringText); - } - } - }, - - getHostNode: function () { - var hostNode = this._commentNodes; - if (hostNode) { - return hostNode; - } - if (!this._closingComment) { - var openingComment = ReactDOMComponentTree.getNodeFromInstance(this); - var node = openingComment.nextSibling; - while (true) { - !(node != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Missing closing comment for text component %s', this._domID) : _prodInvariant('67', this._domID) : void 0; - if (node.nodeType === 8 && node.nodeValue === ' /react-text ') { - this._closingComment = node; - break; - } - node = node.nextSibling; - } - } - hostNode = [this._hostNode, this._closingComment]; - this._commentNodes = hostNode; - return hostNode; - }, - - unmountComponent: function () { - this._closingComment = null; - this._commentNodes = null; - ReactDOMComponentTree.uncacheNode(this); - } - -}); - -module.exports = ReactDOMTextComponent; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 263 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4), - _assign = __webpack_require__(6); - -var LinkedValueUtils = __webpack_require__(50); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactUpdates = __webpack_require__(14); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -var didWarnValueLink = false; -var didWarnValDefaultVal = false; - -function forceUpdateIfMounted() { - if (this._rootNodeID) { - // DOM component is still mounted; update - ReactDOMTextarea.updateWrapper(this); - } -} - -/** - * Implements a <textarea> host component that allows setting `value`, and - * `defaultValue`. This differs from the traditional DOM API because value is - * usually set as PCDATA children. - * - * If `value` is not supplied (or null/undefined), user actions that affect the - * value will trigger updates to the element. - * - * If `value` is supplied (and not null/undefined), the rendered element will - * not trigger updates to the element. Instead, the `value` prop must change in - * order for the rendered element to be updated. - * - * The rendered element will be initialized with an empty value, the prop - * `defaultValue` if specified, or the children content (deprecated). - */ -var ReactDOMTextarea = { - getHostProps: function (inst, props) { - !(props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : _prodInvariant('91') : void 0; - - // Always set children to the same thing. In IE9, the selection range will - // get reset if `textContent` is mutated. We could add a check in setTextContent - // to only set the value if/when the value differs from the node value (which would - // completely solve this IE9 bug), but Sebastian+Ben seemed to like this solution. - // The value can be a boolean or object so that's why it's forced to be a string. - var hostProps = _assign({}, props, { - value: undefined, - defaultValue: undefined, - children: '' + inst._wrapperState.initialValue, - onChange: inst._wrapperState.onChange - }); - - return hostProps; - }, - - mountWrapper: function (inst, props) { - if (process.env.NODE_ENV !== 'production') { - LinkedValueUtils.checkPropTypes('textarea', props, inst._currentElement._owner); - if (props.valueLink !== undefined && !didWarnValueLink) { - process.env.NODE_ENV !== 'production' ? warning(false, '`valueLink` prop on `textarea` is deprecated; set `value` and `onChange` instead.') : void 0; - didWarnValueLink = true; - } - if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0; - didWarnValDefaultVal = true; - } - } - - var value = LinkedValueUtils.getValue(props); - var initialValue = value; - - // Only bother fetching default value if we're going to use it - if (value == null) { - var defaultValue = props.defaultValue; - // TODO (yungsters): Remove support for children content in <textarea>. - var children = props.children; - if (children != null) { - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.') : void 0; - } - !(defaultValue == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : _prodInvariant('92') : void 0; - if (Array.isArray(children)) { - !(children.length <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, '<textarea> can only have at most one child.') : _prodInvariant('93') : void 0; - children = children[0]; - } - - defaultValue = '' + children; - } - if (defaultValue == null) { - defaultValue = ''; - } - initialValue = defaultValue; - } - - inst._wrapperState = { - initialValue: '' + initialValue, - listeners: null, - onChange: _handleChange.bind(inst) - }; - }, - - updateWrapper: function (inst) { - var props = inst._currentElement.props; - - var node = ReactDOMComponentTree.getNodeFromInstance(inst); - var value = LinkedValueUtils.getValue(props); - if (value != null) { - // Cast `value` to a string to ensure the value is set correctly. While - // browsers typically do this as necessary, jsdom doesn't. - var newValue = '' + value; - - // To avoid side effects (such as losing text selection), only set value if changed - if (newValue !== node.value) { - node.value = newValue; - } - if (props.defaultValue == null) { - node.defaultValue = newValue; - } - } - if (props.defaultValue != null) { - node.defaultValue = props.defaultValue; - } - }, - - postMountWrapper: function (inst) { - // This is in postMount because we need access to the DOM node, which is not - // available until after the component has mounted. - var node = ReactDOMComponentTree.getNodeFromInstance(inst); - var textContent = node.textContent; - - // Only set node.value if textContent is equal to the expected - // initial value. In IE10/IE11 there is a bug where the placeholder attribute - // will populate textContent as well. - // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/ - if (textContent === inst._wrapperState.initialValue) { - node.value = textContent; - } - } -}; - -function _handleChange(event) { - var props = this._currentElement.props; - var returnValue = LinkedValueUtils.executeOnChange(props, event); - ReactUpdates.asap(forceUpdateIfMounted, this); - return returnValue; -} - -module.exports = ReactDOMTextarea; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 264 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -/** - * Return the lowest common ancestor of A and B, or null if they are in - * different trees. - */ -function getLowestCommonAncestor(instA, instB) { - !('_hostNode' in instA) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0; - !('_hostNode' in instB) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0; - - var depthA = 0; - for (var tempA = instA; tempA; tempA = tempA._hostParent) { - depthA++; - } - var depthB = 0; - for (var tempB = instB; tempB; tempB = tempB._hostParent) { - depthB++; - } - - // If A is deeper, crawl up. - while (depthA - depthB > 0) { - instA = instA._hostParent; - depthA--; - } - - // If B is deeper, crawl up. - while (depthB - depthA > 0) { - instB = instB._hostParent; - depthB--; - } - - // Walk in lockstep until we find a match. - var depth = depthA; - while (depth--) { - if (instA === instB) { - return instA; - } - instA = instA._hostParent; - instB = instB._hostParent; - } - return null; -} - -/** - * Return if A is an ancestor of B. - */ -function isAncestor(instA, instB) { - !('_hostNode' in instA) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'isAncestor: Invalid argument.') : _prodInvariant('35') : void 0; - !('_hostNode' in instB) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'isAncestor: Invalid argument.') : _prodInvariant('35') : void 0; - - while (instB) { - if (instB === instA) { - return true; - } - instB = instB._hostParent; - } - return false; -} - -/** - * Return the parent instance of the passed-in instance. - */ -function getParentInstance(inst) { - !('_hostNode' in inst) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getParentInstance: Invalid argument.') : _prodInvariant('36') : void 0; - - return inst._hostParent; -} - -/** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. - */ -function traverseTwoPhase(inst, fn, arg) { - var path = []; - while (inst) { - path.push(inst); - inst = inst._hostParent; - } - var i; - for (i = path.length; i-- > 0;) { - fn(path[i], 'captured', arg); - } - for (i = 0; i < path.length; i++) { - fn(path[i], 'bubbled', arg); - } -} - -/** - * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that - * should would receive a `mouseEnter` or `mouseLeave` event. - * - * Does not invoke the callback on the nearest common ancestor because nothing - * "entered" or "left" that element. - */ -function traverseEnterLeave(from, to, fn, argFrom, argTo) { - var common = from && to ? getLowestCommonAncestor(from, to) : null; - var pathFrom = []; - while (from && from !== common) { - pathFrom.push(from); - from = from._hostParent; - } - var pathTo = []; - while (to && to !== common) { - pathTo.push(to); - to = to._hostParent; - } - var i; - for (i = 0; i < pathFrom.length; i++) { - fn(pathFrom[i], 'bubbled', argFrom); - } - for (i = pathTo.length; i-- > 0;) { - fn(pathTo[i], 'captured', argTo); - } -} - -module.exports = { - isAncestor: isAncestor, - getLowestCommonAncestor: getLowestCommonAncestor, - getParentInstance: getParentInstance, - traverseTwoPhase: traverseTwoPhase, - traverseEnterLeave: traverseEnterLeave -}; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 265 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMProperty = __webpack_require__(18); -var EventPluginRegistry = __webpack_require__(35); -var ReactComponentTreeHook = __webpack_require__(9); - -var warning = __webpack_require__(3); - -if (process.env.NODE_ENV !== 'production') { - var reactProps = { - children: true, - dangerouslySetInnerHTML: true, - key: true, - ref: true, - - autoFocus: true, - defaultValue: true, - valueLink: true, - defaultChecked: true, - checkedLink: true, - innerHTML: true, - suppressContentEditableWarning: true, - onFocusIn: true, - onFocusOut: true - }; - var warnedProperties = {}; - - var validateProperty = function (tagName, name, debugID) { - if (DOMProperty.properties.hasOwnProperty(name) || DOMProperty.isCustomAttribute(name)) { - return true; - } - if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { - return true; - } - if (EventPluginRegistry.registrationNameModules.hasOwnProperty(name)) { - return true; - } - warnedProperties[name] = true; - var lowerCasedName = name.toLowerCase(); - - // data-* attributes should be lowercase; suggest the lowercase version - var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null; - - var registrationName = EventPluginRegistry.possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? EventPluginRegistry.possibleRegistrationNames[lowerCasedName] : null; - - if (standardName != null) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Unknown DOM property %s. Did you mean %s?%s', name, standardName, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - return true; - } else if (registrationName != null) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Unknown event handler property %s. Did you mean `%s`?%s', name, registrationName, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - return true; - } else { - // We were unable to guess which prop the user intended. - // It is likely that the user was just blindly spreading/forwarding props - // Components should be careful to only render valid props/attributes. - // Warning will be invoked in warnUnknownProperties to allow grouping. - return false; - } - }; -} - -var warnUnknownProperties = function (debugID, element) { - var unknownProps = []; - for (var key in element.props) { - var isValid = validateProperty(element.type, key, debugID); - if (!isValid) { - unknownProps.push(key); - } - } - - var unknownPropString = unknownProps.map(function (prop) { - return '`' + prop + '`'; - }).join(', '); - - if (unknownProps.length === 1) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Unknown prop %s on <%s> tag. Remove this prop from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - } else if (unknownProps.length > 1) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Unknown props %s on <%s> tag. Remove these props from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; - } -}; - -function handleElement(debugID, element) { - if (element == null || typeof element.type !== 'string') { - return; - } - if (element.type.indexOf('-') >= 0 || element.props.is) { - return; - } - warnUnknownProperties(debugID, element); -} - -var ReactDOMUnknownPropertyHook = { - onBeforeMountComponent: function (debugID, element) { - handleElement(debugID, element); - }, - onBeforeUpdateComponent: function (debugID, element) { - handleElement(debugID, element); - } -}; - -module.exports = ReactDOMUnknownPropertyHook; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 266 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactInvalidSetStateWarningHook = __webpack_require__(274); -var ReactHostOperationHistoryHook = __webpack_require__(272); -var ReactComponentTreeHook = __webpack_require__(9); -var ExecutionEnvironment = __webpack_require__(8); - -var performanceNow = __webpack_require__(227); -var warning = __webpack_require__(3); - -var hooks = []; -var didHookThrowForEvent = {}; - -function callHook(event, fn, context, arg1, arg2, arg3, arg4, arg5) { - try { - fn.call(context, arg1, arg2, arg3, arg4, arg5); - } catch (e) { - process.env.NODE_ENV !== 'production' ? warning(didHookThrowForEvent[event], 'Exception thrown by hook while handling %s: %s', event, e + '\n' + e.stack) : void 0; - didHookThrowForEvent[event] = true; - } -} - -function emitEvent(event, arg1, arg2, arg3, arg4, arg5) { - for (var i = 0; i < hooks.length; i++) { - var hook = hooks[i]; - var fn = hook[event]; - if (fn) { - callHook(event, fn, hook, arg1, arg2, arg3, arg4, arg5); - } - } -} - -var isProfiling = false; -var flushHistory = []; -var lifeCycleTimerStack = []; -var currentFlushNesting = 0; -var currentFlushMeasurements = []; -var currentFlushStartTime = 0; -var currentTimerDebugID = null; -var currentTimerStartTime = 0; -var currentTimerNestedFlushDuration = 0; -var currentTimerType = null; - -var lifeCycleTimerHasWarned = false; - -function clearHistory() { - ReactComponentTreeHook.purgeUnmountedComponents(); - ReactHostOperationHistoryHook.clearHistory(); -} - -function getTreeSnapshot(registeredIDs) { - return registeredIDs.reduce(function (tree, id) { - var ownerID = ReactComponentTreeHook.getOwnerID(id); - var parentID = ReactComponentTreeHook.getParentID(id); - tree[id] = { - displayName: ReactComponentTreeHook.getDisplayName(id), - text: ReactComponentTreeHook.getText(id), - updateCount: ReactComponentTreeHook.getUpdateCount(id), - childIDs: ReactComponentTreeHook.getChildIDs(id), - // Text nodes don't have owners but this is close enough. - ownerID: ownerID || parentID && ReactComponentTreeHook.getOwnerID(parentID) || 0, - parentID: parentID - }; - return tree; - }, {}); -} - -function resetMeasurements() { - var previousStartTime = currentFlushStartTime; - var previousMeasurements = currentFlushMeasurements; - var previousOperations = ReactHostOperationHistoryHook.getHistory(); - - if (currentFlushNesting === 0) { - currentFlushStartTime = 0; - currentFlushMeasurements = []; - clearHistory(); - return; - } - - if (previousMeasurements.length || previousOperations.length) { - var registeredIDs = ReactComponentTreeHook.getRegisteredIDs(); - flushHistory.push({ - duration: performanceNow() - previousStartTime, - measurements: previousMeasurements || [], - operations: previousOperations || [], - treeSnapshot: getTreeSnapshot(registeredIDs) - }); - } - - clearHistory(); - currentFlushStartTime = performanceNow(); - currentFlushMeasurements = []; -} - -function checkDebugID(debugID) { - var allowRoot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - if (allowRoot && debugID === 0) { - return; - } - if (!debugID) { - process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDebugTool: debugID may not be empty.') : void 0; - } -} - -function beginLifeCycleTimer(debugID, timerType) { - if (currentFlushNesting === 0) { - return; - } - if (currentTimerType && !lifeCycleTimerHasWarned) { - process.env.NODE_ENV !== 'production' ? warning(false, 'There is an internal error in the React performance measurement code. ' + 'Did not expect %s timer to start while %s timer is still in ' + 'progress for %s instance.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0; - lifeCycleTimerHasWarned = true; - } - currentTimerStartTime = performanceNow(); - currentTimerNestedFlushDuration = 0; - currentTimerDebugID = debugID; - currentTimerType = timerType; -} - -function endLifeCycleTimer(debugID, timerType) { - if (currentFlushNesting === 0) { - return; - } - if (currentTimerType !== timerType && !lifeCycleTimerHasWarned) { - process.env.NODE_ENV !== 'production' ? warning(false, 'There is an internal error in the React performance measurement code. ' + 'We did not expect %s timer to stop while %s timer is still in ' + 'progress for %s instance. Please report this as a bug in React.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0; - lifeCycleTimerHasWarned = true; - } - if (isProfiling) { - currentFlushMeasurements.push({ - timerType: timerType, - instanceID: debugID, - duration: performanceNow() - currentTimerStartTime - currentTimerNestedFlushDuration - }); - } - currentTimerStartTime = 0; - currentTimerNestedFlushDuration = 0; - currentTimerDebugID = null; - currentTimerType = null; -} - -function pauseCurrentLifeCycleTimer() { - var currentTimer = { - startTime: currentTimerStartTime, - nestedFlushStartTime: performanceNow(), - debugID: currentTimerDebugID, - timerType: currentTimerType - }; - lifeCycleTimerStack.push(currentTimer); - currentTimerStartTime = 0; - currentTimerNestedFlushDuration = 0; - currentTimerDebugID = null; - currentTimerType = null; -} - -function resumeCurrentLifeCycleTimer() { - var _lifeCycleTimerStack$ = lifeCycleTimerStack.pop(), - startTime = _lifeCycleTimerStack$.startTime, - nestedFlushStartTime = _lifeCycleTimerStack$.nestedFlushStartTime, - debugID = _lifeCycleTimerStack$.debugID, - timerType = _lifeCycleTimerStack$.timerType; - - var nestedFlushDuration = performanceNow() - nestedFlushStartTime; - currentTimerStartTime = startTime; - currentTimerNestedFlushDuration += nestedFlushDuration; - currentTimerDebugID = debugID; - currentTimerType = timerType; -} - -var lastMarkTimeStamp = 0; -var canUsePerformanceMeasure = -// $FlowFixMe https://github.com/facebook/flow/issues/2345 -typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; - -function shouldMark(debugID) { - if (!isProfiling || !canUsePerformanceMeasure) { - return false; - } - var element = ReactComponentTreeHook.getElement(debugID); - if (element == null || typeof element !== 'object') { - return false; - } - var isHostElement = typeof element.type === 'string'; - if (isHostElement) { - return false; - } - return true; -} - -function markBegin(debugID, markType) { - if (!shouldMark(debugID)) { - return; - } - - var markName = debugID + '::' + markType; - lastMarkTimeStamp = performanceNow(); - performance.mark(markName); -} - -function markEnd(debugID, markType) { - if (!shouldMark(debugID)) { - return; - } - - var markName = debugID + '::' + markType; - var displayName = ReactComponentTreeHook.getDisplayName(debugID) || 'Unknown'; - - // Chrome has an issue of dropping markers recorded too fast: - // https://bugs.chromium.org/p/chromium/issues/detail?id=640652 - // To work around this, we will not report very small measurements. - // I determined the magic number by tweaking it back and forth. - // 0.05ms was enough to prevent the issue, but I set it to 0.1ms to be safe. - // When the bug is fixed, we can `measure()` unconditionally if we want to. - var timeStamp = performanceNow(); - if (timeStamp - lastMarkTimeStamp > 0.1) { - var measurementName = displayName + ' [' + markType + ']'; - performance.measure(measurementName, markName); - } - - performance.clearMarks(markName); - performance.clearMeasures(measurementName); -} - -var ReactDebugTool = { - addHook: function (hook) { - hooks.push(hook); - }, - removeHook: function (hook) { - for (var i = 0; i < hooks.length; i++) { - if (hooks[i] === hook) { - hooks.splice(i, 1); - i--; - } - } - }, - isProfiling: function () { - return isProfiling; - }, - beginProfiling: function () { - if (isProfiling) { - return; - } - - isProfiling = true; - flushHistory.length = 0; - resetMeasurements(); - ReactDebugTool.addHook(ReactHostOperationHistoryHook); - }, - endProfiling: function () { - if (!isProfiling) { - return; - } - - isProfiling = false; - resetMeasurements(); - ReactDebugTool.removeHook(ReactHostOperationHistoryHook); - }, - getFlushHistory: function () { - return flushHistory; - }, - onBeginFlush: function () { - currentFlushNesting++; - resetMeasurements(); - pauseCurrentLifeCycleTimer(); - emitEvent('onBeginFlush'); - }, - onEndFlush: function () { - resetMeasurements(); - currentFlushNesting--; - resumeCurrentLifeCycleTimer(); - emitEvent('onEndFlush'); - }, - onBeginLifeCycleTimer: function (debugID, timerType) { - checkDebugID(debugID); - emitEvent('onBeginLifeCycleTimer', debugID, timerType); - markBegin(debugID, timerType); - beginLifeCycleTimer(debugID, timerType); - }, - onEndLifeCycleTimer: function (debugID, timerType) { - checkDebugID(debugID); - endLifeCycleTimer(debugID, timerType); - markEnd(debugID, timerType); - emitEvent('onEndLifeCycleTimer', debugID, timerType); - }, - onBeginProcessingChildContext: function () { - emitEvent('onBeginProcessingChildContext'); - }, - onEndProcessingChildContext: function () { - emitEvent('onEndProcessingChildContext'); - }, - onHostOperation: function (operation) { - checkDebugID(operation.instanceID); - emitEvent('onHostOperation', operation); - }, - onSetState: function () { - emitEvent('onSetState'); - }, - onSetChildren: function (debugID, childDebugIDs) { - checkDebugID(debugID); - childDebugIDs.forEach(checkDebugID); - emitEvent('onSetChildren', debugID, childDebugIDs); - }, - onBeforeMountComponent: function (debugID, element, parentDebugID) { - checkDebugID(debugID); - checkDebugID(parentDebugID, true); - emitEvent('onBeforeMountComponent', debugID, element, parentDebugID); - markBegin(debugID, 'mount'); - }, - onMountComponent: function (debugID) { - checkDebugID(debugID); - markEnd(debugID, 'mount'); - emitEvent('onMountComponent', debugID); - }, - onBeforeUpdateComponent: function (debugID, element) { - checkDebugID(debugID); - emitEvent('onBeforeUpdateComponent', debugID, element); - markBegin(debugID, 'update'); - }, - onUpdateComponent: function (debugID) { - checkDebugID(debugID); - markEnd(debugID, 'update'); - emitEvent('onUpdateComponent', debugID); - }, - onBeforeUnmountComponent: function (debugID) { - checkDebugID(debugID); - emitEvent('onBeforeUnmountComponent', debugID); - markBegin(debugID, 'unmount'); - }, - onUnmountComponent: function (debugID) { - checkDebugID(debugID); - markEnd(debugID, 'unmount'); - emitEvent('onUnmountComponent', debugID); - }, - onTestEvent: function () { - emitEvent('onTestEvent'); - } -}; - -// TODO remove these when RN/www gets updated -ReactDebugTool.addDevtool = ReactDebugTool.addHook; -ReactDebugTool.removeDevtool = ReactDebugTool.removeHook; - -ReactDebugTool.addHook(ReactInvalidSetStateWarningHook); -ReactDebugTool.addHook(ReactComponentTreeHook); -var url = ExecutionEnvironment.canUseDOM && window.location.href || ''; -if (/[?&]react_perf\b/.test(url)) { - ReactDebugTool.beginProfiling(); -} - -module.exports = ReactDebugTool; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 267 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var ReactUpdates = __webpack_require__(14); -var Transaction = __webpack_require__(38); - -var emptyFunction = __webpack_require__(12); - -var RESET_BATCHED_UPDATES = { - initialize: emptyFunction, - close: function () { - ReactDefaultBatchingStrategy.isBatchingUpdates = false; - } -}; - -var FLUSH_BATCHED_UPDATES = { - initialize: emptyFunction, - close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates) -}; - -var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES]; - -function ReactDefaultBatchingStrategyTransaction() { - this.reinitializeTransaction(); -} - -_assign(ReactDefaultBatchingStrategyTransaction.prototype, Transaction, { - getTransactionWrappers: function () { - return TRANSACTION_WRAPPERS; - } -}); - -var transaction = new ReactDefaultBatchingStrategyTransaction(); - -var ReactDefaultBatchingStrategy = { - isBatchingUpdates: false, - - /** - * Call the provided function in a context within which calls to `setState` - * and friends are batched such that components aren't updated unnecessarily. - */ - batchedUpdates: function (callback, a, b, c, d, e) { - var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates; - - ReactDefaultBatchingStrategy.isBatchingUpdates = true; - - // The code is written this way to avoid extra allocations - if (alreadyBatchingUpdates) { - return callback(a, b, c, d, e); - } else { - return transaction.perform(callback, null, a, b, c, d, e); - } - } -}; - -module.exports = ReactDefaultBatchingStrategy; - -/***/ }), -/* 268 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ARIADOMPropertyConfig = __webpack_require__(238); -var BeforeInputEventPlugin = __webpack_require__(240); -var ChangeEventPlugin = __webpack_require__(242); -var DefaultEventPluginOrder = __webpack_require__(244); -var EnterLeaveEventPlugin = __webpack_require__(245); -var HTMLDOMPropertyConfig = __webpack_require__(247); -var ReactComponentBrowserEnvironment = __webpack_require__(249); -var ReactDOMComponent = __webpack_require__(252); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactDOMEmptyComponent = __webpack_require__(254); -var ReactDOMTreeTraversal = __webpack_require__(264); -var ReactDOMTextComponent = __webpack_require__(262); -var ReactDefaultBatchingStrategy = __webpack_require__(267); -var ReactEventListener = __webpack_require__(271); -var ReactInjection = __webpack_require__(273); -var ReactReconcileTransaction = __webpack_require__(279); -var SVGDOMPropertyConfig = __webpack_require__(284); -var SelectEventPlugin = __webpack_require__(285); -var SimpleEventPlugin = __webpack_require__(286); - -var alreadyInjected = false; - -function inject() { - if (alreadyInjected) { - // TODO: This is currently true because these injections are shared between - // the client and the server package. They should be built independently - // and not share any injection state. Then this problem will be solved. - return; - } - alreadyInjected = true; - - ReactInjection.EventEmitter.injectReactEventListener(ReactEventListener); - - /** - * Inject modules for resolving DOM hierarchy and plugin ordering. - */ - ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder); - ReactInjection.EventPluginUtils.injectComponentTree(ReactDOMComponentTree); - ReactInjection.EventPluginUtils.injectTreeTraversal(ReactDOMTreeTraversal); - - /** - * Some important event plugins included by default (without having to require - * them). - */ - ReactInjection.EventPluginHub.injectEventPluginsByName({ - SimpleEventPlugin: SimpleEventPlugin, - EnterLeaveEventPlugin: EnterLeaveEventPlugin, - ChangeEventPlugin: ChangeEventPlugin, - SelectEventPlugin: SelectEventPlugin, - BeforeInputEventPlugin: BeforeInputEventPlugin - }); - - ReactInjection.HostComponent.injectGenericComponentClass(ReactDOMComponent); - - ReactInjection.HostComponent.injectTextComponentClass(ReactDOMTextComponent); - - ReactInjection.DOMProperty.injectDOMPropertyConfig(ARIADOMPropertyConfig); - ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig); - ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig); - - ReactInjection.EmptyComponent.injectEmptyComponentFactory(function (instantiate) { - return new ReactDOMEmptyComponent(instantiate); - }); - - ReactInjection.Updates.injectReconcileTransaction(ReactReconcileTransaction); - ReactInjection.Updates.injectBatchingStrategy(ReactDefaultBatchingStrategy); - - ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment); -} - -module.exports = { - inject: inject -}; - -/***/ }), -/* 269 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -// The Symbol used to tag the ReactElement type. If there is no native Symbol -// nor polyfill, then a plain number is used for performance. - -var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7; - -module.exports = REACT_ELEMENT_TYPE; - -/***/ }), -/* 270 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var EventPluginHub = __webpack_require__(30); - -function runEventQueueInBatch(events) { - EventPluginHub.enqueueEvents(events); - EventPluginHub.processEventQueue(false); -} - -var ReactEventEmitterMixin = { - - /** - * Streams a fired top-level event to `EventPluginHub` where plugins have the - * opportunity to create `ReactEvent`s to be dispatched. - */ - handleTopLevel: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var events = EventPluginHub.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); - runEventQueueInBatch(events); - } -}; - -module.exports = ReactEventEmitterMixin; - -/***/ }), -/* 271 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var EventListener = __webpack_require__(72); -var ExecutionEnvironment = __webpack_require__(8); -var PooledClass = __webpack_require__(20); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactUpdates = __webpack_require__(14); - -var getEventTarget = __webpack_require__(57); -var getUnboundedScrollPosition = __webpack_require__(220); - -/** - * Find the deepest React component completely containing the root of the - * passed-in instance (for use when entire React trees are nested within each - * other). If React trees are not nested, returns null. - */ -function findParent(inst) { - // TODO: It may be a good idea to cache this to prevent unnecessary DOM - // traversal, but caching is difficult to do correctly without using a - // mutation observer to listen for all DOM changes. - while (inst._hostParent) { - inst = inst._hostParent; - } - var rootNode = ReactDOMComponentTree.getNodeFromInstance(inst); - var container = rootNode.parentNode; - return ReactDOMComponentTree.getClosestInstanceFromNode(container); -} - -// Used to store ancestor hierarchy in top level callback -function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) { - this.topLevelType = topLevelType; - this.nativeEvent = nativeEvent; - this.ancestors = []; -} -_assign(TopLevelCallbackBookKeeping.prototype, { - destructor: function () { - this.topLevelType = null; - this.nativeEvent = null; - this.ancestors.length = 0; - } -}); -PooledClass.addPoolingTo(TopLevelCallbackBookKeeping, PooledClass.twoArgumentPooler); - -function handleTopLevelImpl(bookKeeping) { - var nativeEventTarget = getEventTarget(bookKeeping.nativeEvent); - var targetInst = ReactDOMComponentTree.getClosestInstanceFromNode(nativeEventTarget); - - // Loop through the hierarchy, in case there's any nested components. - // It's important that we build the array of ancestors before calling any - // event handlers, because event handlers can modify the DOM, leading to - // inconsistencies with ReactMount's node cache. See #1105. - var ancestor = targetInst; - do { - bookKeeping.ancestors.push(ancestor); - ancestor = ancestor && findParent(ancestor); - } while (ancestor); - - for (var i = 0; i < bookKeeping.ancestors.length; i++) { - targetInst = bookKeeping.ancestors[i]; - ReactEventListener._handleTopLevel(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent)); - } -} - -function scrollValueMonitor(cb) { - var scrollPosition = getUnboundedScrollPosition(window); - cb(scrollPosition); -} - -var ReactEventListener = { - _enabled: true, - _handleTopLevel: null, - - WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null, - - setHandleTopLevel: function (handleTopLevel) { - ReactEventListener._handleTopLevel = handleTopLevel; - }, - - setEnabled: function (enabled) { - ReactEventListener._enabled = !!enabled; - }, - - isEnabled: function () { - return ReactEventListener._enabled; - }, - - /** - * Traps top-level events by using event bubbling. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {string} handlerBaseName Event name (e.g. "click"). - * @param {object} element Element on which to attach listener. - * @return {?object} An object with a remove function which will forcefully - * remove the listener. - * @internal - */ - trapBubbledEvent: function (topLevelType, handlerBaseName, element) { - if (!element) { - return null; - } - return EventListener.listen(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType)); - }, - - /** - * Traps a top-level event by using event capturing. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {string} handlerBaseName Event name (e.g. "click"). - * @param {object} element Element on which to attach listener. - * @return {?object} An object with a remove function which will forcefully - * remove the listener. - * @internal - */ - trapCapturedEvent: function (topLevelType, handlerBaseName, element) { - if (!element) { - return null; - } - return EventListener.capture(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType)); - }, - - monitorScrollValue: function (refresh) { - var callback = scrollValueMonitor.bind(null, refresh); - EventListener.listen(window, 'scroll', callback); - }, - - dispatchEvent: function (topLevelType, nativeEvent) { - if (!ReactEventListener._enabled) { - return; - } - - var bookKeeping = TopLevelCallbackBookKeeping.getPooled(topLevelType, nativeEvent); - try { - // Event queue being processed in the same cycle allows - // `preventDefault`. - ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping); - } finally { - TopLevelCallbackBookKeeping.release(bookKeeping); - } - } -}; - -module.exports = ReactEventListener; - -/***/ }), -/* 272 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var history = []; - -var ReactHostOperationHistoryHook = { - onHostOperation: function (operation) { - history.push(operation); - }, - clearHistory: function () { - if (ReactHostOperationHistoryHook._preventClearing) { - // Should only be used for tests. - return; - } - - history = []; - }, - getHistory: function () { - return history; - } -}; - -module.exports = ReactHostOperationHistoryHook; - -/***/ }), -/* 273 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var DOMProperty = __webpack_require__(18); -var EventPluginHub = __webpack_require__(30); -var EventPluginUtils = __webpack_require__(48); -var ReactComponentEnvironment = __webpack_require__(51); -var ReactEmptyComponent = __webpack_require__(83); -var ReactBrowserEventEmitter = __webpack_require__(36); -var ReactHostComponent = __webpack_require__(85); -var ReactUpdates = __webpack_require__(14); - -var ReactInjection = { - Component: ReactComponentEnvironment.injection, - DOMProperty: DOMProperty.injection, - EmptyComponent: ReactEmptyComponent.injection, - EventPluginHub: EventPluginHub.injection, - EventPluginUtils: EventPluginUtils.injection, - EventEmitter: ReactBrowserEventEmitter.injection, - HostComponent: ReactHostComponent.injection, - Updates: ReactUpdates.injection -}; - -module.exports = ReactInjection; - -/***/ }), -/* 274 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var warning = __webpack_require__(3); - -if (process.env.NODE_ENV !== 'production') { - var processingChildContext = false; - - var warnInvalidSetState = function () { - process.env.NODE_ENV !== 'production' ? warning(!processingChildContext, 'setState(...): Cannot call setState() inside getChildContext()') : void 0; - }; -} - -var ReactInvalidSetStateWarningHook = { - onBeginProcessingChildContext: function () { - processingChildContext = true; - }, - onEndProcessingChildContext: function () { - processingChildContext = false; - }, - onSetState: function () { - warnInvalidSetState(); - } -}; - -module.exports = ReactInvalidSetStateWarningHook; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 275 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var adler32 = __webpack_require__(297); - -var TAG_END = /\/?>/; -var COMMENT_START = /^<\!\-\-/; - -var ReactMarkupChecksum = { - CHECKSUM_ATTR_NAME: 'data-react-checksum', - - /** - * @param {string} markup Markup string - * @return {string} Markup string with checksum attribute attached - */ - addChecksumToMarkup: function (markup) { - var checksum = adler32(markup); - - // Add checksum (handle both parent tags, comments and self-closing tags) - if (COMMENT_START.test(markup)) { - return markup; - } else { - return markup.replace(TAG_END, ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '"$&'); - } - }, - - /** - * @param {string} markup to use - * @param {DOMElement} element root React element - * @returns {boolean} whether or not the markup is the same - */ - canReuseMarkup: function (markup, element) { - var existingChecksum = element.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); - existingChecksum = existingChecksum && parseInt(existingChecksum, 10); - var markupChecksum = adler32(markup); - return markupChecksum === existingChecksum; - } -}; - -module.exports = ReactMarkupChecksum; - -/***/ }), -/* 276 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var ReactComponentEnvironment = __webpack_require__(51); -var ReactInstanceMap = __webpack_require__(32); -var ReactInstrumentation = __webpack_require__(10); - -var ReactCurrentOwner = __webpack_require__(15); -var ReactReconciler = __webpack_require__(26); -var ReactChildReconciler = __webpack_require__(248); - -var emptyFunction = __webpack_require__(12); -var flattenChildren = __webpack_require__(301); -var invariant = __webpack_require__(2); - -/** - * Make an update for markup to be rendered and inserted at a supplied index. - * - * @param {string} markup Markup that renders into an element. - * @param {number} toIndex Destination index. - * @private - */ -function makeInsertMarkup(markup, afterNode, toIndex) { - // NOTE: Null values reduce hidden classes. - return { - type: 'INSERT_MARKUP', - content: markup, - fromIndex: null, - fromNode: null, - toIndex: toIndex, - afterNode: afterNode - }; -} - -/** - * Make an update for moving an existing element to another index. - * - * @param {number} fromIndex Source index of the existing element. - * @param {number} toIndex Destination index of the element. - * @private - */ -function makeMove(child, afterNode, toIndex) { - // NOTE: Null values reduce hidden classes. - return { - type: 'MOVE_EXISTING', - content: null, - fromIndex: child._mountIndex, - fromNode: ReactReconciler.getHostNode(child), - toIndex: toIndex, - afterNode: afterNode - }; -} - -/** - * Make an update for removing an element at an index. - * - * @param {number} fromIndex Index of the element to remove. - * @private - */ -function makeRemove(child, node) { - // NOTE: Null values reduce hidden classes. - return { - type: 'REMOVE_NODE', - content: null, - fromIndex: child._mountIndex, - fromNode: node, - toIndex: null, - afterNode: null - }; -} - -/** - * Make an update for setting the markup of a node. - * - * @param {string} markup Markup that renders into an element. - * @private - */ -function makeSetMarkup(markup) { - // NOTE: Null values reduce hidden classes. - return { - type: 'SET_MARKUP', - content: markup, - fromIndex: null, - fromNode: null, - toIndex: null, - afterNode: null - }; -} - -/** - * Make an update for setting the text content. - * - * @param {string} textContent Text content to set. - * @private - */ -function makeTextContent(textContent) { - // NOTE: Null values reduce hidden classes. - return { - type: 'TEXT_CONTENT', - content: textContent, - fromIndex: null, - fromNode: null, - toIndex: null, - afterNode: null - }; -} - -/** - * Push an update, if any, onto the queue. Creates a new queue if none is - * passed and always returns the queue. Mutative. - */ -function enqueue(queue, update) { - if (update) { - queue = queue || []; - queue.push(update); - } - return queue; -} - -/** - * Processes any enqueued updates. - * - * @private - */ -function processQueue(inst, updateQueue) { - ReactComponentEnvironment.processChildrenUpdates(inst, updateQueue); -} - -var setChildrenForInstrumentation = emptyFunction; -if (process.env.NODE_ENV !== 'production') { - var getDebugID = function (inst) { - if (!inst._debugID) { - // Check for ART-like instances. TODO: This is silly/gross. - var internal; - if (internal = ReactInstanceMap.get(inst)) { - inst = internal; - } - } - return inst._debugID; - }; - setChildrenForInstrumentation = function (children) { - var debugID = getDebugID(this); - // TODO: React Native empty components are also multichild. - // This means they still get into this method but don't have _debugID. - if (debugID !== 0) { - ReactInstrumentation.debugTool.onSetChildren(debugID, children ? Object.keys(children).map(function (key) { - return children[key]._debugID; - }) : []); - } - }; -} - -/** - * ReactMultiChild are capable of reconciling multiple children. - * - * @class ReactMultiChild - * @internal - */ -var ReactMultiChild = { - - /** - * Provides common functionality for components that must reconcile multiple - * children. This is used by `ReactDOMComponent` to mount, update, and - * unmount child components. - * - * @lends {ReactMultiChild.prototype} - */ - Mixin: { - - _reconcilerInstantiateChildren: function (nestedChildren, transaction, context) { - if (process.env.NODE_ENV !== 'production') { - var selfDebugID = getDebugID(this); - if (this._currentElement) { - try { - ReactCurrentOwner.current = this._currentElement._owner; - return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context, selfDebugID); - } finally { - ReactCurrentOwner.current = null; - } - } - } - return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context); - }, - - _reconcilerUpdateChildren: function (prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context) { - var nextChildren; - var selfDebugID = 0; - if (process.env.NODE_ENV !== 'production') { - selfDebugID = getDebugID(this); - if (this._currentElement) { - try { - ReactCurrentOwner.current = this._currentElement._owner; - nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID); - } finally { - ReactCurrentOwner.current = null; - } - ReactChildReconciler.updateChildren(prevChildren, nextChildren, mountImages, removedNodes, transaction, this, this._hostContainerInfo, context, selfDebugID); - return nextChildren; - } - } - nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID); - ReactChildReconciler.updateChildren(prevChildren, nextChildren, mountImages, removedNodes, transaction, this, this._hostContainerInfo, context, selfDebugID); - return nextChildren; - }, - - /** - * Generates a "mount image" for each of the supplied children. In the case - * of `ReactDOMComponent`, a mount image is a string of markup. - * - * @param {?object} nestedChildren Nested child maps. - * @return {array} An array of mounted representations. - * @internal - */ - mountChildren: function (nestedChildren, transaction, context) { - var children = this._reconcilerInstantiateChildren(nestedChildren, transaction, context); - this._renderedChildren = children; - - var mountImages = []; - var index = 0; - for (var name in children) { - if (children.hasOwnProperty(name)) { - var child = children[name]; - var selfDebugID = 0; - if (process.env.NODE_ENV !== 'production') { - selfDebugID = getDebugID(this); - } - var mountImage = ReactReconciler.mountComponent(child, transaction, this, this._hostContainerInfo, context, selfDebugID); - child._mountIndex = index++; - mountImages.push(mountImage); - } - } - - if (process.env.NODE_ENV !== 'production') { - setChildrenForInstrumentation.call(this, children); - } - - return mountImages; - }, - - /** - * Replaces any rendered children with a text content string. - * - * @param {string} nextContent String of content. - * @internal - */ - updateTextContent: function (nextContent) { - var prevChildren = this._renderedChildren; - // Remove any rendered children. - ReactChildReconciler.unmountChildren(prevChildren, false); - for (var name in prevChildren) { - if (prevChildren.hasOwnProperty(name)) { - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'updateTextContent called on non-empty component.') : _prodInvariant('118') : void 0; - } - } - // Set new text content. - var updates = [makeTextContent(nextContent)]; - processQueue(this, updates); - }, - - /** - * Replaces any rendered children with a markup string. - * - * @param {string} nextMarkup String of markup. - * @internal - */ - updateMarkup: function (nextMarkup) { - var prevChildren = this._renderedChildren; - // Remove any rendered children. - ReactChildReconciler.unmountChildren(prevChildren, false); - for (var name in prevChildren) { - if (prevChildren.hasOwnProperty(name)) { - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'updateTextContent called on non-empty component.') : _prodInvariant('118') : void 0; - } - } - var updates = [makeSetMarkup(nextMarkup)]; - processQueue(this, updates); - }, - - /** - * Updates the rendered children with new children. - * - * @param {?object} nextNestedChildrenElements Nested child element maps. - * @param {ReactReconcileTransaction} transaction - * @internal - */ - updateChildren: function (nextNestedChildrenElements, transaction, context) { - // Hook used by React ART - this._updateChildren(nextNestedChildrenElements, transaction, context); - }, - - /** - * @param {?object} nextNestedChildrenElements Nested child element maps. - * @param {ReactReconcileTransaction} transaction - * @final - * @protected - */ - _updateChildren: function (nextNestedChildrenElements, transaction, context) { - var prevChildren = this._renderedChildren; - var removedNodes = {}; - var mountImages = []; - var nextChildren = this._reconcilerUpdateChildren(prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context); - if (!nextChildren && !prevChildren) { - return; - } - var updates = null; - var name; - // `nextIndex` will increment for each child in `nextChildren`, but - // `lastIndex` will be the last index visited in `prevChildren`. - var nextIndex = 0; - var lastIndex = 0; - // `nextMountIndex` will increment for each newly mounted child. - var nextMountIndex = 0; - var lastPlacedNode = null; - for (name in nextChildren) { - if (!nextChildren.hasOwnProperty(name)) { - continue; - } - var prevChild = prevChildren && prevChildren[name]; - var nextChild = nextChildren[name]; - if (prevChild === nextChild) { - updates = enqueue(updates, this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex)); - lastIndex = Math.max(prevChild._mountIndex, lastIndex); - prevChild._mountIndex = nextIndex; - } else { - if (prevChild) { - // Update `lastIndex` before `_mountIndex` gets unset by unmounting. - lastIndex = Math.max(prevChild._mountIndex, lastIndex); - // The `removedNodes` loop below will actually remove the child. - } - // The child must be instantiated before it's mounted. - updates = enqueue(updates, this._mountChildAtIndex(nextChild, mountImages[nextMountIndex], lastPlacedNode, nextIndex, transaction, context)); - nextMountIndex++; - } - nextIndex++; - lastPlacedNode = ReactReconciler.getHostNode(nextChild); - } - // Remove children that are no longer present. - for (name in removedNodes) { - if (removedNodes.hasOwnProperty(name)) { - updates = enqueue(updates, this._unmountChild(prevChildren[name], removedNodes[name])); - } - } - if (updates) { - processQueue(this, updates); - } - this._renderedChildren = nextChildren; - - if (process.env.NODE_ENV !== 'production') { - setChildrenForInstrumentation.call(this, nextChildren); - } - }, - - /** - * Unmounts all rendered children. This should be used to clean up children - * when this component is unmounted. It does not actually perform any - * backend operations. - * - * @internal - */ - unmountChildren: function (safely) { - var renderedChildren = this._renderedChildren; - ReactChildReconciler.unmountChildren(renderedChildren, safely); - this._renderedChildren = null; - }, - - /** - * Moves a child component to the supplied index. - * - * @param {ReactComponent} child Component to move. - * @param {number} toIndex Destination index of the element. - * @param {number} lastIndex Last index visited of the siblings of `child`. - * @protected - */ - moveChild: function (child, afterNode, toIndex, lastIndex) { - // If the index of `child` is less than `lastIndex`, then it needs to - // be moved. Otherwise, we do not need to move it because a child will be - // inserted or moved before `child`. - if (child._mountIndex < lastIndex) { - return makeMove(child, afterNode, toIndex); - } - }, - - /** - * Creates a child component. - * - * @param {ReactComponent} child Component to create. - * @param {string} mountImage Markup to insert. - * @protected - */ - createChild: function (child, afterNode, mountImage) { - return makeInsertMarkup(mountImage, afterNode, child._mountIndex); - }, - - /** - * Removes a child component. - * - * @param {ReactComponent} child Child to remove. - * @protected - */ - removeChild: function (child, node) { - return makeRemove(child, node); - }, - - /** - * Mounts a child with the supplied name. - * - * NOTE: This is part of `updateChildren` and is here for readability. - * - * @param {ReactComponent} child Component to mount. - * @param {string} name Name of the child. - * @param {number} index Index at which to insert the child. - * @param {ReactReconcileTransaction} transaction - * @private - */ - _mountChildAtIndex: function (child, mountImage, afterNode, index, transaction, context) { - child._mountIndex = index; - return this.createChild(child, afterNode, mountImage); - }, - - /** - * Unmounts a rendered child. - * - * NOTE: This is part of `updateChildren` and is here for readability. - * - * @param {ReactComponent} child Component to unmount. - * @private - */ - _unmountChild: function (child, node) { - var update = this.removeChild(child, node); - child._mountIndex = null; - return update; - } - - } - -}; - -module.exports = ReactMultiChild; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 277 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var invariant = __webpack_require__(2); - -/** - * @param {?object} object - * @return {boolean} True if `object` is a valid owner. - * @final - */ -function isValidOwner(object) { - return !!(object && typeof object.attachRef === 'function' && typeof object.detachRef === 'function'); -} - -/** - * ReactOwners are capable of storing references to owned components. - * - * All components are capable of //being// referenced by owner components, but - * only ReactOwner components are capable of //referencing// owned components. - * The named reference is known as a "ref". - * - * Refs are available when mounted and updated during reconciliation. - * - * var MyComponent = React.createClass({ - * render: function() { - * return ( - * <div onClick={this.handleClick}> - * <CustomComponent ref="custom" /> - * </div> - * ); - * }, - * handleClick: function() { - * this.refs.custom.handleClick(); - * }, - * componentDidMount: function() { - * this.refs.custom.initialize(); - * } - * }); - * - * Refs should rarely be used. When refs are used, they should only be done to - * control data that is not handled by React's data flow. - * - * @class ReactOwner - */ -var ReactOwner = { - /** - * Adds a component by ref to an owner component. - * - * @param {ReactComponent} component Component to reference. - * @param {string} ref Name by which to refer to the component. - * @param {ReactOwner} owner Component on which to record the ref. - * @final - * @internal - */ - addComponentAsRefTo: function (component, ref, owner) { - !isValidOwner(owner) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component\'s `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).') : _prodInvariant('119') : void 0; - owner.attachRef(ref, component); - }, - - /** - * Removes a component by ref from an owner component. - * - * @param {ReactComponent} component Component to dereference. - * @param {string} ref Name of the ref to remove. - * @param {ReactOwner} owner Component on which the ref is recorded. - * @final - * @internal - */ - removeComponentAsRefFrom: function (component, ref, owner) { - !isValidOwner(owner) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might be removing a ref to a component that was not created inside a component\'s `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).') : _prodInvariant('120') : void 0; - var ownerPublicInstance = owner.getPublicInstance(); - // Check that `component`'s owner is still alive and that `component` is still the current ref - // because we do not want to detach the ref if another component stole it. - if (ownerPublicInstance && ownerPublicInstance.refs[ref] === component.getPublicInstance()) { - owner.detachRef(ref); - } - } - -}; - -module.exports = ReactOwner; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 278 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactPropTypeLocationNames = {}; - -if (process.env.NODE_ENV !== 'production') { - ReactPropTypeLocationNames = { - prop: 'prop', - context: 'context', - childContext: 'child context' - }; -} - -module.exports = ReactPropTypeLocationNames; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 279 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var CallbackQueue = __webpack_require__(79); -var PooledClass = __webpack_require__(20); -var ReactBrowserEventEmitter = __webpack_require__(36); -var ReactInputSelection = __webpack_require__(86); -var ReactInstrumentation = __webpack_require__(10); -var Transaction = __webpack_require__(38); -var ReactUpdateQueue = __webpack_require__(53); - -/** - * Ensures that, when possible, the selection range (currently selected text - * input) is not disturbed by performing the transaction. - */ -var SELECTION_RESTORATION = { - /** - * @return {Selection} Selection information. - */ - initialize: ReactInputSelection.getSelectionInformation, - /** - * @param {Selection} sel Selection information returned from `initialize`. - */ - close: ReactInputSelection.restoreSelection -}; - -/** - * Suppresses events (blur/focus) that could be inadvertently dispatched due to - * high level DOM manipulations (like temporarily removing a text input from the - * DOM). - */ -var EVENT_SUPPRESSION = { - /** - * @return {boolean} The enabled status of `ReactBrowserEventEmitter` before - * the reconciliation. - */ - initialize: function () { - var currentlyEnabled = ReactBrowserEventEmitter.isEnabled(); - ReactBrowserEventEmitter.setEnabled(false); - return currentlyEnabled; - }, - - /** - * @param {boolean} previouslyEnabled Enabled status of - * `ReactBrowserEventEmitter` before the reconciliation occurred. `close` - * restores the previous value. - */ - close: function (previouslyEnabled) { - ReactBrowserEventEmitter.setEnabled(previouslyEnabled); - } -}; - -/** - * Provides a queue for collecting `componentDidMount` and - * `componentDidUpdate` callbacks during the transaction. - */ -var ON_DOM_READY_QUEUEING = { - /** - * Initializes the internal `onDOMReady` queue. - */ - initialize: function () { - this.reactMountReady.reset(); - }, - - /** - * After DOM is flushed, invoke all registered `onDOMReady` callbacks. - */ - close: function () { - this.reactMountReady.notifyAll(); - } -}; - -/** - * Executed within the scope of the `Transaction` instance. Consider these as - * being member methods, but with an implied ordering while being isolated from - * each other. - */ -var TRANSACTION_WRAPPERS = [SELECTION_RESTORATION, EVENT_SUPPRESSION, ON_DOM_READY_QUEUEING]; - -if (process.env.NODE_ENV !== 'production') { - TRANSACTION_WRAPPERS.push({ - initialize: ReactInstrumentation.debugTool.onBeginFlush, - close: ReactInstrumentation.debugTool.onEndFlush - }); -} - -/** - * Currently: - * - The order that these are listed in the transaction is critical: - * - Suppresses events. - * - Restores selection range. - * - * Future: - * - Restore document/overflow scroll positions that were unintentionally - * modified via DOM insertions above the top viewport boundary. - * - Implement/integrate with customized constraint based layout system and keep - * track of which dimensions must be remeasured. - * - * @class ReactReconcileTransaction - */ -function ReactReconcileTransaction(useCreateElement) { - this.reinitializeTransaction(); - // Only server-side rendering really needs this option (see - // `ReactServerRendering`), but server-side uses - // `ReactServerRenderingTransaction` instead. This option is here so that it's - // accessible and defaults to false when `ReactDOMComponent` and - // `ReactDOMTextComponent` checks it in `mountComponent`.` - this.renderToStaticMarkup = false; - this.reactMountReady = CallbackQueue.getPooled(null); - this.useCreateElement = useCreateElement; -} - -var Mixin = { - /** - * @see Transaction - * @abstract - * @final - * @return {array<object>} List of operation wrap procedures. - * TODO: convert to array<TransactionWrapper> - */ - getTransactionWrappers: function () { - return TRANSACTION_WRAPPERS; - }, - - /** - * @return {object} The queue to collect `onDOMReady` callbacks with. - */ - getReactMountReady: function () { - return this.reactMountReady; - }, - - /** - * @return {object} The queue to collect React async events. - */ - getUpdateQueue: function () { - return ReactUpdateQueue; - }, - - /** - * Save current transaction state -- if the return value from this method is - * passed to `rollback`, the transaction will be reset to that state. - */ - checkpoint: function () { - // reactMountReady is the our only stateful wrapper - return this.reactMountReady.checkpoint(); - }, - - rollback: function (checkpoint) { - this.reactMountReady.rollback(checkpoint); - }, - - /** - * `PooledClass` looks for this, and will invoke this before allowing this - * instance to be reused. - */ - destructor: function () { - CallbackQueue.release(this.reactMountReady); - this.reactMountReady = null; - } -}; - -_assign(ReactReconcileTransaction.prototype, Transaction, Mixin); - -PooledClass.addPoolingTo(ReactReconcileTransaction); - -module.exports = ReactReconcileTransaction; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 280 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var ReactOwner = __webpack_require__(277); - -var ReactRef = {}; - -function attachRef(ref, component, owner) { - if (typeof ref === 'function') { - ref(component.getPublicInstance()); - } else { - // Legacy ref - ReactOwner.addComponentAsRefTo(component, ref, owner); - } -} - -function detachRef(ref, component, owner) { - if (typeof ref === 'function') { - ref(null); - } else { - // Legacy ref - ReactOwner.removeComponentAsRefFrom(component, ref, owner); - } -} - -ReactRef.attachRefs = function (instance, element) { - if (element === null || typeof element !== 'object') { - return; - } - var ref = element.ref; - if (ref != null) { - attachRef(ref, instance, element._owner); - } -}; - -ReactRef.shouldUpdateRefs = function (prevElement, nextElement) { - // If either the owner or a `ref` has changed, make sure the newest owner - // has stored a reference to `this`, and the previous owner (if different) - // has forgotten the reference to `this`. We use the element instead - // of the public this.props because the post processing cannot determine - // a ref. The ref conceptually lives on the element. - - // TODO: Should this even be possible? The owner cannot change because - // it's forbidden by shouldUpdateReactComponent. The ref can change - // if you swap the keys of but not the refs. Reconsider where this check - // is made. It probably belongs where the key checking and - // instantiateReactComponent is done. - - var prevRef = null; - var prevOwner = null; - if (prevElement !== null && typeof prevElement === 'object') { - prevRef = prevElement.ref; - prevOwner = prevElement._owner; - } - - var nextRef = null; - var nextOwner = null; - if (nextElement !== null && typeof nextElement === 'object') { - nextRef = nextElement.ref; - nextOwner = nextElement._owner; - } - - return prevRef !== nextRef || - // If owner changes but we have an unchanged function ref, don't update refs - typeof nextRef === 'string' && nextOwner !== prevOwner; -}; - -ReactRef.detachRefs = function (instance, element) { - if (element === null || typeof element !== 'object') { - return; - } - var ref = element.ref; - if (ref != null) { - detachRef(ref, instance, element._owner); - } -}; - -module.exports = ReactRef; - -/***/ }), -/* 281 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var PooledClass = __webpack_require__(20); -var Transaction = __webpack_require__(38); -var ReactInstrumentation = __webpack_require__(10); -var ReactServerUpdateQueue = __webpack_require__(282); - -/** - * Executed within the scope of the `Transaction` instance. Consider these as - * being member methods, but with an implied ordering while being isolated from - * each other. - */ -var TRANSACTION_WRAPPERS = []; - -if (process.env.NODE_ENV !== 'production') { - TRANSACTION_WRAPPERS.push({ - initialize: ReactInstrumentation.debugTool.onBeginFlush, - close: ReactInstrumentation.debugTool.onEndFlush - }); -} - -var noopCallbackQueue = { - enqueue: function () {} -}; - -/** - * @class ReactServerRenderingTransaction - * @param {boolean} renderToStaticMarkup - */ -function ReactServerRenderingTransaction(renderToStaticMarkup) { - this.reinitializeTransaction(); - this.renderToStaticMarkup = renderToStaticMarkup; - this.useCreateElement = false; - this.updateQueue = new ReactServerUpdateQueue(this); -} - -var Mixin = { - /** - * @see Transaction - * @abstract - * @final - * @return {array} Empty list of operation wrap procedures. - */ - getTransactionWrappers: function () { - return TRANSACTION_WRAPPERS; - }, - - /** - * @return {object} The queue to collect `onDOMReady` callbacks with. - */ - getReactMountReady: function () { - return noopCallbackQueue; - }, - - /** - * @return {object} The queue to collect React async events. - */ - getUpdateQueue: function () { - return this.updateQueue; - }, - - /** - * `PooledClass` looks for this, and will invoke this before allowing this - * instance to be reused. - */ - destructor: function () {}, - - checkpoint: function () {}, - - rollback: function () {} -}; - -_assign(ReactServerRenderingTransaction.prototype, Transaction, Mixin); - -PooledClass.addPoolingTo(ReactServerRenderingTransaction); - -module.exports = ReactServerRenderingTransaction; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 282 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var ReactUpdateQueue = __webpack_require__(53); - -var warning = __webpack_require__(3); - -function warnNoop(publicInstance, callerName) { - if (process.env.NODE_ENV !== 'production') { - var constructor = publicInstance.constructor; - process.env.NODE_ENV !== 'production' ? warning(false, '%s(...): Can only update a mounting component. ' + 'This usually means you called %s() outside componentWillMount() on the server. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, constructor && (constructor.displayName || constructor.name) || 'ReactClass') : void 0; - } -} - -/** - * This is the update queue used for server rendering. - * It delegates to ReactUpdateQueue while server rendering is in progress and - * switches to ReactNoopUpdateQueue after the transaction has completed. - * @class ReactServerUpdateQueue - * @param {Transaction} transaction - */ - -var ReactServerUpdateQueue = function () { - function ReactServerUpdateQueue(transaction) { - _classCallCheck(this, ReactServerUpdateQueue); - - this.transaction = transaction; - } - - /** - * Checks whether or not this composite component is mounted. - * @param {ReactClass} publicInstance The instance we want to test. - * @return {boolean} True if mounted, false otherwise. - * @protected - * @final - */ - - - ReactServerUpdateQueue.prototype.isMounted = function isMounted(publicInstance) { - return false; - }; - - /** - * Enqueue a callback that will be executed after all the pending updates - * have processed. - * - * @param {ReactClass} publicInstance The instance to use as `this` context. - * @param {?function} callback Called after state is updated. - * @internal - */ - - - ReactServerUpdateQueue.prototype.enqueueCallback = function enqueueCallback(publicInstance, callback, callerName) { - if (this.transaction.isInTransaction()) { - ReactUpdateQueue.enqueueCallback(publicInstance, callback, callerName); - } - }; - - /** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldComponentUpdate`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @internal - */ - - - ReactServerUpdateQueue.prototype.enqueueForceUpdate = function enqueueForceUpdate(publicInstance) { - if (this.transaction.isInTransaction()) { - ReactUpdateQueue.enqueueForceUpdate(publicInstance); - } else { - warnNoop(publicInstance, 'forceUpdate'); - } - }; - - /** - * Replaces all of the state. Always use this or `setState` to mutate state. - * You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object|function} completeState Next state. - * @internal - */ - - - ReactServerUpdateQueue.prototype.enqueueReplaceState = function enqueueReplaceState(publicInstance, completeState) { - if (this.transaction.isInTransaction()) { - ReactUpdateQueue.enqueueReplaceState(publicInstance, completeState); - } else { - warnNoop(publicInstance, 'replaceState'); - } - }; - - /** - * Sets a subset of the state. This only exists because _pendingState is - * internal. This provides a merging strategy that is not available to deep - * properties which is confusing. TODO: Expose pendingState or don't use it - * during the merge. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object|function} partialState Next partial state to be merged with state. - * @internal - */ - - - ReactServerUpdateQueue.prototype.enqueueSetState = function enqueueSetState(publicInstance, partialState) { - if (this.transaction.isInTransaction()) { - ReactUpdateQueue.enqueueSetState(publicInstance, partialState); - } else { - warnNoop(publicInstance, 'setState'); - } - }; - - return ReactServerUpdateQueue; -}(); - -module.exports = ReactServerUpdateQueue; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 283 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -module.exports = '15.4.2'; - -/***/ }), -/* 284 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var NS = { - xlink: 'http://www.w3.org/1999/xlink', - xml: 'http://www.w3.org/XML/1998/namespace' -}; - -// We use attributes for everything SVG so let's avoid some duplication and run -// code instead. -// The following are all specified in the HTML config already so we exclude here. -// - class (as className) -// - color -// - height -// - id -// - lang -// - max -// - media -// - method -// - min -// - name -// - style -// - target -// - type -// - width -var ATTRS = { - accentHeight: 'accent-height', - accumulate: 0, - additive: 0, - alignmentBaseline: 'alignment-baseline', - allowReorder: 'allowReorder', - alphabetic: 0, - amplitude: 0, - arabicForm: 'arabic-form', - ascent: 0, - attributeName: 'attributeName', - attributeType: 'attributeType', - autoReverse: 'autoReverse', - azimuth: 0, - baseFrequency: 'baseFrequency', - baseProfile: 'baseProfile', - baselineShift: 'baseline-shift', - bbox: 0, - begin: 0, - bias: 0, - by: 0, - calcMode: 'calcMode', - capHeight: 'cap-height', - clip: 0, - clipPath: 'clip-path', - clipRule: 'clip-rule', - clipPathUnits: 'clipPathUnits', - colorInterpolation: 'color-interpolation', - colorInterpolationFilters: 'color-interpolation-filters', - colorProfile: 'color-profile', - colorRendering: 'color-rendering', - contentScriptType: 'contentScriptType', - contentStyleType: 'contentStyleType', - cursor: 0, - cx: 0, - cy: 0, - d: 0, - decelerate: 0, - descent: 0, - diffuseConstant: 'diffuseConstant', - direction: 0, - display: 0, - divisor: 0, - dominantBaseline: 'dominant-baseline', - dur: 0, - dx: 0, - dy: 0, - edgeMode: 'edgeMode', - elevation: 0, - enableBackground: 'enable-background', - end: 0, - exponent: 0, - externalResourcesRequired: 'externalResourcesRequired', - fill: 0, - fillOpacity: 'fill-opacity', - fillRule: 'fill-rule', - filter: 0, - filterRes: 'filterRes', - filterUnits: 'filterUnits', - floodColor: 'flood-color', - floodOpacity: 'flood-opacity', - focusable: 0, - fontFamily: 'font-family', - fontSize: 'font-size', - fontSizeAdjust: 'font-size-adjust', - fontStretch: 'font-stretch', - fontStyle: 'font-style', - fontVariant: 'font-variant', - fontWeight: 'font-weight', - format: 0, - from: 0, - fx: 0, - fy: 0, - g1: 0, - g2: 0, - glyphName: 'glyph-name', - glyphOrientationHorizontal: 'glyph-orientation-horizontal', - glyphOrientationVertical: 'glyph-orientation-vertical', - glyphRef: 'glyphRef', - gradientTransform: 'gradientTransform', - gradientUnits: 'gradientUnits', - hanging: 0, - horizAdvX: 'horiz-adv-x', - horizOriginX: 'horiz-origin-x', - ideographic: 0, - imageRendering: 'image-rendering', - 'in': 0, - in2: 0, - intercept: 0, - k: 0, - k1: 0, - k2: 0, - k3: 0, - k4: 0, - kernelMatrix: 'kernelMatrix', - kernelUnitLength: 'kernelUnitLength', - kerning: 0, - keyPoints: 'keyPoints', - keySplines: 'keySplines', - keyTimes: 'keyTimes', - lengthAdjust: 'lengthAdjust', - letterSpacing: 'letter-spacing', - lightingColor: 'lighting-color', - limitingConeAngle: 'limitingConeAngle', - local: 0, - markerEnd: 'marker-end', - markerMid: 'marker-mid', - markerStart: 'marker-start', - markerHeight: 'markerHeight', - markerUnits: 'markerUnits', - markerWidth: 'markerWidth', - mask: 0, - maskContentUnits: 'maskContentUnits', - maskUnits: 'maskUnits', - mathematical: 0, - mode: 0, - numOctaves: 'numOctaves', - offset: 0, - opacity: 0, - operator: 0, - order: 0, - orient: 0, - orientation: 0, - origin: 0, - overflow: 0, - overlinePosition: 'overline-position', - overlineThickness: 'overline-thickness', - paintOrder: 'paint-order', - panose1: 'panose-1', - pathLength: 'pathLength', - patternContentUnits: 'patternContentUnits', - patternTransform: 'patternTransform', - patternUnits: 'patternUnits', - pointerEvents: 'pointer-events', - points: 0, - pointsAtX: 'pointsAtX', - pointsAtY: 'pointsAtY', - pointsAtZ: 'pointsAtZ', - preserveAlpha: 'preserveAlpha', - preserveAspectRatio: 'preserveAspectRatio', - primitiveUnits: 'primitiveUnits', - r: 0, - radius: 0, - refX: 'refX', - refY: 'refY', - renderingIntent: 'rendering-intent', - repeatCount: 'repeatCount', - repeatDur: 'repeatDur', - requiredExtensions: 'requiredExtensions', - requiredFeatures: 'requiredFeatures', - restart: 0, - result: 0, - rotate: 0, - rx: 0, - ry: 0, - scale: 0, - seed: 0, - shapeRendering: 'shape-rendering', - slope: 0, - spacing: 0, - specularConstant: 'specularConstant', - specularExponent: 'specularExponent', - speed: 0, - spreadMethod: 'spreadMethod', - startOffset: 'startOffset', - stdDeviation: 'stdDeviation', - stemh: 0, - stemv: 0, - stitchTiles: 'stitchTiles', - stopColor: 'stop-color', - stopOpacity: 'stop-opacity', - strikethroughPosition: 'strikethrough-position', - strikethroughThickness: 'strikethrough-thickness', - string: 0, - stroke: 0, - strokeDasharray: 'stroke-dasharray', - strokeDashoffset: 'stroke-dashoffset', - strokeLinecap: 'stroke-linecap', - strokeLinejoin: 'stroke-linejoin', - strokeMiterlimit: 'stroke-miterlimit', - strokeOpacity: 'stroke-opacity', - strokeWidth: 'stroke-width', - surfaceScale: 'surfaceScale', - systemLanguage: 'systemLanguage', - tableValues: 'tableValues', - targetX: 'targetX', - targetY: 'targetY', - textAnchor: 'text-anchor', - textDecoration: 'text-decoration', - textRendering: 'text-rendering', - textLength: 'textLength', - to: 0, - transform: 0, - u1: 0, - u2: 0, - underlinePosition: 'underline-position', - underlineThickness: 'underline-thickness', - unicode: 0, - unicodeBidi: 'unicode-bidi', - unicodeRange: 'unicode-range', - unitsPerEm: 'units-per-em', - vAlphabetic: 'v-alphabetic', - vHanging: 'v-hanging', - vIdeographic: 'v-ideographic', - vMathematical: 'v-mathematical', - values: 0, - vectorEffect: 'vector-effect', - version: 0, - vertAdvY: 'vert-adv-y', - vertOriginX: 'vert-origin-x', - vertOriginY: 'vert-origin-y', - viewBox: 'viewBox', - viewTarget: 'viewTarget', - visibility: 0, - widths: 0, - wordSpacing: 'word-spacing', - writingMode: 'writing-mode', - x: 0, - xHeight: 'x-height', - x1: 0, - x2: 0, - xChannelSelector: 'xChannelSelector', - xlinkActuate: 'xlink:actuate', - xlinkArcrole: 'xlink:arcrole', - xlinkHref: 'xlink:href', - xlinkRole: 'xlink:role', - xlinkShow: 'xlink:show', - xlinkTitle: 'xlink:title', - xlinkType: 'xlink:type', - xmlBase: 'xml:base', - xmlns: 0, - xmlnsXlink: 'xmlns:xlink', - xmlLang: 'xml:lang', - xmlSpace: 'xml:space', - y: 0, - y1: 0, - y2: 0, - yChannelSelector: 'yChannelSelector', - z: 0, - zoomAndPan: 'zoomAndPan' -}; - -var SVGDOMPropertyConfig = { - Properties: {}, - DOMAttributeNamespaces: { - xlinkActuate: NS.xlink, - xlinkArcrole: NS.xlink, - xlinkHref: NS.xlink, - xlinkRole: NS.xlink, - xlinkShow: NS.xlink, - xlinkTitle: NS.xlink, - xlinkType: NS.xlink, - xmlBase: NS.xml, - xmlLang: NS.xml, - xmlSpace: NS.xml - }, - DOMAttributeNames: {} -}; - -Object.keys(ATTRS).forEach(function (key) { - SVGDOMPropertyConfig.Properties[key] = 0; - if (ATTRS[key]) { - SVGDOMPropertyConfig.DOMAttributeNames[key] = ATTRS[key]; - } -}); - -module.exports = SVGDOMPropertyConfig; - -/***/ }), -/* 285 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var EventPropagators = __webpack_require__(31); -var ExecutionEnvironment = __webpack_require__(8); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactInputSelection = __webpack_require__(86); -var SyntheticEvent = __webpack_require__(17); - -var getActiveElement = __webpack_require__(74); -var isTextInputElement = __webpack_require__(96); -var shallowEqual = __webpack_require__(42); - -var skipSelectionChangeEvent = ExecutionEnvironment.canUseDOM && 'documentMode' in document && document.documentMode <= 11; - -var eventTypes = { - select: { - phasedRegistrationNames: { - bubbled: 'onSelect', - captured: 'onSelectCapture' - }, - dependencies: ['topBlur', 'topContextMenu', 'topFocus', 'topKeyDown', 'topKeyUp', 'topMouseDown', 'topMouseUp', 'topSelectionChange'] - } -}; - -var activeElement = null; -var activeElementInst = null; -var lastSelection = null; -var mouseDown = false; - -// Track whether a listener exists for this plugin. If none exist, we do -// not extract events. See #3639. -var hasListener = false; - -/** - * Get an object which is a unique representation of the current selection. - * - * The return value will not be consistent across nodes or browsers, but - * two identical selections on the same node will return identical objects. - * - * @param {DOMElement} node - * @return {object} - */ -function getSelection(node) { - if ('selectionStart' in node && ReactInputSelection.hasSelectionCapabilities(node)) { - return { - start: node.selectionStart, - end: node.selectionEnd - }; - } else if (window.getSelection) { - var selection = window.getSelection(); - return { - anchorNode: selection.anchorNode, - anchorOffset: selection.anchorOffset, - focusNode: selection.focusNode, - focusOffset: selection.focusOffset - }; - } else if (document.selection) { - var range = document.selection.createRange(); - return { - parentElement: range.parentElement(), - text: range.text, - top: range.boundingTop, - left: range.boundingLeft - }; - } -} - -/** - * Poll selection to see whether it's changed. - * - * @param {object} nativeEvent - * @return {?SyntheticEvent} - */ -function constructSelectEvent(nativeEvent, nativeEventTarget) { - // Ensure we have the right element, and that the user is not dragging a - // selection (this matches native `select` event behavior). In HTML5, select - // fires only on input and textarea thus if there's no focused element we - // won't dispatch. - if (mouseDown || activeElement == null || activeElement !== getActiveElement()) { - return null; - } - - // Only fire when selection has actually changed. - var currentSelection = getSelection(activeElement); - if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { - lastSelection = currentSelection; - - var syntheticEvent = SyntheticEvent.getPooled(eventTypes.select, activeElementInst, nativeEvent, nativeEventTarget); - - syntheticEvent.type = 'select'; - syntheticEvent.target = activeElement; - - EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent); - - return syntheticEvent; - } - - return null; -} - -/** - * This plugin creates an `onSelect` event that normalizes select events - * across form elements. - * - * Supported elements are: - * - input (see `isTextInputElement`) - * - textarea - * - contentEditable - * - * This differs from native browser implementations in the following ways: - * - Fires on contentEditable fields as well as inputs. - * - Fires for collapsed selection. - * - Fires after user input. - */ -var SelectEventPlugin = { - - eventTypes: eventTypes, - - extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - if (!hasListener) { - return null; - } - - var targetNode = targetInst ? ReactDOMComponentTree.getNodeFromInstance(targetInst) : window; - - switch (topLevelType) { - // Track the input node that has focus. - case 'topFocus': - if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') { - activeElement = targetNode; - activeElementInst = targetInst; - lastSelection = null; - } - break; - case 'topBlur': - activeElement = null; - activeElementInst = null; - lastSelection = null; - break; - - // Don't fire the event while the user is dragging. This matches the - // semantics of the native select event. - case 'topMouseDown': - mouseDown = true; - break; - case 'topContextMenu': - case 'topMouseUp': - mouseDown = false; - return constructSelectEvent(nativeEvent, nativeEventTarget); - - // Chrome and IE fire non-standard event when selection is changed (and - // sometimes when it hasn't). IE's event fires out of order with respect - // to key and input events on deletion, so we discard it. - // - // Firefox doesn't support selectionchange, so check selection status - // after each key entry. The selection changes after keydown and before - // keyup, but we check on keydown as well in the case of holding down a - // key, when multiple keydown events are fired but only one keyup is. - // This is also our approach for IE handling, for the reason above. - case 'topSelectionChange': - if (skipSelectionChangeEvent) { - break; - } - // falls through - case 'topKeyDown': - case 'topKeyUp': - return constructSelectEvent(nativeEvent, nativeEventTarget); - } - - return null; - }, - - didPutListener: function (inst, registrationName, listener) { - if (registrationName === 'onSelect') { - hasListener = true; - } - } -}; - -module.exports = SelectEventPlugin; - -/***/ }), -/* 286 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var EventListener = __webpack_require__(72); -var EventPropagators = __webpack_require__(31); -var ReactDOMComponentTree = __webpack_require__(7); -var SyntheticAnimationEvent = __webpack_require__(287); -var SyntheticClipboardEvent = __webpack_require__(288); -var SyntheticEvent = __webpack_require__(17); -var SyntheticFocusEvent = __webpack_require__(291); -var SyntheticKeyboardEvent = __webpack_require__(293); -var SyntheticMouseEvent = __webpack_require__(37); -var SyntheticDragEvent = __webpack_require__(290); -var SyntheticTouchEvent = __webpack_require__(294); -var SyntheticTransitionEvent = __webpack_require__(295); -var SyntheticUIEvent = __webpack_require__(33); -var SyntheticWheelEvent = __webpack_require__(296); - -var emptyFunction = __webpack_require__(12); -var getEventCharCode = __webpack_require__(55); -var invariant = __webpack_require__(2); - -/** - * Turns - * ['abort', ...] - * into - * eventTypes = { - * 'abort': { - * phasedRegistrationNames: { - * bubbled: 'onAbort', - * captured: 'onAbortCapture', - * }, - * dependencies: ['topAbort'], - * }, - * ... - * }; - * topLevelEventsToDispatchConfig = { - * 'topAbort': { sameConfig } - * }; - */ -var eventTypes = {}; -var topLevelEventsToDispatchConfig = {}; -['abort', 'animationEnd', 'animationIteration', 'animationStart', 'blur', 'canPlay', 'canPlayThrough', 'click', 'contextMenu', 'copy', 'cut', 'doubleClick', 'drag', 'dragEnd', 'dragEnter', 'dragExit', 'dragLeave', 'dragOver', 'dragStart', 'drop', 'durationChange', 'emptied', 'encrypted', 'ended', 'error', 'focus', 'input', 'invalid', 'keyDown', 'keyPress', 'keyUp', 'load', 'loadedData', 'loadedMetadata', 'loadStart', 'mouseDown', 'mouseMove', 'mouseOut', 'mouseOver', 'mouseUp', 'paste', 'pause', 'play', 'playing', 'progress', 'rateChange', 'reset', 'scroll', 'seeked', 'seeking', 'stalled', 'submit', 'suspend', 'timeUpdate', 'touchCancel', 'touchEnd', 'touchMove', 'touchStart', 'transitionEnd', 'volumeChange', 'waiting', 'wheel'].forEach(function (event) { - var capitalizedEvent = event[0].toUpperCase() + event.slice(1); - var onEvent = 'on' + capitalizedEvent; - var topEvent = 'top' + capitalizedEvent; - - var type = { - phasedRegistrationNames: { - bubbled: onEvent, - captured: onEvent + 'Capture' - }, - dependencies: [topEvent] - }; - eventTypes[event] = type; - topLevelEventsToDispatchConfig[topEvent] = type; -}); - -var onClickListeners = {}; - -function getDictionaryKey(inst) { - // Prevents V8 performance issue: - // https://github.com/facebook/react/pull/7232 - return '.' + inst._rootNodeID; -} - -function isInteractive(tag) { - return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; -} - -var SimpleEventPlugin = { - - eventTypes: eventTypes, - - extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType]; - if (!dispatchConfig) { - return null; - } - var EventConstructor; - switch (topLevelType) { - case 'topAbort': - case 'topCanPlay': - case 'topCanPlayThrough': - case 'topDurationChange': - case 'topEmptied': - case 'topEncrypted': - case 'topEnded': - case 'topError': - case 'topInput': - case 'topInvalid': - case 'topLoad': - case 'topLoadedData': - case 'topLoadedMetadata': - case 'topLoadStart': - case 'topPause': - case 'topPlay': - case 'topPlaying': - case 'topProgress': - case 'topRateChange': - case 'topReset': - case 'topSeeked': - case 'topSeeking': - case 'topStalled': - case 'topSubmit': - case 'topSuspend': - case 'topTimeUpdate': - case 'topVolumeChange': - case 'topWaiting': - // HTML Events - // @see http://www.w3.org/TR/html5/index.html#events-0 - EventConstructor = SyntheticEvent; - break; - case 'topKeyPress': - // Firefox creates a keypress event for function keys too. This removes - // the unwanted keypress events. Enter is however both printable and - // non-printable. One would expect Tab to be as well (but it isn't). - if (getEventCharCode(nativeEvent) === 0) { - return null; - } - /* falls through */ - case 'topKeyDown': - case 'topKeyUp': - EventConstructor = SyntheticKeyboardEvent; - break; - case 'topBlur': - case 'topFocus': - EventConstructor = SyntheticFocusEvent; - break; - case 'topClick': - // Firefox creates a click event on right mouse clicks. This removes the - // unwanted click events. - if (nativeEvent.button === 2) { - return null; - } - /* falls through */ - case 'topDoubleClick': - case 'topMouseDown': - case 'topMouseMove': - case 'topMouseUp': - // TODO: Disabled elements should not respond to mouse events - /* falls through */ - case 'topMouseOut': - case 'topMouseOver': - case 'topContextMenu': - EventConstructor = SyntheticMouseEvent; - break; - case 'topDrag': - case 'topDragEnd': - case 'topDragEnter': - case 'topDragExit': - case 'topDragLeave': - case 'topDragOver': - case 'topDragStart': - case 'topDrop': - EventConstructor = SyntheticDragEvent; - break; - case 'topTouchCancel': - case 'topTouchEnd': - case 'topTouchMove': - case 'topTouchStart': - EventConstructor = SyntheticTouchEvent; - break; - case 'topAnimationEnd': - case 'topAnimationIteration': - case 'topAnimationStart': - EventConstructor = SyntheticAnimationEvent; - break; - case 'topTransitionEnd': - EventConstructor = SyntheticTransitionEvent; - break; - case 'topScroll': - EventConstructor = SyntheticUIEvent; - break; - case 'topWheel': - EventConstructor = SyntheticWheelEvent; - break; - case 'topCopy': - case 'topCut': - case 'topPaste': - EventConstructor = SyntheticClipboardEvent; - break; - } - !EventConstructor ? process.env.NODE_ENV !== 'production' ? invariant(false, 'SimpleEventPlugin: Unhandled event type, `%s`.', topLevelType) : _prodInvariant('86', topLevelType) : void 0; - var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget); - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - }, - - didPutListener: function (inst, registrationName, listener) { - // Mobile Safari does not fire properly bubble click events on - // non-interactive elements, which means delegated click listeners do not - // fire. The workaround for this bug involves attaching an empty click - // listener on the target node. - // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html - if (registrationName === 'onClick' && !isInteractive(inst._tag)) { - var key = getDictionaryKey(inst); - var node = ReactDOMComponentTree.getNodeFromInstance(inst); - if (!onClickListeners[key]) { - onClickListeners[key] = EventListener.listen(node, 'click', emptyFunction); - } - } - }, - - willDeleteListener: function (inst, registrationName) { - if (registrationName === 'onClick' && !isInteractive(inst._tag)) { - var key = getDictionaryKey(inst); - onClickListeners[key].remove(); - delete onClickListeners[key]; - } - } - -}; - -module.exports = SimpleEventPlugin; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 287 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticEvent = __webpack_require__(17); - -/** - * @interface Event - * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface - * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent - */ -var AnimationEventInterface = { - animationName: null, - elapsedTime: null, - pseudoElement: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticEvent} - */ -function SyntheticAnimationEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticEvent.augmentClass(SyntheticAnimationEvent, AnimationEventInterface); - -module.exports = SyntheticAnimationEvent; - -/***/ }), -/* 288 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticEvent = __webpack_require__(17); - -/** - * @interface Event - * @see http://www.w3.org/TR/clipboard-apis/ - */ -var ClipboardEventInterface = { - clipboardData: function (event) { - return 'clipboardData' in event ? event.clipboardData : window.clipboardData; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface); - -module.exports = SyntheticClipboardEvent; - -/***/ }), -/* 289 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticEvent = __webpack_require__(17); - -/** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents - */ -var CompositionEventInterface = { - data: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticCompositionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticEvent.augmentClass(SyntheticCompositionEvent, CompositionEventInterface); - -module.exports = SyntheticCompositionEvent; - -/***/ }), -/* 290 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticMouseEvent = __webpack_require__(37); - -/** - * @interface DragEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var DragEventInterface = { - dataTransfer: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface); - -module.exports = SyntheticDragEvent; - -/***/ }), -/* 291 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticUIEvent = __webpack_require__(33); - -/** - * @interface FocusEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var FocusEventInterface = { - relatedTarget: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface); - -module.exports = SyntheticFocusEvent; - -/***/ }), -/* 292 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticEvent = __webpack_require__(17); - -/** - * @interface Event - * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105 - * /#events-inputevents - */ -var InputEventInterface = { - data: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticInputEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticEvent.augmentClass(SyntheticInputEvent, InputEventInterface); - -module.exports = SyntheticInputEvent; - -/***/ }), -/* 293 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticUIEvent = __webpack_require__(33); - -var getEventCharCode = __webpack_require__(55); -var getEventKey = __webpack_require__(302); -var getEventModifierState = __webpack_require__(56); - -/** - * @interface KeyboardEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var KeyboardEventInterface = { - key: getEventKey, - location: null, - ctrlKey: null, - shiftKey: null, - altKey: null, - metaKey: null, - repeat: null, - locale: null, - getModifierState: getEventModifierState, - // Legacy Interface - charCode: function (event) { - // `charCode` is the result of a KeyPress event and represents the value of - // the actual printable character. - - // KeyPress is deprecated, but its replacement is not yet final and not - // implemented in any major browser. Only KeyPress has charCode. - if (event.type === 'keypress') { - return getEventCharCode(event); - } - return 0; - }, - keyCode: function (event) { - // `keyCode` is the result of a KeyDown/Up event and represents the value of - // physical keyboard key. - - // The actual meaning of the value depends on the users' keyboard layout - // which cannot be detected. Assuming that it is a US keyboard layout - // provides a surprisingly accurate mapping for US and European users. - // Due to this, it is left to the user to implement at this time. - if (event.type === 'keydown' || event.type === 'keyup') { - return event.keyCode; - } - return 0; - }, - which: function (event) { - // `which` is an alias for either `keyCode` or `charCode` depending on the - // type of the event. - if (event.type === 'keypress') { - return getEventCharCode(event); - } - if (event.type === 'keydown' || event.type === 'keyup') { - return event.keyCode; - } - return 0; - } -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface); - -module.exports = SyntheticKeyboardEvent; - -/***/ }), -/* 294 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticUIEvent = __webpack_require__(33); - -var getEventModifierState = __webpack_require__(56); - -/** - * @interface TouchEvent - * @see http://www.w3.org/TR/touch-events/ - */ -var TouchEventInterface = { - touches: null, - targetTouches: null, - changedTouches: null, - altKey: null, - metaKey: null, - ctrlKey: null, - shiftKey: null, - getModifierState: getEventModifierState -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticUIEvent} - */ -function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface); - -module.exports = SyntheticTouchEvent; - -/***/ }), -/* 295 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticEvent = __webpack_require__(17); - -/** - * @interface Event - * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events- - * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent - */ -var TransitionEventInterface = { - propertyName: null, - elapsedTime: null, - pseudoElement: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticEvent} - */ -function SyntheticTransitionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticEvent.augmentClass(SyntheticTransitionEvent, TransitionEventInterface); - -module.exports = SyntheticTransitionEvent; - -/***/ }), -/* 296 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var SyntheticMouseEvent = __webpack_require__(37); - -/** - * @interface WheelEvent - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ -var WheelEventInterface = { - deltaX: function (event) { - return 'deltaX' in event ? event.deltaX : - // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). - 'wheelDeltaX' in event ? -event.wheelDeltaX : 0; - }, - deltaY: function (event) { - return 'deltaY' in event ? event.deltaY : - // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). - 'wheelDeltaY' in event ? -event.wheelDeltaY : - // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). - 'wheelDelta' in event ? -event.wheelDelta : 0; - }, - deltaZ: null, - - // Browsers without "deltaMode" is reporting in raw wheel delta where one - // notch on the scroll is always +/- 120, roughly equivalent to pixels. - // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or - // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size. - deltaMode: null -}; - -/** - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {string} dispatchMarker Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @extends {SyntheticMouseEvent} - */ -function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { - return SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); -} - -SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface); - -module.exports = SyntheticWheelEvent; - -/***/ }), -/* 297 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var MOD = 65521; - -// adler32 is not cryptographically strong, and is only used to sanity check that -// markup generated on the server matches the markup generated on the client. -// This implementation (a modified version of the SheetJS version) has been optimized -// for our use case, at the expense of conforming to the adler32 specification -// for non-ascii inputs. -function adler32(data) { - var a = 1; - var b = 0; - var i = 0; - var l = data.length; - var m = l & ~0x3; - while (i < m) { - var n = Math.min(i + 4096, m); - for (; i < n; i += 4) { - b += (a += data.charCodeAt(i)) + (a += data.charCodeAt(i + 1)) + (a += data.charCodeAt(i + 2)) + (a += data.charCodeAt(i + 3)); - } - a %= MOD; - b %= MOD; - } - for (; i < l; i++) { - b += a += data.charCodeAt(i); - } - a %= MOD; - b %= MOD; - return a | b << 16; -} - -module.exports = adler32; - -/***/ }), -/* 298 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var ReactPropTypeLocationNames = __webpack_require__(278); -var ReactPropTypesSecret = __webpack_require__(89); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -var ReactComponentTreeHook; - -if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'test') { - // Temporary hack. - // Inline requires don't work well with Jest: - // https://github.com/facebook/react/issues/7240 - // Remove the inline requires when we don't need them anymore: - // https://github.com/facebook/react/pull/7178 - ReactComponentTreeHook = __webpack_require__(9); -} - -var loggedTypeFailures = {}; - -/** - * Assert that the values match with the type specs. - * Error messages are memorized and will only be shown once. - * - * @param {object} typeSpecs Map of name to a ReactPropType - * @param {object} values Runtime values that need to be type-checked - * @param {string} location e.g. "prop", "context", "child context" - * @param {string} componentName Name of the component for error messages. - * @param {?object} element The React element that is being type-checked - * @param {?number} debugID The React component instance that is being type-checked - * @private - */ -function checkReactTypeSpec(typeSpecs, values, location, componentName, element, debugID) { - for (var typeSpecName in typeSpecs) { - if (typeSpecs.hasOwnProperty(typeSpecName)) { - var error; - // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - !(typeof typeSpecs[typeSpecName] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : _prodInvariant('84', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : void 0; - error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); - } catch (ex) { - error = ex; - } - process.env.NODE_ENV !== 'production' ? warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName, typeof error) : void 0; - if (error instanceof Error && !(error.message in loggedTypeFailures)) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error.message] = true; - - var componentStackInfo = ''; - - if (process.env.NODE_ENV !== 'production') { - if (!ReactComponentTreeHook) { - ReactComponentTreeHook = __webpack_require__(9); - } - if (debugID !== null) { - componentStackInfo = ReactComponentTreeHook.getStackAddendumByID(debugID); - } else if (element !== null) { - componentStackInfo = ReactComponentTreeHook.getCurrentStackAddendum(element); - } - } - - process.env.NODE_ENV !== 'production' ? warning(false, 'Failed %s type: %s%s', location, error.message, componentStackInfo) : void 0; - } - } - } -} - -module.exports = checkReactTypeSpec; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 299 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var CSSProperty = __webpack_require__(78); -var warning = __webpack_require__(3); - -var isUnitlessNumber = CSSProperty.isUnitlessNumber; -var styleWarnings = {}; - -/** - * Convert a value into the proper css writable value. The style name `name` - * should be logical (no hyphens), as specified - * in `CSSProperty.isUnitlessNumber`. - * - * @param {string} name CSS property name such as `topMargin`. - * @param {*} value CSS property value such as `10px`. - * @param {ReactDOMComponent} component - * @return {string} Normalized style value with dimensions applied. - */ -function dangerousStyleValue(name, value, component) { - // Note that we've removed escapeTextForBrowser() calls here since the - // whole string will be escaped when the attribute is injected into - // the markup. If you provide unsafe user data here they can inject - // arbitrary CSS which may be problematic (I couldn't repro this): - // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet - // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ - // This is not an XSS hole but instead a potential CSS injection issue - // which has lead to a greater discussion about how we're going to - // trust URLs moving forward. See #2115901 - - var isEmpty = value == null || typeof value === 'boolean' || value === ''; - if (isEmpty) { - return ''; - } - - var isNonNumeric = isNaN(value); - if (isNonNumeric || value === 0 || isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) { - return '' + value; // cast to string - } - - if (typeof value === 'string') { - if (process.env.NODE_ENV !== 'production') { - // Allow '0' to pass through without warning. 0 is already special and - // doesn't require units, so we don't need to warn about it. - if (component && value !== '0') { - var owner = component._currentElement._owner; - var ownerName = owner ? owner.getName() : null; - if (ownerName && !styleWarnings[ownerName]) { - styleWarnings[ownerName] = {}; - } - var warned = false; - if (ownerName) { - var warnings = styleWarnings[ownerName]; - warned = warnings[name]; - if (!warned) { - warnings[name] = true; - } - } - if (!warned) { - process.env.NODE_ENV !== 'production' ? warning(false, 'a `%s` tag (owner: `%s`) was passed a numeric string value ' + 'for CSS property `%s` (value: `%s`) which will be treated ' + 'as a unitless number in a future version of React.', component._currentElement.type, ownerName || 'unknown', name, value) : void 0; - } - } - } - value = value.trim(); - } - return value + 'px'; -} - -module.exports = dangerousStyleValue; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 300 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(4); - -var ReactCurrentOwner = __webpack_require__(15); -var ReactDOMComponentTree = __webpack_require__(7); -var ReactInstanceMap = __webpack_require__(32); - -var getHostComponentFromComposite = __webpack_require__(93); -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -/** - * Returns the DOM node rendered by this element. - * - * See https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode - * - * @param {ReactComponent|DOMElement} componentOrElement - * @return {?DOMElement} The root node of this element. - */ -function findDOMNode(componentOrElement) { - if (process.env.NODE_ENV !== 'production') { - var owner = ReactCurrentOwner.current; - if (owner !== null) { - process.env.NODE_ENV !== 'production' ? warning(owner._warnedAboutRefsInRender, '%s is accessing findDOMNode inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : void 0; - owner._warnedAboutRefsInRender = true; - } - } - if (componentOrElement == null) { - return null; - } - if (componentOrElement.nodeType === 1) { - return componentOrElement; - } - - var inst = ReactInstanceMap.get(componentOrElement); - if (inst) { - inst = getHostComponentFromComposite(inst); - return inst ? ReactDOMComponentTree.getNodeFromInstance(inst) : null; - } - - if (typeof componentOrElement.render === 'function') { - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'findDOMNode was called on an unmounted component.') : _prodInvariant('44') : void 0; - } else { - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Element appears to be neither ReactComponent nor DOMNode (keys: %s)', Object.keys(componentOrElement)) : _prodInvariant('45', Object.keys(componentOrElement)) : void 0; - } -} - -module.exports = findDOMNode; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 301 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var KeyEscapeUtils = __webpack_require__(49); -var traverseAllChildren = __webpack_require__(98); -var warning = __webpack_require__(3); - -var ReactComponentTreeHook; - -if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'test') { - // Temporary hack. - // Inline requires don't work well with Jest: - // https://github.com/facebook/react/issues/7240 - // Remove the inline requires when we don't need them anymore: - // https://github.com/facebook/react/pull/7178 - ReactComponentTreeHook = __webpack_require__(9); -} - -/** - * @param {function} traverseContext Context passed through traversal. - * @param {?ReactComponent} child React child component. - * @param {!string} name String name of key path to child. - * @param {number=} selfDebugID Optional debugID of the current internal instance. - */ -function flattenSingleChildIntoContext(traverseContext, child, name, selfDebugID) { - // We found a component instance. - if (traverseContext && typeof traverseContext === 'object') { - var result = traverseContext; - var keyUnique = result[name] === undefined; - if (process.env.NODE_ENV !== 'production') { - if (!ReactComponentTreeHook) { - ReactComponentTreeHook = __webpack_require__(9); - } - if (!keyUnique) { - process.env.NODE_ENV !== 'production' ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0; - } - } - if (keyUnique && child != null) { - result[name] = child; - } - } -} - -/** - * Flattens children that are typically specified as `props.children`. Any null - * children will not be included in the resulting object. - * @return {!object} flattened children keyed by name. - */ -function flattenChildren(children, selfDebugID) { - if (children == null) { - return children; - } - var result = {}; - - if (process.env.NODE_ENV !== 'production') { - traverseAllChildren(children, function (traverseContext, child, name) { - return flattenSingleChildIntoContext(traverseContext, child, name, selfDebugID); - }, result); - } else { - traverseAllChildren(children, flattenSingleChildIntoContext, result); - } - return result; -} - -module.exports = flattenChildren; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 302 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var getEventCharCode = __webpack_require__(55); - -/** - * Normalization of deprecated HTML5 `key` values - * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names - */ -var normalizeKey = { - 'Esc': 'Escape', - 'Spacebar': ' ', - 'Left': 'ArrowLeft', - 'Up': 'ArrowUp', - 'Right': 'ArrowRight', - 'Down': 'ArrowDown', - 'Del': 'Delete', - 'Win': 'OS', - 'Menu': 'ContextMenu', - 'Apps': 'ContextMenu', - 'Scroll': 'ScrollLock', - 'MozPrintableKey': 'Unidentified' -}; - -/** - * Translation from legacy `keyCode` to HTML5 `key` - * Only special keys supported, all others depend on keyboard layout or browser - * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names - */ -var translateToKey = { - 8: 'Backspace', - 9: 'Tab', - 12: 'Clear', - 13: 'Enter', - 16: 'Shift', - 17: 'Control', - 18: 'Alt', - 19: 'Pause', - 20: 'CapsLock', - 27: 'Escape', - 32: ' ', - 33: 'PageUp', - 34: 'PageDown', - 35: 'End', - 36: 'Home', - 37: 'ArrowLeft', - 38: 'ArrowUp', - 39: 'ArrowRight', - 40: 'ArrowDown', - 45: 'Insert', - 46: 'Delete', - 112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6', - 118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12', - 144: 'NumLock', - 145: 'ScrollLock', - 224: 'Meta' -}; - -/** - * @param {object} nativeEvent Native browser event. - * @return {string} Normalized `key` property. - */ -function getEventKey(nativeEvent) { - if (nativeEvent.key) { - // Normalize inconsistent values reported by browsers due to - // implementations of a working draft specification. - - // FireFox implements `key` but returns `MozPrintableKey` for all - // printable characters (normalized to `Unidentified`), ignore it. - var key = normalizeKey[nativeEvent.key] || nativeEvent.key; - if (key !== 'Unidentified') { - return key; - } - } - - // Browser does not implement `key`, polyfill as much of it as we can. - if (nativeEvent.type === 'keypress') { - var charCode = getEventCharCode(nativeEvent); - - // The enter-key is technically both printable and non-printable and can - // thus be captured by `keypress`, no other non-printable key should. - return charCode === 13 ? 'Enter' : String.fromCharCode(charCode); - } - if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') { - // While user keyboard layout determines the actual meaning of each - // `keyCode` value, almost all function keys have a universal value. - return translateToKey[nativeEvent.keyCode] || 'Unidentified'; - } - return ''; -} - -module.exports = getEventKey; - -/***/ }), -/* 303 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/* global Symbol */ - -var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; -var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. - -/** - * Returns the iterator method function contained on the iterable object. - * - * Be sure to invoke the function with the iterable as context: - * - * var iteratorFn = getIteratorFn(myIterable); - * if (iteratorFn) { - * var iterator = iteratorFn.call(myIterable); - * ... - * } - * - * @param {?object} maybeIterable - * @return {?function} - */ -function getIteratorFn(maybeIterable) { - var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); - if (typeof iteratorFn === 'function') { - return iteratorFn; - } -} - -module.exports = getIteratorFn; - -/***/ }), -/* 304 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var nextDebugID = 1; - -function getNextDebugID() { - return nextDebugID++; -} - -module.exports = getNextDebugID; - -/***/ }), -/* 305 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -/** - * Given any node return the first leaf node without children. - * - * @param {DOMElement|DOMTextNode} node - * @return {DOMElement|DOMTextNode} - */ - -function getLeafNode(node) { - while (node && node.firstChild) { - node = node.firstChild; - } - return node; -} - -/** - * Get the next sibling within a container. This will walk up the - * DOM if a node's siblings have been exhausted. - * - * @param {DOMElement|DOMTextNode} node - * @return {?DOMElement|DOMTextNode} - */ -function getSiblingNode(node) { - while (node) { - if (node.nextSibling) { - return node.nextSibling; - } - node = node.parentNode; - } -} - -/** - * Get object describing the nodes which contain characters at offset. - * - * @param {DOMElement|DOMTextNode} root - * @param {number} offset - * @return {?object} - */ -function getNodeForCharacterOffset(root, offset) { - var node = getLeafNode(root); - var nodeStart = 0; - var nodeEnd = 0; - - while (node) { - if (node.nodeType === 3) { - nodeEnd = nodeStart + node.textContent.length; - - if (nodeStart <= offset && nodeEnd >= offset) { - return { - node: node, - offset: offset - nodeStart - }; - } - - nodeStart = nodeEnd; - } - - node = getLeafNode(getSiblingNode(node)); - } -} - -module.exports = getNodeForCharacterOffset; - -/***/ }), -/* 306 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ExecutionEnvironment = __webpack_require__(8); - -/** - * Generate a mapping of standard vendor prefixes using the defined style property and event name. - * - * @param {string} styleProp - * @param {string} eventName - * @returns {object} - */ -function makePrefixMap(styleProp, eventName) { - var prefixes = {}; - - prefixes[styleProp.toLowerCase()] = eventName.toLowerCase(); - prefixes['Webkit' + styleProp] = 'webkit' + eventName; - prefixes['Moz' + styleProp] = 'moz' + eventName; - prefixes['ms' + styleProp] = 'MS' + eventName; - prefixes['O' + styleProp] = 'o' + eventName.toLowerCase(); - - return prefixes; -} - -/** - * A list of event names to a configurable list of vendor prefixes. - */ -var vendorPrefixes = { - animationend: makePrefixMap('Animation', 'AnimationEnd'), - animationiteration: makePrefixMap('Animation', 'AnimationIteration'), - animationstart: makePrefixMap('Animation', 'AnimationStart'), - transitionend: makePrefixMap('Transition', 'TransitionEnd') -}; - -/** - * Event names that have already been detected and prefixed (if applicable). - */ -var prefixedEventNames = {}; - -/** - * Element to check for prefixes on. - */ -var style = {}; - -/** - * Bootstrap if a DOM exists. - */ -if (ExecutionEnvironment.canUseDOM) { - style = document.createElement('div').style; - - // On some platforms, in particular some releases of Android 4.x, - // the un-prefixed "animation" and "transition" properties are defined on the - // style object but the events that fire will still be prefixed, so we need - // to check if the un-prefixed events are usable, and if not remove them from the map. - if (!('AnimationEvent' in window)) { - delete vendorPrefixes.animationend.animation; - delete vendorPrefixes.animationiteration.animation; - delete vendorPrefixes.animationstart.animation; - } - - // Same as above - if (!('TransitionEvent' in window)) { - delete vendorPrefixes.transitionend.transition; - } -} - -/** - * Attempts to determine the correct vendor prefixed event name. - * - * @param {string} eventName - * @returns {string} - */ -function getVendorPrefixedEventName(eventName) { - if (prefixedEventNames[eventName]) { - return prefixedEventNames[eventName]; - } else if (!vendorPrefixes[eventName]) { - return eventName; - } - - var prefixMap = vendorPrefixes[eventName]; - - for (var styleProp in prefixMap) { - if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) { - return prefixedEventNames[eventName] = prefixMap[styleProp]; - } - } - - return ''; -} - -module.exports = getVendorPrefixedEventName; - -/***/ }), -/* 307 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var escapeTextContentForBrowser = __webpack_require__(39); - -/** - * Escapes attribute value to prevent scripting attacks. - * - * @param {*} value Value to escape. - * @return {string} An escaped string. - */ -function quoteAttributeValueForBrowser(value) { - return '"' + escapeTextContentForBrowser(value) + '"'; -} - -module.exports = quoteAttributeValueForBrowser; - -/***/ }), -/* 308 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactMount = __webpack_require__(87); - -module.exports = ReactMount.renderSubtreeIntoContainer; - -/***/ }), -/* 309 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _PropTypes = __webpack_require__(21); - -/** - * A mixin that adds the "history" instance variable to components. - */ -var History = { - - contextTypes: { - history: _PropTypes.history - }, - - componentWillMount: function componentWillMount() { - this.history = this.context.history; - } - -}; - -exports['default'] = History; -module.exports = exports['default']; - -/***/ }), -/* 310 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _Link = __webpack_require__(99); - -var _Link2 = _interopRequireDefault(_Link); - -/** - * An <IndexLink> is used to link to an <IndexRoute>. - */ - -var IndexLink = (function (_Component) { - _inherits(IndexLink, _Component); - - function IndexLink() { - _classCallCheck(this, IndexLink); - - _Component.apply(this, arguments); - } - - IndexLink.prototype.render = function render() { - return _react2['default'].createElement(_Link2['default'], _extends({}, this.props, { onlyActiveOnIndex: true })); - }; - - return IndexLink; -})(_react.Component); - -exports['default'] = IndexLink; -module.exports = exports['default']; - -/***/ }), -/* 311 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _Redirect = __webpack_require__(100); - -var _Redirect2 = _interopRequireDefault(_Redirect); - -var _PropTypes = __webpack_require__(21); - -var _React$PropTypes = _react2['default'].PropTypes; -var string = _React$PropTypes.string; -var object = _React$PropTypes.object; - -/** - * An <IndexRedirect> is used to redirect from an indexRoute. - */ - -var IndexRedirect = (function (_Component) { - _inherits(IndexRedirect, _Component); - - function IndexRedirect() { - _classCallCheck(this, IndexRedirect); - - _Component.apply(this, arguments); - } - - /* istanbul ignore next: sanity check */ - - IndexRedirect.prototype.render = function render() { - true ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, '<IndexRedirect> elements are for router configuration only and should not be rendered') : _invariant2['default'](false) : undefined; - }; - - return IndexRedirect; -})(_react.Component); - -IndexRedirect.propTypes = { - to: string.isRequired, - query: object, - state: object, - onEnter: _PropTypes.falsy, - children: _PropTypes.falsy -}; - -IndexRedirect.createRouteFromReactElement = function (element, parentRoute) { - /* istanbul ignore else: sanity check */ - if (parentRoute) { - parentRoute.indexRoute = _Redirect2['default'].createRouteFromReactElement(element); - } else { - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'An <IndexRedirect> does not make sense at the root of your route config') : undefined; - } -}; - -exports['default'] = IndexRedirect; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 312 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _RouteUtils = __webpack_require__(19); - -var _PropTypes = __webpack_require__(21); - -var func = _react2['default'].PropTypes.func; - -/** - * An <IndexRoute> is used to specify its parent's <Route indexRoute> in - * a JSX route config. - */ - -var IndexRoute = (function (_Component) { - _inherits(IndexRoute, _Component); - - function IndexRoute() { - _classCallCheck(this, IndexRoute); - - _Component.apply(this, arguments); - } - - /* istanbul ignore next: sanity check */ - - IndexRoute.prototype.render = function render() { - true ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, '<IndexRoute> elements are for router configuration only and should not be rendered') : _invariant2['default'](false) : undefined; - }; - - return IndexRoute; -})(_react.Component); - -IndexRoute.propTypes = { - path: _PropTypes.falsy, - component: _PropTypes.component, - components: _PropTypes.components, - getComponent: func, - getComponents: func -}; - -IndexRoute.createRouteFromReactElement = function (element, parentRoute) { - /* istanbul ignore else: sanity check */ - if (parentRoute) { - parentRoute.indexRoute = _RouteUtils.createRouteFromReactElement(element); - } else { - process.env.NODE_ENV !== 'production' ? _warning2['default'](false, 'An <IndexRoute> does not make sense at the root of your route config') : undefined; - } -}; - -exports['default'] = IndexRoute; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 313 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var object = _react2['default'].PropTypes.object; - -/** - * The Lifecycle mixin adds the routerWillLeave lifecycle method to a - * component that may be used to cancel a transition or prompt the user - * for confirmation. - * - * On standard transitions, routerWillLeave receives a single argument: the - * location we're transitioning to. To cancel the transition, return false. - * To prompt the user for confirmation, return a prompt message (string). - * - * During the beforeunload event (assuming you're using the useBeforeUnload - * history enhancer), routerWillLeave does not receive a location object - * because it isn't possible for us to know the location we're transitioning - * to. In this case routerWillLeave must return a prompt message to prevent - * the user from closing the window/tab. - */ -var Lifecycle = { - - contextTypes: { - history: object.isRequired, - // Nested children receive the route as context, either - // set by the route component using the RouteContext mixin - // or by some other ancestor. - route: object - }, - - propTypes: { - // Route components receive the route object as a prop. - route: object - }, - - componentDidMount: function componentDidMount() { - !this.routerWillLeave ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'The Lifecycle mixin requires you to define a routerWillLeave method') : _invariant2['default'](false) : undefined; - - var route = this.props.route || this.context.route; - - !route ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'The Lifecycle mixin must be used on either a) a <Route component> or ' + 'b) a descendant of a <Route component> that uses the RouteContext mixin') : _invariant2['default'](false) : undefined; - - this._unlistenBeforeLeavingRoute = this.context.history.listenBeforeLeavingRoute(route, this.routerWillLeave); - }, - - componentWillUnmount: function componentWillUnmount() { - if (this._unlistenBeforeLeavingRoute) this._unlistenBeforeLeavingRoute(); - } - -}; - -exports['default'] = Lifecycle; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 314 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _RouteUtils = __webpack_require__(19); - -var _PropTypes = __webpack_require__(21); - -var _React$PropTypes = _react2['default'].PropTypes; -var string = _React$PropTypes.string; -var func = _React$PropTypes.func; - -/** - * A <Route> is used to declare which components are rendered to the - * page when the URL matches a given pattern. - * - * Routes are arranged in a nested tree structure. When a new URL is - * requested, the tree is searched depth-first to find a route whose - * path matches the URL. When one is found, all routes in the tree - * that lead to it are considered "active" and their components are - * rendered into the DOM, nested in the same order as in the tree. - */ - -var Route = (function (_Component) { - _inherits(Route, _Component); - - function Route() { - _classCallCheck(this, Route); - - _Component.apply(this, arguments); - } - - /* istanbul ignore next: sanity check */ - - Route.prototype.render = function render() { - true ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, '<Route> elements are for router configuration only and should not be rendered') : _invariant2['default'](false) : undefined; - }; - - return Route; -})(_react.Component); - -Route.createRouteFromReactElement = _RouteUtils.createRouteFromReactElement; - -Route.propTypes = { - path: string, - component: _PropTypes.component, - components: _PropTypes.components, - getComponent: func, - getComponents: func -}; - -exports['default'] = Route; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 315 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var object = _react2['default'].PropTypes.object; - -/** - * The RouteContext mixin provides a convenient way for route - * components to set the route in context. This is needed for - * routes that render elements that want to use the Lifecycle - * mixin to prevent transitions. - */ -var RouteContext = { - - propTypes: { - route: object.isRequired - }, - - childContextTypes: { - route: object.isRequired - }, - - getChildContext: function getChildContext() { - return { - route: this.props.route - }; - } - -}; - -exports['default'] = RouteContext; -module.exports = exports['default']; - -/***/ }), -/* 316 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _react = __webpack_require__(5); - -var _react2 = _interopRequireDefault(_react); - -var _historyLibCreateHashHistory = __webpack_require__(231); - -var _historyLibCreateHashHistory2 = _interopRequireDefault(_historyLibCreateHashHistory); - -var _RouteUtils = __webpack_require__(19); - -var _RoutingContext = __webpack_require__(101); - -var _RoutingContext2 = _interopRequireDefault(_RoutingContext); - -var _useRoutes = __webpack_require__(62); - -var _useRoutes2 = _interopRequireDefault(_useRoutes); - -var _PropTypes = __webpack_require__(21); - -var _React$PropTypes = _react2['default'].PropTypes; -var func = _React$PropTypes.func; -var object = _React$PropTypes.object; - -/** - * A <Router> is a high-level API for automatically setting up - * a router that renders a <RoutingContext> with all the props - * it needs each time the URL changes. - */ - -var Router = (function (_Component) { - _inherits(Router, _Component); - - function Router(props, context) { - _classCallCheck(this, Router); - - _Component.call(this, props, context); - - this.state = { - location: null, - routes: null, - params: null, - components: null - }; - } - - Router.prototype.handleError = function handleError(error) { - if (this.props.onError) { - this.props.onError.call(this, error); - } else { - // Throw errors by default so we don't silently swallow them! - throw error; // This error probably occurred in getChildRoutes or getComponents. - } - }; - - Router.prototype.componentWillMount = function componentWillMount() { - var _this = this; - - var _props = this.props; - var history = _props.history; - var children = _props.children; - var routes = _props.routes; - var parseQueryString = _props.parseQueryString; - var stringifyQuery = _props.stringifyQuery; - - var createHistory = history ? function () { - return history; - } : _historyLibCreateHashHistory2['default']; - - this.history = _useRoutes2['default'](createHistory)({ - routes: _RouteUtils.createRoutes(routes || children), - parseQueryString: parseQueryString, - stringifyQuery: stringifyQuery - }); - - this._unlisten = this.history.listen(function (error, state) { - if (error) { - _this.handleError(error); - } else { - _this.setState(state, _this.props.onUpdate); - } - }); - }; - - /* istanbul ignore next: sanity check */ - - Router.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](nextProps.history === this.props.history, 'You cannot change <Router history>; it will be ignored') : undefined; - - process.env.NODE_ENV !== 'production' ? _warning2['default']((nextProps.routes || nextProps.children) === (this.props.routes || this.props.children), 'You cannot change <Router routes>; it will be ignored') : undefined; - }; - - Router.prototype.componentWillUnmount = function componentWillUnmount() { - if (this._unlisten) this._unlisten(); - }; - - Router.prototype.render = function render() { - var _state = this.state; - var location = _state.location; - var routes = _state.routes; - var params = _state.params; - var components = _state.components; - var _props2 = this.props; - var RoutingContext = _props2.RoutingContext; - var createElement = _props2.createElement; - - var props = _objectWithoutProperties(_props2, ['RoutingContext', 'createElement']); - - if (location == null) return null; // Async match - - // Only forward non-Router-specific props to routing context, as those are - // the only ones that might be custom routing context props. - Object.keys(Router.propTypes).forEach(function (propType) { - return delete props[propType]; - }); - - return _react2['default'].createElement(RoutingContext, _extends({}, props, { - history: this.history, - createElement: createElement, - location: location, - routes: routes, - params: params, - components: components - })); - }; - - return Router; -})(_react.Component); - -Router.propTypes = { - history: object, - children: _PropTypes.routes, - routes: _PropTypes.routes, // alias for children - RoutingContext: func.isRequired, - createElement: func, - onError: func, - onUpdate: func, - parseQueryString: func, - stringifyQuery: func -}; - -Router.defaultProps = { - RoutingContext: _RoutingContext2['default'] -}; - -exports['default'] = Router; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 317 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.runEnterHooks = runEnterHooks; -exports.runLeaveHooks = runLeaveHooks; - -var _AsyncUtils = __webpack_require__(61); - -function createEnterHook(hook, route) { - return function (a, b, callback) { - hook.apply(route, arguments); - - if (hook.length < 3) { - // Assume hook executes synchronously and - // automatically call the callback. - callback(); - } - }; -} - -function getEnterHooks(routes) { - return routes.reduce(function (hooks, route) { - if (route.onEnter) hooks.push(createEnterHook(route.onEnter, route)); - - return hooks; - }, []); -} - -/** - * Runs all onEnter hooks in the given array of routes in order - * with onEnter(nextState, replaceState, callback) and calls - * callback(error, redirectInfo) when finished. The first hook - * to use replaceState short-circuits the loop. - * - * If a hook needs to run asynchronously, it may use the callback - * function. However, doing so will cause the transition to pause, - * which could lead to a non-responsive UI if the hook is slow. - */ - -function runEnterHooks(routes, nextState, callback) { - var hooks = getEnterHooks(routes); - - if (!hooks.length) { - callback(); - return; - } - - var redirectInfo = undefined; - function replaceState(state, pathname, query) { - redirectInfo = { pathname: pathname, query: query, state: state }; - } - - _AsyncUtils.loopAsync(hooks.length, function (index, next, done) { - hooks[index](nextState, replaceState, function (error) { - if (error || redirectInfo) { - done(error, redirectInfo); // No need to continue. - } else { - next(); - } - }); - }, callback); -} - -/** - * Runs all onLeave hooks in the given array of routes in order. - */ - -function runLeaveHooks(routes) { - for (var i = 0, len = routes.length; i < len; ++i) { - if (routes[i].onLeave) routes[i].onLeave.call(routes[i]); - } -} - -/***/ }), -/* 318 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _PatternUtils = __webpack_require__(34); - -function routeParamsChanged(route, prevState, nextState) { - if (!route.path) return false; - - var paramNames = _PatternUtils.getParamNames(route.path); - - return paramNames.some(function (paramName) { - return prevState.params[paramName] !== nextState.params[paramName]; - }); -} - -/** - * Returns an object of { leaveRoutes, enterRoutes } determined by - * the change from prevState to nextState. We leave routes if either - * 1) they are not in the next state or 2) they are in the next state - * but their params have changed (i.e. /users/123 => /users/456). - * - * leaveRoutes are ordered starting at the leaf route of the tree - * we're leaving up to the common parent route. enterRoutes are ordered - * from the top of the tree we're entering down to the leaf route. - */ -function computeChangedRoutes(prevState, nextState) { - var prevRoutes = prevState && prevState.routes; - var nextRoutes = nextState.routes; - - var leaveRoutes = undefined, - enterRoutes = undefined; - if (prevRoutes) { - leaveRoutes = prevRoutes.filter(function (route) { - return nextRoutes.indexOf(route) === -1 || routeParamsChanged(route, prevState, nextState); - }); - - // onLeave hooks start at the leaf route. - leaveRoutes.reverse(); - - enterRoutes = nextRoutes.filter(function (route) { - return prevRoutes.indexOf(route) === -1 || leaveRoutes.indexOf(route) !== -1; - }); - } else { - leaveRoutes = []; - enterRoutes = nextRoutes; - } - - return { - leaveRoutes: leaveRoutes, - enterRoutes: enterRoutes - }; -} - -exports['default'] = computeChangedRoutes; -module.exports = exports['default']; - -/***/ }), -/* 319 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _AsyncUtils = __webpack_require__(61); - -function getComponentsForRoute(location, route, callback) { - if (route.component || route.components) { - callback(null, route.component || route.components); - } else if (route.getComponent) { - route.getComponent(location, callback); - } else if (route.getComponents) { - route.getComponents(location, callback); - } else { - callback(); - } -} - -/** - * Asynchronously fetches all components needed for the given router - * state and calls callback(error, components) when finished. - * - * Note: This operation may finish synchronously if no routes have an - * asynchronous getComponents method. - */ -function getComponents(nextState, callback) { - _AsyncUtils.mapAsync(nextState.routes, function (route, index, callback) { - getComponentsForRoute(nextState.location, route, callback); - }, callback); -} - -exports['default'] = getComponents; -module.exports = exports['default']; - -/***/ }), -/* 320 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _PatternUtils = __webpack_require__(34); - -/** - * Extracts an object of params the given route cares about from - * the given params object. - */ -function getRouteParams(route, params) { - var routeParams = {}; - - if (!route.path) return routeParams; - - var paramNames = _PatternUtils.getParamNames(route.path); - - for (var p in params) { - if (params.hasOwnProperty(p) && paramNames.indexOf(p) !== -1) routeParams[p] = params[p]; - }return routeParams; -} - -exports['default'] = getRouteParams; -module.exports = exports['default']; - -/***/ }), -/* 321 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _PatternUtils = __webpack_require__(34); - -function deepEqual(a, b) { - if (a == b) return true; - - if (a == null || b == null) return false; - - if (Array.isArray(a)) { - return Array.isArray(b) && a.length === b.length && a.every(function (item, index) { - return deepEqual(item, b[index]); - }); - } - - if (typeof a === 'object') { - for (var p in a) { - if (!a.hasOwnProperty(p)) { - continue; - } - - if (a[p] === undefined) { - if (b[p] !== undefined) { - return false; - } - } else if (!b.hasOwnProperty(p)) { - return false; - } else if (!deepEqual(a[p], b[p])) { - return false; - } - } - - return true; - } - - return String(a) === String(b); -} - -function paramsAreActive(paramNames, paramValues, activeParams) { - // FIXME: This doesn't work on repeated params in activeParams. - return paramNames.every(function (paramName, index) { - return String(paramValues[index]) === String(activeParams[paramName]); - }); -} - -function getMatchingRouteIndex(pathname, activeRoutes, activeParams) { - var remainingPathname = pathname, - paramNames = [], - paramValues = []; - - for (var i = 0, len = activeRoutes.length; i < len; ++i) { - var route = activeRoutes[i]; - var pattern = route.path || ''; - - if (pattern.charAt(0) === '/') { - remainingPathname = pathname; - paramNames = []; - paramValues = []; - } - - if (remainingPathname !== null) { - var matched = _PatternUtils.matchPattern(pattern, remainingPathname); - remainingPathname = matched.remainingPathname; - paramNames = [].concat(paramNames, matched.paramNames); - paramValues = [].concat(paramValues, matched.paramValues); - } - - if (remainingPathname === '' && route.path && paramsAreActive(paramNames, paramValues, activeParams)) return i; - } - - return null; -} - -/** - * Returns true if the given pathname matches the active routes - * and params. - */ -function routeIsActive(pathname, routes, params, indexOnly) { - var i = getMatchingRouteIndex(pathname, routes, params); - - if (i === null) { - // No match. - return false; - } else if (!indexOnly) { - // Any match is good enough. - return true; - } - - // If any remaining routes past the match index have paths, then we can't - // be on the index route. - return routes.slice(i + 1).every(function (route) { - return !route.path; - }); -} - -/** - * Returns true if all key/value pairs in the given query are - * currently active. - */ -function queryIsActive(query, activeQuery) { - if (activeQuery == null) return query == null; - - if (query == null) return true; - - return deepEqual(query, activeQuery); -} - -/** - * Returns true if a <Link> to the given pathname/query combination is - * currently active. - */ -function isActive(pathname, query, indexOnly, location, routes, params) { - if (location == null) return false; - - if (!routeIsActive(pathname, routes, params, indexOnly)) return false; - - return queryIsActive(query, location.query); -} - -exports['default'] = isActive; -module.exports = exports['default']; - -/***/ }), -/* 322 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _invariant = __webpack_require__(13); - -var _invariant2 = _interopRequireDefault(_invariant); - -var _historyLibCreateMemoryHistory = __webpack_require__(233); - -var _historyLibCreateMemoryHistory2 = _interopRequireDefault(_historyLibCreateMemoryHistory); - -var _historyLibUseBasename = __webpack_require__(234); - -var _historyLibUseBasename2 = _interopRequireDefault(_historyLibUseBasename); - -var _RouteUtils = __webpack_require__(19); - -var _useRoutes = __webpack_require__(62); - -var _useRoutes2 = _interopRequireDefault(_useRoutes); - -var createHistory = _useRoutes2['default'](_historyLibUseBasename2['default'](_historyLibCreateMemoryHistory2['default'])); - -/** - * A high-level API to be used for server-side rendering. - * - * This function matches a location to a set of routes and calls - * callback(error, redirectLocation, renderProps) when finished. - * - * Note: You probably don't want to use this in a browser. Use - * the history.listen API instead. - */ -function match(_ref, callback) { - var routes = _ref.routes; - var location = _ref.location; - var parseQueryString = _ref.parseQueryString; - var stringifyQuery = _ref.stringifyQuery; - var basename = _ref.basename; - - !location ? process.env.NODE_ENV !== 'production' ? _invariant2['default'](false, 'match needs a location') : _invariant2['default'](false) : undefined; - - var history = createHistory({ - routes: _RouteUtils.createRoutes(routes), - parseQueryString: parseQueryString, - stringifyQuery: stringifyQuery, - basename: basename - }); - - // Allow match({ location: '/the/path', ... }) - if (typeof location === 'string') location = history.createLocation(location); - - history.match(location, function (error, redirectLocation, nextState) { - callback(error, redirectLocation, nextState && _extends({}, nextState, { history: history })); - }); -} - -exports['default'] = match; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 323 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _warning = __webpack_require__(11); - -var _warning2 = _interopRequireDefault(_warning); - -var _AsyncUtils = __webpack_require__(61); - -var _PatternUtils = __webpack_require__(34); - -var _RouteUtils = __webpack_require__(19); - -function getChildRoutes(route, location, callback) { - if (route.childRoutes) { - callback(null, route.childRoutes); - } else if (route.getChildRoutes) { - route.getChildRoutes(location, function (error, childRoutes) { - callback(error, !error && _RouteUtils.createRoutes(childRoutes)); - }); - } else { - callback(); - } -} - -function getIndexRoute(route, location, callback) { - if (route.indexRoute) { - callback(null, route.indexRoute); - } else if (route.getIndexRoute) { - route.getIndexRoute(location, function (error, indexRoute) { - callback(error, !error && _RouteUtils.createRoutes(indexRoute)[0]); - }); - } else if (route.childRoutes) { - (function () { - var pathless = route.childRoutes.filter(function (obj) { - return !obj.hasOwnProperty('path'); - }); - - _AsyncUtils.loopAsync(pathless.length, function (index, next, done) { - getIndexRoute(pathless[index], location, function (error, indexRoute) { - if (error || indexRoute) { - var routes = [pathless[index]].concat(Array.isArray(indexRoute) ? indexRoute : [indexRoute]); - done(error, routes); - } else { - next(); - } - }); - }, function (err, routes) { - callback(null, routes); - }); - })(); - } else { - callback(); - } -} - -function assignParams(params, paramNames, paramValues) { - return paramNames.reduce(function (params, paramName, index) { - var paramValue = paramValues && paramValues[index]; - - if (Array.isArray(params[paramName])) { - params[paramName].push(paramValue); - } else if (paramName in params) { - params[paramName] = [params[paramName], paramValue]; - } else { - params[paramName] = paramValue; - } - - return params; - }, params); -} - -function createParams(paramNames, paramValues) { - return assignParams({}, paramNames, paramValues); -} - -function matchRouteDeep(route, location, remainingPathname, paramNames, paramValues, callback) { - var pattern = route.path || ''; - - if (pattern.charAt(0) === '/') { - remainingPathname = location.pathname; - paramNames = []; - paramValues = []; - } - - if (remainingPathname !== null) { - var matched = _PatternUtils.matchPattern(pattern, remainingPathname); - remainingPathname = matched.remainingPathname; - paramNames = [].concat(paramNames, matched.paramNames); - paramValues = [].concat(paramValues, matched.paramValues); - - if (remainingPathname === '' && route.path) { - var _ret2 = (function () { - var match = { - routes: [route], - params: createParams(paramNames, paramValues) - }; - - getIndexRoute(route, location, function (error, indexRoute) { - if (error) { - callback(error); - } else { - if (Array.isArray(indexRoute)) { - var _match$routes; - - process.env.NODE_ENV !== 'production' ? _warning2['default'](indexRoute.every(function (route) { - return !route.path; - }), 'Index routes should not have paths') : undefined; - (_match$routes = match.routes).push.apply(_match$routes, indexRoute); - } else if (indexRoute) { - process.env.NODE_ENV !== 'production' ? _warning2['default'](!indexRoute.path, 'Index routes should not have paths') : undefined; - match.routes.push(indexRoute); - } - - callback(null, match); - } - }); - return { - v: undefined - }; - })(); - - if (typeof _ret2 === 'object') return _ret2.v; - } - } - - if (remainingPathname != null || route.childRoutes) { - // Either a) this route matched at least some of the path or b) - // we don't have to load this route's children asynchronously. In - // either case continue checking for matches in the subtree. - getChildRoutes(route, location, function (error, childRoutes) { - if (error) { - callback(error); - } else if (childRoutes) { - // Check the child routes to see if any of them match. - matchRoutes(childRoutes, location, function (error, match) { - if (error) { - callback(error); - } else if (match) { - // A child route matched! Augment the match and pass it up the stack. - match.routes.unshift(route); - callback(null, match); - } else { - callback(); - } - }, remainingPathname, paramNames, paramValues); - } else { - callback(); - } - }); - } else { - callback(); - } -} - -/** - * Asynchronously matches the given location to a set of routes and calls - * callback(error, state) when finished. The state object will have the - * following properties: - * - * - routes An array of routes that matched, in hierarchical order - * - params An object of URL parameters - * - * Note: This operation may finish synchronously if no routes have an - * asynchronous getChildRoutes method. - */ -function matchRoutes(routes, location, callback) { - var remainingPathname = arguments.length <= 3 || arguments[3] === undefined ? location.pathname : arguments[3]; - var paramNames = arguments.length <= 4 || arguments[4] === undefined ? [] : arguments[4]; - var paramValues = arguments.length <= 5 || arguments[5] === undefined ? [] : arguments[5]; - return (function () { - _AsyncUtils.loopAsync(routes.length, function (index, next, done) { - matchRouteDeep(routes[index], location, remainingPathname, paramNames, paramValues, function (error, match) { - if (error || match) { - done(error, match); - } else { - next(); - } - }); - }, callback); - })(); -} - -exports['default'] = matchRoutes; -module.exports = exports['default']; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 324 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -/** - * Escape and wrap key so it is safe to use as a reactid - * - * @param {string} key to be escaped. - * @return {string} the escaped key. - */ - -function escape(key) { - var escapeRegex = /[=:]/g; - var escaperLookup = { - '=': '=0', - ':': '=2' - }; - var escapedString = ('' + key).replace(escapeRegex, function (match) { - return escaperLookup[match]; - }); - - return '$' + escapedString; -} - -/** - * Unescape and unwrap key for human-readable display - * - * @param {string} key to unescape. - * @return {string} the unescaped key. - */ -function unescape(key) { - var unescapeRegex = /(=0|=2)/g; - var unescaperLookup = { - '=0': '=', - '=2': ':' - }; - var keySubstring = key[0] === '.' && key[1] === '$' ? key.substring(2) : key.substring(1); - - return ('' + keySubstring).replace(unescapeRegex, function (match) { - return unescaperLookup[match]; - }); -} - -var KeyEscapeUtils = { - escape: escape, - unescape: unescape -}; - -module.exports = KeyEscapeUtils; - -/***/ }), -/* 325 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - - - -var _prodInvariant = __webpack_require__(23); - -var invariant = __webpack_require__(2); - -/** - * Static poolers. Several custom versions for each potential number of - * arguments. A completely generic pooler is easy to implement, but would - * require accessing the `arguments` object. In each of these, `this` refers to - * the Class itself, not an instance. If any others are needed, simply add them - * here, or in their own files. - */ -var oneArgumentPooler = function (copyFieldsFrom) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, copyFieldsFrom); - return instance; - } else { - return new Klass(copyFieldsFrom); - } -}; - -var twoArgumentPooler = function (a1, a2) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2); - return instance; - } else { - return new Klass(a1, a2); - } -}; - -var threeArgumentPooler = function (a1, a2, a3) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3); - return instance; - } else { - return new Klass(a1, a2, a3); - } -}; - -var fourArgumentPooler = function (a1, a2, a3, a4) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3, a4); - return instance; - } else { - return new Klass(a1, a2, a3, a4); - } -}; - -var standardReleaser = function (instance) { - var Klass = this; - !(instance instanceof Klass) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : _prodInvariant('25') : void 0; - instance.destructor(); - if (Klass.instancePool.length < Klass.poolSize) { - Klass.instancePool.push(instance); - } -}; - -var DEFAULT_POOL_SIZE = 10; -var DEFAULT_POOLER = oneArgumentPooler; - -/** - * Augments `CopyConstructor` to be a poolable class, augmenting only the class - * itself (statically) not adding any prototypical fields. Any CopyConstructor - * you give this may have a `poolSize` property, and will look for a - * prototypical `destructor` on instances. - * - * @param {Function} CopyConstructor Constructor that can be used to reset. - * @param {Function} pooler Customizable pooler. - */ -var addPoolingTo = function (CopyConstructor, pooler) { - // Casting as any so that flow ignores the actual implementation and trusts - // it to match the type we declared - var NewKlass = CopyConstructor; - NewKlass.instancePool = []; - NewKlass.getPooled = pooler || DEFAULT_POOLER; - if (!NewKlass.poolSize) { - NewKlass.poolSize = DEFAULT_POOL_SIZE; - } - NewKlass.release = standardReleaser; - return NewKlass; -}; - -var PooledClass = { - addPoolingTo: addPoolingTo, - oneArgumentPooler: oneArgumentPooler, - twoArgumentPooler: twoArgumentPooler, - threeArgumentPooler: threeArgumentPooler, - fourArgumentPooler: fourArgumentPooler -}; - -module.exports = PooledClass; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 326 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var PooledClass = __webpack_require__(325); -var ReactElement = __webpack_require__(22); - -var emptyFunction = __webpack_require__(12); -var traverseAllChildren = __webpack_require__(334); - -var twoArgumentPooler = PooledClass.twoArgumentPooler; -var fourArgumentPooler = PooledClass.fourArgumentPooler; - -var userProvidedKeyEscapeRegex = /\/+/g; -function escapeUserProvidedKey(text) { - return ('' + text).replace(userProvidedKeyEscapeRegex, '$&/'); -} - -/** - * PooledClass representing the bookkeeping associated with performing a child - * traversal. Allows avoiding binding callbacks. - * - * @constructor ForEachBookKeeping - * @param {!function} forEachFunction Function to perform traversal with. - * @param {?*} forEachContext Context to perform context with. - */ -function ForEachBookKeeping(forEachFunction, forEachContext) { - this.func = forEachFunction; - this.context = forEachContext; - this.count = 0; -} -ForEachBookKeeping.prototype.destructor = function () { - this.func = null; - this.context = null; - this.count = 0; -}; -PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler); - -function forEachSingleChild(bookKeeping, child, name) { - var func = bookKeeping.func, - context = bookKeeping.context; - - func.call(context, child, bookKeeping.count++); -} - -/** - * Iterates through children that are typically specified as `props.children`. - * - * See https://facebook.github.io/react/docs/top-level-api.html#react.children.foreach - * - * The provided forEachFunc(child, index) will be called for each - * leaf child. - * - * @param {?*} children Children tree container. - * @param {function(*, int)} forEachFunc - * @param {*} forEachContext Context for forEachContext. - */ -function forEachChildren(children, forEachFunc, forEachContext) { - if (children == null) { - return children; - } - var traverseContext = ForEachBookKeeping.getPooled(forEachFunc, forEachContext); - traverseAllChildren(children, forEachSingleChild, traverseContext); - ForEachBookKeeping.release(traverseContext); -} - -/** - * PooledClass representing the bookkeeping associated with performing a child - * mapping. Allows avoiding binding callbacks. - * - * @constructor MapBookKeeping - * @param {!*} mapResult Object containing the ordered map of results. - * @param {!function} mapFunction Function to perform mapping with. - * @param {?*} mapContext Context to perform mapping with. - */ -function MapBookKeeping(mapResult, keyPrefix, mapFunction, mapContext) { - this.result = mapResult; - this.keyPrefix = keyPrefix; - this.func = mapFunction; - this.context = mapContext; - this.count = 0; -} -MapBookKeeping.prototype.destructor = function () { - this.result = null; - this.keyPrefix = null; - this.func = null; - this.context = null; - this.count = 0; -}; -PooledClass.addPoolingTo(MapBookKeeping, fourArgumentPooler); - -function mapSingleChildIntoContext(bookKeeping, child, childKey) { - var result = bookKeeping.result, - keyPrefix = bookKeeping.keyPrefix, - func = bookKeeping.func, - context = bookKeeping.context; - - - var mappedChild = func.call(context, child, bookKeeping.count++); - if (Array.isArray(mappedChild)) { - mapIntoWithKeyPrefixInternal(mappedChild, result, childKey, emptyFunction.thatReturnsArgument); - } else if (mappedChild != null) { - if (ReactElement.isValidElement(mappedChild)) { - mappedChild = ReactElement.cloneAndReplaceKey(mappedChild, - // Keep both the (mapped) and old keys if they differ, just as - // traverseAllChildren used to do for objects as children - keyPrefix + (mappedChild.key && (!child || child.key !== mappedChild.key) ? escapeUserProvidedKey(mappedChild.key) + '/' : '') + childKey); - } - result.push(mappedChild); - } -} - -function mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) { - var escapedPrefix = ''; - if (prefix != null) { - escapedPrefix = escapeUserProvidedKey(prefix) + '/'; - } - var traverseContext = MapBookKeeping.getPooled(array, escapedPrefix, func, context); - traverseAllChildren(children, mapSingleChildIntoContext, traverseContext); - MapBookKeeping.release(traverseContext); -} - -/** - * Maps children that are typically specified as `props.children`. - * - * See https://facebook.github.io/react/docs/top-level-api.html#react.children.map - * - * The provided mapFunction(child, key, index) will be called for each - * leaf child. - * - * @param {?*} children Children tree container. - * @param {function(*, int)} func The map function. - * @param {*} context Context for mapFunction. - * @return {object} Object containing the ordered map of results. - */ -function mapChildren(children, func, context) { - if (children == null) { - return children; - } - var result = []; - mapIntoWithKeyPrefixInternal(children, result, null, func, context); - return result; -} - -function forEachSingleChildDummy(traverseContext, child, name) { - return null; -} - -/** - * Count the number of children that are typically specified as - * `props.children`. - * - * See https://facebook.github.io/react/docs/top-level-api.html#react.children.count - * - * @param {?*} children Children tree container. - * @return {number} The number of children. - */ -function countChildren(children, context) { - return traverseAllChildren(children, forEachSingleChildDummy, null); -} - -/** - * Flatten a children object (typically specified as `props.children`) and - * return an array with appropriately re-keyed children. - * - * See https://facebook.github.io/react/docs/top-level-api.html#react.children.toarray - */ -function toArray(children) { - var result = []; - mapIntoWithKeyPrefixInternal(children, result, null, emptyFunction.thatReturnsArgument); - return result; -} - -var ReactChildren = { - forEach: forEachChildren, - map: mapChildren, - mapIntoWithKeyPrefixInternal: mapIntoWithKeyPrefixInternal, - count: countChildren, - toArray: toArray -}; - -module.exports = ReactChildren; - -/***/ }), -/* 327 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(23), - _assign = __webpack_require__(6); - -var ReactComponent = __webpack_require__(63); -var ReactElement = __webpack_require__(22); -var ReactPropTypeLocationNames = __webpack_require__(65); -var ReactNoopUpdateQueue = __webpack_require__(64); - -var emptyObject = __webpack_require__(28); -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -var MIXINS_KEY = 'mixins'; - -// Helper function to allow the creation of anonymous functions which do not -// have .name set to the name of the variable being assigned to. -function identity(fn) { - return fn; -} - -/** - * Policies that describe methods in `ReactClassInterface`. - */ - - -var injectedMixins = []; - -/** - * Composite components are higher-level components that compose other composite - * or host components. - * - * To create a new type of `ReactClass`, pass a specification of - * your new class to `React.createClass`. The only requirement of your class - * specification is that you implement a `render` method. - * - * var MyComponent = React.createClass({ - * render: function() { - * return <div>Hello World</div>; - * } - * }); - * - * The class specification supports a specific protocol of methods that have - * special meaning (e.g. `render`). See `ReactClassInterface` for - * more the comprehensive protocol. Any other properties and methods in the - * class specification will be available on the prototype. - * - * @interface ReactClassInterface - * @internal - */ -var ReactClassInterface = { - - /** - * An array of Mixin objects to include when defining your component. - * - * @type {array} - * @optional - */ - mixins: 'DEFINE_MANY', - - /** - * An object containing properties and methods that should be defined on - * the component's constructor instead of its prototype (static methods). - * - * @type {object} - * @optional - */ - statics: 'DEFINE_MANY', - - /** - * Definition of prop types for this component. - * - * @type {object} - * @optional - */ - propTypes: 'DEFINE_MANY', - - /** - * Definition of context types for this component. - * - * @type {object} - * @optional - */ - contextTypes: 'DEFINE_MANY', - - /** - * Definition of context types this component sets for its children. - * - * @type {object} - * @optional - */ - childContextTypes: 'DEFINE_MANY', - - // ==== Definition methods ==== - - /** - * Invoked when the component is mounted. Values in the mapping will be set on - * `this.props` if that prop is not specified (i.e. using an `in` check). - * - * This method is invoked before `getInitialState` and therefore cannot rely - * on `this.state` or use `this.setState`. - * - * @return {object} - * @optional - */ - getDefaultProps: 'DEFINE_MANY_MERGED', - - /** - * Invoked once before the component is mounted. The return value will be used - * as the initial value of `this.state`. - * - * getInitialState: function() { - * return { - * isOn: false, - * fooBaz: new BazFoo() - * } - * } - * - * @return {object} - * @optional - */ - getInitialState: 'DEFINE_MANY_MERGED', - - /** - * @return {object} - * @optional - */ - getChildContext: 'DEFINE_MANY_MERGED', - - /** - * Uses props from `this.props` and state from `this.state` to render the - * structure of the component. - * - * No guarantees are made about when or how often this method is invoked, so - * it must not have side effects. - * - * render: function() { - * var name = this.props.name; - * return <div>Hello, {name}!</div>; - * } - * - * @return {ReactComponent} - * @nosideeffects - * @required - */ - render: 'DEFINE_ONCE', - - // ==== Delegate methods ==== - - /** - * Invoked when the component is initially created and about to be mounted. - * This may have side effects, but any external subscriptions or data created - * by this method must be cleaned up in `componentWillUnmount`. - * - * @optional - */ - componentWillMount: 'DEFINE_MANY', - - /** - * Invoked when the component has been mounted and has a DOM representation. - * However, there is no guarantee that the DOM node is in the document. - * - * Use this as an opportunity to operate on the DOM when the component has - * been mounted (initialized and rendered) for the first time. - * - * @param {DOMElement} rootNode DOM element representing the component. - * @optional - */ - componentDidMount: 'DEFINE_MANY', - - /** - * Invoked before the component receives new props. - * - * Use this as an opportunity to react to a prop transition by updating the - * state using `this.setState`. Current props are accessed via `this.props`. - * - * componentWillReceiveProps: function(nextProps, nextContext) { - * this.setState({ - * likesIncreasing: nextProps.likeCount > this.props.likeCount - * }); - * } - * - * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop - * transition may cause a state change, but the opposite is not true. If you - * need it, you are probably looking for `componentWillUpdate`. - * - * @param {object} nextProps - * @optional - */ - componentWillReceiveProps: 'DEFINE_MANY', - - /** - * Invoked while deciding if the component should be updated as a result of - * receiving new props, state and/or context. - * - * Use this as an opportunity to `return false` when you're certain that the - * transition to the new props/state/context will not require a component - * update. - * - * shouldComponentUpdate: function(nextProps, nextState, nextContext) { - * return !equal(nextProps, this.props) || - * !equal(nextState, this.state) || - * !equal(nextContext, this.context); - * } - * - * @param {object} nextProps - * @param {?object} nextState - * @param {?object} nextContext - * @return {boolean} True if the component should update. - * @optional - */ - shouldComponentUpdate: 'DEFINE_ONCE', - - /** - * Invoked when the component is about to update due to a transition from - * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` - * and `nextContext`. - * - * Use this as an opportunity to perform preparation before an update occurs. - * - * NOTE: You **cannot** use `this.setState()` in this method. - * - * @param {object} nextProps - * @param {?object} nextState - * @param {?object} nextContext - * @param {ReactReconcileTransaction} transaction - * @optional - */ - componentWillUpdate: 'DEFINE_MANY', - - /** - * Invoked when the component's DOM representation has been updated. - * - * Use this as an opportunity to operate on the DOM when the component has - * been updated. - * - * @param {object} prevProps - * @param {?object} prevState - * @param {?object} prevContext - * @param {DOMElement} rootNode DOM element representing the component. - * @optional - */ - componentDidUpdate: 'DEFINE_MANY', - - /** - * Invoked when the component is about to be removed from its parent and have - * its DOM representation destroyed. - * - * Use this as an opportunity to deallocate any external resources. - * - * NOTE: There is no `componentDidUnmount` since your component will have been - * destroyed by that point. - * - * @optional - */ - componentWillUnmount: 'DEFINE_MANY', - - // ==== Advanced methods ==== - - /** - * Updates the component's currently mounted DOM representation. - * - * By default, this implements React's rendering and reconciliation algorithm. - * Sophisticated clients may wish to override this. - * - * @param {ReactReconcileTransaction} transaction - * @internal - * @overridable - */ - updateComponent: 'OVERRIDE_BASE' - -}; - -/** - * Mapping from class specification keys to special processing functions. - * - * Although these are declared like instance properties in the specification - * when defining classes using `React.createClass`, they are actually static - * and are accessible on the constructor instead of the prototype. Despite - * being static, they must be defined outside of the "statics" key under - * which all other static methods are defined. - */ -var RESERVED_SPEC_KEYS = { - displayName: function (Constructor, displayName) { - Constructor.displayName = displayName; - }, - mixins: function (Constructor, mixins) { - if (mixins) { - for (var i = 0; i < mixins.length; i++) { - mixSpecIntoComponent(Constructor, mixins[i]); - } - } - }, - childContextTypes: function (Constructor, childContextTypes) { - if (process.env.NODE_ENV !== 'production') { - validateTypeDef(Constructor, childContextTypes, 'childContext'); - } - Constructor.childContextTypes = _assign({}, Constructor.childContextTypes, childContextTypes); - }, - contextTypes: function (Constructor, contextTypes) { - if (process.env.NODE_ENV !== 'production') { - validateTypeDef(Constructor, contextTypes, 'context'); - } - Constructor.contextTypes = _assign({}, Constructor.contextTypes, contextTypes); - }, - /** - * Special case getDefaultProps which should move into statics but requires - * automatic merging. - */ - getDefaultProps: function (Constructor, getDefaultProps) { - if (Constructor.getDefaultProps) { - Constructor.getDefaultProps = createMergedResultFunction(Constructor.getDefaultProps, getDefaultProps); - } else { - Constructor.getDefaultProps = getDefaultProps; - } - }, - propTypes: function (Constructor, propTypes) { - if (process.env.NODE_ENV !== 'production') { - validateTypeDef(Constructor, propTypes, 'prop'); - } - Constructor.propTypes = _assign({}, Constructor.propTypes, propTypes); - }, - statics: function (Constructor, statics) { - mixStaticSpecIntoComponent(Constructor, statics); - }, - autobind: function () {} }; - -function validateTypeDef(Constructor, typeDef, location) { - for (var propName in typeDef) { - if (typeDef.hasOwnProperty(propName)) { - // use a warning instead of an invariant so components - // don't show up in prod but only in __DEV__ - process.env.NODE_ENV !== 'production' ? warning(typeof typeDef[propName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', Constructor.displayName || 'ReactClass', ReactPropTypeLocationNames[location], propName) : void 0; - } - } -} - -function validateMethodOverride(isAlreadyDefined, name) { - var specPolicy = ReactClassInterface.hasOwnProperty(name) ? ReactClassInterface[name] : null; - - // Disallow overriding of base class methods unless explicitly allowed. - if (ReactClassMixin.hasOwnProperty(name)) { - !(specPolicy === 'OVERRIDE_BASE') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to override `%s` from your class specification. Ensure that your method names do not overlap with React methods.', name) : _prodInvariant('73', name) : void 0; - } - - // Disallow defining methods more than once unless explicitly allowed. - if (isAlreadyDefined) { - !(specPolicy === 'DEFINE_MANY' || specPolicy === 'DEFINE_MANY_MERGED') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to define `%s` on your component more than once. This conflict may be due to a mixin.', name) : _prodInvariant('74', name) : void 0; - } -} - -/** - * Mixin helper which handles policy validation and reserved - * specification keys when building React classes. - */ -function mixSpecIntoComponent(Constructor, spec) { - if (!spec) { - if (process.env.NODE_ENV !== 'production') { - var typeofSpec = typeof spec; - var isMixinValid = typeofSpec === 'object' && spec !== null; - - process.env.NODE_ENV !== 'production' ? warning(isMixinValid, '%s: You\'re attempting to include a mixin that is either null ' + 'or not an object. Check the mixins included by the component, ' + 'as well as any mixins they include themselves. ' + 'Expected object but got %s.', Constructor.displayName || 'ReactClass', spec === null ? null : typeofSpec) : void 0; - } - - return; - } - - !(typeof spec !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You\'re attempting to use a component class or function as a mixin. Instead, just use a regular object.') : _prodInvariant('75') : void 0; - !!ReactElement.isValidElement(spec) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You\'re attempting to use a component as a mixin. Instead, just use a regular object.') : _prodInvariant('76') : void 0; - - var proto = Constructor.prototype; - var autoBindPairs = proto.__reactAutoBindPairs; - - // By handling mixins before any other properties, we ensure the same - // chaining order is applied to methods with DEFINE_MANY policy, whether - // mixins are listed before or after these methods in the spec. - if (spec.hasOwnProperty(MIXINS_KEY)) { - RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins); - } - - for (var name in spec) { - if (!spec.hasOwnProperty(name)) { - continue; - } - - if (name === MIXINS_KEY) { - // We have already handled mixins in a special case above. - continue; - } - - var property = spec[name]; - var isAlreadyDefined = proto.hasOwnProperty(name); - validateMethodOverride(isAlreadyDefined, name); - - if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { - RESERVED_SPEC_KEYS[name](Constructor, property); - } else { - // Setup methods on prototype: - // The following member methods should not be automatically bound: - // 1. Expected ReactClass methods (in the "interface"). - // 2. Overridden methods (that were mixed in). - var isReactClassMethod = ReactClassInterface.hasOwnProperty(name); - var isFunction = typeof property === 'function'; - var shouldAutoBind = isFunction && !isReactClassMethod && !isAlreadyDefined && spec.autobind !== false; - - if (shouldAutoBind) { - autoBindPairs.push(name, property); - proto[name] = property; - } else { - if (isAlreadyDefined) { - var specPolicy = ReactClassInterface[name]; - - // These cases should already be caught by validateMethodOverride. - !(isReactClassMethod && (specPolicy === 'DEFINE_MANY_MERGED' || specPolicy === 'DEFINE_MANY')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: Unexpected spec policy %s for key %s when mixing in component specs.', specPolicy, name) : _prodInvariant('77', specPolicy, name) : void 0; - - // For methods which are defined more than once, call the existing - // methods before calling the new property, merging if appropriate. - if (specPolicy === 'DEFINE_MANY_MERGED') { - proto[name] = createMergedResultFunction(proto[name], property); - } else if (specPolicy === 'DEFINE_MANY') { - proto[name] = createChainedFunction(proto[name], property); - } - } else { - proto[name] = property; - if (process.env.NODE_ENV !== 'production') { - // Add verbose displayName to the function, which helps when looking - // at profiling tools. - if (typeof property === 'function' && spec.displayName) { - proto[name].displayName = spec.displayName + '_' + name; - } - } - } - } - } - } -} - -function mixStaticSpecIntoComponent(Constructor, statics) { - if (!statics) { - return; - } - for (var name in statics) { - var property = statics[name]; - if (!statics.hasOwnProperty(name)) { - continue; - } - - var isReserved = name in RESERVED_SPEC_KEYS; - !!isReserved ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You are attempting to define a reserved property, `%s`, that shouldn\'t be on the "statics" key. Define it as an instance property instead; it will still be accessible on the constructor.', name) : _prodInvariant('78', name) : void 0; - - var isInherited = name in Constructor; - !!isInherited ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You are attempting to define `%s` on your component more than once. This conflict may be due to a mixin.', name) : _prodInvariant('79', name) : void 0; - Constructor[name] = property; - } -} - -/** - * Merge two objects, but throw if both contain the same key. - * - * @param {object} one The first object, which is mutated. - * @param {object} two The second object - * @return {object} one after it has been mutated to contain everything in two. - */ -function mergeIntoWithNoDuplicateKeys(one, two) { - !(one && two && typeof one === 'object' && typeof two === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.') : _prodInvariant('80') : void 0; - - for (var key in two) { - if (two.hasOwnProperty(key)) { - !(one[key] === undefined) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mergeIntoWithNoDuplicateKeys(): Tried to merge two objects with the same key: `%s`. This conflict may be due to a mixin; in particular, this may be caused by two getInitialState() or getDefaultProps() methods returning objects with clashing keys.', key) : _prodInvariant('81', key) : void 0; - one[key] = two[key]; - } - } - return one; -} - -/** - * Creates a function that invokes two functions and merges their return values. - * - * @param {function} one Function to invoke first. - * @param {function} two Function to invoke second. - * @return {function} Function that invokes the two argument functions. - * @private - */ -function createMergedResultFunction(one, two) { - return function mergedResult() { - var a = one.apply(this, arguments); - var b = two.apply(this, arguments); - if (a == null) { - return b; - } else if (b == null) { - return a; - } - var c = {}; - mergeIntoWithNoDuplicateKeys(c, a); - mergeIntoWithNoDuplicateKeys(c, b); - return c; - }; -} - -/** - * Creates a function that invokes two functions and ignores their return vales. - * - * @param {function} one Function to invoke first. - * @param {function} two Function to invoke second. - * @return {function} Function that invokes the two argument functions. - * @private - */ -function createChainedFunction(one, two) { - return function chainedFunction() { - one.apply(this, arguments); - two.apply(this, arguments); - }; -} - -/** - * Binds a method to the component. - * - * @param {object} component Component whose method is going to be bound. - * @param {function} method Method to be bound. - * @return {function} The bound method. - */ -function bindAutoBindMethod(component, method) { - var boundMethod = method.bind(component); - if (process.env.NODE_ENV !== 'production') { - boundMethod.__reactBoundContext = component; - boundMethod.__reactBoundMethod = method; - boundMethod.__reactBoundArguments = null; - var componentName = component.constructor.displayName; - var _bind = boundMethod.bind; - boundMethod.bind = function (newThis) { - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - // User is trying to bind() an autobound method; we effectively will - // ignore the value of "this" that the user is trying to use, so - // let's warn. - if (newThis !== component && newThis !== null) { - process.env.NODE_ENV !== 'production' ? warning(false, 'bind(): React component methods may only be bound to the ' + 'component instance. See %s', componentName) : void 0; - } else if (!args.length) { - process.env.NODE_ENV !== 'production' ? warning(false, 'bind(): You are binding a component method to the component. ' + 'React does this for you automatically in a high-performance ' + 'way, so you can safely remove this call. See %s', componentName) : void 0; - return boundMethod; - } - var reboundMethod = _bind.apply(boundMethod, arguments); - reboundMethod.__reactBoundContext = component; - reboundMethod.__reactBoundMethod = method; - reboundMethod.__reactBoundArguments = args; - return reboundMethod; - }; - } - return boundMethod; -} - -/** - * Binds all auto-bound methods in a component. - * - * @param {object} component Component whose method is going to be bound. - */ -function bindAutoBindMethods(component) { - var pairs = component.__reactAutoBindPairs; - for (var i = 0; i < pairs.length; i += 2) { - var autoBindKey = pairs[i]; - var method = pairs[i + 1]; - component[autoBindKey] = bindAutoBindMethod(component, method); - } -} - -/** - * Add more to the ReactClass base class. These are all legacy features and - * therefore not already part of the modern ReactComponent. - */ -var ReactClassMixin = { - - /** - * TODO: This will be deprecated because state should always keep a consistent - * type signature and the only use case for this, is to avoid that. - */ - replaceState: function (newState, callback) { - this.updater.enqueueReplaceState(this, newState); - if (callback) { - this.updater.enqueueCallback(this, callback, 'replaceState'); - } - }, - - /** - * Checks whether or not this composite component is mounted. - * @return {boolean} True if mounted, false otherwise. - * @protected - * @final - */ - isMounted: function () { - return this.updater.isMounted(this); - } -}; - -var ReactClassComponent = function () {}; -_assign(ReactClassComponent.prototype, ReactComponent.prototype, ReactClassMixin); - -/** - * Module for creating composite components. - * - * @class ReactClass - */ -var ReactClass = { - - /** - * Creates a composite component class given a class specification. - * See https://facebook.github.io/react/docs/top-level-api.html#react.createclass - * - * @param {object} spec Class specification (which must define `render`). - * @return {function} Component constructor function. - * @public - */ - createClass: function (spec) { - // To keep our warnings more understandable, we'll use a little hack here to - // ensure that Constructor.name !== 'Constructor'. This makes sure we don't - // unnecessarily identify a class without displayName as 'Constructor'. - var Constructor = identity(function (props, context, updater) { - // This constructor gets overridden by mocks. The argument is used - // by mocks to assert on what gets mounted. - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(this instanceof Constructor, 'Something is calling a React component directly. Use a factory or ' + 'JSX instead. See: https://fb.me/react-legacyfactory') : void 0; - } - - // Wire up auto-binding - if (this.__reactAutoBindPairs.length) { - bindAutoBindMethods(this); - } - - this.props = props; - this.context = context; - this.refs = emptyObject; - this.updater = updater || ReactNoopUpdateQueue; - - this.state = null; - - // ReactClasses doesn't have constructors. Instead, they use the - // getInitialState and componentWillMount methods for initialization. - - var initialState = this.getInitialState ? this.getInitialState() : null; - if (process.env.NODE_ENV !== 'production') { - // We allow auto-mocks to proceed as if they're returning null. - if (initialState === undefined && this.getInitialState._isMockFunction) { - // This is probably bad practice. Consider warning here and - // deprecating this convenience. - initialState = null; - } - } - !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getInitialState(): must return an object or null', Constructor.displayName || 'ReactCompositeComponent') : _prodInvariant('82', Constructor.displayName || 'ReactCompositeComponent') : void 0; - - this.state = initialState; - }); - Constructor.prototype = new ReactClassComponent(); - Constructor.prototype.constructor = Constructor; - Constructor.prototype.__reactAutoBindPairs = []; - - injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor)); - - mixSpecIntoComponent(Constructor, spec); - - // Initialize the defaultProps property after all mixins have been merged. - if (Constructor.getDefaultProps) { - Constructor.defaultProps = Constructor.getDefaultProps(); - } - - if (process.env.NODE_ENV !== 'production') { - // This is a tag to indicate that the use of these method names is ok, - // since it's used with createClass. If it's not, then it's likely a - // mistake so we'll warn you to use the static property, property - // initializer or constructor respectively. - if (Constructor.getDefaultProps) { - Constructor.getDefaultProps.isReactClassApproved = {}; - } - if (Constructor.prototype.getInitialState) { - Constructor.prototype.getInitialState.isReactClassApproved = {}; - } - } - - !Constructor.prototype.render ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createClass(...): Class specification must implement a `render` method.') : _prodInvariant('83') : void 0; - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(!Constructor.prototype.componentShouldUpdate, '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', spec.displayName || 'A component') : void 0; - process.env.NODE_ENV !== 'production' ? warning(!Constructor.prototype.componentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', spec.displayName || 'A component') : void 0; - } - - // Reduce time spent doing lookups by setting these on the prototype. - for (var methodName in ReactClassInterface) { - if (!Constructor.prototype[methodName]) { - Constructor.prototype[methodName] = null; - } - } - - return Constructor; - }, - - injection: { - injectMixin: function (mixin) { - injectedMixins.push(mixin); - } - } - -}; - -module.exports = ReactClass; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 328 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactElement = __webpack_require__(22); - -/** - * Create a factory that creates HTML tag elements. - * - * @private - */ -var createDOMFactory = ReactElement.createFactory; -if (process.env.NODE_ENV !== 'production') { - var ReactElementValidator = __webpack_require__(104); - createDOMFactory = ReactElementValidator.createFactory; -} - -/** - * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. - * This is also accessible via `React.DOM`. - * - * @public - */ -var ReactDOMFactories = { - a: createDOMFactory('a'), - abbr: createDOMFactory('abbr'), - address: createDOMFactory('address'), - area: createDOMFactory('area'), - article: createDOMFactory('article'), - aside: createDOMFactory('aside'), - audio: createDOMFactory('audio'), - b: createDOMFactory('b'), - base: createDOMFactory('base'), - bdi: createDOMFactory('bdi'), - bdo: createDOMFactory('bdo'), - big: createDOMFactory('big'), - blockquote: createDOMFactory('blockquote'), - body: createDOMFactory('body'), - br: createDOMFactory('br'), - button: createDOMFactory('button'), - canvas: createDOMFactory('canvas'), - caption: createDOMFactory('caption'), - cite: createDOMFactory('cite'), - code: createDOMFactory('code'), - col: createDOMFactory('col'), - colgroup: createDOMFactory('colgroup'), - data: createDOMFactory('data'), - datalist: createDOMFactory('datalist'), - dd: createDOMFactory('dd'), - del: createDOMFactory('del'), - details: createDOMFactory('details'), - dfn: createDOMFactory('dfn'), - dialog: createDOMFactory('dialog'), - div: createDOMFactory('div'), - dl: createDOMFactory('dl'), - dt: createDOMFactory('dt'), - em: createDOMFactory('em'), - embed: createDOMFactory('embed'), - fieldset: createDOMFactory('fieldset'), - figcaption: createDOMFactory('figcaption'), - figure: createDOMFactory('figure'), - footer: createDOMFactory('footer'), - form: createDOMFactory('form'), - h1: createDOMFactory('h1'), - h2: createDOMFactory('h2'), - h3: createDOMFactory('h3'), - h4: createDOMFactory('h4'), - h5: createDOMFactory('h5'), - h6: createDOMFactory('h6'), - head: createDOMFactory('head'), - header: createDOMFactory('header'), - hgroup: createDOMFactory('hgroup'), - hr: createDOMFactory('hr'), - html: createDOMFactory('html'), - i: createDOMFactory('i'), - iframe: createDOMFactory('iframe'), - img: createDOMFactory('img'), - input: createDOMFactory('input'), - ins: createDOMFactory('ins'), - kbd: createDOMFactory('kbd'), - keygen: createDOMFactory('keygen'), - label: createDOMFactory('label'), - legend: createDOMFactory('legend'), - li: createDOMFactory('li'), - link: createDOMFactory('link'), - main: createDOMFactory('main'), - map: createDOMFactory('map'), - mark: createDOMFactory('mark'), - menu: createDOMFactory('menu'), - menuitem: createDOMFactory('menuitem'), - meta: createDOMFactory('meta'), - meter: createDOMFactory('meter'), - nav: createDOMFactory('nav'), - noscript: createDOMFactory('noscript'), - object: createDOMFactory('object'), - ol: createDOMFactory('ol'), - optgroup: createDOMFactory('optgroup'), - option: createDOMFactory('option'), - output: createDOMFactory('output'), - p: createDOMFactory('p'), - param: createDOMFactory('param'), - picture: createDOMFactory('picture'), - pre: createDOMFactory('pre'), - progress: createDOMFactory('progress'), - q: createDOMFactory('q'), - rp: createDOMFactory('rp'), - rt: createDOMFactory('rt'), - ruby: createDOMFactory('ruby'), - s: createDOMFactory('s'), - samp: createDOMFactory('samp'), - script: createDOMFactory('script'), - section: createDOMFactory('section'), - select: createDOMFactory('select'), - small: createDOMFactory('small'), - source: createDOMFactory('source'), - span: createDOMFactory('span'), - strong: createDOMFactory('strong'), - style: createDOMFactory('style'), - sub: createDOMFactory('sub'), - summary: createDOMFactory('summary'), - sup: createDOMFactory('sup'), - table: createDOMFactory('table'), - tbody: createDOMFactory('tbody'), - td: createDOMFactory('td'), - textarea: createDOMFactory('textarea'), - tfoot: createDOMFactory('tfoot'), - th: createDOMFactory('th'), - thead: createDOMFactory('thead'), - time: createDOMFactory('time'), - title: createDOMFactory('title'), - tr: createDOMFactory('tr'), - track: createDOMFactory('track'), - u: createDOMFactory('u'), - ul: createDOMFactory('ul'), - 'var': createDOMFactory('var'), - video: createDOMFactory('video'), - wbr: createDOMFactory('wbr'), - - // SVG - circle: createDOMFactory('circle'), - clipPath: createDOMFactory('clipPath'), - defs: createDOMFactory('defs'), - ellipse: createDOMFactory('ellipse'), - g: createDOMFactory('g'), - image: createDOMFactory('image'), - line: createDOMFactory('line'), - linearGradient: createDOMFactory('linearGradient'), - mask: createDOMFactory('mask'), - path: createDOMFactory('path'), - pattern: createDOMFactory('pattern'), - polygon: createDOMFactory('polygon'), - polyline: createDOMFactory('polyline'), - radialGradient: createDOMFactory('radialGradient'), - rect: createDOMFactory('rect'), - stop: createDOMFactory('stop'), - svg: createDOMFactory('svg'), - text: createDOMFactory('text'), - tspan: createDOMFactory('tspan') -}; - -module.exports = ReactDOMFactories; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 329 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var ReactElement = __webpack_require__(22); -var ReactPropTypeLocationNames = __webpack_require__(65); -var ReactPropTypesSecret = __webpack_require__(105); - -var emptyFunction = __webpack_require__(12); -var getIteratorFn = __webpack_require__(67); -var warning = __webpack_require__(3); - -/** - * Collection of methods that allow declaration and validation of props that are - * supplied to React components. Example usage: - * - * var Props = require('ReactPropTypes'); - * var MyArticle = React.createClass({ - * propTypes: { - * // An optional string prop named "description". - * description: Props.string, - * - * // A required enum prop named "category". - * category: Props.oneOf(['News','Photos']).isRequired, - * - * // A prop named "dialog" that requires an instance of Dialog. - * dialog: Props.instanceOf(Dialog).isRequired - * }, - * render: function() { ... } - * }); - * - * A more formal specification of how these methods are used: - * - * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) - * decl := ReactPropTypes.{type}(.isRequired)? - * - * Each and every declaration produces a function with the same signature. This - * allows the creation of custom validation functions. For example: - * - * var MyLink = React.createClass({ - * propTypes: { - * // An optional string or URI prop named "href". - * href: function(props, propName, componentName) { - * var propValue = props[propName]; - * if (propValue != null && typeof propValue !== 'string' && - * !(propValue instanceof URI)) { - * return new Error( - * 'Expected a string or an URI for ' + propName + ' in ' + - * componentName - * ); - * } - * } - * }, - * render: function() {...} - * }); - * - * @internal - */ - -var ANONYMOUS = '<<anonymous>>'; - -var ReactPropTypes = { - array: createPrimitiveTypeChecker('array'), - bool: createPrimitiveTypeChecker('boolean'), - func: createPrimitiveTypeChecker('function'), - number: createPrimitiveTypeChecker('number'), - object: createPrimitiveTypeChecker('object'), - string: createPrimitiveTypeChecker('string'), - symbol: createPrimitiveTypeChecker('symbol'), - - any: createAnyTypeChecker(), - arrayOf: createArrayOfTypeChecker, - element: createElementTypeChecker(), - instanceOf: createInstanceTypeChecker, - node: createNodeChecker(), - objectOf: createObjectOfTypeChecker, - oneOf: createEnumTypeChecker, - oneOfType: createUnionTypeChecker, - shape: createShapeTypeChecker -}; - -/** - * inlined Object.is polyfill to avoid requiring consumers ship their own - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is - */ -/*eslint-disable no-self-compare*/ -function is(x, y) { - // SameValue algorithm - if (x === y) { - // Steps 1-5, 7-10 - // Steps 6.b-6.e: +0 != -0 - return x !== 0 || 1 / x === 1 / y; - } else { - // Step 6.a: NaN == NaN - return x !== x && y !== y; - } -} -/*eslint-enable no-self-compare*/ - -/** - * We use an Error-like object for backward compatibility as people may call - * PropTypes directly and inspect their output. However we don't use real - * Errors anymore. We don't inspect their stack anyway, and creating them - * is prohibitively expensive if they are created too often, such as what - * happens in oneOfType() for any type before the one that matched. - */ -function PropTypeError(message) { - this.message = message; - this.stack = ''; -} -// Make `instanceof Error` still work for returned errors. -PropTypeError.prototype = Error.prototype; - -function createChainableTypeChecker(validate) { - if (process.env.NODE_ENV !== 'production') { - var manualPropTypeCallCache = {}; - } - function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { - componentName = componentName || ANONYMOUS; - propFullName = propFullName || propName; - if (process.env.NODE_ENV !== 'production') { - if (secret !== ReactPropTypesSecret && typeof console !== 'undefined') { - var cacheKey = componentName + ':' + propName; - if (!manualPropTypeCallCache[cacheKey]) { - process.env.NODE_ENV !== 'production' ? warning(false, 'You are manually calling a React.PropTypes validation ' + 'function for the `%s` prop on `%s`. This is deprecated ' + 'and will not work in production with the next major version. ' + 'You may be seeing this warning due to a third-party PropTypes ' + 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.', propFullName, componentName) : void 0; - manualPropTypeCallCache[cacheKey] = true; - } - } - } - if (props[propName] == null) { - var locationName = ReactPropTypeLocationNames[location]; - if (isRequired) { - if (props[propName] === null) { - return new PropTypeError('The ' + locationName + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); - } - return new PropTypeError('The ' + locationName + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.')); - } - return null; - } else { - return validate(props, propName, componentName, location, propFullName); - } - } - - var chainedCheckType = checkType.bind(null, false); - chainedCheckType.isRequired = checkType.bind(null, true); - - return chainedCheckType; -} - -function createPrimitiveTypeChecker(expectedType) { - function validate(props, propName, componentName, location, propFullName, secret) { - var propValue = props[propName]; - var propType = getPropType(propValue); - if (propType !== expectedType) { - var locationName = ReactPropTypeLocationNames[location]; - // `propValue` being instance of, say, date/regexp, pass the 'object' - // check, but we can offer a more precise error message here rather than - // 'of type `object`'. - var preciseType = getPreciseType(propValue); - - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.')); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createAnyTypeChecker() { - return createChainableTypeChecker(emptyFunction.thatReturns(null)); -} - -function createArrayOfTypeChecker(typeChecker) { - function validate(props, propName, componentName, location, propFullName) { - if (typeof typeChecker !== 'function') { - return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.'); - } - var propValue = props[propName]; - if (!Array.isArray(propValue)) { - var locationName = ReactPropTypeLocationNames[location]; - var propType = getPropType(propValue); - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); - } - for (var i = 0; i < propValue.length; i++) { - var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret); - if (error instanceof Error) { - return error; - } - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createElementTypeChecker() { - function validate(props, propName, componentName, location, propFullName) { - var propValue = props[propName]; - if (!ReactElement.isValidElement(propValue)) { - var locationName = ReactPropTypeLocationNames[location]; - var propType = getPropType(propValue); - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.')); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createInstanceTypeChecker(expectedClass) { - function validate(props, propName, componentName, location, propFullName) { - if (!(props[propName] instanceof expectedClass)) { - var locationName = ReactPropTypeLocationNames[location]; - var expectedClassName = expectedClass.name || ANONYMOUS; - var actualClassName = getClassName(props[propName]); - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createEnumTypeChecker(expectedValues) { - if (!Array.isArray(expectedValues)) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOf, expected an instance of array.') : void 0; - return emptyFunction.thatReturnsNull; - } - - function validate(props, propName, componentName, location, propFullName) { - var propValue = props[propName]; - for (var i = 0; i < expectedValues.length; i++) { - if (is(propValue, expectedValues[i])) { - return null; - } - } - - var locationName = ReactPropTypeLocationNames[location]; - var valuesString = JSON.stringify(expectedValues); - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); - } - return createChainableTypeChecker(validate); -} - -function createObjectOfTypeChecker(typeChecker) { - function validate(props, propName, componentName, location, propFullName) { - if (typeof typeChecker !== 'function') { - return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.'); - } - var propValue = props[propName]; - var propType = getPropType(propValue); - if (propType !== 'object') { - var locationName = ReactPropTypeLocationNames[location]; - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.')); - } - for (var key in propValue) { - if (propValue.hasOwnProperty(key)) { - var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); - if (error instanceof Error) { - return error; - } - } - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createUnionTypeChecker(arrayOfTypeCheckers) { - if (!Array.isArray(arrayOfTypeCheckers)) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOfType, expected an instance of array.') : void 0; - return emptyFunction.thatReturnsNull; - } - - function validate(props, propName, componentName, location, propFullName) { - for (var i = 0; i < arrayOfTypeCheckers.length; i++) { - var checker = arrayOfTypeCheckers[i]; - if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret) == null) { - return null; - } - } - - var locationName = ReactPropTypeLocationNames[location]; - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.')); - } - return createChainableTypeChecker(validate); -} - -function createNodeChecker() { - function validate(props, propName, componentName, location, propFullName) { - if (!isNode(props[propName])) { - var locationName = ReactPropTypeLocationNames[location]; - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); - } - return null; - } - return createChainableTypeChecker(validate); -} - -function createShapeTypeChecker(shapeTypes) { - function validate(props, propName, componentName, location, propFullName) { - var propValue = props[propName]; - var propType = getPropType(propValue); - if (propType !== 'object') { - var locationName = ReactPropTypeLocationNames[location]; - return new PropTypeError('Invalid ' + locationName + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); - } - for (var key in shapeTypes) { - var checker = shapeTypes[key]; - if (!checker) { - continue; - } - var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); - if (error) { - return error; - } - } - return null; - } - return createChainableTypeChecker(validate); -} - -function isNode(propValue) { - switch (typeof propValue) { - case 'number': - case 'string': - case 'undefined': - return true; - case 'boolean': - return !propValue; - case 'object': - if (Array.isArray(propValue)) { - return propValue.every(isNode); - } - if (propValue === null || ReactElement.isValidElement(propValue)) { - return true; - } - - var iteratorFn = getIteratorFn(propValue); - if (iteratorFn) { - var iterator = iteratorFn.call(propValue); - var step; - if (iteratorFn !== propValue.entries) { - while (!(step = iterator.next()).done) { - if (!isNode(step.value)) { - return false; - } - } - } else { - // Iterator will provide entry [k,v] tuples rather than values. - while (!(step = iterator.next()).done) { - var entry = step.value; - if (entry) { - if (!isNode(entry[1])) { - return false; - } - } - } - } - } else { - return false; - } - - return true; - default: - return false; - } -} - -function isSymbol(propType, propValue) { - // Native Symbol. - if (propType === 'symbol') { - return true; - } - - // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' - if (propValue['@@toStringTag'] === 'Symbol') { - return true; - } - - // Fallback for non-spec compliant Symbols which are polyfilled. - if (typeof Symbol === 'function' && propValue instanceof Symbol) { - return true; - } - - return false; -} - -// Equivalent of `typeof` but with special handling for array and regexp. -function getPropType(propValue) { - var propType = typeof propValue; - if (Array.isArray(propValue)) { - return 'array'; - } - if (propValue instanceof RegExp) { - // Old webkits (at least until Android 4.0) return 'function' rather than - // 'object' for typeof a RegExp. We'll normalize this here so that /bla/ - // passes PropTypes.object. - return 'object'; - } - if (isSymbol(propType, propValue)) { - return 'symbol'; - } - return propType; -} - -// This handles more types than `getPropType`. Only used for error messages. -// See `createPrimitiveTypeChecker`. -function getPreciseType(propValue) { - var propType = getPropType(propValue); - if (propType === 'object') { - if (propValue instanceof Date) { - return 'date'; - } else if (propValue instanceof RegExp) { - return 'regexp'; - } - } - return propType; -} - -// Returns class name of the object, if any. -function getClassName(propValue) { - if (!propValue.constructor || !propValue.constructor.name) { - return ANONYMOUS; - } - return propValue.constructor.name; -} - -module.exports = ReactPropTypes; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 330 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _assign = __webpack_require__(6); - -var ReactComponent = __webpack_require__(63); -var ReactNoopUpdateQueue = __webpack_require__(64); - -var emptyObject = __webpack_require__(28); - -/** - * Base class helpers for the updating state of a component. - */ -function ReactPureComponent(props, context, updater) { - // Duplicated from ReactComponent. - this.props = props; - this.context = context; - this.refs = emptyObject; - // We initialize the default updater but the real one gets injected by the - // renderer. - this.updater = updater || ReactNoopUpdateQueue; -} - -function ComponentDummy() {} -ComponentDummy.prototype = ReactComponent.prototype; -ReactPureComponent.prototype = new ComponentDummy(); -ReactPureComponent.prototype.constructor = ReactPureComponent; -// Avoid an extra prototype jump for these methods. -_assign(ReactPureComponent.prototype, ReactComponent.prototype); -ReactPureComponent.prototype.isPureReactComponent = true; - -module.exports = ReactPureComponent; - -/***/ }), -/* 331 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -module.exports = '15.4.2'; - -/***/ }), -/* 332 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(23); - -var ReactPropTypeLocationNames = __webpack_require__(65); -var ReactPropTypesSecret = __webpack_require__(105); - -var invariant = __webpack_require__(2); -var warning = __webpack_require__(3); - -var ReactComponentTreeHook; - -if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'test') { - // Temporary hack. - // Inline requires don't work well with Jest: - // https://github.com/facebook/react/issues/7240 - // Remove the inline requires when we don't need them anymore: - // https://github.com/facebook/react/pull/7178 - ReactComponentTreeHook = __webpack_require__(9); -} - -var loggedTypeFailures = {}; - -/** - * Assert that the values match with the type specs. - * Error messages are memorized and will only be shown once. - * - * @param {object} typeSpecs Map of name to a ReactPropType - * @param {object} values Runtime values that need to be type-checked - * @param {string} location e.g. "prop", "context", "child context" - * @param {string} componentName Name of the component for error messages. - * @param {?object} element The React element that is being type-checked - * @param {?number} debugID The React component instance that is being type-checked - * @private - */ -function checkReactTypeSpec(typeSpecs, values, location, componentName, element, debugID) { - for (var typeSpecName in typeSpecs) { - if (typeSpecs.hasOwnProperty(typeSpecName)) { - var error; - // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - !(typeof typeSpecs[typeSpecName] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : _prodInvariant('84', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : void 0; - error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); - } catch (ex) { - error = ex; - } - process.env.NODE_ENV !== 'production' ? warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName, typeof error) : void 0; - if (error instanceof Error && !(error.message in loggedTypeFailures)) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error.message] = true; - - var componentStackInfo = ''; - - if (process.env.NODE_ENV !== 'production') { - if (!ReactComponentTreeHook) { - ReactComponentTreeHook = __webpack_require__(9); - } - if (debugID !== null) { - componentStackInfo = ReactComponentTreeHook.getStackAddendumByID(debugID); - } else if (element !== null) { - componentStackInfo = ReactComponentTreeHook.getCurrentStackAddendum(element); - } - } - - process.env.NODE_ENV !== 'production' ? warning(false, 'Failed %s type: %s%s', location, error.message, componentStackInfo) : void 0; - } - } - } -} - -module.exports = checkReactTypeSpec; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 333 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - -var _prodInvariant = __webpack_require__(23); - -var ReactElement = __webpack_require__(22); - -var invariant = __webpack_require__(2); - -/** - * Returns the first child in a collection of children and verifies that there - * is only one child in the collection. - * - * See https://facebook.github.io/react/docs/top-level-api.html#react.children.only - * - * The current implementation of this function assumes that a single child gets - * passed without a wrapper, but the purpose of this helper function is to - * abstract away the particular structure of children. - * - * @param {?object} children Child collection structure. - * @return {ReactElement} The first and only `ReactElement` contained in the - * structure. - */ -function onlyChild(children) { - !ReactElement.isValidElement(children) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'React.Children.only expected to receive a single React element child.') : _prodInvariant('143') : void 0; - return children; -} - -module.exports = onlyChild; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 334 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - - -var _prodInvariant = __webpack_require__(23); - -var ReactCurrentOwner = __webpack_require__(15); -var REACT_ELEMENT_TYPE = __webpack_require__(103); - -var getIteratorFn = __webpack_require__(67); -var invariant = __webpack_require__(2); -var KeyEscapeUtils = __webpack_require__(324); -var warning = __webpack_require__(3); - -var SEPARATOR = '.'; -var SUBSEPARATOR = ':'; - -/** - * This is inlined from ReactElement since this file is shared between - * isomorphic and renderers. We could extract this to a - * - */ - -/** - * TODO: Test that a single child and an array with one item have the same key - * pattern. - */ - -var didWarnAboutMaps = false; - -/** - * Generate a key string that identifies a component within a set. - * - * @param {*} component A component that could contain a manual key. - * @param {number} index Index that is used if a manual key is not provided. - * @return {string} - */ -function getComponentKey(component, index) { - // Do some typechecking here since we call this blindly. We want to ensure - // that we don't block potential future ES APIs. - if (component && typeof component === 'object' && component.key != null) { - // Explicit key - return KeyEscapeUtils.escape(component.key); - } - // Implicit key determined by the index in the set - return index.toString(36); -} - -/** - * @param {?*} children Children tree container. - * @param {!string} nameSoFar Name of the key path so far. - * @param {!function} callback Callback to invoke with each child found. - * @param {?*} traverseContext Used to pass information throughout the traversal - * process. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) { - var type = typeof children; - - if (type === 'undefined' || type === 'boolean') { - // All of the above are perceived as null. - children = null; - } - - if (children === null || type === 'string' || type === 'number' || - // The following is inlined from ReactElement. This means we can optimize - // some checks. React Fiber also inlines this logic for similar purposes. - type === 'object' && children.$$typeof === REACT_ELEMENT_TYPE) { - callback(traverseContext, children, - // If it's the only child, treat the name as if it was wrapped in an array - // so that it's consistent if the number of children grows. - nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar); - return 1; - } - - var child; - var nextName; - var subtreeCount = 0; // Count of children found in the current subtree. - var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR; - - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - child = children[i]; - nextName = nextNamePrefix + getComponentKey(child, i); - subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); - } - } else { - var iteratorFn = getIteratorFn(children); - if (iteratorFn) { - var iterator = iteratorFn.call(children); - var step; - if (iteratorFn !== children.entries) { - var ii = 0; - while (!(step = iterator.next()).done) { - child = step.value; - nextName = nextNamePrefix + getComponentKey(child, ii++); - subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); - } - } else { - if (process.env.NODE_ENV !== 'production') { - var mapsAsChildrenAddendum = ''; - if (ReactCurrentOwner.current) { - var mapsAsChildrenOwnerName = ReactCurrentOwner.current.getName(); - if (mapsAsChildrenOwnerName) { - mapsAsChildrenAddendum = ' Check the render method of `' + mapsAsChildrenOwnerName + '`.'; - } - } - process.env.NODE_ENV !== 'production' ? warning(didWarnAboutMaps, 'Using Maps as children is not yet fully supported. It is an ' + 'experimental feature that might be removed. Convert it to a ' + 'sequence / iterable of keyed ReactElements instead.%s', mapsAsChildrenAddendum) : void 0; - didWarnAboutMaps = true; - } - // Iterator will provide entry [k,v] tuples rather than values. - while (!(step = iterator.next()).done) { - var entry = step.value; - if (entry) { - child = entry[1]; - nextName = nextNamePrefix + KeyEscapeUtils.escape(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0); - subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); - } - } - } - } else if (type === 'object') { - var addendum = ''; - if (process.env.NODE_ENV !== 'production') { - addendum = ' If you meant to render a collection of children, use an array ' + 'instead or wrap the object using createFragment(object) from the ' + 'React add-ons.'; - if (children._isReactElement) { - addendum = ' It looks like you\'re using an element created by a different ' + 'version of React. Make sure to use only one copy of React.'; - } - if (ReactCurrentOwner.current) { - var name = ReactCurrentOwner.current.getName(); - if (name) { - addendum += ' Check the render method of `' + name + '`.'; - } - } - } - var childrenString = String(children); - true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : _prodInvariant('31', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : void 0; - } - } - - return subtreeCount; -} - -/** - * Traverses children that are typically specified as `props.children`, but - * might also be specified through attributes: - * - * - `traverseAllChildren(this.props.children, ...)` - * - `traverseAllChildren(this.props.leftPanelChildren, ...)` - * - * The `traverseContext` is an optional argument that is passed through the - * entire traversal. It can be used to store accumulations or anything else that - * the callback might find relevant. - * - * @param {?*} children Children tree object. - * @param {!function} callback To invoke upon traversing each child. - * @param {?*} traverseContext Context for traversal. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildren(children, callback, traverseContext) { - if (children == null) { - return 0; - } - - return traverseAllChildrenImpl(children, '', callback, traverseContext); -} - -module.exports = traverseAllChildren; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 335 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -module.exports = function (str) { - return encodeURIComponent(str).replace(/[!'()*]/g, function (c) { - return '%' + c.charCodeAt(0).toString(16).toUpperCase(); - }); -}; - - -/***/ }), -/* 336 */ -/***/ (function(module, exports) { - -module.exports = function(module) { - if(!module.webpackPolyfill) { - module.deprecate = function() {}; - module.paths = []; - // module.parent = undefined by default - if(!module.children) module.children = []; - Object.defineProperty(module, "loaded", { - enumerable: true, - get: function() { - return module.l; - } - }); - Object.defineProperty(module, "id", { - enumerable: true, - get: function() { - return module.i; - } - }); - module.webpackPolyfill = 1; - } - return module; -}; - - -/***/ }), -/* 337 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(106); - - -/***/ }) -/******/ ]); -}); \ No newline at end of file +x.brewer=b={OrRd:["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"],PuBu:["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"],BuPu:["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"],Oranges:["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"],BuGn:["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"],YlOrBr:["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"],YlGn:["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"],Reds:["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"],RdPu:["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"],Greens:["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"],YlGnBu:["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"],Purples:["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"],GnBu:["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"],Greys:["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"],YlOrRd:["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"],PuRd:["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"],Blues:["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"],PuBuGn:["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"],Spectral:["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"],RdYlGn:["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"],RdBu:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"],PiYG:["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"],PRGn:["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"],RdYlBu:["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"],BrBG:["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"],RdGy:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"],PuOr:["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"],Set2:["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"],Accent:["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"],Set1:["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"],Set3:["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"],Dark2:["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"],Paired:["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"],Pastel2:["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"],Pastel1:["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"]},ke={indigo:"#4b0082",gold:"#ffd700",hotpink:"#ff69b4",firebrick:"#b22222",indianred:"#cd5c5c",yellow:"#ffff00",mistyrose:"#ffe4e1",darkolivegreen:"#556b2f",olive:"#808000",darkseagreen:"#8fbc8f",pink:"#ffc0cb",tomato:"#ff6347",lightcoral:"#f08080",orangered:"#ff4500",navajowhite:"#ffdead",lime:"#00ff00",palegreen:"#98fb98",darkslategrey:"#2f4f4f",greenyellow:"#adff2f",burlywood:"#deb887",seashell:"#fff5ee",mediumspringgreen:"#00fa9a",fuchsia:"#ff00ff",papayawhip:"#ffefd5",blanchedalmond:"#ffebcd",chartreuse:"#7fff00",dimgray:"#696969",black:"#000000",peachpuff:"#ffdab9",springgreen:"#00ff7f",aquamarine:"#7fffd4",white:"#ffffff",orange:"#ffa500",lightsalmon:"#ffa07a",darkslategray:"#2f4f4f",brown:"#a52a2a",ivory:"#fffff0",dodgerblue:"#1e90ff",peru:"#cd853f",lawngreen:"#7cfc00",chocolate:"#d2691e",crimson:"#dc143c",forestgreen:"#228b22",darkgrey:"#a9a9a9",lightseagreen:"#20b2aa",cyan:"#00ffff",mintcream:"#f5fffa",silver:"#c0c0c0",antiquewhite:"#faebd7",mediumorchid:"#ba55d3",skyblue:"#87ceeb",gray:"#808080",darkturquoise:"#00ced1",goldenrod:"#daa520",darkgreen:"#006400",floralwhite:"#fffaf0",darkviolet:"#9400d3",darkgray:"#a9a9a9",moccasin:"#ffe4b5",saddlebrown:"#8b4513",grey:"#808080",darkslateblue:"#483d8b",lightskyblue:"#87cefa",lightpink:"#ffb6c1",mediumvioletred:"#c71585",slategrey:"#708090",red:"#ff0000",deeppink:"#ff1493",limegreen:"#32cd32",darkmagenta:"#8b008b",palegoldenrod:"#eee8aa",plum:"#dda0dd",turquoise:"#40e0d0",lightgrey:"#d3d3d3",lightgoldenrodyellow:"#fafad2",darkgoldenrod:"#b8860b",lavender:"#e6e6fa",maroon:"#800000",yellowgreen:"#9acd32",sandybrown:"#f4a460",thistle:"#d8bfd8",violet:"#ee82ee",navy:"#000080",magenta:"#ff00ff",dimgrey:"#696969",tan:"#d2b48c",rosybrown:"#bc8f8f",olivedrab:"#6b8e23",blue:"#0000ff",lightblue:"#add8e6",ghostwhite:"#f8f8ff",honeydew:"#f0fff0",cornflowerblue:"#6495ed",slateblue:"#6a5acd",linen:"#faf0e6",darkblue:"#00008b",powderblue:"#b0e0e6",seagreen:"#2e8b57",darkkhaki:"#bdb76b",snow:"#fffafa",sienna:"#a0522d",mediumblue:"#0000cd",royalblue:"#4169e1",lightcyan:"#e0ffff",green:"#008000",mediumpurple:"#9370db",midnightblue:"#191970",cornsilk:"#fff8dc",paleturquoise:"#afeeee",bisque:"#ffe4c4",slategray:"#708090",darkcyan:"#008b8b",khaki:"#f0e68c",wheat:"#f5deb3",teal:"#008080",darkorchid:"#9932cc",deepskyblue:"#00bfff",salmon:"#fa8072",darkred:"#8b0000",steelblue:"#4682b4",palevioletred:"#db7093",lightslategray:"#778899",aliceblue:"#f0f8ff",lightslategrey:"#778899",lightgreen:"#90ee90",orchid:"#da70d6",gainsboro:"#dcdcdc",mediumseagreen:"#3cb371",lightgray:"#d3d3d3",mediumturquoise:"#48d1cc",lemonchiffon:"#fffacd",cadetblue:"#5f9ea0",lightyellow:"#ffffe0",lavenderblush:"#fff0f5",coral:"#ff7f50",purple:"#800080",aqua:"#00ffff",whitesmoke:"#f5f5f5",mediumslateblue:"#7b68ee",darkorange:"#ff8c00",mediumaquamarine:"#66cdaa",darksalmon:"#e9967a",beige:"#f5f5dc",blueviolet:"#8a2be2",azure:"#f0ffff",lightsteelblue:"#b0c4de",oldlace:"#fdf5e6",rebeccapurple:"#663399"},x.colors=k=ke,U=function(){var e,t,n,r,i,a,s,l,c;return t=Ce(arguments),i=t[0],e=t[1],n=t[2],l=(i+16)/116,s=isNaN(e)?l:l+e/500,c=isNaN(n)?l:l-n/200,l=o.Yn*W(l),s=o.Xn*W(s),c=o.Zn*W(c),a=Pe(3.2404542*s-1.5371385*l-.4985314*c),r=Pe(-.969266*s+1.8760108*l+.041556*c),n=Pe(.0556434*s-.2040259*l+1.0572252*c),a=K(a,0,255),r=K(r,0,255),n=K(n,0,255),[a,r,n,t.length>3?t[3]:1]},Pe=function(e){return we(255*(e<=.00304?12.92*e:1.055*re(e,1/2.4)-.055))},W=function(e){return e>o.t1?e*e*e:o.t2*(e-o.t0)},o={Kn:18,Xn:.95047,Yn:1,Zn:1.08883,t0:.137931034,t1:.206896552,t2:.12841855,t3:.008856452},ue=function(){var e,t,n,r,i,a,o,s;return r=Ce(arguments),n=r[0],t=r[1],e=r[2],i=me(n,t,e),a=i[0],o=i[1],s=i[2],[116*o-16,500*(a-o),200*(o-s)]},ge=function(e){return(e/=255)<=.04045?e/12.92:re((e+.055)/1.055,2.4)},Se=function(e){return e>o.t3?re(e,1/3):e/o.t2+o.t0},me=function(){var e,t,n,r,i,a,s;return r=Ce(arguments),n=r[0],t=r[1],e=r[2],n=ge(n),t=ge(t),e=ge(e),i=Se((.4124564*n+.3575761*t+.1804375*e)/o.Xn),a=Se((.2126729*n+.7151522*t+.072175*e)/o.Yn),s=Se((.0193339*n+.119192*t+.9503041*e)/o.Zn),[i,a,s]},x.lab=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["lab"]),function(){})},f.lab=U,i.prototype.lab=function(){return ue(this._rgb)},v=function(e){var t,n,r,i,a,o,s,l,c,u,h;return e=function(){var t,n,r;for(r=[],n=0,t=e.length;n<t;n++)i=e[n],r.push(x(i));return r}(),2===e.length?(c=function(){var t,n,r;for(r=[],n=0,t=e.length;n<t;n++)i=e[n],r.push(i.lab());return r}(),a=c[0],o=c[1],t=function(e){var t,n;return n=function(){var n,r;for(r=[],t=n=0;n<=2;t=++n)r.push(a[t]+e*(o[t]-a[t]));return r}(),x.lab.apply(x,n)}):3===e.length?(u=function(){var t,n,r;for(r=[],n=0,t=e.length;n<t;n++)i=e[n],r.push(i.lab());return r}(),a=u[0],o=u[1],s=u[2],t=function(e){var t,n;return n=function(){var n,r;for(r=[],t=n=0;n<=2;t=++n)r.push((1-e)*(1-e)*a[t]+2*(1-e)*e*o[t]+e*e*s[t]);return r}(),x.lab.apply(x,n)}):4===e.length?(h=function(){var t,n,r;for(r=[],n=0,t=e.length;n<t;n++)i=e[n],r.push(i.lab());return r}(),a=h[0],o=h[1],s=h[2],l=h[3],t=function(e){var t,n;return n=function(){var n,r;for(r=[],t=n=0;n<=2;t=++n)r.push((1-e)*(1-e)*(1-e)*a[t]+3*(1-e)*(1-e)*e*o[t]+3*(1-e)*e*e*s[t]+e*e*e*l[t]);return r}(),x.lab.apply(x,n)}):5===e.length&&(n=v(e.slice(0,3)),r=v(e.slice(2,5)),t=function(e){return e<.5?n(2*e):r(2*(e-.5))}),t},x.bezier=function(e){var t;return t=v(e),t.scale=function(){return x.scale(t)},t},x.cubehelix=function(e,t,n,r,i){var a,o,s;return null==e&&(e=300),null==t&&(t=-1.5),null==n&&(n=1),null==r&&(r=1),null==i&&(i=[0,1]),o=i[1]-i[0],a=0,s=function(s){var l,c,h,d,f,p,m,g,v;return l=u*((e+120)/360+t*s),m=re(i[0]+o*s,r),p=0!==a?n[0]+s*a:n,c=p*m*(1-m)/2,d=S(l),v=be(l),g=m+c*(-.14861*d+1.78277*v),f=m+c*(-.29227*d-.90649*v),h=m+c*(1.97294*d),x(E([255*g,255*f,255*h]))},s.start=function(t){return null==t?e:(e=t,s)},s.rotations=function(e){return null==e?t:(t=e,s)},s.gamma=function(e){return null==e?r:(r=e,s)},s.hue=function(e){return null==e?n:(n=e,"array"===Ee(n)?(a=n[1]-n[0],0===a&&(n=n[1])):a=0,s)},s.lightness=function(e){return null==e?i:(i=e,"array"===Ee(i)?(o=i[1]-i[0],0===o&&(i=i[1])):o=0,s)},s.scale=function(){return x.scale(s)},s.hue(n),s},x.random=function(){var e,t,n,r;for(t="0123456789abcdef",e="#",n=r=0;r<6;n=++r)e+=t.charAt(I(16*Math.random()));return new i(e)},x.average=function(e){var t,n,r,a,o,s,l,c,u;for(c=a=n=t=0,o=e.length,l=0,s=e.length;l<s;l++)r=e[l],u=x(r).rgba(),c+=u[0],a+=u[1],n+=u[2],t+=u[3];return new i(c/o,a/o,n/o,t/o)},f.rgb=function(){var e,t,n,r;t=Ce(arguments),n=[];for(e in t)r=t[e],n.push(r);return n},x.rgb=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["rgb"]),function(){})},i.prototype.rgb=function(){return this._rgb.slice(0,3)},i.prototype.rgba=function(){return this._rgb},h.push({p:15,test:function(e){var t;return t=Ce(arguments),"array"===Ee(t)&&3===t.length?"rgb":4===t.length&&"number"===Ee(t[3])&&t[3]>=0&&t[3]<=1?"rgb":void 0}}),L=function(e){var t,n,r,i,a,o;if(e.match(/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/))return 4!==e.length&&7!==e.length||(e=e.substr(1)),3===e.length&&(e=e.split(""),e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),o=parseInt(e,16),i=o>>16,r=o>>8&255,n=255&o,[i,r,n,1];if(e.match(/^#?([A-Fa-f0-9]{8})$/))return 9===e.length&&(e=e.substr(1)),o=parseInt(e,16),i=o>>24&255,r=o>>16&255,n=o>>8&255,t=we((255&o)/255*100)/100,[i,r,n,t];if(null!=f.css&&(a=f.css(e)))return a;throw"unknown color: "+e},oe=function(e,t){var n,r,i,a,o,s,l;return null==t&&(t="rgb"),o=e[0],i=e[1],r=e[2],n=e[3],l=o<<16|i<<8|r,s="000000"+l.toString(16),s=s.substr(s.length-6),a="0"+we(255*n).toString(16),a=a.substr(a.length-2),"#"+function(){switch(t.toLowerCase()){case"rgba":return s+a;case"argb":return a+s;default:return s}}()},f.hex=function(e){return L(e)},x.hex=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["hex"]),function(){})},i.prototype.hex=function(e){return null==e&&(e="rgb"),oe(this._rgb,e)},h.push({p:10,test:function(e){if(1===arguments.length&&"string"===Ee(e))return"hex"}}),B=function(){var e,t,n,r,i,a,o,s,l,c,u,h,d,f;if(e=Ce(arguments),i=e[0],u=e[1],o=e[2],0===u)l=r=t=255*o;else{for(f=[0,0,0],n=[0,0,0],d=o<.5?o*(1+u):o+u-o*u,h=2*o-d,i/=360,f[0]=i+1/3,f[1]=i,f[2]=i-1/3,a=s=0;s<=2;a=++s)f[a]<0&&(f[a]+=1),f[a]>1&&(f[a]-=1),6*f[a]<1?n[a]=h+6*(d-h)*f[a]:2*f[a]<1?n[a]=d:3*f[a]<2?n[a]=h+(d-h)*(2/3-f[a])*6:n[a]=h;c=[we(255*n[0]),we(255*n[1]),we(255*n[2])],l=c[0],r=c[1],t=c[2]}return e.length>3?[l,r,t,e[3]]:[l,r,t]},le=function(e,t,n){var r,i,a,o,s;return void 0!==e&&e.length>=3&&(o=e,e=o[0],t=o[1],n=o[2]),e/=255,t/=255,n/=255,a=Math.min(e,t,n),$=Math.max(e,t,n),i=($+a)/2,$===a?(s=0,r=Number.NaN):s=i<.5?($-a)/($+a):($-a)/(2-$-a),e===$?r=(t-n)/($-a):t===$?r=2+(n-e)/($-a):n===$&&(r=4+(e-t)/($-a)),r*=60,r<0&&(r+=360),[r,s,i]},x.hsl=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["hsl"]),function(){})},f.hsl=B,i.prototype.hsl=function(){return le(this._rgb)},z=function(){var e,t,n,r,i,a,o,s,l,c,u,h,d,f,p,m,g,v;if(e=Ce(arguments),i=e[0],m=e[1],v=e[2],v*=255,0===m)l=r=t=v;else switch(360===i&&(i=0),i>360&&(i-=360),i<0&&(i+=360),i/=60,a=I(i),n=i-a,o=v*(1-m),s=v*(1-m*n),g=v*(1-m*(1-n)),a){case 0:c=[v,g,o],l=c[0],r=c[1],t=c[2];break;case 1:u=[s,v,o],l=u[0],r=u[1],t=u[2];break;case 2:h=[o,v,g],l=h[0],r=h[1],t=h[2];break;case 3:d=[o,s,v],l=d[0],r=d[1],t=d[2];break;case 4:f=[g,o,v],l=f[0],r=f[1],t=f[2];break;case 5:p=[v,o,s],l=p[0],r=p[1],t=p[2]}return l=we(l),r=we(r),t=we(t),[l,r,t,e.length>3?e[3]:1]},ce=function(){var e,t,n,r,i,a,o,s,l;return o=Ce(arguments),a=o[0],n=o[1],e=o[2],i=Math.min(a,n,e),$=Math.max(a,n,e),t=$-i,l=$/255,0===$?(r=Number.NaN,s=0):(s=t/$,a===$&&(r=(n-e)/t),n===$&&(r=2+(e-a)/t),e===$&&(r=4+(a-n)/t),r*=60,r<0&&(r+=360)),[r,s,l]},x.hsv=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["hsv"]),function(){})},f.hsv=z,i.prototype.hsv=function(){return ce(this._rgb)},te=function(e){var t,n,r;return"number"===Ee(e)&&e>=0&&e<=16777215?(r=e>>16,n=e>>8&255,t=255&e,[r,n,t,1]):(console.warn("unknown num color: "+e),[0,0,0,1])},fe=function(){var e,t,n,r;return r=Ce(arguments),n=r[0],t=r[1],e=r[2],(n<<16)+(t<<8)+e},x.num=function(e){return new i(e,"num")},i.prototype.num=function(e){return null==e&&(e="rgb"),fe(this._rgb,e)},f.num=te,h.push({p:10,test:function(e){if(1===arguments.length&&"number"===Ee(e)&&e>=0&&e<=16777215)return"num"}}),P=function(e){var t,n,r,i,a,o,s,l;if(e=e.toLowerCase(),null!=x.colors&&x.colors[e])return L(x.colors[e]);if(a=e.match(/rgb\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*\)/)){for(s=a.slice(1,4),i=o=0;o<=2;i=++o)s[i]=+s[i];s[3]=1}else if(a=e.match(/rgba\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*,\s*([01]|[01]?\.\d+)\)/))for(s=a.slice(1,5),i=l=0;l<=3;i=++l)s[i]=+s[i];else if(a=e.match(/rgb\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/)){for(s=a.slice(1,4),i=t=0;t<=2;i=++t)s[i]=we(2.55*s[i]);s[3]=1}else if(a=e.match(/rgba\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/)){for(s=a.slice(1,5),i=n=0;n<=2;i=++n)s[i]=we(2.55*s[i]);s[3]=+s[3]}else(a=e.match(/hsl\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/))?(r=a.slice(1,4),r[1]*=.01,r[2]*=.01,s=B(r),s[3]=1):(a=e.match(/hsla\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/))&&(r=a.slice(1,4),r[1]*=.01,r[2]*=.01,s=B(r),s[3]=+a[4]);return s},ae=function(e){var t;return t=e[3]<1?"rgba":"rgb","rgb"===t?t+"("+e.slice(0,3).map(we).join(",")+")":"rgba"===t?t+"("+e.slice(0,3).map(we).join(",")+","+e[3]+")":void 0},ve=function(e){return we(100*e)/100},O=function(e,t){var n;return n=t<1?"hsla":"hsl",e[0]=ve(e[0]||0),e[1]=ve(100*e[1])+"%",e[2]=ve(100*e[2])+"%","hsla"===n&&(e[3]=t),n+"("+e.join(",")+")"},f.css=function(e){return P(e)},x.css=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["css"]),function(){})},i.prototype.css=function(e){return null==e&&(e="rgb"),"rgb"===e.slice(0,3)?ae(this._rgb):"hsl"===e.slice(0,3)?O(this.hsl(),this.alpha()):void 0},f.named=function(e){return L(ke[e])},h.push({p:20,test:function(e){if(1===arguments.length&&null!=ke[e])return"named"}}),i.prototype.name=function(e){var t,n;arguments.length&&(ke[e]&&(this._rgb=L(ke[e])),this._rgb[3]=1),t=this.hex();for(n in ke)if(t===ke[n])return n;return t},G=function(){var e,t,n,r;return r=Ce(arguments),n=r[0],e=r[1],t=r[2],t*=a,[n,S(t)*e,be(t)*e]},H=function(){var e,t,n,r,i,a,o,s,l,c,u;return n=Ce(arguments),s=n[0],i=n[1],o=n[2],c=G(s,i,o),e=c[0],t=c[1],r=c[2],u=U(e,t,r),l=u[0],a=u[1],r=u[2],[K(l,0,255),K(a,0,255),K(r,0,255),n.length>3?n[3]:1]},V=function(){var e,t,n,r,i,a;return a=Ce(arguments),i=a[0],e=a[1],t=a[2],n=_e(e*e+t*t),r=(g(t,e)*c+360)%360,0===we(1e4*n)&&(r=Number.NaN),[i,n,r]},he=function(){var e,t,n,r,i,a,o;return a=Ce(arguments),i=a[0],n=a[1],t=a[2],o=ue(i,n,t),r=o[0],e=o[1],t=o[2],V(r,e,t)},x.lch=function(){var e;return e=Ce(arguments),new i(e,"lch")},x.hcl=function(){var e;return e=Ce(arguments),new i(e,"hcl")},f.lch=H,f.hcl=function(){var e,t,n,r;return r=Ce(arguments),t=r[0],e=r[1],n=r[2],H([n,e,t])},i.prototype.lch=function(){return he(this._rgb)},i.prototype.hcl=function(){return he(this._rgb).reverse()},ie=function(e){var t,n,r,i,a,o,s,l,c;return null==e&&(e="rgb"),l=Ce(arguments),s=l[0],i=l[1],t=l[2],s/=255,i/=255,t/=255,a=1-Math.max(s,Math.max(i,t)),r=a<1?1/(1-a):0,n=(1-s-a)*r,o=(1-i-a)*r,c=(1-t-a)*r,[n,o,c,a]},C=function(){var e,t,n,r,i,a,o,s,l;return t=Ce(arguments),r=t[0],o=t[1],l=t[2],a=t[3],e=t.length>4?t[4]:1,1===a?[0,0,0,e]:(s=r>=1?0:we(255*(1-r)*(1-a)),i=o>=1?0:we(255*(1-o)*(1-a)),n=l>=1?0:we(255*(1-l)*(1-a)),[s,i,n,e])},f.cmyk=function(){return C(Ce(arguments))},x.cmyk=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["cmyk"]),function(){})},i.prototype.cmyk=function(){return ie(this._rgb)},f.gl=function(){var e,t,n,r,i;for(r=function(){var e,n;e=Ce(arguments),n=[];for(t in e)i=e[t],n.push(i);return n}.apply(this,arguments),e=n=0;n<=2;e=++n)r[e]*=255;return r},x.gl=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["gl"]),function(){})},i.prototype.gl=function(){var e;return e=this._rgb,[e[0]/255,e[1]/255,e[2]/255,e[3]]},de=function(e,t,n){var r;return r=Ce(arguments),e=r[0],t=r[1],n=r[2],e=Y(e),t=Y(t),n=Y(n),.2126*e+.7152*t+.0722*n},Y=function(e){return e/=255,e<=.03928?e/12.92:re((e+.055)/1.055,2.4)},p=[],R=function(e,t,n,r){var i,a,o,s;for(null==n&&(n=.5),null==r&&(r="rgb"),"object"!==Ee(e)&&(e=x(e)),"object"!==Ee(t)&&(t=x(t)),o=0,a=p.length;o<a;o++)if(i=p[o],r===i[0]){s=i[1](e,t,n,r);break}if(null==s)throw"color mode "+r+" is not supported";return s.alpha(e.alpha()+n*(t.alpha()-e.alpha())),s},x.interpolate=R,i.prototype.interpolate=function(e,t,n){return R(this,e,t,n)},x.mix=R,i.prototype.mix=i.prototype.interpolate,q=function(e,t,n,r){var a,o;return a=e._rgb,o=t._rgb,new i(a[0]+n*(o[0]-a[0]),a[1]+n*(o[1]-a[1]),a[2]+n*(o[2]-a[2]),r)},p.push(["rgb",q]),i.prototype.luminance=function(e,t){var n,r,i,a;return null==t&&(t="rgb"),arguments.length?(0===e?this._rgb=[0,0,0,this._rgb[3]]:1===e?this._rgb=[255,255,255,this._rgb[3]]:(r=1e-7,i=20,a=function(n,o){var s,l;return l=n.interpolate(o,.5,t),s=l.luminance(),Math.abs(e-s)<r||!i--?l:s>e?a(n,l):a(l,o)},n=de(this._rgb),this._rgb=(n>e?a(x("black"),this):a(this,x("white"))).rgba()),this):de(this._rgb)},xe=function(e){var t,n,r,i;return i=e/100,i<66?(r=255,n=-155.25485562709179-.44596950469579133*(n=i-2)+104.49216199393888*Q(n),t=i<20?0:-254.76935184120902+.8274096064007395*(t=i-10)+115.67994401066147*Q(t)):(r=351.97690566805693+.114206453784165*(r=i-55)-40.25366309332127*Q(r),n=325.4494125711974+.07943456536662342*(n=i-50)-28.0852963507957*Q(n),t=255),E([r,n,t])},pe=function(){var e,t,n,r,i,a,o,s,l;for(o=Ce(arguments),a=o[0],n=o[1],e=o[2],i=1e3,r=4e4,t=.4;r-i>t;)l=.5*(r+i),s=xe(l),s[2]/s[0]>=e/a?r=l:i=l;return we(l)},x.temperature=x.kelvin=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["temperature"]),function(){})},f.temperature=f.kelvin=f.K=xe,i.prototype.temperature=function(){return pe(this._rgb)},i.prototype.kelvin=i.prototype.temperature,x.contrast=function(e,t){var n,r,a,o;return"string"!==(a=Ee(e))&&"number"!==a||(e=new i(e)),"string"!==(o=Ee(t))&&"number"!==o||(t=new i(t)),n=e.luminance(),r=t.luminance(),n>r?(n+.05)/(r+.05):(r+.05)/(n+.05)},i.prototype.get=function(e){var t,n,r,i,a,o;return r=this,a=e.split("."),i=a[0],t=a[1],o=r[i](),t?(n=i.indexOf(t),n>-1?o[n]:console.warn("unknown channel "+t+" in mode "+i)):o},i.prototype.set=function(e,t){var n,r,i,a,o,s;if(i=this,o=e.split("."),a=o[0],n=o[1],n)if(s=i[a](),r=a.indexOf(n),r>-1)if("string"===Ee(t))switch(t.charAt(0)){case"+":s[r]+=+t;break;case"-":s[r]+=+t;break;case"*":s[r]*=+t.substr(1);break;case"/":s[r]/=+t.substr(1);break;default:s[r]=+t}else s[r]=t;else console.warn("unknown channel "+n+" in mode "+a);else s=t;return i._rgb=x(s,a).alpha(i.alpha())._rgb,i},i.prototype.darken=function(e){var t,n;return null==e&&(e=1),n=this,t=n.lab(),t[0]-=o.Kn*e,x.lab(t).alpha(n.alpha())},i.prototype.brighten=function(e){return null==e&&(e=1),this.darken(-e)},i.prototype.darker=i.prototype.darken,i.prototype.brighter=i.prototype.brighten,i.prototype.saturate=function(e){var t,n;return null==e&&(e=1),n=this,t=n.lch(),t[1]+=e*o.Kn,t[1]<0&&(t[1]=0),x.lch(t).alpha(n.alpha())},i.prototype.desaturate=function(e){return null==e&&(e=1),this.saturate(-e)},i.prototype.premultiply=function(){var e,t;return t=this.rgb(),e=this.alpha(),x(t[0]*e,t[1]*e,t[2]*e,e)},w=function(e,t,n){if(!w[n])throw"unknown blend mode "+n;return w[n](e,t)},y=function(e){return function(t,n){var r,i;return r=x(n).rgb(),i=x(t).rgb(),x(e(r,i),"rgb")}},N=function(e){return function(t,n){var r,i,a;for(a=[],r=i=0;i<=3;r=++i)a[r]=e(t[r],n[r]);return a}},ee=function(e,t){return e},J=function(e,t){return e*t/255},T=function(e,t){return e>t?t:e},X=function(e,t){return e>t?e:t},ye=function(e,t){return 255*(1-(1-e/255)*(1-t/255))},ne=function(e,t){return t<128?2*e*t/255:255*(1-2*(1-e/255)*(1-t/255))},_=function(e,t){return 255*(1-(1-t/255)/(e/255))},M=function(e,t){return 255===e?255:(e=255*(t/255)/(1-e/255),e>255?255:e)},w.normal=y(N(ee)),w.multiply=y(N(J)),w.screen=y(N(ye)),w.overlay=y(N(ne)),w.darken=y(N(T)),w.lighten=y(N(X)),w.dodge=y(N(M)),w.burn=y(N(_)),x.blend=w,x.analyze=function(e){var t,n,r,i;for(r={min:Number.MAX_VALUE,max:Number.MAX_VALUE*-1,sum:0,values:[],count:0},n=0,t=e.length;n<t;n++)i=e[n],null==i||isNaN(i)||(r.values.push(i),r.sum+=i,i<r.min&&(r.min=i),i>r.max&&(r.max=i),r.count+=1);return r.domain=[r.min,r.max],r.limits=function(e,t){return x.limits(r,e,t)},r},x.scale=function(e,t){var n,r,i,a,o,s,l,c,u,h,d,f,p,m,g,v,w,y,b,_,E;return u="rgb",h=x("#ccc"),m=0,s=!1,o=[0,1],p=[],f=[0,0],n=!1,i=[],d=!1,c=0,l=1,a=!1,r={},_=function(e){var t,n,r,a,o,s,l;if(null==e&&(e=["#fff","#000"]),null!=e&&"string"===Ee(e)&&null!=(null!=(a=x.brewer)?a[e]:void 0)&&(e=x.brewer[e]),"array"===Ee(e)){for(e=e.slice(0),t=r=0,o=e.length-1;0<=o?r<=o:r>=o;t=0<=o?++r:--r)n=e[t],"string"===Ee(n)&&(e[t]=x(n));for(p.length=0,t=l=0,s=e.length-1;0<=s?l<=s:l>=s;t=0<=s?++l:--l)p.push(t/(e.length-1))}return b(),i=e},w=function(e){var t,r;if(null!=n){for(r=n.length-1,t=0;t<r&&e>=n[t];)t++;return t-1}return 0},E=function(e){return e},g=function(e){var t,r,i,a,o;return o=e,n.length>2&&(a=n.length-1,t=w(e),i=n[0]+(n[1]-n[0])*(0+.5*m),r=n[a-1]+(n[a]-n[a-1])*(1-.5*m),o=c+(n[t]+.5*(n[t+1]-n[t])-i)/(r-i)*(l-c)),o},y=function(e,t){var a,o,s,d,m,g,v,y;if(null==t&&(t=!1),isNaN(e))return h;if(t?y=e:n&&n.length>2?(a=w(e),y=a/(n.length-2),y=f[0]+y*(1-f[0]-f[1])):l!==c?(y=(e-c)/(l-c),y=f[0]+y*(1-f[0]-f[1]),y=Math.min(1,Math.max(0,y))):y=1,t||(y=E(y)),d=Math.floor(1e4*y),r[d])o=r[d];else{if("array"===Ee(i))for(s=m=0,v=p.length-1;0<=v?m<=v:m>=v;s=0<=v?++m:--m){if(g=p[s],y<=g){o=i[s];break}if(y>=g&&s===p.length-1){o=i[s];break}if(y>g&&y<p[s+1]){y=(y-g)/(p[s+1]-g),o=x.interpolate(i[s],i[s+1],y,u);break}}else"function"===Ee(i)&&(o=i(y));r[d]=o}return o},b=function(){return r={}},_(e),v=function(e){var t;return t=x(y(e)),d&&t[d]?t[d]():t},v.classes=function(e){var t;return null!=e?("array"===Ee(e)?(n=e,o=[e[0],e[e.length-1]]):(t=x.analyze(o),n=0===e?[t.min,t.max]:x.limits(t,"e",e)),v):n},v.domain=function(e){var t,n,r,a,s,u,h;if(!arguments.length)return o;if(c=e[0],l=e[e.length-1],p=[],r=i.length,e.length===r&&c!==l)for(s=0,a=e.length;s<a;s++)n=e[s],p.push((n-c)/(l-c));else for(t=h=0,u=r-1;0<=u?h<=u:h>=u;t=0<=u?++h:--h)p.push(t/(r-1));return o=[c,l],v},v.mode=function(e){return arguments.length?(u=e,b(),v):u},v.range=function(e,t){return _(e,t),v},v.out=function(e){return d=e,v},v.spread=function(e){return arguments.length?(m=e,v):m},v.correctLightness=function(e){return null==e&&(e=!0),a=e,b(),E=a?function(e){var t,n,r,i,a,o,s,l,c;for(t=y(0,!0).lab()[0],n=y(1,!0).lab()[0],s=t>n,r=y(e,!0).lab()[0],a=t+(n-t)*e,i=r-a,l=0,c=1,o=20;Math.abs(i)>.01&&o-- >0;)!function(){return s&&(i*=-1),i<0?(l=e,e+=.5*(c-e)):(c=e,e+=.5*(l-e)),r=y(e,!0).lab()[0],i=r-a}();return e}:function(e){return e},v},v.padding=function(e){return null!=e?("number"===Ee(e)&&(e=[e,e]),f=e,v):f},v.colors=function(){var t,r,i,a,s,l,c,u,h;if(a=0,s="hex",1===arguments.length&&("string"===Ee(arguments[0])?s=arguments[0]:a=arguments[0]),2===arguments.length&&(a=arguments[0],s=arguments[1]),a)return r=o[0],t=o[1]-r,function(){c=[];for(var e=0;0<=a?e<a:e>a;0<=a?e++:e--)c.push(e);return c}.apply(this).map(function(e){return v(r+e/(a-1)*t)[s]()});if(e=[],u=[],n&&n.length>2)for(i=h=1,l=n.length;1<=l?h<l:h>l;i=1<=l?++h:--h)u.push(.5*(n[i-1]+n[i]));else u=o;return u.map(function(e){return v(e)[s]()})},v},null==x.scales&&(x.scales={}),x.scales.cool=function(){return x.scale([x.hsl(180,1,.9),x.hsl(250,.7,.4)])},x.scales.hot=function(){return x.scale(["#000","#f00","#ff0","#fff"],[0,.25,.75,1]).mode("rgb")},x.analyze=function(e,t,n){var r,i,a,o,s,l,c;if(s={min:Number.MAX_VALUE,max:Number.MAX_VALUE*-1,sum:0,values:[],count:0},null==n&&(n=function(){return!0}),r=function(e){null==e||isNaN(e)||(s.values.push(e),s.sum+=e,e<s.min&&(s.min=e),e>s.max&&(s.max=e),s.count+=1)},c=function(e,i){if(n(e,i))return r(null!=t&&"function"===Ee(t)?t(e):null!=t&&"string"===Ee(t)||"number"===Ee(t)?e[t]:e)},"array"===Ee(e))for(o=0,a=e.length;o<a;o++)l=e[o],c(l);else for(i in e)l=e[i],c(l,i);return s.domain=[s.min,s.max],s.limits=function(e,t){return x.limits(s,e,t)},s},x.limits=function(e,t,n){var r,i,a,o,s,l,c,u,h,d,f,p,g,v,w,y,b,_,E,C,k,S,P,T,M,N,L,A,O,B,z,R,D,j,F,q,V,U,W,G,H,X,K,Y,Z,J,ee,te,ne,ie,ae,oe,se,le,ce;if(null==t&&(t="equal"),null==n&&(n=7),"array"===Ee(e)&&(e=x.analyze(e)),M=e.min,$=e.max,ae=e.sum,le=e.values.sort(function(e,t){return e-t}),P=[],"c"===t.substr(0,1)&&(P.push(M),P.push($)),"e"===t.substr(0,1)){for(P.push(M),C=z=1,F=n-1;1<=F?z<=F:z>=F;C=1<=F?++z:--z)P.push(M+C/n*($-M));P.push($)}else if("l"===t.substr(0,1)){if(M<=0)throw"Logarithmic scales are only possible for values > 0";for(N=Math.LOG10E*Q(M),T=Math.LOG10E*Q($),P.push(M),C=ce=1,q=n-1;1<=q?ce<=q:ce>=q;C=1<=q?++ce:--ce)P.push(re(10,N+C/n*(T-N)));P.push($)}else if("q"===t.substr(0,1)){for(P.push(M),C=r=1,X=n-1;1<=X?r<=X:r>=X;C=1<=X?++r:--r)R=le.length*C/n,D=I(R),D===R?P.push(le[D]):(j=R-D,P.push(le[D]*j+le[D+1]*(1-j)));P.push($)}else if("k"===t.substr(0,1)){for(A=le.length,v=new Array(A),_=new Array(n),ie=!0,O=0,y=null,y=[],y.push(M),C=i=1,K=n-1;1<=K?i<=K:i>=K;C=1<=K?++i:--i)y.push(M+C/n*($-M));for(y.push($);ie;){for(k=a=0,Y=n-1;0<=Y?a<=Y:a>=Y;k=0<=Y?++a:--a)_[k]=0;for(C=o=0,Z=A-1;0<=Z?o<=Z:o>=Z;C=0<=Z?++o:--o){for(se=le[C],L=Number.MAX_VALUE,k=s=0,J=n-1;0<=J?s<=J:s>=J;k=0<=J?++s:--s)E=m(y[k]-se),E<L&&(L=E,w=k);_[w]++,v[C]=w}for(B=new Array(n),k=l=0,ee=n-1;0<=ee?l<=ee:l>=ee;k=0<=ee?++l:--l)B[k]=null;for(C=c=0,te=A-1;0<=te?c<=te:c>=te;C=0<=te?++c:--c)b=v[C],null===B[b]?B[b]=le[C]:B[b]+=le[C];for(k=u=0,ne=n-1;0<=ne?u<=ne:u>=ne;k=0<=ne?++u:--u)B[k]*=1/_[k];for(ie=!1,k=h=0,V=n-1;0<=V?h<=V:h>=V;k=0<=V?++h:--h)if(B[k]!==y[C]){ie=!0;break}y=B,O++,O>200&&(ie=!1)}for(S={},k=d=0,U=n-1;0<=U?d<=U:d>=U;k=0<=U?++d:--d)S[k]=[];for(C=f=0,W=A-1;0<=W?f<=W:f>=W;C=0<=W?++f:--f)b=v[C],S[b].push(le[C]);for(oe=[],k=p=0,G=n-1;0<=G?p<=G:p>=G;k=0<=G?++p:--p)oe.push(S[k][0]),oe.push(S[k][S[k].length-1]);for(oe=oe.sort(function(e,t){return e-t}),P.push(oe[0]),C=g=1,H=oe.length-1;g<=H;C=g+=2)isNaN(oe[C])||P.push(oe[C])}return P},A=function(e,t,n){var r,i,a,o;return r=Ce(arguments),e=r[0],t=r[1],n=r[2],e/=360,e<1/3?(i=(1-t)/3,o=(1+t*S(u*e)/S(l-u*e))/3,a=1-(i+o)):e<2/3?(e-=1/3,o=(1-t)/3,a=(1+t*S(u*e)/S(l-u*e))/3,i=1-(o+a)):(e-=2/3,a=(1-t)/3,i=(1+t*S(u*e)/S(l-u*e))/3,o=1-(a+i)),o=K(n*o*3),a=K(n*a*3),i=K(n*i*3),[255*o,255*a,255*i,r.length>3?r[3]:1]},se=function(){var e,t,n,r,i,a,o,s;return o=Ce(arguments),a=o[0],t=o[1],e=o[2],u=2*Math.PI,a/=255,t/=255,e/=255,i=Math.min(a,t,e),r=(a+t+e)/3,s=1-i/r,0===s?n=0:(n=(a-t+(a-e))/2,n/=Math.sqrt((a-t)*(a-t)+(a-e)*(t-e)),n=Math.acos(n),e>t&&(n=u-n),n/=u),[360*n,s,r]},x.hsi=function(){return function(e,t,n){n.prototype=e.prototype;var r=new n,i=e.apply(r,t);return Object(i)===i?i:r}(i,Te.call(arguments).concat(["hsi"]),function(){})},f.hsi=A,i.prototype.hsi=function(){return se(this._rgb)},D=function(e,t,n,r){var i,a,o,s,l,c,u,h,d,f,p,m,g;return"hsl"===r?(m=e.hsl(),g=t.hsl()):"hsv"===r?(m=e.hsv(),g=t.hsv()):"hsi"===r?(m=e.hsi(),g=t.hsi()):"lch"!==r&&"hcl"!==r||(r="hcl",m=e.hcl(),g=t.hcl()),"h"===r.substr(0,1)&&(o=m[0],f=m[1],c=m[2],s=g[0],p=g[1],u=g[2]),isNaN(o)||isNaN(s)?isNaN(o)?isNaN(s)?a=Number.NaN:(a=s,1!==c&&0!==c||"hsv"===r||(d=p)):(a=o,1!==u&&0!==u||"hsv"===r||(d=f)):(i=s>o&&s-o>180?s-(o+360):s<o&&o-s>180?s+360-o:s-o,a=o+n*i),null==d&&(d=f+n*(p-f)),l=c+n*(u-c),h=x[r](a,d,l)},p=p.concat(function(){var e,t,n,r;for(n=["hsv","hsl","hsi","hcl","lch"],r=[],t=0,e=n.length;t<e;t++)Z=n[t],r.push([Z,D]);return r}()),F=function(e,t,n,r){var i,a;return i=e.num(),a=t.num(),x.num(i+(a-i)*n,"num")},p.push(["num",F]),j=function(e,t,n,r){var a,o,s;return o=e.lab(),s=t.lab(),a=new i(o[0]+n*(s[0]-o[0]),o[1]+n*(s[1]-o[1]),o[2]+n*(s[2]-o[2]),r)},p.push(["lab",j])}).call(this)}).call(t,n(324)(e))},function(e,t,n){function r(e){return null===e||void 0===e}function i(e){return!(!e||"object"!=typeof e||"number"!=typeof e.length)&&("function"==typeof e.copy&&"function"==typeof e.slice&&!(e.length>0&&"number"!=typeof e[0]))}function a(e,t,n){var a,u;if(r(e)||r(t))return!1;if(e.prototype!==t.prototype)return!1;if(l(e))return!!l(t)&&(e=o.call(e),t=o.call(t),c(e,t,n));if(i(e)){if(!i(t))return!1;if(e.length!==t.length)return!1;for(a=0;a<e.length;a++)if(e[a]!==t[a])return!1;return!0}try{var h=s(e),d=s(t)}catch(e){return!1}if(h.length!=d.length)return!1;for(h.sort(),d.sort(),a=h.length-1;a>=0;a--)if(h[a]!=d[a])return!1;for(a=h.length-1;a>=0;a--)if(u=h[a],!c(e[u],t[u],n))return!1;return typeof e==typeof t}var o=Array.prototype.slice,s=n(210),l=n(209),c=e.exports=function(e,t,n){return n||(n={}),e===t||(e instanceof Date&&t instanceof Date?e.getTime()===t.getTime():!e||!t||"object"!=typeof e&&"object"!=typeof t?n.strict?e===t:e==t:a(e,t,n))}},function(e,t){function n(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function r(e){return e&&"object"==typeof e&&"number"==typeof e.length&&Object.prototype.hasOwnProperty.call(e,"callee")&&!Object.prototype.propertyIsEnumerable.call(e,"callee")||!1}var i="[object Arguments]"==function(){return Object.prototype.toString.call(arguments)}();t=e.exports=i?n:r,t.supported=n,t.unsupported=r},function(e,t){function n(e){var t=[];for(var n in e)t.push(n);return t}t=e.exports="function"==typeof Object.keys?Object.keys:n,t.shim=n},function(e,t,n){"use strict";function r(e){return e.replace(i,function(e,t){return t.toUpperCase()})}var i=/-(.)/g;e.exports=r},function(e,t,n){"use strict";function r(e){return i(e.replace(a,"ms-"))}var i=n(211),a=/^-ms-/;e.exports=r},function(e,t,n){ +"use strict";function r(e,t){return!(!e||!t)&&(e===t||!i(e)&&(i(t)?r(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}var i=n(221);e.exports=r},function(e,t,n){"use strict";function r(e){var t=e.length;if(Array.isArray(e)||"object"!=typeof e&&"function"!=typeof e?o(!1):void 0,"number"!=typeof t?o(!1):void 0,0===t||t-1 in e?void 0:o(!1),"function"==typeof e.callee?o(!1):void 0,e.hasOwnProperty)try{return Array.prototype.slice.call(e)}catch(e){}for(var n=Array(t),r=0;r<t;r++)n[r]=e[r];return n}function i(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"length"in e&&!("setInterval"in e)&&"number"!=typeof e.nodeType&&(Array.isArray(e)||"callee"in e||"item"in e)}function a(e){return i(e)?Array.isArray(e)?e.slice():r(e):[e]}var o=n(1);e.exports=a},function(e,t,n){"use strict";function r(e){var t=e.match(u);return t&&t[1].toLowerCase()}function i(e,t){var n=c;c?void 0:l(!1);var i=r(e),a=i&&s(i);if(a){n.innerHTML=a[1]+e+a[2];for(var u=a[0];u--;)n=n.lastChild}else n.innerHTML=e;var h=n.getElementsByTagName("script");h.length&&(t?void 0:l(!1),o(h).forEach(t));for(var d=Array.from(n.childNodes);n.lastChild;)n.removeChild(n.lastChild);return d}var a=n(7),o=n(214),s=n(216),l=n(1),c=a.canUseDOM?document.createElement("div"):null,u=/^\s*<(\w+)/;e.exports=i},function(e,t,n){"use strict";function r(e){return o?void 0:a(!1),d.hasOwnProperty(e)||(e="*"),s.hasOwnProperty(e)||("*"===e?o.innerHTML="<link />":o.innerHTML="<"+e+"></"+e+">",s[e]=!o.firstChild),s[e]?d[e]:null}var i=n(7),a=n(1),o=i.canUseDOM?document.createElement("div"):null,s={},l=[1,'<select multiple="true">',"</select>"],c=[1,"<table>","</table>"],u=[3,"<table><tbody><tr>","</tr></tbody></table>"],h=[1,'<svg xmlns="http://www.w3.org/2000/svg">',"</svg>"],d={"*":[1,"?<div>","</div>"],area:[1,"<map>","</map>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],legend:[1,"<fieldset>","</fieldset>"],param:[1,"<object>","</object>"],tr:[2,"<table><tbody>","</tbody></table>"],optgroup:l,option:l,caption:c,colgroup:c,tbody:c,tfoot:c,thead:c,td:u,th:u},f=["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"];f.forEach(function(e){d[e]=h,s[e]=!0}),e.exports=r},function(e,t,n){"use strict";function r(e){return e===window?{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}:{x:e.scrollLeft,y:e.scrollTop}}e.exports=r},function(e,t,n){"use strict";function r(e){return e.replace(i,"-$1").toLowerCase()}var i=/([A-Z])/g;e.exports=r},function(e,t,n){"use strict";function r(e){return i(e).replace(a,"-ms-")}var i=n(218),a=/^ms-/;e.exports=r},function(e,t,n){"use strict";function r(e){return!(!e||!("function"==typeof Node?e instanceof Node:"object"==typeof e&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName))}e.exports=r},function(e,t,n){"use strict";function r(e){return i(e)&&3==e.nodeType}var i=n(220);e.exports=r},function(e,t,n){"use strict";function r(e){var t={};return function(n){return t.hasOwnProperty(n)||(t[n]=e.call(this,n)),t[n]}}e.exports=r},function(e,t,n){"use strict";function r(e,t,n){function r(){o=!0,n.apply(this,arguments)}function i(){o||(a<e?t.call(this,a++,i,r):r.apply(this,arguments))}var a=0,o=!1;i()}t.__esModule=!0,t.loopAsync=r},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){return l+e}function a(e,t){try{window.sessionStorage.setItem(i(e),JSON.stringify(t))}catch(e){if(e.name===u)return;if(e.name===c&&0===window.sessionStorage.length)return;throw e}}function o(e){var t=void 0;try{t=window.sessionStorage.getItem(i(e))}catch(e){if(e.name===u)return null}if(t)try{return JSON.parse(t)}catch(e){}return null}t.__esModule=!0,t.saveState=a,t.readState=o;var s=n(8),l=(r(s),"@@History/"),c="QuotaExceededError",u="SecurityError"},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){function t(e){return l.canUseDOM?void 0:s.default(!1),n.listen(e)}var n=h.default(a({getUserConfirmation:c.getUserConfirmation},e,{go:c.go}));return a({},n,{listen:t})}t.__esModule=!0;var a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=n(10),s=r(o),l=n(40),c=n(70),u=n(71),h=r(u);t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){return"string"==typeof e&&"/"===e.charAt(0)}function a(){var e=g.getHashPath();return!!i(e)||(g.replaceHashPath("/"+e),!1)}function o(e,t,n){return e+(e.indexOf("?")===-1?"?":"&")+(t+"="+n)}function s(e,t){return e.replace(new RegExp("[?&]?"+t+"=[a-zA-Z0-9]+"),"")}function l(e,t){var n=e.match(new RegExp("\\?.*?\\b"+t+"=(.+?)\\b"));return n&&n[1]}function c(){function e(){var e=g.getHashPath(),t=void 0,n=void 0;P?(t=l(e,P),e=s(e,P),t?n=v.readState(t):(n=null,t=T.createKey(),g.replaceHashPath(o(e,P,t)))):t=n=null;var r=_.default(e);return T.createLocation(u({},r,{state:n}),void 0,t)}function t(t){function n(){a()&&r(e())}var r=t.transitionTo;return a(),g.addEventListener(window,"hashchange",n),function(){g.removeEventListener(window,"hashchange",n)}}function n(e){var t=e.basename,n=e.pathname,r=e.search,i=e.state,a=e.action,s=e.key;if(a!==p.POP){var l=(t||"")+n+r;P?(l=o(l,P,s),v.saveState(s,i)):e.key=e.state=null;var c=g.getHashPath();a===p.PUSH?c!==l&&(window.location.hash=l):c!==l&&g.replaceHashPath(l)}}function r(e){1===++M&&(N=t(T));var n=T.listenBefore(e);return function(){n(),0===--M&&N()}}function i(e){1===++M&&(N=t(T));var n=T.listen(e);return function(){n(),0===--M&&N()}}function c(e){T.push(e)}function h(e){T.replace(e)}function d(e){T.go(e)}function w(e){return"#"+T.createHref(e)}function b(e){1===++M&&(N=t(T)),T.registerTransitionHook(e)}function E(e){T.unregisterTransitionHook(e),0===--M&&N()}function C(e,t){T.pushState(e,t)}function k(e,t){T.replaceState(e,t)}var S=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];m.canUseDOM?void 0:f.default(!1);var P=S.queryKey;(void 0===P||P)&&(P="string"==typeof P?P:x);var T=y.default(u({},S,{getCurrentLocation:e,finishTransition:n,saveState:v.saveState})),M=0,N=void 0;g.supportsGoWithoutReloadUsingHash();return u({},T,{listenBefore:r,listen:i,push:c,replace:h,go:d,createHref:w,registerTransitionHook:b,unregisterTransitionHook:E,pushState:C,replaceState:k})}t.__esModule=!0;var u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},h=n(8),d=(r(h),n(10)),f=r(d),p=n(27),m=n(40),g=n(70),v=n(224),w=n(225),y=r(w),b=n(19),_=r(b),x="_k";t.default=c,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(){var e=arguments.length<=0||void 0===arguments[0]?"/":arguments[0],t=arguments.length<=1||void 0===arguments[1]?o.POP:arguments[1],n=arguments.length<=2||void 0===arguments[2]?null:arguments[2],r=arguments.length<=3||void 0===arguments[3]?null:arguments[3];"string"==typeof e&&(e=l.default(e)),"object"==typeof t&&(e=a({},e,{state:t}),t=n||o.POP,n=r);var i=e.pathname||"/",s=e.search||"",c=e.hash||"",u=e.state||null;return{pathname:i,search:s,hash:c,state:u,action:t,key:n}}t.__esModule=!0;var a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=n(27),s=n(19),l=r(s);t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e){return e.filter(function(e){return e.state}).reduce(function(e,t){return e[t.key]=t.state,e},{})}function a(){function e(e,t){v[e]=t}function t(e){return v[e]}function n(){var e=m[g],n=e.key,r=e.basename,i=e.pathname,a=e.search,s=(r||"")+i+(a||""),l=void 0;n?l=t(n):(l=null,n=h.createKey(),e.key=n);var c=p.default(s);return h.createLocation(o({},c,{state:l}),void 0,n)}function r(e){var t=g+e;return t>=0&&t<m.length}function a(e){if(e){if(!r(e))return;g+=e;var t=n();h.transitionTo(o({},t,{action:u.POP}))}}function s(t){switch(t.action){case u.PUSH:g+=1,g<m.length&&m.splice(g),m.push(t),e(t.key,t.state);break;case u.REPLACE:m[g]=t,e(t.key,t.state)}}var l=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];Array.isArray(l)?l={entries:l}:"string"==typeof l&&(l={entries:[l]});var h=d.default(o({},l,{getCurrentLocation:n,finishTransition:s,saveState:e,go:a})),f=l,m=f.entries,g=f.current;"string"==typeof m?m=[m]:Array.isArray(m)||(m=["/"]),m=m.map(function(e){var t=h.createKey();return"string"==typeof e?{pathname:e,key:t}:"object"==typeof e&&e?o({},e,{key:t}):void c.default(!1)}),null==g?g=m.length-1:g>=0&&g<m.length?void 0:c.default(!1);var v=i(m);return h}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s=n(8),l=(r(s),n(10)),c=r(l),u=n(27),h=n(71),d=r(h),f=n(19),p=r(f);t.default=a,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e){return function(){function t(e){return b&&null==e.basename&&(0===e.pathname.indexOf(b)?(e.pathname=e.pathname.substring(b.length),e.basename=b,""===e.pathname&&(e.pathname="/")):e.basename=""),e}function n(e){if(!b)return e;"string"==typeof e&&(e=f.default(e));var t=e.pathname,n="/"===b.slice(-1)?b:b+"/",r="/"===t.charAt(0)?t.slice(1):t,i=n+r;return o({},e,{pathname:i})}function r(e){return x.listenBefore(function(n,r){c.default(e,t(n),r)})}function a(e){return x.listen(function(n){e(t(n))})}function l(e){x.push(n(e))}function u(e){x.replace(n(e))}function d(e){return x.createPath(n(e))}function p(e){return x.createHref(n(e))}function g(){return t(x.createLocation.apply(x,arguments))}function v(e,t){"string"==typeof t&&(t=f.default(t)),l(o({state:e},t))}function w(e,t){"string"==typeof t&&(t=f.default(t)),u(o({state:e},t))}var y=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],b=y.basename,_=i(y,["basename"]),x=e(_);if(null==b&&s.canUseDOM){var E=document.getElementsByTagName("base")[0];E&&(b=h.default(E.href))}return o({},x,{listenBefore:r,listen:a,push:l,replace:u,createPath:d,createHref:p,createLocation:g,pushState:m.default(v,"pushState is deprecated; use push instead"),replaceState:m.default(w,"replaceState is deprecated; use replace instead")})}}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s=n(40),l=n(42),c=r(l),u=n(72),h=r(u),d=n(19),f=r(d),p=n(41),m=r(p);t.default=a,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e){return c.stringify(e).replace(/%20/g,"+")}function o(e){return function(){function t(e){if(null==e.query){var t=e.search;e.query=x(t.substring(1)),e[g]={search:t,searchBase:""}}return e}function n(e,t){var n,r=void 0;if(!t||""===(r=_(t)))return e;"string"==typeof e&&(e=f.default(e));var i=e[g],a=void 0;a=i&&e.search===i.search?i.searchBase:e.search||"";var o=a+(a?"&":"?")+r;return s({},e,(n={search:o},n[g]={search:o,searchBase:a},n))}function r(e){return C.listenBefore(function(n,r){h.default(e,t(n),r)})}function o(e){return C.listen(function(n){e(t(n))})}function l(e){C.push(n(e,e.query))}function c(e){C.replace(n(e,e.query))}function u(e,t){return C.createPath(n(e,t||e.query))}function d(e,t){return C.createHref(n(e,t||e.query))}function p(){return t(C.createLocation.apply(C,arguments))}function w(e,t,n){"string"==typeof t&&(t=f.default(t)),l(s({state:e},t,{query:n}))}function y(e,t,n){"string"==typeof t&&(t=f.default(t)),c(s({state:e},t,{query:n}))}var b=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],_=b.stringifyQuery,x=b.parseQueryString,E=i(b,["stringifyQuery","parseQueryString"]),C=e(E);return"function"!=typeof _&&(_=a),"function"!=typeof x&&(x=v),s({},C,{listenBefore:r,listen:o,push:l,replace:c,createPath:u,createHref:d,createLocation:p,pushState:m.default(w,"pushState is deprecated; use push instead"),replaceState:m.default(y,"replaceState is deprecated; use replace instead")})}}t.__esModule=!0;var s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l=n(8),c=(r(l),n(231)),u=n(42),h=r(u),d=n(19),f=r(d),p=n(41),m=r(p),g="$searchBase",v=c.parse;t.default=o,e.exports=t.default},function(e,t,n){"use strict";var r=n(323);t.extract=function(e){return e.split("?")[1]||""},t.parse=function(e){return"string"!=typeof e?{}:(e=e.trim().replace(/^(\?|#|&)/,""),e?e.split("&").reduce(function(e,t){var n=t.replace(/\+/g," ").split("="),r=n.shift(),i=n.length>0?n.join("="):void 0;return r=decodeURIComponent(r),i=void 0===i?null:decodeURIComponent(i),e.hasOwnProperty(r)?Array.isArray(e[r])?e[r].push(i):e[r]=[e[r],i]:e[r]=i,e},{}):{})},t.stringify=function(e){return e?Object.keys(e).sort().map(function(t){var n=e[t];return void 0===n?"":null===n?t:Array.isArray(n)?n.slice().sort().map(function(e){return r(t)+"="+r(e)}).join("&"):r(t)+"="+r(n)}).filter(function(e){return e.length>0}).join("&"):""}},function(e,t,n){"use strict";e.exports=n(246)},function(e,t,n){"use strict";var r={Properties:{"aria-current":0,"aria-details":0,"aria-disabled":0,"aria-hidden":0,"aria-invalid":0,"aria-keyshortcuts":0,"aria-label":0,"aria-roledescription":0,"aria-autocomplete":0,"aria-checked":0,"aria-expanded":0,"aria-haspopup":0,"aria-level":0,"aria-modal":0,"aria-multiline":0,"aria-multiselectable":0,"aria-orientation":0,"aria-placeholder":0,"aria-pressed":0,"aria-readonly":0,"aria-required":0,"aria-selected":0,"aria-sort":0,"aria-valuemax":0,"aria-valuemin":0,"aria-valuenow":0,"aria-valuetext":0,"aria-atomic":0,"aria-busy":0,"aria-live":0,"aria-relevant":0,"aria-dropeffect":0,"aria-grabbed":0,"aria-activedescendant":0,"aria-colcount":0,"aria-colindex":0,"aria-colspan":0,"aria-controls":0,"aria-describedby":0,"aria-errormessage":0,"aria-flowto":0,"aria-labelledby":0,"aria-owns":0,"aria-posinset":0,"aria-rowcount":0,"aria-rowindex":0,"aria-rowspan":0,"aria-setsize":0},DOMAttributeNames:{},DOMPropertyNames:{}};e.exports=r},function(e,t,n){"use strict";var r=n(6),i=n(68),a={focusDOMComponent:function(){i(r.getNodeFromInstance(this))}};e.exports=a},function(e,t,n){"use strict";function r(){var e=window.opera;return"object"==typeof e&&"function"==typeof e.version&&parseInt(e.version(),10)<=12}function i(e){return(e.ctrlKey||e.altKey||e.metaKey)&&!(e.ctrlKey&&e.altKey)}function a(e){switch(e){case"topCompositionStart":return S.compositionStart;case"topCompositionEnd":return S.compositionEnd;case"topCompositionUpdate":return S.compositionUpdate}}function o(e,t){return"topKeyDown"===e&&t.keyCode===y}function s(e,t){switch(e){case"topKeyUp":return w.indexOf(t.keyCode)!==-1;case"topKeyDown":return t.keyCode!==y;case"topKeyPress":case"topMouseDown":case"topBlur":return!0;default:return!1}}function l(e){var t=e.detail;return"object"==typeof t&&"data"in t?t.data:null}function c(e,t,n,r){var i,c;if(b?i=a(e):T?s(e,n)&&(i=S.compositionEnd):o(e,n)&&(i=S.compositionStart),!i)return null;E&&(T||i!==S.compositionStart?i===S.compositionEnd&&T&&(c=T.getData()):T=m.getPooled(r));var u=g.getPooled(i,t,n,r);if(c)u.data=c;else{var h=l(n);null!==h&&(u.data=h)}return f.accumulateTwoPhaseDispatches(u),u}function u(e,t){switch(e){case"topCompositionEnd":return l(t);case"topKeyPress":var n=t.which;return n!==C?null:(P=!0,k);case"topTextInput":var r=t.data;return r===k&&P?null:r;default:return null}}function h(e,t){if(T){if("topCompositionEnd"===e||!b&&s(e,t)){var n=T.getData();return m.release(T),T=null,n}return null}switch(e){case"topPaste":return null;case"topKeyPress":return t.which&&!i(t)?String.fromCharCode(t.which):null;case"topCompositionEnd":return E?null:t.data;default:return null}}function d(e,t,n,r){var i;if(i=x?u(e,n):h(e,n),!i)return null;var a=v.getPooled(S.beforeInput,t,n,r);return a.data=i,f.accumulateTwoPhaseDispatches(a),a}var f=n(29),p=n(7),m=n(241),g=n(278),v=n(281),w=[9,13,27,32],y=229,b=p.canUseDOM&&"CompositionEvent"in window,_=null;p.canUseDOM&&"documentMode"in document&&(_=document.documentMode);var x=p.canUseDOM&&"TextEvent"in window&&!_&&!r(),E=p.canUseDOM&&(!b||_&&_>8&&_<=11),C=32,k=String.fromCharCode(C),S={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["topCompositionEnd","topKeyPress","topTextInput","topPaste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:["topBlur","topCompositionEnd","topKeyDown","topKeyPress","topKeyUp","topMouseDown"]},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:["topBlur","topCompositionStart","topKeyDown","topKeyPress","topKeyUp","topMouseDown"]},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:["topBlur","topCompositionUpdate","topKeyDown","topKeyPress","topKeyUp","topMouseDown"]}},P=!1,T=null,M={eventTypes:S,extractEvents:function(e,t,n,r){return[c(e,t,n,r),d(e,t,n,r)]}};e.exports=M},function(e,t,n){"use strict";var r=n(74),i=n(7),a=(n(11),n(212),n(287)),o=n(219),s=n(222),l=(n(2),s(function(e){return o(e)})),c=!1,u="cssFloat";if(i.canUseDOM){var h=document.createElement("div").style;try{h.font=""}catch(e){c=!0}void 0===document.documentElement.style.cssFloat&&(u="styleFloat")}var d={createMarkupForStyles:function(e,t){var n="";for(var r in e)if(e.hasOwnProperty(r)){var i=e[r];null!=i&&(n+=l(r)+":",n+=a(r,i,t)+";")}return n||null},setValueForStyles:function(e,t,n){var i=e.style;for(var o in t)if(t.hasOwnProperty(o)){var s=a(o,t[o],n);if("float"!==o&&"cssFloat"!==o||(o=u),s)i[o]=s;else{var l=c&&r.shorthandPropertyExpansions[o];if(l)for(var h in l)i[h]="";else i[o]=""}}}};e.exports=d},function(e,t,n){"use strict";function r(e){var t=e.nodeName&&e.nodeName.toLowerCase();return"select"===t||"input"===t&&"file"===e.type}function i(e){var t=E.getPooled(P.change,M,e,C(e));y.accumulateTwoPhaseDispatches(t),x.batchedUpdates(a,t)}function a(e){w.enqueueEvents(e),w.processEventQueue(!1)}function o(e,t){T=e,M=t,T.attachEvent("onchange",i)}function s(){T&&(T.detachEvent("onchange",i),T=null,M=null)}function l(e,t){if("topChange"===e)return t}function c(e,t,n){"topFocus"===e?(s(),o(t,n)):"topBlur"===e&&s()}function u(e,t){T=e,M=t,N=e.value,I=Object.getOwnPropertyDescriptor(e.constructor.prototype,"value"),Object.defineProperty(T,"value",O),T.attachEvent?T.attachEvent("onpropertychange",d):T.addEventListener("propertychange",d,!1)}function h(){T&&(delete T.value,T.detachEvent?T.detachEvent("onpropertychange",d):T.removeEventListener("propertychange",d,!1),T=null,M=null,N=null,I=null)}function d(e){if("value"===e.propertyName){var t=e.srcElement.value;t!==N&&(N=t,i(e))}}function f(e,t){if("topInput"===e)return t}function p(e,t,n){"topFocus"===e?(h(),u(t,n)):"topBlur"===e&&h()}function m(e,t){if(("topSelectionChange"===e||"topKeyUp"===e||"topKeyDown"===e)&&T&&T.value!==N)return N=T.value,M}function g(e){return e.nodeName&&"input"===e.nodeName.toLowerCase()&&("checkbox"===e.type||"radio"===e.type)}function v(e,t){if("topClick"===e)return t}var w=n(28),y=n(29),b=n(7),_=n(6),x=n(12),E=n(14),C=n(55),k=n(56),S=n(91),P={change:{phasedRegistrationNames:{bubbled:"onChange",captured:"onChangeCapture"},dependencies:["topBlur","topChange","topClick","topFocus","topInput","topKeyDown","topKeyUp","topSelectionChange"]}},T=null,M=null,N=null,I=null,L=!1;b.canUseDOM&&(L=k("change")&&(!document.documentMode||document.documentMode>8));var A=!1;b.canUseDOM&&(A=k("input")&&(!document.documentMode||document.documentMode>11));var O={get:function(){return I.get.call(this)},set:function(e){N=""+e,I.set.call(this,e)}},B={eventTypes:P,extractEvents:function(e,t,n,i){var a,o,s=t?_.getNodeFromInstance(t):window;if(r(s)?L?a=l:o=c:S(s)?A?a=f:(a=m,o=p):g(s)&&(a=v),a){var u=a(e,t);if(u){var h=E.getPooled(P.change,u,n,i);return h.type="change",y.accumulateTwoPhaseDispatches(h),h}}o&&o(e,s,t)}};e.exports=B},function(e,t,n){"use strict";var r=n(3),i=n(20),a=n(7),o=n(215),s=n(9),l=(n(1),{dangerouslyReplaceNodeWithMarkup:function(e,t){if(a.canUseDOM?void 0:r("56"),t?void 0:r("57"),"HTML"===e.nodeName?r("58"):void 0,"string"==typeof t){var n=o(t,s)[0];e.parentNode.replaceChild(n,e)}else i.replaceChildWithTree(e,t)}});e.exports=l},function(e,t,n){"use strict";var r=["ResponderEventPlugin","SimpleEventPlugin","TapEventPlugin","EnterLeaveEventPlugin","ChangeEventPlugin","SelectEventPlugin","BeforeInputEventPlugin"];e.exports=r},function(e,t,n){"use strict";var r=n(29),i=n(6),a=n(34),o={mouseEnter:{registrationName:"onMouseEnter",dependencies:["topMouseOut","topMouseOver"]},mouseLeave:{registrationName:"onMouseLeave",dependencies:["topMouseOut","topMouseOver"]}},s={eventTypes:o,extractEvents:function(e,t,n,s){if("topMouseOver"===e&&(n.relatedTarget||n.fromElement))return null;if("topMouseOut"!==e&&"topMouseOver"!==e)return null;var l;if(s.window===s)l=s;else{var c=s.ownerDocument;l=c?c.defaultView||c.parentWindow:window}var u,h;if("topMouseOut"===e){u=t;var d=n.relatedTarget||n.toElement;h=d?i.getClosestInstanceFromNode(d):null}else u=null,h=t;if(u===h)return null;var f=null==u?l:i.getNodeFromInstance(u),p=null==h?l:i.getNodeFromInstance(h),m=a.getPooled(o.mouseLeave,u,n,s);m.type="mouseleave",m.target=f,m.relatedTarget=p;var g=a.getPooled(o.mouseEnter,h,n,s);return g.type="mouseenter",g.target=p,g.relatedTarget=f,r.accumulateEnterLeaveDispatches(m,g,u,h),[m,g]}};e.exports=s},function(e,t,n){"use strict";function r(e){this._root=e,this._startText=this.getText(),this._fallbackText=null}var i=n(5),a=n(17),o=n(89);i(r.prototype,{destructor:function(){this._root=null,this._startText=null,this._fallbackText=null},getText:function(){return"value"in this._root?this._root.value:this._root[o()]},getData:function(){if(this._fallbackText)return this._fallbackText;var e,t,n=this._startText,r=n.length,i=this.getText(),a=i.length;for(e=0;e<r&&n[e]===i[e];e++);var o=r-e;for(t=1;t<=o&&n[r-t]===i[a-t];t++);var s=t>1?1-t:void 0;return this._fallbackText=i.slice(e,s),this._fallbackText}}),a.addPoolingTo(r),e.exports=r},function(e,t,n){"use strict";var r=n(21),i=r.injection.MUST_USE_PROPERTY,a=r.injection.HAS_BOOLEAN_VALUE,o=r.injection.HAS_NUMERIC_VALUE,s=r.injection.HAS_POSITIVE_NUMERIC_VALUE,l=r.injection.HAS_OVERLOADED_BOOLEAN_VALUE,c={isCustomAttribute:RegExp.prototype.test.bind(new RegExp("^(data|aria)-["+r.ATTRIBUTE_NAME_CHAR+"]*$")),Properties:{accept:0,acceptCharset:0,accessKey:0,action:0,allowFullScreen:a,allowTransparency:0,alt:0,as:0,async:a,autoComplete:0,autoPlay:a,capture:a,cellPadding:0,cellSpacing:0,charSet:0,challenge:0,checked:i|a,cite:0,classID:0,className:0,cols:s,colSpan:0,content:0,contentEditable:0,contextMenu:0,controls:a,coords:0,crossOrigin:0,data:0,dateTime:0,default:a,defer:a,dir:0,disabled:a,download:l,draggable:0,encType:0,form:0,formAction:0,formEncType:0,formMethod:0,formNoValidate:a,formTarget:0,frameBorder:0,headers:0,height:0,hidden:a,high:0,href:0,hrefLang:0,htmlFor:0,httpEquiv:0,icon:0,id:0,inputMode:0,integrity:0,is:0,keyParams:0,keyType:0,kind:0,label:0,lang:0,list:0,loop:a,low:0,manifest:0,marginHeight:0,marginWidth:0,max:0,maxLength:0,media:0,mediaGroup:0,method:0,min:0,minLength:0,multiple:i|a,muted:i|a,name:0,nonce:0,noValidate:a,open:a,optimum:0,pattern:0,placeholder:0,playsInline:a,poster:0,preload:0,profile:0,radioGroup:0,readOnly:a,referrerPolicy:0,rel:0,required:a,reversed:a,role:0,rows:s,rowSpan:o,sandbox:0,scope:0,scoped:a,scrolling:0,seamless:a,selected:i|a,shape:0,size:s,sizes:0,span:s,spellCheck:0,src:0,srcDoc:0,srcLang:0,srcSet:0,start:o,step:0,style:0,summary:0,tabIndex:0,target:0,title:0,type:0,useMap:0,value:0,width:0,wmode:0,wrap:0,about:0,datatype:0,inlist:0,prefix:0,property:0,resource:0,typeof:0,vocab:0,autoCapitalize:0,autoCorrect:0,autoSave:0,color:0,itemProp:0,itemScope:a,itemType:0,itemID:0,itemRef:0,results:0,security:0,unselectable:0},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{}};e.exports=c},function(e,t,n){"use strict";(function(t){function r(e,t,n,r){var i=void 0===e[n];null!=t&&i&&(e[n]=a(t,!0))}var i=n(22),a=n(90),o=(n(47),n(57)),s=n(93);n(2);"undefined"!=typeof t&&t.env,1;var l={instantiateChildren:function(e,t,n,i){if(null==e)return null;var a={};return s(e,r,a),a},updateChildren:function(e,t,n,r,s,l,c,u,h){if(t||e){var d,f;for(d in t)if(t.hasOwnProperty(d)){f=e&&e[d];var p=f&&f._currentElement,m=t[d];if(null!=f&&o(p,m))i.receiveComponent(f,m,s,u),t[d]=f;else{f&&(r[d]=i.getHostNode(f),i.unmountComponent(f,!1));var g=a(m,!0);t[d]=g;var v=i.mountComponent(g,s,l,c,u,h);n.push(v)}}for(d in e)!e.hasOwnProperty(d)||t&&t.hasOwnProperty(d)||(f=e[d],r[d]=i.getHostNode(f),i.unmountComponent(f,!1))}},unmountChildren:function(e,t){for(var n in e)if(e.hasOwnProperty(n)){var r=e[n];i.unmountComponent(r,t)}}};e.exports=l}).call(t,n(73))},function(e,t,n){"use strict";var r=n(43),i=n(251),a={processChildrenUpdates:i.dangerouslyProcessChildrenUpdates,replaceNodeWithMarkup:r.dangerouslyReplaceNodeWithMarkup};e.exports=a},function(e,t,n){"use strict";function r(e){}function i(e,t){}function a(e){return!(!e.prototype||!e.prototype.isReactComponent)}function o(e){return!(!e.prototype||!e.prototype.isPureReactComponent)}var s=n(3),l=n(5),c=n(23),u=n(49),h=n(15),d=n(50),f=n(30),p=(n(11),n(84)),m=n(22),g=n(26),v=(n(1),n(39)),w=n(57),y=(n(2),{ImpureClass:0,PureClass:1,StatelessFunctional:2});r.prototype.render=function(){var e=f.get(this)._currentElement.type,t=e(this.props,this.context,this.updater);return i(e,t),t};var b=1,_={construct:function(e){this._currentElement=e,this._rootNodeID=0,this._compositeType=null,this._instance=null,this._hostParent=null,this._hostContainerInfo=null,this._updateBatchNumber=null,this._pendingElement=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._renderedNodeType=null,this._renderedComponent=null,this._context=null,this._mountOrder=0,this._topLevelWrapper=null,this._pendingCallbacks=null,this._calledComponentWillUnmount=!1},mountComponent:function(e,t,n,l){this._context=l,this._mountOrder=b++,this._hostParent=t,this._hostContainerInfo=n;var u,h=this._currentElement.props,d=this._processContext(l),p=this._currentElement.type,m=e.getUpdateQueue(),v=a(p),w=this._constructComponent(v,h,d,m);v||null!=w&&null!=w.render?o(p)?this._compositeType=y.PureClass:this._compositeType=y.ImpureClass:(u=w,i(p,u),null===w||w===!1||c.isValidElement(w)?void 0:s("105",p.displayName||p.name||"Component"),w=new r(p),this._compositeType=y.StatelessFunctional);w.props=h,w.context=d,w.refs=g,w.updater=m,this._instance=w,f.set(w,this);var _=w.state;void 0===_&&(w.state=_=null),"object"!=typeof _||Array.isArray(_)?s("106",this.getName()||"ReactCompositeComponent"):void 0,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1;var x;return x=w.unstable_handleError?this.performInitialMountWithErrorHandling(u,t,n,e,l):this.performInitialMount(u,t,n,e,l),w.componentDidMount&&e.getReactMountReady().enqueue(w.componentDidMount,w),x},_constructComponent:function(e,t,n,r){return this._constructComponentWithoutOwner(e,t,n,r)},_constructComponentWithoutOwner:function(e,t,n,r){var i=this._currentElement.type;return e?new i(t,n,r):i(t,n,r)},performInitialMountWithErrorHandling:function(e,t,n,r,i){var a,o=r.checkpoint();try{a=this.performInitialMount(e,t,n,r,i)}catch(s){r.rollback(o),this._instance.unstable_handleError(s),this._pendingStateQueue&&(this._instance.state=this._processPendingState(this._instance.props,this._instance.context)),o=r.checkpoint(),this._renderedComponent.unmountComponent(!0),r.rollback(o),a=this.performInitialMount(e,t,n,r,i)}return a},performInitialMount:function(e,t,n,r,i){var a=this._instance,o=0;a.componentWillMount&&(a.componentWillMount(),this._pendingStateQueue&&(a.state=this._processPendingState(a.props,a.context))),void 0===e&&(e=this._renderValidatedComponent());var s=p.getType(e);this._renderedNodeType=s;var l=this._instantiateReactComponent(e,s!==p.EMPTY);this._renderedComponent=l;var c=m.mountComponent(l,r,t,n,this._processChildContext(i),o);return c},getHostNode:function(){return m.getHostNode(this._renderedComponent)},unmountComponent:function(e){if(this._renderedComponent){var t=this._instance;if(t.componentWillUnmount&&!t._calledComponentWillUnmount)if(t._calledComponentWillUnmount=!0,e){var n=this.getName()+".componentWillUnmount()";d.invokeGuardedCallback(n,t.componentWillUnmount.bind(t))}else t.componentWillUnmount();this._renderedComponent&&(m.unmountComponent(this._renderedComponent,e),this._renderedNodeType=null,this._renderedComponent=null,this._instance=null),this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._pendingCallbacks=null,this._pendingElement=null,this._context=null,this._rootNodeID=0,this._topLevelWrapper=null,f.remove(t)}},_maskContext:function(e){var t=this._currentElement.type,n=t.contextTypes;if(!n)return g;var r={};for(var i in n)r[i]=e[i];return r},_processContext:function(e){var t=this._maskContext(e);return t},_processChildContext:function(e){var t,n=this._currentElement.type,r=this._instance;if(r.getChildContext&&(t=r.getChildContext()),t){"object"!=typeof n.childContextTypes?s("107",this.getName()||"ReactCompositeComponent"):void 0;for(var i in t)i in n.childContextTypes?void 0:s("108",this.getName()||"ReactCompositeComponent",i);return l({},e,t)}return e},_checkContextTypes:function(e,t,n){},receiveComponent:function(e,t,n){var r=this._currentElement,i=this._context;this._pendingElement=null,this.updateComponent(t,r,e,i,n)},performUpdateIfNecessary:function(e){null!=this._pendingElement?m.receiveComponent(this,this._pendingElement,e,this._context):null!==this._pendingStateQueue||this._pendingForceUpdate?this.updateComponent(e,this._currentElement,this._currentElement,this._context,this._context):this._updateBatchNumber=null},updateComponent:function(e,t,n,r,i){var a=this._instance;null==a?s("136",this.getName()||"ReactCompositeComponent"):void 0;var o,l=!1;this._context===i?o=a.context:(o=this._processContext(i),l=!0);var c=t.props,u=n.props;t!==n&&(l=!0),l&&a.componentWillReceiveProps&&a.componentWillReceiveProps(u,o);var h=this._processPendingState(u,o),d=!0;this._pendingForceUpdate||(a.shouldComponentUpdate?d=a.shouldComponentUpdate(u,h,o):this._compositeType===y.PureClass&&(d=!v(c,u)||!v(a.state,h))),this._updateBatchNumber=null,d?(this._pendingForceUpdate=!1,this._performComponentUpdate(n,u,h,o,e,i)):(this._currentElement=n,this._context=i,a.props=u,a.state=h,a.context=o)},_processPendingState:function(e,t){var n=this._instance,r=this._pendingStateQueue,i=this._pendingReplaceState;if(this._pendingReplaceState=!1,this._pendingStateQueue=null,!r)return n.state;if(i&&1===r.length)return r[0];for(var a=l({},i?r[0]:n.state),o=i?1:0;o<r.length;o++){var s=r[o];l(a,"function"==typeof s?s.call(n,a,e,t):s)}return a},_performComponentUpdate:function(e,t,n,r,i,a){var o,s,l,c=this._instance,u=Boolean(c.componentDidUpdate);u&&(o=c.props,s=c.state,l=c.context),c.componentWillUpdate&&c.componentWillUpdate(t,n,r),this._currentElement=e,this._context=a,c.props=t,c.state=n,c.context=r,this._updateRenderedComponent(i,a),u&&i.getReactMountReady().enqueue(c.componentDidUpdate.bind(c,o,s,l),c); +},_updateRenderedComponent:function(e,t){var n=this._renderedComponent,r=n._currentElement,i=this._renderValidatedComponent(),a=0;if(w(r,i))m.receiveComponent(n,i,e,this._processChildContext(t));else{var o=m.getHostNode(n);m.unmountComponent(n,!1);var s=p.getType(i);this._renderedNodeType=s;var l=this._instantiateReactComponent(i,s!==p.EMPTY);this._renderedComponent=l;var c=m.mountComponent(l,e,this._hostParent,this._hostContainerInfo,this._processChildContext(t),a);this._replaceNodeWithMarkup(o,c,n)}},_replaceNodeWithMarkup:function(e,t,n){u.replaceNodeWithMarkup(e,t,n)},_renderValidatedComponentWithoutOwnerOrContext:function(){var e,t=this._instance;return e=t.render()},_renderValidatedComponent:function(){var e;if(this._compositeType!==y.StatelessFunctional){h.current=this;try{e=this._renderValidatedComponentWithoutOwnerOrContext()}finally{h.current=null}}else e=this._renderValidatedComponentWithoutOwnerOrContext();return null===e||e===!1||c.isValidElement(e)?void 0:s("109",this.getName()||"ReactCompositeComponent"),e},attachRef:function(e,t){var n=this.getPublicInstance();null==n?s("110"):void 0;var r=t.getPublicInstance(),i=n.refs===g?n.refs={}:n.refs;i[e]=r},detachRef:function(e){var t=this.getPublicInstance().refs;delete t[e]},getName:function(){var e=this._currentElement.type,t=this._instance&&this._instance.constructor;return e.displayName||t&&t.displayName||e.name||t&&t.name||null},getPublicInstance:function(){var e=this._instance;return this._compositeType===y.StatelessFunctional?null:e},_instantiateReactComponent:null};e.exports=_},function(e,t,n){"use strict";var r=n(6),i=n(259),a=n(83),o=n(22),s=n(12),l=n(272),c=n(288),u=n(88),h=n(296);n(2);i.inject();var d={findDOMNode:c,render:a.render,unmountComponentAtNode:a.unmountComponentAtNode,version:l,unstable_batchedUpdates:s.batchedUpdates,unstable_renderSubtreeIntoContainer:h};"undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject&&__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ComponentTree:{getClosestInstanceFromNode:r.getClosestInstanceFromNode,getNodeFromInstance:function(e){return e._renderedComponent&&(e=u(e)),e?r.getNodeFromInstance(e):null}},Mount:a,Reconciler:o});e.exports=d},function(e,t,n){"use strict";function r(e){if(e){var t=e._currentElement._owner||null;if(t){var n=t.getName();if(n)return" This DOM node was rendered by `"+n+"`."}}return""}function i(e,t){t&&(K[e._tag]&&(null!=t.children||null!=t.dangerouslySetInnerHTML?m("137",e._tag,e._currentElement._owner?" Check the render method of "+e._currentElement._owner.getName()+".":""):void 0),null!=t.dangerouslySetInnerHTML&&(null!=t.children?m("60"):void 0,"object"==typeof t.dangerouslySetInnerHTML&&V in t.dangerouslySetInnerHTML?void 0:m("61")),null!=t.style&&"object"!=typeof t.style?m("62",r(e)):void 0)}function a(e,t,n,r){if(!(r instanceof A)){var i=e._hostContainerInfo,a=i._node&&i._node.nodeType===W,s=a?i._node:i._ownerDocument;D(t,s),r.getReactMountReady().enqueue(o,{inst:e,registrationName:t,listener:n})}}function o(){var e=this;E.putListener(e.inst,e.registrationName,e.listener)}function s(){var e=this;T.postMountWrapper(e)}function l(){var e=this;I.postMountWrapper(e)}function c(){var e=this;M.postMountWrapper(e)}function u(){var e=this;e._rootNodeID?void 0:m("63");var t=R(e);switch(t?void 0:m("64"),e._tag){case"iframe":case"object":e._wrapperState.listeners=[k.trapBubbledEvent("topLoad","load",t)];break;case"video":case"audio":e._wrapperState.listeners=[];for(var n in G)G.hasOwnProperty(n)&&e._wrapperState.listeners.push(k.trapBubbledEvent(n,G[n],t));break;case"source":e._wrapperState.listeners=[k.trapBubbledEvent("topError","error",t)];break;case"img":e._wrapperState.listeners=[k.trapBubbledEvent("topError","error",t),k.trapBubbledEvent("topLoad","load",t)];break;case"form":e._wrapperState.listeners=[k.trapBubbledEvent("topReset","reset",t),k.trapBubbledEvent("topSubmit","submit",t)];break;case"input":case"select":case"textarea":e._wrapperState.listeners=[k.trapBubbledEvent("topInvalid","invalid",t)]}}function h(){N.postUpdateWrapper(this)}function d(e){Z.call(Y,e)||(Q.test(e)?void 0:m("65",e),Y[e]=!0)}function f(e,t){return e.indexOf("-")>=0||null!=t.is}function p(e){var t=e.type;d(t),this._currentElement=e,this._tag=t.toLowerCase(),this._namespaceURI=null,this._renderedChildren=null,this._previousStyle=null,this._previousStyleCopy=null,this._hostNode=null,this._hostParent=null,this._rootNodeID=0,this._domID=0,this._hostContainerInfo=null,this._wrapperState=null,this._topLevelWrapper=null,this._flags=0}var m=n(3),g=n(5),v=n(234),w=n(236),y=n(20),b=n(44),_=n(21),x=n(76),E=n(28),C=n(45),k=n(33),S=n(77),P=n(6),T=n(252),M=n(253),N=n(78),I=n(256),L=(n(11),n(265)),A=n(270),O=(n(9),n(36)),B=(n(1),n(56),n(39),n(58),n(2),S),z=E.deleteListener,R=P.getNodeFromInstance,D=k.listenTo,j=C.registrationNameModules,F={string:!0,number:!0},q="style",V="__html",U={children:null,dangerouslySetInnerHTML:null,suppressContentEditableWarning:null},W=11,G={topAbort:"abort",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topSeeked:"seeked",topSeeking:"seeking",topStalled:"stalled",topSuspend:"suspend",topTimeUpdate:"timeupdate",topVolumeChange:"volumechange",topWaiting:"waiting"},H={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},X={listing:!0,pre:!0,textarea:!0},K=g({menuitem:!0},H),Q=/^[a-zA-Z][a-zA-Z:_\.\-\d]*$/,Y={},Z={}.hasOwnProperty,$=1;p.displayName="ReactDOMComponent",p.Mixin={mountComponent:function(e,t,n,r){this._rootNodeID=$++,this._domID=n._idCounter++,this._hostParent=t,this._hostContainerInfo=n;var a=this._currentElement.props;switch(this._tag){case"audio":case"form":case"iframe":case"img":case"link":case"object":case"source":case"video":this._wrapperState={listeners:null},e.getReactMountReady().enqueue(u,this);break;case"input":T.mountWrapper(this,a,t),a=T.getHostProps(this,a),e.getReactMountReady().enqueue(u,this);break;case"option":M.mountWrapper(this,a,t),a=M.getHostProps(this,a);break;case"select":N.mountWrapper(this,a,t),a=N.getHostProps(this,a),e.getReactMountReady().enqueue(u,this);break;case"textarea":I.mountWrapper(this,a,t),a=I.getHostProps(this,a),e.getReactMountReady().enqueue(u,this)}i(this,a);var o,h;null!=t?(o=t._namespaceURI,h=t._tag):n._tag&&(o=n._namespaceURI,h=n._tag),(null==o||o===b.svg&&"foreignobject"===h)&&(o=b.html),o===b.html&&("svg"===this._tag?o=b.svg:"math"===this._tag&&(o=b.mathml)),this._namespaceURI=o;var d;if(e.useCreateElement){var f,p=n._ownerDocument;if(o===b.html)if("script"===this._tag){var m=p.createElement("div"),g=this._currentElement.type;m.innerHTML="<"+g+"></"+g+">",f=m.removeChild(m.firstChild)}else f=a.is?p.createElement(this._currentElement.type,a.is):p.createElement(this._currentElement.type);else f=p.createElementNS(o,this._currentElement.type);P.precacheNode(this,f),this._flags|=B.hasCachedChildNodes,this._hostParent||x.setAttributeForRoot(f),this._updateDOMProperties(null,a,e);var w=y(f);this._createInitialChildren(e,a,r,w),d=w}else{var _=this._createOpenTagMarkupAndPutListeners(e,a),E=this._createContentMarkup(e,a,r);d=!E&&H[this._tag]?_+"/>":_+">"+E+"</"+this._currentElement.type+">"}switch(this._tag){case"input":e.getReactMountReady().enqueue(s,this),a.autoFocus&&e.getReactMountReady().enqueue(v.focusDOMComponent,this);break;case"textarea":e.getReactMountReady().enqueue(l,this),a.autoFocus&&e.getReactMountReady().enqueue(v.focusDOMComponent,this);break;case"select":a.autoFocus&&e.getReactMountReady().enqueue(v.focusDOMComponent,this);break;case"button":a.autoFocus&&e.getReactMountReady().enqueue(v.focusDOMComponent,this);break;case"option":e.getReactMountReady().enqueue(c,this)}return d},_createOpenTagMarkupAndPutListeners:function(e,t){var n="<"+this._currentElement.type;for(var r in t)if(t.hasOwnProperty(r)){var i=t[r];if(null!=i)if(j.hasOwnProperty(r))i&&a(this,r,i,e);else{r===q&&(i&&(i=this._previousStyleCopy=g({},t.style)),i=w.createMarkupForStyles(i,this));var o=null;null!=this._tag&&f(this._tag,t)?U.hasOwnProperty(r)||(o=x.createMarkupForCustomAttribute(r,i)):o=x.createMarkupForProperty(r,i),o&&(n+=" "+o)}}return e.renderToStaticMarkup?n:(this._hostParent||(n+=" "+x.createMarkupForRoot()),n+=" "+x.createMarkupForID(this._domID))},_createContentMarkup:function(e,t,n){var r="",i=t.dangerouslySetInnerHTML;if(null!=i)null!=i.__html&&(r=i.__html);else{var a=F[typeof t.children]?t.children:null,o=null!=a?null:t.children;if(null!=a)r=O(a);else if(null!=o){var s=this.mountChildren(o,e,n);r=s.join("")}}return X[this._tag]&&"\n"===r.charAt(0)?"\n"+r:r},_createInitialChildren:function(e,t,n,r){var i=t.dangerouslySetInnerHTML;if(null!=i)null!=i.__html&&y.queueHTML(r,i.__html);else{var a=F[typeof t.children]?t.children:null,o=null!=a?null:t.children;if(null!=a)""!==a&&y.queueText(r,a);else if(null!=o)for(var s=this.mountChildren(o,e,n),l=0;l<s.length;l++)y.queueChild(r,s[l])}},receiveComponent:function(e,t,n){var r=this._currentElement;this._currentElement=e,this.updateComponent(t,r,e,n)},updateComponent:function(e,t,n,r){var a=t.props,o=this._currentElement.props;switch(this._tag){case"input":a=T.getHostProps(this,a),o=T.getHostProps(this,o);break;case"option":a=M.getHostProps(this,a),o=M.getHostProps(this,o);break;case"select":a=N.getHostProps(this,a),o=N.getHostProps(this,o);break;case"textarea":a=I.getHostProps(this,a),o=I.getHostProps(this,o)}switch(i(this,o),this._updateDOMProperties(a,o,e),this._updateDOMChildren(a,o,e,r),this._tag){case"input":T.updateWrapper(this);break;case"textarea":I.updateWrapper(this);break;case"select":e.getReactMountReady().enqueue(h,this)}},_updateDOMProperties:function(e,t,n){var r,i,o;for(r in e)if(!t.hasOwnProperty(r)&&e.hasOwnProperty(r)&&null!=e[r])if(r===q){var s=this._previousStyleCopy;for(i in s)s.hasOwnProperty(i)&&(o=o||{},o[i]="");this._previousStyleCopy=null}else j.hasOwnProperty(r)?e[r]&&z(this,r):f(this._tag,e)?U.hasOwnProperty(r)||x.deleteValueForAttribute(R(this),r):(_.properties[r]||_.isCustomAttribute(r))&&x.deleteValueForProperty(R(this),r);for(r in t){var l=t[r],c=r===q?this._previousStyleCopy:null!=e?e[r]:void 0;if(t.hasOwnProperty(r)&&l!==c&&(null!=l||null!=c))if(r===q)if(l?l=this._previousStyleCopy=g({},l):this._previousStyleCopy=null,c){for(i in c)!c.hasOwnProperty(i)||l&&l.hasOwnProperty(i)||(o=o||{},o[i]="");for(i in l)l.hasOwnProperty(i)&&c[i]!==l[i]&&(o=o||{},o[i]=l[i])}else o=l;else if(j.hasOwnProperty(r))l?a(this,r,l,n):c&&z(this,r);else if(f(this._tag,t))U.hasOwnProperty(r)||x.setValueForAttribute(R(this),r,l);else if(_.properties[r]||_.isCustomAttribute(r)){var u=R(this);null!=l?x.setValueForProperty(u,r,l):x.deleteValueForProperty(u,r)}}o&&w.setValueForStyles(R(this),o,this)},_updateDOMChildren:function(e,t,n,r){var i=F[typeof e.children]?e.children:null,a=F[typeof t.children]?t.children:null,o=e.dangerouslySetInnerHTML&&e.dangerouslySetInnerHTML.__html,s=t.dangerouslySetInnerHTML&&t.dangerouslySetInnerHTML.__html,l=null!=i?null:e.children,c=null!=a?null:t.children,u=null!=i||null!=o,h=null!=a||null!=s;null!=l&&null==c?this.updateChildren(null,n,r):u&&!h&&this.updateTextContent(""),null!=a?i!==a&&this.updateTextContent(""+a):null!=s?o!==s&&this.updateMarkup(""+s):null!=c&&this.updateChildren(c,n,r)},getHostNode:function(){return R(this)},unmountComponent:function(e){switch(this._tag){case"audio":case"form":case"iframe":case"img":case"link":case"object":case"source":case"video":var t=this._wrapperState.listeners;if(t)for(var n=0;n<t.length;n++)t[n].remove();break;case"html":case"head":case"body":m("66",this._tag)}this.unmountChildren(e),P.uncacheNode(this),E.deleteAllListeners(this),this._rootNodeID=0,this._domID=0,this._wrapperState=null},getPublicInstance:function(){return R(this)}},g(p.prototype,p.Mixin,L.Mixin),e.exports=p},function(e,t,n){"use strict";function r(e,t){var n={_topLevelWrapper:e,_idCounter:1,_ownerDocument:t?t.nodeType===i?t:t.ownerDocument:null,_node:t,_tag:t?t.nodeName.toLowerCase():null,_namespaceURI:t?t.namespaceURI:null};return n}var i=(n(58),9);e.exports=r},function(e,t,n){"use strict";var r=n(5),i=n(20),a=n(6),o=function(e){this._currentElement=null,this._hostNode=null,this._hostParent=null,this._hostContainerInfo=null,this._domID=0};r(o.prototype,{mountComponent:function(e,t,n,r){var o=n._idCounter++;this._domID=o,this._hostParent=t,this._hostContainerInfo=n;var s=" react-empty: "+this._domID+" ";if(e.useCreateElement){var l=n._ownerDocument,c=l.createComment(s);return a.precacheNode(this,c),i(c)}return e.renderToStaticMarkup?"":"<!--"+s+"-->"},receiveComponent:function(){},getHostNode:function(){return a.getNodeFromInstance(this)},unmountComponent:function(){a.uncacheNode(this)}}),e.exports=o},function(e,t,n){"use strict";var r={useCreateElement:!0,useFiber:!1};e.exports=r},function(e,t,n){"use strict";var r=n(43),i=n(6),a={dangerouslyProcessChildrenUpdates:function(e,t){var n=i.getNodeFromInstance(e);r.processUpdates(n,t)}};e.exports=a},function(e,t,n){"use strict";function r(){this._rootNodeID&&h.updateWrapper(this)}function i(e){var t=this._currentElement.props,n=l.executeOnChange(t,e);u.asap(r,this);var i=t.name;if("radio"===t.type&&null!=i){for(var o=c.getNodeFromInstance(this),s=o;s.parentNode;)s=s.parentNode;for(var h=s.querySelectorAll("input[name="+JSON.stringify(""+i)+'][type="radio"]'),d=0;d<h.length;d++){var f=h[d];if(f!==o&&f.form===o.form){var p=c.getInstanceFromNode(f);p?void 0:a("90"),u.asap(r,p)}}}return n}var a=n(3),o=n(5),s=n(76),l=n(48),c=n(6),u=n(12),h=(n(1),n(2),{getHostProps:function(e,t){var n=l.getValue(t),r=l.getChecked(t),i=o({type:void 0,step:void 0,min:void 0,max:void 0},t,{defaultChecked:void 0,defaultValue:void 0,value:null!=n?n:e._wrapperState.initialValue,checked:null!=r?r:e._wrapperState.initialChecked,onChange:e._wrapperState.onChange});return i},mountWrapper:function(e,t){var n=t.defaultValue;e._wrapperState={initialChecked:null!=t.checked?t.checked:t.defaultChecked,initialValue:null!=t.value?t.value:n,listeners:null,onChange:i.bind(e)}},updateWrapper:function(e){var t=e._currentElement.props,n=t.checked;null!=n&&s.setValueForProperty(c.getNodeFromInstance(e),"checked",n||!1);var r=c.getNodeFromInstance(e),i=l.getValue(t);if(null!=i){var a=""+i;a!==r.value&&(r.value=a)}else null==t.value&&null!=t.defaultValue&&r.defaultValue!==""+t.defaultValue&&(r.defaultValue=""+t.defaultValue),null==t.checked&&null!=t.defaultChecked&&(r.defaultChecked=!!t.defaultChecked)},postMountWrapper:function(e){var t=e._currentElement.props,n=c.getNodeFromInstance(e);switch(t.type){case"submit":case"reset":break;case"color":case"date":case"datetime":case"datetime-local":case"month":case"time":case"week":n.value="",n.value=n.defaultValue;break;default:n.value=n.value}var r=n.name;""!==r&&(n.name=""),n.defaultChecked=!n.defaultChecked,n.defaultChecked=!n.defaultChecked,""!==r&&(n.name=r)}});e.exports=h},function(e,t,n){"use strict";function r(e){var t="";return a.Children.forEach(e,function(e){null!=e&&("string"==typeof e||"number"==typeof e?t+=e:l||(l=!0))}),t}var i=n(5),a=n(23),o=n(6),s=n(78),l=(n(2),!1),c={mountWrapper:function(e,t,n){var i=null;if(null!=n){var a=n;"optgroup"===a._tag&&(a=a._hostParent),null!=a&&"select"===a._tag&&(i=s.getSelectValueContext(a))}var o=null;if(null!=i){var l;if(l=null!=t.value?t.value+"":r(t.children),o=!1,Array.isArray(i)){for(var c=0;c<i.length;c++)if(""+i[c]===l){o=!0;break}}else o=""+i===l}e._wrapperState={selected:o}},postMountWrapper:function(e){var t=e._currentElement.props;if(null!=t.value){var n=o.getNodeFromInstance(e);n.setAttribute("value",t.value)}},getHostProps:function(e,t){var n=i({selected:void 0,children:void 0},t);null!=e._wrapperState.selected&&(n.selected=e._wrapperState.selected);var a=r(t.children);return a&&(n.children=a),n}};e.exports=c},function(e,t,n){"use strict";function r(e,t,n,r){return e===n&&t===r}function i(e){var t=document.selection,n=t.createRange(),r=n.text.length,i=n.duplicate();i.moveToElementText(e),i.setEndPoint("EndToStart",n);var a=i.text.length,o=a+r;return{start:a,end:o}}function a(e){var t=window.getSelection&&window.getSelection();if(!t||0===t.rangeCount)return null;var n=t.anchorNode,i=t.anchorOffset,a=t.focusNode,o=t.focusOffset,s=t.getRangeAt(0);try{s.startContainer.nodeType,s.endContainer.nodeType}catch(e){return null}var l=r(t.anchorNode,t.anchorOffset,t.focusNode,t.focusOffset),c=l?0:s.toString().length,u=s.cloneRange();u.selectNodeContents(e),u.setEnd(s.startContainer,s.startOffset);var h=r(u.startContainer,u.startOffset,u.endContainer,u.endOffset),d=h?0:u.toString().length,f=d+c,p=document.createRange();p.setStart(n,i),p.setEnd(a,o);var m=p.collapsed;return{start:m?f:d,end:m?d:f}}function o(e,t){var n,r,i=document.selection.createRange().duplicate();void 0===t.end?(n=t.start,r=n):t.start>t.end?(n=t.end,r=t.start):(n=t.start,r=t.end),i.moveToElementText(e),i.moveStart("character",n),i.setEndPoint("EndToStart",i),i.moveEnd("character",r-n),i.select()}function s(e,t){if(window.getSelection){var n=window.getSelection(),r=e[u()].length,i=Math.min(t.start,r),a=void 0===t.end?i:Math.min(t.end,r);if(!n.extend&&i>a){var o=a;a=i,i=o}var s=c(e,i),l=c(e,a);if(s&&l){var h=document.createRange();h.setStart(s.node,s.offset),n.removeAllRanges(),i>a?(n.addRange(h),n.extend(l.node,l.offset)):(h.setEnd(l.node,l.offset),n.addRange(h))}}}var l=n(7),c=n(293),u=n(89),h=l.canUseDOM&&"selection"in document&&!("getSelection"in window),d={getOffsets:h?i:a,setOffsets:h?o:s};e.exports=d},function(e,t,n){"use strict";var r=n(3),i=n(5),a=n(43),o=n(20),s=n(6),l=n(36),c=(n(1),n(58),function(e){this._currentElement=e,this._stringText=""+e,this._hostNode=null,this._hostParent=null,this._domID=0,this._mountIndex=0,this._closingComment=null,this._commentNodes=null});i(c.prototype,{mountComponent:function(e,t,n,r){var i=n._idCounter++,a=" react-text: "+i+" ",c=" /react-text ";if(this._domID=i,this._hostParent=t,e.useCreateElement){var u=n._ownerDocument,h=u.createComment(a),d=u.createComment(c),f=o(u.createDocumentFragment());return o.queueChild(f,o(h)),this._stringText&&o.queueChild(f,o(u.createTextNode(this._stringText))),o.queueChild(f,o(d)),s.precacheNode(this,h),this._closingComment=d,f}var p=l(this._stringText);return e.renderToStaticMarkup?p:"<!--"+a+"-->"+p+"<!--"+c+"-->"},receiveComponent:function(e,t){if(e!==this._currentElement){this._currentElement=e;var n=""+e;if(n!==this._stringText){this._stringText=n;var r=this.getHostNode();a.replaceDelimitedText(r[0],r[1],n)}}},getHostNode:function(){var e=this._commentNodes;if(e)return e;if(!this._closingComment)for(var t=s.getNodeFromInstance(this),n=t.nextSibling;;){if(null==n?r("67",this._domID):void 0,8===n.nodeType&&" /react-text "===n.nodeValue){this._closingComment=n;break}n=n.nextSibling}return e=[this._hostNode,this._closingComment],this._commentNodes=e,e},unmountComponent:function(){this._closingComment=null,this._commentNodes=null,s.uncacheNode(this)}}),e.exports=c},function(e,t,n){"use strict";function r(){this._rootNodeID&&u.updateWrapper(this)}function i(e){var t=this._currentElement.props,n=s.executeOnChange(t,e);return c.asap(r,this),n}var a=n(3),o=n(5),s=n(48),l=n(6),c=n(12),u=(n(1),n(2),{getHostProps:function(e,t){null!=t.dangerouslySetInnerHTML?a("91"):void 0;var n=o({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue,onChange:e._wrapperState.onChange});return n},mountWrapper:function(e,t){var n=s.getValue(t),r=n;if(null==n){var o=t.defaultValue,l=t.children;null!=l&&(null!=o?a("92"):void 0,Array.isArray(l)&&(l.length<=1?void 0:a("93"),l=l[0]),o=""+l),null==o&&(o=""),r=o}e._wrapperState={initialValue:""+r,listeners:null,onChange:i.bind(e)}},updateWrapper:function(e){var t=e._currentElement.props,n=l.getNodeFromInstance(e),r=s.getValue(t);if(null!=r){var i=""+r;i!==n.value&&(n.value=i),null==t.defaultValue&&(n.defaultValue=i)}null!=t.defaultValue&&(n.defaultValue=t.defaultValue)},postMountWrapper:function(e){var t=l.getNodeFromInstance(e),n=t.textContent;n===e._wrapperState.initialValue&&(t.value=n)}});e.exports=u},function(e,t,n){"use strict";function r(e,t){"_hostNode"in e?void 0:l("33"),"_hostNode"in t?void 0:l("33");for(var n=0,r=e;r;r=r._hostParent)n++;for(var i=0,a=t;a;a=a._hostParent)i++;for(;n-i>0;)e=e._hostParent,n--;for(;i-n>0;)t=t._hostParent,i--;for(var o=n;o--;){if(e===t)return e;e=e._hostParent,t=t._hostParent}return null}function i(e,t){"_hostNode"in e?void 0:l("35"),"_hostNode"in t?void 0:l("35");for(;t;){if(t===e)return!0;t=t._hostParent}return!1}function a(e){return"_hostNode"in e?void 0:l("36"),e._hostParent}function o(e,t,n){for(var r=[];e;)r.push(e),e=e._hostParent;var i;for(i=r.length;i-- >0;)t(r[i],"captured",n);for(i=0;i<r.length;i++)t(r[i],"bubbled",n)}function s(e,t,n,i,a){for(var o=e&&t?r(e,t):null,s=[];e&&e!==o;)s.push(e),e=e._hostParent;for(var l=[];t&&t!==o;)l.push(t),t=t._hostParent;var c;for(c=0;c<s.length;c++)n(s[c],"bubbled",i);for(c=l.length;c-- >0;)n(l[c],"captured",a)}var l=n(3);n(1);e.exports={isAncestor:i,getLowestCommonAncestor:r,getParentInstance:a,traverseTwoPhase:o,traverseEnterLeave:s}},function(e,t,n){"use strict";function r(){this.reinitializeTransaction()}var i=n(5),a=n(12),o=n(35),s=n(9),l={initialize:s,close:function(){d.isBatchingUpdates=!1}},c={initialize:s,close:a.flushBatchedUpdates.bind(a)},u=[c,l];i(r.prototype,o,{getTransactionWrappers:function(){return u}});var h=new r,d={isBatchingUpdates:!1,batchedUpdates:function(e,t,n,r,i,a){var o=d.isBatchingUpdates;return d.isBatchingUpdates=!0,o?e(t,n,r,i,a):h.perform(e,null,t,n,r,i,a)}};e.exports=d},function(e,t,n){"use strict";function r(){E||(E=!0,w.EventEmitter.injectReactEventListener(v),w.EventPluginHub.injectEventPluginOrder(s),w.EventPluginUtils.injectComponentTree(d),w.EventPluginUtils.injectTreeTraversal(p),w.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:x,EnterLeaveEventPlugin:l,ChangeEventPlugin:o,SelectEventPlugin:_,BeforeInputEventPlugin:a}),w.HostComponent.injectGenericComponentClass(h),w.HostComponent.injectTextComponentClass(m),w.DOMProperty.injectDOMPropertyConfig(i),w.DOMProperty.injectDOMPropertyConfig(c),w.DOMProperty.injectDOMPropertyConfig(b),w.EmptyComponent.injectEmptyComponentFactory(function(e){return new f(e)}),w.Updates.injectReconcileTransaction(y),w.Updates.injectBatchingStrategy(g),w.Component.injectEnvironment(u))}var i=n(233),a=n(235),o=n(237),s=n(239),l=n(240),c=n(242),u=n(244),h=n(247),d=n(6),f=n(249),p=n(257),m=n(255),g=n(258),v=n(262),w=n(263),y=n(268),b=n(273),_=n(274),x=n(275),E=!1;e.exports={inject:r}},function(e,t,n){"use strict";var r="function"==typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103;e.exports=r},function(e,t,n){"use strict";function r(e){i.enqueueEvents(e),i.processEventQueue(!1)}var i=n(28),a={handleTopLevel:function(e,t,n,a){var o=i.extractEvents(e,t,n,a);r(o)}};e.exports=a},function(e,t,n){"use strict";function r(e){for(;e._hostParent;)e=e._hostParent;var t=h.getNodeFromInstance(e),n=t.parentNode;return h.getClosestInstanceFromNode(n)}function i(e,t){this.topLevelType=e,this.nativeEvent=t,this.ancestors=[]}function a(e){var t=f(e.nativeEvent),n=h.getClosestInstanceFromNode(t),i=n;do e.ancestors.push(i),i=i&&r(i);while(i);for(var a=0;a<e.ancestors.length;a++)n=e.ancestors[a],m._handleTopLevel(e.topLevelType,n,e.nativeEvent,f(e.nativeEvent))}function o(e){var t=p(window);e(t)}var s=n(5),l=n(67),c=n(7),u=n(17),h=n(6),d=n(12),f=n(55),p=n(217);s(i.prototype,{destructor:function(){this.topLevelType=null,this.nativeEvent=null,this.ancestors.length=0}}),u.addPoolingTo(i,u.twoArgumentPooler);var m={_enabled:!0,_handleTopLevel:null,WINDOW_HANDLE:c.canUseDOM?window:null,setHandleTopLevel:function(e){m._handleTopLevel=e},setEnabled:function(e){m._enabled=!!e},isEnabled:function(){return m._enabled},trapBubbledEvent:function(e,t,n){return n?l.listen(n,t,m.dispatchEvent.bind(null,e)):null},trapCapturedEvent:function(e,t,n){return n?l.capture(n,t,m.dispatchEvent.bind(null,e)):null},monitorScrollValue:function(e){var t=o.bind(null,e);l.listen(window,"scroll",t)},dispatchEvent:function(e,t){if(m._enabled){var n=i.getPooled(e,t);try{d.batchedUpdates(a,n)}finally{i.release(n)}}}};e.exports=m},function(e,t,n){"use strict";var r=n(21),i=n(28),a=n(46),o=n(49),s=n(79),l=n(33),c=n(81),u=n(12),h={Component:o.injection,DOMProperty:r.injection,EmptyComponent:s.injection,EventPluginHub:i.injection,EventPluginUtils:a.injection,EventEmitter:l.injection,HostComponent:c.injection,Updates:u.injection};e.exports=h},function(e,t,n){"use strict";var r=n(286),i=/\/?>/,a=/^<\!\-\-/,o={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(e){var t=r(e);return a.test(e)?e:e.replace(i," "+o.CHECKSUM_ATTR_NAME+'="'+t+'"$&')},canReuseMarkup:function(e,t){var n=t.getAttribute(o.CHECKSUM_ATTR_NAME);n=n&&parseInt(n,10);var i=r(e);return i===n}};e.exports=o},function(e,t,n){"use strict";function r(e,t,n){return{type:"INSERT_MARKUP",content:e,fromIndex:null,fromNode:null,toIndex:n,afterNode:t}}function i(e,t,n){return{type:"MOVE_EXISTING",content:null,fromIndex:e._mountIndex,fromNode:d.getHostNode(e),toIndex:n,afterNode:t}}function a(e,t){return{type:"REMOVE_NODE",content:null,fromIndex:e._mountIndex,fromNode:t,toIndex:null,afterNode:null}}function o(e){return{type:"SET_MARKUP",content:e,fromIndex:null,fromNode:null,toIndex:null,afterNode:null}}function s(e){return{type:"TEXT_CONTENT",content:e,fromIndex:null,fromNode:null,toIndex:null,afterNode:null}}function l(e,t){return t&&(e=e||[],e.push(t)),e}function c(e,t){h.processChildrenUpdates(e,t)}var u=n(3),h=n(49),d=(n(30),n(11),n(15),n(22)),f=n(243),p=(n(9),n(289)),m=(n(1),{Mixin:{_reconcilerInstantiateChildren:function(e,t,n){return f.instantiateChildren(e,t,n)},_reconcilerUpdateChildren:function(e,t,n,r,i,a){var o,s=0;return o=p(t,s),f.updateChildren(e,o,n,r,i,this,this._hostContainerInfo,a,s),o},mountChildren:function(e,t,n){var r=this._reconcilerInstantiateChildren(e,t,n);this._renderedChildren=r;var i=[],a=0;for(var o in r)if(r.hasOwnProperty(o)){var s=r[o],l=0,c=d.mountComponent(s,t,this,this._hostContainerInfo,n,l);s._mountIndex=a++,i.push(c)}return i},updateTextContent:function(e){var t=this._renderedChildren;f.unmountChildren(t,!1);for(var n in t)t.hasOwnProperty(n)&&u("118");var r=[s(e)];c(this,r)},updateMarkup:function(e){var t=this._renderedChildren;f.unmountChildren(t,!1);for(var n in t)t.hasOwnProperty(n)&&u("118");var r=[o(e)];c(this,r)},updateChildren:function(e,t,n){this._updateChildren(e,t,n)},_updateChildren:function(e,t,n){var r=this._renderedChildren,i={},a=[],o=this._reconcilerUpdateChildren(r,e,a,i,t,n);if(o||r){var s,u=null,h=0,f=0,p=0,m=null;for(s in o)if(o.hasOwnProperty(s)){var g=r&&r[s],v=o[s];g===v?(u=l(u,this.moveChild(g,m,h,f)),f=Math.max(g._mountIndex,f),g._mountIndex=h):(g&&(f=Math.max(g._mountIndex,f)),u=l(u,this._mountChildAtIndex(v,a[p],m,h,t,n)),p++),h++,m=d.getHostNode(v)}for(s in i)i.hasOwnProperty(s)&&(u=l(u,this._unmountChild(r[s],i[s])));u&&c(this,u),this._renderedChildren=o}},unmountChildren:function(e){var t=this._renderedChildren;f.unmountChildren(t,e),this._renderedChildren=null},moveChild:function(e,t,n,r){if(e._mountIndex<r)return i(e,t,n)},createChild:function(e,t,n){return r(n,t,e._mountIndex)},removeChild:function(e,t){return a(e,t)},_mountChildAtIndex:function(e,t,n,r,i,a){return e._mountIndex=r,this.createChild(e,n,t)},_unmountChild:function(e,t){var n=this.removeChild(e,t);return e._mountIndex=null,n}}});e.exports=m},function(e,t,n){"use strict";function r(e){return!(!e||"function"!=typeof e.attachRef||"function"!=typeof e.detachRef)}var i=n(3),a=(n(1),{addComponentAsRefTo:function(e,t,n){r(n)?void 0:i("119"),n.attachRef(t,e)},removeComponentAsRefFrom:function(e,t,n){r(n)?void 0:i("120");var a=n.getPublicInstance();a&&a.refs[t]===e.getPublicInstance()&&n.detachRef(t)}});e.exports=a},function(e,t,n){"use strict";var r="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";e.exports=r},function(e,t,n){"use strict";function r(e){this.reinitializeTransaction(),this.renderToStaticMarkup=!1,this.reactMountReady=a.getPooled(null),this.useCreateElement=e}var i=n(5),a=n(75),o=n(17),s=n(33),l=n(82),c=(n(11),n(35)),u=n(51),h={initialize:l.getSelectionInformation,close:l.restoreSelection},d={initialize:function(){var e=s.isEnabled();return s.setEnabled(!1),e},close:function(e){s.setEnabled(e)}},f={initialize:function(){this.reactMountReady.reset()},close:function(){this.reactMountReady.notifyAll()}},p=[h,d,f],m={getTransactionWrappers:function(){return p},getReactMountReady:function(){return this.reactMountReady},getUpdateQueue:function(){return u},checkpoint:function(){return this.reactMountReady.checkpoint()},rollback:function(e){this.reactMountReady.rollback(e)},destructor:function(){a.release(this.reactMountReady),this.reactMountReady=null}};i(r.prototype,c,m),o.addPoolingTo(r),e.exports=r},function(e,t,n){"use strict";function r(e,t,n){"function"==typeof e?e(t.getPublicInstance()):a.addComponentAsRefTo(t,e,n)}function i(e,t,n){"function"==typeof e?e(null):a.removeComponentAsRefFrom(t,e,n)}var a=n(266),o={};o.attachRefs=function(e,t){if(null!==t&&"object"==typeof t){var n=t.ref;null!=n&&r(n,e,t._owner)}},o.shouldUpdateRefs=function(e,t){var n=null,r=null;null!==e&&"object"==typeof e&&(n=e.ref,r=e._owner);var i=null,a=null;return null!==t&&"object"==typeof t&&(i=t.ref,a=t._owner),n!==i||"string"==typeof i&&a!==r},o.detachRefs=function(e,t){if(null!==t&&"object"==typeof t){var n=t.ref;null!=n&&i(n,e,t._owner)}},e.exports=o},function(e,t,n){"use strict";function r(e){this.reinitializeTransaction(),this.renderToStaticMarkup=e,this.useCreateElement=!1,this.updateQueue=new s(this)}var i=n(5),a=n(17),o=n(35),s=(n(11),n(271)),l=[],c={enqueue:function(){}},u={getTransactionWrappers:function(){return l},getReactMountReady:function(){return c},getUpdateQueue:function(){return this.updateQueue},destructor:function(){},checkpoint:function(){},rollback:function(){}};i(r.prototype,o,u),a.addPoolingTo(r),e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){}var a=n(51),o=(n(2),function(){function e(t){r(this,e),this.transaction=t}return e.prototype.isMounted=function(e){return!1},e.prototype.enqueueCallback=function(e,t,n){this.transaction.isInTransaction()&&a.enqueueCallback(e,t,n)},e.prototype.enqueueForceUpdate=function(e){this.transaction.isInTransaction()?a.enqueueForceUpdate(e):i(e,"forceUpdate")},e.prototype.enqueueReplaceState=function(e,t){this.transaction.isInTransaction()?a.enqueueReplaceState(e,t):i(e,"replaceState")},e.prototype.enqueueSetState=function(e,t){this.transaction.isInTransaction()?a.enqueueSetState(e,t):i(e,"setState")},e}());e.exports=o},function(e,t,n){"use strict";e.exports="15.4.2"},function(e,t,n){"use strict";var r={xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace"},i={accentHeight:"accent-height",accumulate:0,additive:0,alignmentBaseline:"alignment-baseline",allowReorder:"allowReorder",alphabetic:0,amplitude:0,arabicForm:"arabic-form",ascent:0,attributeName:"attributeName",attributeType:"attributeType",autoReverse:"autoReverse",azimuth:0,baseFrequency:"baseFrequency",baseProfile:"baseProfile",baselineShift:"baseline-shift",bbox:0,begin:0,bias:0,by:0,calcMode:"calcMode",capHeight:"cap-height",clip:0,clipPath:"clip-path",clipRule:"clip-rule",clipPathUnits:"clipPathUnits",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorProfile:"color-profile",colorRendering:"color-rendering",contentScriptType:"contentScriptType",contentStyleType:"contentStyleType",cursor:0,cx:0,cy:0,d:0,decelerate:0,descent:0,diffuseConstant:"diffuseConstant", +direction:0,display:0,divisor:0,dominantBaseline:"dominant-baseline",dur:0,dx:0,dy:0,edgeMode:"edgeMode",elevation:0,enableBackground:"enable-background",end:0,exponent:0,externalResourcesRequired:"externalResourcesRequired",fill:0,fillOpacity:"fill-opacity",fillRule:"fill-rule",filter:0,filterRes:"filterRes",filterUnits:"filterUnits",floodColor:"flood-color",floodOpacity:"flood-opacity",focusable:0,fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",format:0,from:0,fx:0,fy:0,g1:0,g2:0,glyphName:"glyph-name",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",glyphRef:"glyphRef",gradientTransform:"gradientTransform",gradientUnits:"gradientUnits",hanging:0,horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",ideographic:0,imageRendering:"image-rendering",in:0,in2:0,intercept:0,k:0,k1:0,k2:0,k3:0,k4:0,kernelMatrix:"kernelMatrix",kernelUnitLength:"kernelUnitLength",kerning:0,keyPoints:"keyPoints",keySplines:"keySplines",keyTimes:"keyTimes",lengthAdjust:"lengthAdjust",letterSpacing:"letter-spacing",lightingColor:"lighting-color",limitingConeAngle:"limitingConeAngle",local:0,markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",markerHeight:"markerHeight",markerUnits:"markerUnits",markerWidth:"markerWidth",mask:0,maskContentUnits:"maskContentUnits",maskUnits:"maskUnits",mathematical:0,mode:0,numOctaves:"numOctaves",offset:0,opacity:0,operator:0,order:0,orient:0,orientation:0,origin:0,overflow:0,overlinePosition:"overline-position",overlineThickness:"overline-thickness",paintOrder:"paint-order",panose1:"panose-1",pathLength:"pathLength",patternContentUnits:"patternContentUnits",patternTransform:"patternTransform",patternUnits:"patternUnits",pointerEvents:"pointer-events",points:0,pointsAtX:"pointsAtX",pointsAtY:"pointsAtY",pointsAtZ:"pointsAtZ",preserveAlpha:"preserveAlpha",preserveAspectRatio:"preserveAspectRatio",primitiveUnits:"primitiveUnits",r:0,radius:0,refX:"refX",refY:"refY",renderingIntent:"rendering-intent",repeatCount:"repeatCount",repeatDur:"repeatDur",requiredExtensions:"requiredExtensions",requiredFeatures:"requiredFeatures",restart:0,result:0,rotate:0,rx:0,ry:0,scale:0,seed:0,shapeRendering:"shape-rendering",slope:0,spacing:0,specularConstant:"specularConstant",specularExponent:"specularExponent",speed:0,spreadMethod:"spreadMethod",startOffset:"startOffset",stdDeviation:"stdDeviation",stemh:0,stemv:0,stitchTiles:"stitchTiles",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",string:0,stroke:0,strokeDasharray:"stroke-dasharray",strokeDashoffset:"stroke-dashoffset",strokeLinecap:"stroke-linecap",strokeLinejoin:"stroke-linejoin",strokeMiterlimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",surfaceScale:"surfaceScale",systemLanguage:"systemLanguage",tableValues:"tableValues",targetX:"targetX",targetY:"targetY",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",textLength:"textLength",to:0,transform:0,u1:0,u2:0,underlinePosition:"underline-position",underlineThickness:"underline-thickness",unicode:0,unicodeBidi:"unicode-bidi",unicodeRange:"unicode-range",unitsPerEm:"units-per-em",vAlphabetic:"v-alphabetic",vHanging:"v-hanging",vIdeographic:"v-ideographic",vMathematical:"v-mathematical",values:0,vectorEffect:"vector-effect",version:0,vertAdvY:"vert-adv-y",vertOriginX:"vert-origin-x",vertOriginY:"vert-origin-y",viewBox:"viewBox",viewTarget:"viewTarget",visibility:0,widths:0,wordSpacing:"word-spacing",writingMode:"writing-mode",x:0,xHeight:"x-height",x1:0,x2:0,xChannelSelector:"xChannelSelector",xlinkActuate:"xlink:actuate",xlinkArcrole:"xlink:arcrole",xlinkHref:"xlink:href",xlinkRole:"xlink:role",xlinkShow:"xlink:show",xlinkTitle:"xlink:title",xlinkType:"xlink:type",xmlBase:"xml:base",xmlns:0,xmlnsXlink:"xmlns:xlink",xmlLang:"xml:lang",xmlSpace:"xml:space",y:0,y1:0,y2:0,yChannelSelector:"yChannelSelector",z:0,zoomAndPan:"zoomAndPan"},a={Properties:{},DOMAttributeNamespaces:{xlinkActuate:r.xlink,xlinkArcrole:r.xlink,xlinkHref:r.xlink,xlinkRole:r.xlink,xlinkShow:r.xlink,xlinkTitle:r.xlink,xlinkType:r.xlink,xmlBase:r.xml,xmlLang:r.xml,xmlSpace:r.xml},DOMAttributeNames:{}};Object.keys(i).forEach(function(e){a.Properties[e]=0,i[e]&&(a.DOMAttributeNames[e]=i[e])}),e.exports=a},function(e,t,n){"use strict";function r(e){if("selectionStart"in e&&l.hasSelectionCapabilities(e))return{start:e.selectionStart,end:e.selectionEnd};if(window.getSelection){var t=window.getSelection();return{anchorNode:t.anchorNode,anchorOffset:t.anchorOffset,focusNode:t.focusNode,focusOffset:t.focusOffset}}if(document.selection){var n=document.selection.createRange();return{parentElement:n.parentElement(),text:n.text,top:n.boundingTop,left:n.boundingLeft}}}function i(e,t){if(w||null==m||m!==u())return null;var n=r(m);if(!v||!d(v,n)){v=n;var i=c.getPooled(p.select,g,e,t);return i.type="select",i.target=m,a.accumulateTwoPhaseDispatches(i),i}return null}var a=n(29),o=n(7),s=n(6),l=n(82),c=n(14),u=n(69),h=n(91),d=n(39),f=o.canUseDOM&&"documentMode"in document&&document.documentMode<=11,p={select:{phasedRegistrationNames:{bubbled:"onSelect",captured:"onSelectCapture"},dependencies:["topBlur","topContextMenu","topFocus","topKeyDown","topKeyUp","topMouseDown","topMouseUp","topSelectionChange"]}},m=null,g=null,v=null,w=!1,y=!1,b={eventTypes:p,extractEvents:function(e,t,n,r){if(!y)return null;var a=t?s.getNodeFromInstance(t):window;switch(e){case"topFocus":(h(a)||"true"===a.contentEditable)&&(m=a,g=t,v=null);break;case"topBlur":m=null,g=null,v=null;break;case"topMouseDown":w=!0;break;case"topContextMenu":case"topMouseUp":return w=!1,i(n,r);case"topSelectionChange":if(f)break;case"topKeyDown":case"topKeyUp":return i(n,r)}return null},didPutListener:function(e,t,n){"onSelect"===t&&(y=!0)}};e.exports=b},function(e,t,n){"use strict";function r(e){return"."+e._rootNodeID}function i(e){return"button"===e||"input"===e||"select"===e||"textarea"===e}var a=n(3),o=n(67),s=n(29),l=n(6),c=n(276),u=n(277),h=n(14),d=n(280),f=n(282),p=n(34),m=n(279),g=n(283),v=n(284),w=n(31),y=n(285),b=n(9),_=n(53),x=(n(1),{}),E={};["abort","animationEnd","animationIteration","animationStart","blur","canPlay","canPlayThrough","click","contextMenu","copy","cut","doubleClick","drag","dragEnd","dragEnter","dragExit","dragLeave","dragOver","dragStart","drop","durationChange","emptied","encrypted","ended","error","focus","input","invalid","keyDown","keyPress","keyUp","load","loadedData","loadedMetadata","loadStart","mouseDown","mouseMove","mouseOut","mouseOver","mouseUp","paste","pause","play","playing","progress","rateChange","reset","scroll","seeked","seeking","stalled","submit","suspend","timeUpdate","touchCancel","touchEnd","touchMove","touchStart","transitionEnd","volumeChange","waiting","wheel"].forEach(function(e){var t=e[0].toUpperCase()+e.slice(1),n="on"+t,r="top"+t,i={phasedRegistrationNames:{bubbled:n,captured:n+"Capture"},dependencies:[r]};x[e]=i,E[r]=i});var C={},k={eventTypes:x,extractEvents:function(e,t,n,r){var i=E[e];if(!i)return null;var o;switch(e){case"topAbort":case"topCanPlay":case"topCanPlayThrough":case"topDurationChange":case"topEmptied":case"topEncrypted":case"topEnded":case"topError":case"topInput":case"topInvalid":case"topLoad":case"topLoadedData":case"topLoadedMetadata":case"topLoadStart":case"topPause":case"topPlay":case"topPlaying":case"topProgress":case"topRateChange":case"topReset":case"topSeeked":case"topSeeking":case"topStalled":case"topSubmit":case"topSuspend":case"topTimeUpdate":case"topVolumeChange":case"topWaiting":o=h;break;case"topKeyPress":if(0===_(n))return null;case"topKeyDown":case"topKeyUp":o=f;break;case"topBlur":case"topFocus":o=d;break;case"topClick":if(2===n.button)return null;case"topDoubleClick":case"topMouseDown":case"topMouseMove":case"topMouseUp":case"topMouseOut":case"topMouseOver":case"topContextMenu":o=p;break;case"topDrag":case"topDragEnd":case"topDragEnter":case"topDragExit":case"topDragLeave":case"topDragOver":case"topDragStart":case"topDrop":o=m;break;case"topTouchCancel":case"topTouchEnd":case"topTouchMove":case"topTouchStart":o=g;break;case"topAnimationEnd":case"topAnimationIteration":case"topAnimationStart":o=c;break;case"topTransitionEnd":o=v;break;case"topScroll":o=w;break;case"topWheel":o=y;break;case"topCopy":case"topCut":case"topPaste":o=u}o?void 0:a("86",e);var l=o.getPooled(i,t,n,r);return s.accumulateTwoPhaseDispatches(l),l},didPutListener:function(e,t,n){if("onClick"===t&&!i(e._tag)){var a=r(e),s=l.getNodeFromInstance(e);C[a]||(C[a]=o.listen(s,"click",b))}},willDeleteListener:function(e,t){if("onClick"===t&&!i(e._tag)){var n=r(e);C[n].remove(),delete C[n]}}};e.exports=k},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(14),a={animationName:null,elapsedTime:null,pseudoElement:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(14),a={clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(14),a={data:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(34),a={dataTransfer:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(31),a={relatedTarget:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(14),a={data:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(31),a=n(53),o=n(290),s=n(54),l={key:o,location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:s,charCode:function(e){return"keypress"===e.type?a(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?a(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}};i.augmentClass(r,l),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(31),a=n(54),o={touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:a};i.augmentClass(r,o),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(14),a={propertyName:null,elapsedTime:null,pseudoElement:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){return i.call(this,e,t,n,r)}var i=n(34),a={deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:null,deltaMode:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e){for(var t=1,n=0,r=0,a=e.length,o=a&-4;r<o;){for(var s=Math.min(r+4096,o);r<s;r+=4)n+=(t+=e.charCodeAt(r))+(t+=e.charCodeAt(r+1))+(t+=e.charCodeAt(r+2))+(t+=e.charCodeAt(r+3));t%=i,n%=i}for(;r<a;r++)n+=t+=e.charCodeAt(r);return t%=i,n%=i,t|n<<16}var i=65521;e.exports=r},function(e,t,n){"use strict";function r(e,t,n){var r=null==t||"boolean"==typeof t||""===t;if(r)return"";var i=isNaN(t);if(i||0===t||a.hasOwnProperty(e)&&a[e])return""+t;if("string"==typeof t){t=t.trim()}return t+"px"}var i=n(74),a=(n(2),i.isUnitlessNumber);e.exports=r},function(e,t,n){"use strict";function r(e){if(null==e)return null;if(1===e.nodeType)return e;var t=o.get(e);return t?(t=s(t),t?a.getNodeFromInstance(t):null):void("function"==typeof e.render?i("44"):i("45",Object.keys(e)))}var i=n(3),a=(n(15),n(6)),o=n(30),s=n(88);n(1),n(2);e.exports=r},function(e,t,n){"use strict";(function(t){function r(e,t,n,r){if(e&&"object"==typeof e){var i=e,a=void 0===i[n];a&&null!=t&&(i[n]=t)}}function i(e,t){if(null==e)return e;var n={};return a(e,r,n),n}var a=(n(47),n(93));n(2);"undefined"!=typeof t&&t.env,1,e.exports=i}).call(t,n(73))},function(e,t,n){"use strict";function r(e){if(e.key){var t=a[e.key]||e.key;if("Unidentified"!==t)return t}if("keypress"===e.type){var n=i(e);return 13===n?"Enter":String.fromCharCode(n)}return"keydown"===e.type||"keyup"===e.type?o[e.keyCode]||"Unidentified":""}var i=n(53),a={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},o={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"};e.exports=r},function(e,t,n){"use strict";function r(e){var t=e&&(i&&e[i]||e[a]);if("function"==typeof t)return t}var i="function"==typeof Symbol&&Symbol.iterator,a="@@iterator";e.exports=r},function(e,t,n){"use strict";function r(){return i++}var i=1;e.exports=r},function(e,t,n){"use strict";function r(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function i(e){for(;e;){if(e.nextSibling)return e.nextSibling;e=e.parentNode}}function a(e,t){for(var n=r(e),a=0,o=0;n;){if(3===n.nodeType){if(o=a+n.textContent.length,a<=t&&o>=t)return{node:n,offset:t-a};a=o}n=r(i(n))}}e.exports=a},function(e,t,n){"use strict";function r(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n["ms"+e]="MS"+t,n["O"+e]="o"+t.toLowerCase(),n}function i(e){if(s[e])return s[e];if(!o[e])return e;var t=o[e];for(var n in t)if(t.hasOwnProperty(n)&&n in l)return s[e]=t[n];return""}var a=n(7),o={animationend:r("Animation","AnimationEnd"),animationiteration:r("Animation","AnimationIteration"),animationstart:r("Animation","AnimationStart"),transitionend:r("Transition","TransitionEnd")},s={},l={};a.canUseDOM&&(l=document.createElement("div").style,"AnimationEvent"in window||(delete o.animationend.animation,delete o.animationiteration.animation,delete o.animationstart.animation),"TransitionEvent"in window||delete o.transitionend.transition),e.exports=i},function(e,t,n){"use strict";function r(e){return'"'+i(e)+'"'}var i=n(36);e.exports=r},function(e,t,n){"use strict";var r=n(83);e.exports=r.renderSubtreeIntoContainer},function(e,t,n){"use strict";t.__esModule=!0;var r=n(18),i={contextTypes:{history:r.history},componentWillMount:function(){this.history=this.context.history}};t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s=n(4),l=r(s),c=n(94),u=r(c),h=function(e){function t(){i(this,t),e.apply(this,arguments)}return a(t,e),t.prototype.render=function(){return l.default.createElement(u.default,o({},this.props,{onlyActiveOnIndex:!0}))},t}(s.Component);t.default=h,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var o=n(8),s=(r(o),n(10)),l=r(s),c=n(4),u=r(c),h=n(95),d=r(h),f=n(18),p=u.default.PropTypes,m=p.string,g=p.object,v=function(e){function t(){i(this,t),e.apply(this,arguments)}return a(t,e),t.prototype.render=function(){l.default(!1)},t}(c.Component);v.propTypes={to:m.isRequired,query:g,state:g,onEnter:f.falsy,children:f.falsy},v.createRouteFromReactElement=function(e,t){t&&(t.indexRoute=d.default.createRouteFromReactElement(e))},t.default=v,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var o=n(8),s=(r(o),n(10)),l=r(s),c=n(4),u=r(c),h=n(16),d=n(18),f=u.default.PropTypes.func,p=function(e){function t(){i(this,t),e.apply(this,arguments)}return a(t,e),t.prototype.render=function(){l.default(!1)},t}(c.Component);p.propTypes={path:d.falsy,component:d.component,components:d.components,getComponent:f,getComponents:f},p.createRouteFromReactElement=function(e,t){t&&(t.indexRoute=h.createRouteFromReactElement(e))},t.default=p,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(4),a=r(i),o=n(10),s=r(o),l=a.default.PropTypes.object,c={contextTypes:{history:l.isRequired,route:l},propTypes:{route:l},componentDidMount:function(){this.routerWillLeave?void 0:s.default(!1);var e=this.props.route||this.context.route;e?void 0:s.default(!1),this._unlistenBeforeLeavingRoute=this.context.history.listenBeforeLeavingRoute(e,this.routerWillLeave)},componentWillUnmount:function(){this._unlistenBeforeLeavingRoute&&this._unlistenBeforeLeavingRoute()}};t.default=c,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var o=n(10),s=r(o),l=n(4),c=r(l),u=n(16),h=n(18),d=c.default.PropTypes,f=d.string,p=d.func,m=function(e){function t(){i(this,t),e.apply(this,arguments)}return a(t,e),t.prototype.render=function(){s.default(!1)},t}(l.Component);m.createRouteFromReactElement=u.createRouteFromReactElement,m.propTypes={path:f,component:h.component,components:h.components,getComponent:p,getComponents:p},t.default=m,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(4),a=r(i),o=a.default.PropTypes.object,s={propTypes:{route:o.isRequired},childContextTypes:{route:o.isRequired},getChildContext:function(){return{route:this.props.route}}};t.default=s,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l=n(8),c=(r(l),n(4)),u=r(c),h=n(226),d=r(h),f=n(16),p=n(96),m=r(p),g=n(60),v=r(g),w=n(18),y=u.default.PropTypes,b=y.func,_=y.object,x=function(e){function t(n,r){a(this,t),e.call(this,n,r),this.state={location:null,routes:null,params:null,components:null}}return o(t,e),t.prototype.handleError=function(e){if(!this.props.onError)throw e;this.props.onError.call(this,e)},t.prototype.componentWillMount=function(){var e=this,t=this.props,n=t.history,r=t.children,i=t.routes,a=t.parseQueryString,o=t.stringifyQuery,s=n?function(){return n}:d.default;this.history=v.default(s)({routes:f.createRoutes(i||r),parseQueryString:a,stringifyQuery:o}),this._unlisten=this.history.listen(function(t,n){t?e.handleError(t):e.setState(n,e.props.onUpdate)})},t.prototype.componentWillReceiveProps=function(e){},t.prototype.componentWillUnmount=function(){this._unlisten&&this._unlisten()},t.prototype.render=function(){var e=this.state,n=e.location,r=e.routes,a=e.params,o=e.components,l=this.props,c=l.RoutingContext,h=l.createElement,d=i(l,["RoutingContext","createElement"]);return null==n?null:(Object.keys(t.propTypes).forEach(function(e){return delete d[e]}),u.default.createElement(c,s({},d,{history:this.history,createElement:h,location:n,routes:r,params:a,components:o})))},t}(c.Component);x.propTypes={history:_,children:w.routes,routes:w.routes,RoutingContext:b.isRequired,createElement:b,onError:b,onUpdate:b,parseQueryString:b,stringifyQuery:b},x.defaultProps={RoutingContext:m.default},t.default=x,e.exports=t.default},function(e,t,n){"use strict";function r(e,t){return function(n,r,i){e.apply(t,arguments),e.length<3&&i()}}function i(e){return e.reduce(function(e,t){return t.onEnter&&e.push(r(t.onEnter,t)),e},[])}function a(e,t,n){function r(e,t,n){o={pathname:t,query:n,state:e}}var a=i(e);if(!a.length)return void n();var o=void 0;s.loopAsync(a.length,function(e,n,i){a[e](t,r,function(e){e||o?i(e,o):n()})},n)}function o(e){for(var t=0,n=e.length;t<n;++t)e[t].onLeave&&e[t].onLeave.call(e[t])}t.__esModule=!0,t.runEnterHooks=a,t.runLeaveHooks=o;var s=n(59)},function(e,t,n){"use strict";function r(e,t,n){if(!e.path)return!1;var r=a.getParamNames(e.path);return r.some(function(e){return t.params[e]!==n.params[e]})}function i(e,t){var n=e&&e.routes,i=t.routes,a=void 0,o=void 0;return n?(a=n.filter(function(n){return i.indexOf(n)===-1||r(n,e,t)}),a.reverse(),o=i.filter(function(e){return n.indexOf(e)===-1||a.indexOf(e)!==-1})):(a=[],o=i),{leaveRoutes:a,enterRoutes:o}}t.__esModule=!0;var a=n(32);t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e,t,n){t.component||t.components?n(null,t.component||t.components):t.getComponent?t.getComponent(e,n):t.getComponents?t.getComponents(e,n):n()}function i(e,t){a.mapAsync(e.routes,function(t,n,i){r(e.location,t,i)},t)}t.__esModule=!0;var a=n(59);t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e,t){var n={};if(!e.path)return n;var r=i.getParamNames(e.path);for(var a in t)t.hasOwnProperty(a)&&r.indexOf(a)!==-1&&(n[a]=t[a]);return n}t.__esModule=!0;var i=n(32);t.default=r,e.exports=t.default},function(e,t,n){"use strict";function r(e,t){if(e==t)return!0;if(null==e||null==t)return!1;if(Array.isArray(e))return Array.isArray(t)&&e.length===t.length&&e.every(function(e,n){return r(e,t[n])});if("object"==typeof e){for(var n in e)if(e.hasOwnProperty(n))if(void 0===e[n]){if(void 0!==t[n])return!1}else{if(!t.hasOwnProperty(n))return!1;if(!r(e[n],t[n]))return!1}return!0}return String(e)===String(t)}function i(e,t,n){return e.every(function(e,r){return String(t[r])===String(n[e])})}function a(e,t,n){for(var r=e,a=[],o=[],s=0,l=t.length;s<l;++s){var u=t[s],h=u.path||"";if("/"===h.charAt(0)&&(r=e,a=[],o=[]),null!==r){var d=c.matchPattern(h,r);r=d.remainingPathname,a=[].concat(a,d.paramNames),o=[].concat(o,d.paramValues)}if(""===r&&u.path&&i(a,o,n))return s}return null}function o(e,t,n,r){var i=a(e,t,n);return null!==i&&(!r||t.slice(i+1).every(function(e){return!e.path}))}function s(e,t){return null==t?null==e:null==e||r(e,t)}function l(e,t,n,r,i,a){return null!=r&&(!!o(e,i,a,n)&&s(t,r.query))}t.__esModule=!0;var c=n(32);t.default=l,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n=e.routes,r=e.location,i=e.parseQueryString,o=e.stringifyQuery,l=e.basename;r?void 0:s.default(!1);var c=m({routes:d.createRoutes(n),parseQueryString:i,stringifyQuery:o,basename:l});"string"==typeof r&&(r=c.createLocation(r)),c.match(r,function(e,n,r){t(e,n,r&&a({},r,{history:c}))})}t.__esModule=!0;var a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=n(10),s=r(o),l=n(228),c=r(l),u=n(229),h=r(u),d=n(16),f=n(60),p=r(f),m=p.default(h.default(c.default));t.default=i,e.exports=t.default},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t,n){e.childRoutes?n(null,e.childRoutes):e.getChildRoutes?e.getChildRoutes(t,function(e,t){n(e,!e&&f.createRoutes(t))}):n()}function a(e,t,n){e.indexRoute?n(null,e.indexRoute):e.getIndexRoute?e.getIndexRoute(t,function(e,t){n(e,!e&&f.createRoutes(t)[0])}):e.childRoutes?!function(){var r=e.childRoutes.filter(function(e){return!e.hasOwnProperty("path")});h.loopAsync(r.length,function(e,n,i){a(r[e],t,function(t,a){if(t||a){var o=[r[e]].concat(Array.isArray(a)?a:[a]);i(t,o)}else n()})},function(e,t){n(null,t)})}():n()}function o(e,t,n){return t.reduce(function(e,t,r){var i=n&&n[r];return Array.isArray(e[t])?e[t].push(i):t in e?e[t]=[e[t],i]:e[t]=i,e},e)}function s(e,t){return o({},e,t)}function l(e,t,n,r,o,l){var u=e.path||"";if("/"===u.charAt(0)&&(n=t.pathname,r=[],o=[]),null!==n){var h=d.matchPattern(u,n);if(n=h.remainingPathname,r=[].concat(r,h.paramNames),o=[].concat(o,h.paramValues),""===n&&e.path){var f=function(){var n={routes:[e],params:s(r,o)};return a(e,t,function(e,t){if(e)l(e);else{if(Array.isArray(t)){var r;(r=n.routes).push.apply(r,t)}else t&&n.routes.push(t);l(null,n)}}),{v:void 0}}();if("object"==typeof f)return f.v}}null!=n||e.childRoutes?i(e,t,function(i,a){i?l(i):a?c(a,t,function(t,n){t?l(t):n?(n.routes.unshift(e),l(null,n)):l()},n,r,o):l()}):l()}function c(e,t,n){var r=arguments.length<=3||void 0===arguments[3]?t.pathname:arguments[3],i=arguments.length<=4||void 0===arguments[4]?[]:arguments[4],a=arguments.length<=5||void 0===arguments[5]?[]:arguments[5];return function(){h.loopAsync(e.length,function(n,o,s){l(e[n],t,r,i,a,function(e,t){e||t?s(e,t):o()})},n)}()}t.__esModule=!0;var u=n(8),h=(r(u),n(59)),d=n(32),f=n(16);t.default=c,e.exports=t.default},function(e,t,n){"use strict";function r(e){var t=/[=:]/g,n={"=":"=0",":":"=2"},r=(""+e).replace(t,function(e){return n[e]});return"$"+r}function i(e){var t=/(=0|=2)/g,n={"=0":"=","=2":":"},r="."===e[0]&&"$"===e[1]?e.substring(2):e.substring(1);return(""+r).replace(t,function(e){return n[e]})}var a={escape:r,unescape:i};e.exports=a},function(e,t,n){"use strict";var r=n(25),i=(n(1),function(e){var t=this;if(t.instancePool.length){var n=t.instancePool.pop();return t.call(n,e),n}return new t(e)}),a=function(e,t){var n=this;if(n.instancePool.length){var r=n.instancePool.pop();return n.call(r,e,t),r}return new n(e,t)},o=function(e,t,n){var r=this;if(r.instancePool.length){var i=r.instancePool.pop();return r.call(i,e,t,n),i}return new r(e,t,n)},s=function(e,t,n,r){var i=this;if(i.instancePool.length){var a=i.instancePool.pop();return i.call(a,e,t,n,r),a}return new i(e,t,n,r)},l=function(e){var t=this;e instanceof t?void 0:r("25"),e.destructor(),t.instancePool.length<t.poolSize&&t.instancePool.push(e)},c=10,u=i,h=function(e,t){var n=e;return n.instancePool=[],n.getPooled=t||u,n.poolSize||(n.poolSize=c),n.release=l,n},d={addPoolingTo:h,oneArgumentPooler:i,twoArgumentPooler:a,threeArgumentPooler:o,fourArgumentPooler:s};e.exports=d},function(e,t,n){"use strict";function r(e){return(""+e).replace(b,"$&/")}function i(e,t){this.func=e,this.context=t,this.count=0}function a(e,t,n){var r=e.func,i=e.context;r.call(i,t,e.count++)}function o(e,t,n){if(null==e)return e;var r=i.getPooled(t,n);v(e,a,r),i.release(r)}function s(e,t,n,r){this.result=e,this.keyPrefix=t,this.func=n,this.context=r,this.count=0}function l(e,t,n){var i=e.result,a=e.keyPrefix,o=e.func,s=e.context,l=o.call(s,t,e.count++);Array.isArray(l)?c(l,i,n,g.thatReturnsArgument):null!=l&&(m.isValidElement(l)&&(l=m.cloneAndReplaceKey(l,a+(!l.key||t&&t.key===l.key?"":r(l.key)+"/")+n)),i.push(l))}function c(e,t,n,i,a){var o="";null!=n&&(o=r(n)+"/");var c=s.getPooled(t,o,i,a);v(e,l,c),s.release(c)}function u(e,t,n){if(null==e)return e;var r=[];return c(e,r,null,t,n),r}function h(e,t,n){return null}function d(e,t){return v(e,h,null)}function f(e){var t=[];return c(e,t,null,g.thatReturnsArgument),t}var p=n(313),m=n(24),g=n(9),v=n(322),w=p.twoArgumentPooler,y=p.fourArgumentPooler,b=/\/+/g;i.prototype.destructor=function(){this.func=null,this.context=null,this.count=0},p.addPoolingTo(i,w),s.prototype.destructor=function(){this.result=null,this.keyPrefix=null,this.func=null,this.context=null,this.count=0},p.addPoolingTo(s,y);var _={forEach:o,map:u,mapIntoWithKeyPrefixInternal:c,count:d,toArray:f};e.exports=_},function(e,t,n){"use strict";function r(e){return e}function i(e,t){var n=b.hasOwnProperty(t)?b[t]:null;x.hasOwnProperty(t)&&("OVERRIDE_BASE"!==n?d("73",t):void 0),e&&("DEFINE_MANY"!==n&&"DEFINE_MANY_MERGED"!==n?d("74",t):void 0)}function a(e,t){if(t){"function"==typeof t?d("75"):void 0,m.isValidElement(t)?d("76"):void 0;var n=e.prototype,r=n.__reactAutoBindPairs;t.hasOwnProperty(w)&&_.mixins(e,t.mixins);for(var a in t)if(t.hasOwnProperty(a)&&a!==w){var o=t[a],s=n.hasOwnProperty(a);if(i(s,a),_.hasOwnProperty(a))_[a](e,o);else{var u=b.hasOwnProperty(a),h="function"==typeof o,f=h&&!u&&!s&&t.autobind!==!1;if(f)r.push(a,o),n[a]=o;else if(s){var p=b[a];!u||"DEFINE_MANY_MERGED"!==p&&"DEFINE_MANY"!==p?d("77",p,a):void 0,"DEFINE_MANY_MERGED"===p?n[a]=l(n[a],o):"DEFINE_MANY"===p&&(n[a]=c(n[a],o))}else n[a]=o}}}else;}function o(e,t){if(t)for(var n in t){var r=t[n];if(t.hasOwnProperty(n)){var i=n in _;i?d("78",n):void 0;var a=n in e;a?d("79",n):void 0,e[n]=r}}}function s(e,t){e&&t&&"object"==typeof e&&"object"==typeof t?void 0:d("80");for(var n in t)t.hasOwnProperty(n)&&(void 0!==e[n]?d("81",n):void 0,e[n]=t[n]);return e}function l(e,t){return function(){var n=e.apply(this,arguments),r=t.apply(this,arguments);if(null==n)return r;if(null==r)return n;var i={};return s(i,n),s(i,r),i}}function c(e,t){return function(){e.apply(this,arguments),t.apply(this,arguments)}}function u(e,t){var n=t.bind(e);return n}function h(e){for(var t=e.__reactAutoBindPairs,n=0;n<t.length;n+=2){var r=t[n],i=t[n+1];e[r]=u(e,i)}}var d=n(25),f=n(5),p=n(61),m=n(24),g=(n(100),n(62)),v=n(26),w=(n(1),n(2),"mixins"),y=[],b={mixins:"DEFINE_MANY",statics:"DEFINE_MANY",propTypes:"DEFINE_MANY",contextTypes:"DEFINE_MANY",childContextTypes:"DEFINE_MANY",getDefaultProps:"DEFINE_MANY_MERGED",getInitialState:"DEFINE_MANY_MERGED",getChildContext:"DEFINE_MANY_MERGED",render:"DEFINE_ONCE",componentWillMount:"DEFINE_MANY",componentDidMount:"DEFINE_MANY",componentWillReceiveProps:"DEFINE_MANY",shouldComponentUpdate:"DEFINE_ONCE",componentWillUpdate:"DEFINE_MANY",componentDidUpdate:"DEFINE_MANY",componentWillUnmount:"DEFINE_MANY",updateComponent:"OVERRIDE_BASE"},_={displayName:function(e,t){e.displayName=t},mixins:function(e,t){if(t)for(var n=0;n<t.length;n++)a(e,t[n])},childContextTypes:function(e,t){e.childContextTypes=f({},e.childContextTypes,t); +},contextTypes:function(e,t){e.contextTypes=f({},e.contextTypes,t)},getDefaultProps:function(e,t){e.getDefaultProps?e.getDefaultProps=l(e.getDefaultProps,t):e.getDefaultProps=t},propTypes:function(e,t){e.propTypes=f({},e.propTypes,t)},statics:function(e,t){o(e,t)},autobind:function(){}},x={replaceState:function(e,t){this.updater.enqueueReplaceState(this,e),t&&this.updater.enqueueCallback(this,t,"replaceState")},isMounted:function(){return this.updater.isMounted(this)}},E=function(){};f(E.prototype,p.prototype,x);var C={createClass:function(e){var t=r(function(e,n,r){this.__reactAutoBindPairs.length&&h(this),this.props=e,this.context=n,this.refs=v,this.updater=r||g,this.state=null;var i=this.getInitialState?this.getInitialState():null;"object"!=typeof i||Array.isArray(i)?d("82",t.displayName||"ReactCompositeComponent"):void 0,this.state=i});t.prototype=new E,t.prototype.constructor=t,t.prototype.__reactAutoBindPairs=[],y.forEach(a.bind(null,t)),a(t,e),t.getDefaultProps&&(t.defaultProps=t.getDefaultProps()),t.prototype.render?void 0:d("83");for(var n in b)t.prototype[n]||(t.prototype[n]=null);return t},injection:{injectMixin:function(e){y.push(e)}}};e.exports=C},function(e,t,n){"use strict";var r=n(24),i=r.createFactory,a={a:i("a"),abbr:i("abbr"),address:i("address"),area:i("area"),article:i("article"),aside:i("aside"),audio:i("audio"),b:i("b"),base:i("base"),bdi:i("bdi"),bdo:i("bdo"),big:i("big"),blockquote:i("blockquote"),body:i("body"),br:i("br"),button:i("button"),canvas:i("canvas"),caption:i("caption"),cite:i("cite"),code:i("code"),col:i("col"),colgroup:i("colgroup"),data:i("data"),datalist:i("datalist"),dd:i("dd"),del:i("del"),details:i("details"),dfn:i("dfn"),dialog:i("dialog"),div:i("div"),dl:i("dl"),dt:i("dt"),em:i("em"),embed:i("embed"),fieldset:i("fieldset"),figcaption:i("figcaption"),figure:i("figure"),footer:i("footer"),form:i("form"),h1:i("h1"),h2:i("h2"),h3:i("h3"),h4:i("h4"),h5:i("h5"),h6:i("h6"),head:i("head"),header:i("header"),hgroup:i("hgroup"),hr:i("hr"),html:i("html"),i:i("i"),iframe:i("iframe"),img:i("img"),input:i("input"),ins:i("ins"),kbd:i("kbd"),keygen:i("keygen"),label:i("label"),legend:i("legend"),li:i("li"),link:i("link"),main:i("main"),map:i("map"),mark:i("mark"),menu:i("menu"),menuitem:i("menuitem"),meta:i("meta"),meter:i("meter"),nav:i("nav"),noscript:i("noscript"),object:i("object"),ol:i("ol"),optgroup:i("optgroup"),option:i("option"),output:i("output"),p:i("p"),param:i("param"),picture:i("picture"),pre:i("pre"),progress:i("progress"),q:i("q"),rp:i("rp"),rt:i("rt"),ruby:i("ruby"),s:i("s"),samp:i("samp"),script:i("script"),section:i("section"),select:i("select"),small:i("small"),source:i("source"),span:i("span"),strong:i("strong"),style:i("style"),sub:i("sub"),summary:i("summary"),sup:i("sup"),table:i("table"),tbody:i("tbody"),td:i("td"),textarea:i("textarea"),tfoot:i("tfoot"),th:i("th"),thead:i("thead"),time:i("time"),title:i("title"),tr:i("tr"),track:i("track"),u:i("u"),ul:i("ul"),var:i("var"),video:i("video"),wbr:i("wbr"),circle:i("circle"),clipPath:i("clipPath"),defs:i("defs"),ellipse:i("ellipse"),g:i("g"),image:i("image"),line:i("line"),linearGradient:i("linearGradient"),mask:i("mask"),path:i("path"),pattern:i("pattern"),polygon:i("polygon"),polyline:i("polyline"),radialGradient:i("radialGradient"),rect:i("rect"),stop:i("stop"),svg:i("svg"),text:i("text"),tspan:i("tspan")};e.exports=a},function(e,t,n){"use strict";function r(e,t){return e===t?0!==e||1/e===1/t:e!==e&&t!==t}function i(e){this.message=e,this.stack=""}function a(e){function t(t,n,r,a,o,s,l){a=a||S,s=s||r;if(null==n[r]){var c=x[o];return t?new i(null===n[r]?"The "+c+" `"+s+"` is marked as required "+("in `"+a+"`, but its value is `null`."):"The "+c+" `"+s+"` is marked as required in "+("`"+a+"`, but its value is `undefined`.")):null}return e(n,r,a,o,s)}var n=t.bind(null,!1);return n.isRequired=t.bind(null,!0),n}function o(e){function t(t,n,r,a,o,s){var l=t[n],c=w(l);if(c!==e){var u=x[a],h=y(l);return new i("Invalid "+u+" `"+o+"` of type "+("`"+h+"` supplied to `"+r+"`, expected ")+("`"+e+"`."))}return null}return a(t)}function s(){return a(C.thatReturns(null))}function l(e){function t(t,n,r,a,o){if("function"!=typeof e)return new i("Property `"+o+"` of component `"+r+"` has invalid PropType notation inside arrayOf.");var s=t[n];if(!Array.isArray(s)){var l=x[a],c=w(s);return new i("Invalid "+l+" `"+o+"` of type "+("`"+c+"` supplied to `"+r+"`, expected an array."))}for(var u=0;u<s.length;u++){var h=e(s,u,r,a,o+"["+u+"]",E);if(h instanceof Error)return h}return null}return a(t)}function c(){function e(e,t,n,r,a){var o=e[t];if(!_.isValidElement(o)){var s=x[r],l=w(o);return new i("Invalid "+s+" `"+a+"` of type "+("`"+l+"` supplied to `"+n+"`, expected a single ReactElement."))}return null}return a(e)}function u(e){function t(t,n,r,a,o){if(!(t[n]instanceof e)){var s=x[a],l=e.name||S,c=b(t[n]);return new i("Invalid "+s+" `"+o+"` of type "+("`"+c+"` supplied to `"+r+"`, expected ")+("instance of `"+l+"`."))}return null}return a(t)}function h(e){function t(t,n,a,o,s){for(var l=t[n],c=0;c<e.length;c++)if(r(l,e[c]))return null;var u=x[o],h=JSON.stringify(e);return new i("Invalid "+u+" `"+s+"` of value `"+l+"` "+("supplied to `"+a+"`, expected one of "+h+"."))}return Array.isArray(e)?a(t):C.thatReturnsNull}function d(e){function t(t,n,r,a,o){if("function"!=typeof e)return new i("Property `"+o+"` of component `"+r+"` has invalid PropType notation inside objectOf.");var s=t[n],l=w(s);if("object"!==l){var c=x[a];return new i("Invalid "+c+" `"+o+"` of type "+("`"+l+"` supplied to `"+r+"`, expected an object."))}for(var u in s)if(s.hasOwnProperty(u)){var h=e(s,u,r,a,o+"."+u,E);if(h instanceof Error)return h}return null}return a(t)}function f(e){function t(t,n,r,a,o){for(var s=0;s<e.length;s++){var l=e[s];if(null==l(t,n,r,a,o,E))return null}var c=x[a];return new i("Invalid "+c+" `"+o+"` supplied to "+("`"+r+"`."))}return Array.isArray(e)?a(t):C.thatReturnsNull}function p(){function e(e,t,n,r,a){if(!g(e[t])){var o=x[r];return new i("Invalid "+o+" `"+a+"` supplied to "+("`"+n+"`, expected a ReactNode."))}return null}return a(e)}function m(e){function t(t,n,r,a,o){var s=t[n],l=w(s);if("object"!==l){var c=x[a];return new i("Invalid "+c+" `"+o+"` of type `"+l+"` "+("supplied to `"+r+"`, expected `object`."))}for(var u in e){var h=e[u];if(h){var d=h(s,u,r,a,o+"."+u,E);if(d)return d}}return null}return a(t)}function g(e){switch(typeof e){case"number":case"string":case"undefined":return!0;case"boolean":return!e;case"object":if(Array.isArray(e))return e.every(g);if(null===e||_.isValidElement(e))return!0;var t=k(e);if(!t)return!1;var n,r=t.call(e);if(t!==e.entries){for(;!(n=r.next()).done;)if(!g(n.value))return!1}else for(;!(n=r.next()).done;){var i=n.value;if(i&&!g(i[1]))return!1}return!0;default:return!1}}function v(e,t){return"symbol"===e||("Symbol"===t["@@toStringTag"]||"function"==typeof Symbol&&t instanceof Symbol)}function w(e){var t=typeof e;return Array.isArray(e)?"array":e instanceof RegExp?"object":v(t,e)?"symbol":t}function y(e){var t=w(e);if("object"===t){if(e instanceof Date)return"date";if(e instanceof RegExp)return"regexp"}return t}function b(e){return e.constructor&&e.constructor.name?e.constructor.name:S}var _=n(24),x=n(100),E=n(318),C=n(9),k=n(102),S=(n(2),"<<anonymous>>"),P={array:o("array"),bool:o("boolean"),func:o("function"),number:o("number"),object:o("object"),string:o("string"),symbol:o("symbol"),any:s(),arrayOf:l,element:c(),instanceOf:u,node:p(),objectOf:d,oneOf:h,oneOfType:f,shape:m};i.prototype=Error.prototype,e.exports=P},function(e,t,n){"use strict";var r="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";e.exports=r},function(e,t,n){"use strict";function r(e,t,n){this.props=e,this.context=t,this.refs=l,this.updater=n||s}function i(){}var a=n(5),o=n(61),s=n(62),l=n(26);i.prototype=o.prototype,r.prototype=new i,r.prototype.constructor=r,a(r.prototype,o.prototype),r.prototype.isPureReactComponent=!0,e.exports=r},function(e,t,n){"use strict";e.exports="15.4.2"},function(e,t,n){"use strict";function r(e){return a.isValidElement(e)?void 0:i("143"),e}var i=n(25),a=n(24);n(1);e.exports=r},function(e,t,n){"use strict";function r(e,t){return e&&"object"==typeof e&&null!=e.key?c.escape(e.key):t.toString(36)}function i(e,t,n,a){var d=typeof e;if("undefined"!==d&&"boolean"!==d||(e=null),null===e||"string"===d||"number"===d||"object"===d&&e.$$typeof===s)return n(a,e,""===t?u+r(e,0):t),1;var f,p,m=0,g=""===t?u:t+h;if(Array.isArray(e))for(var v=0;v<e.length;v++)f=e[v],p=g+r(f,v),m+=i(f,p,n,a);else{var w=l(e);if(w){var y,b=w.call(e);if(w!==e.entries)for(var _=0;!(y=b.next()).done;)f=y.value,p=g+r(f,_++),m+=i(f,p,n,a);else for(;!(y=b.next()).done;){var x=y.value;x&&(f=x[1],p=g+c.escape(x[0])+h+r(f,0),m+=i(f,p,n,a))}}else if("object"===d){var E="",C=String(e);o("31","[object Object]"===C?"object with keys {"+Object.keys(e).join(", ")+"}":C,E)}}return m}function a(e,t,n){return null==e?0:i(e,"",t,n)}var o=n(25),s=(n(15),n(99)),l=n(102),c=(n(1),n(312)),u=(n(2),"."),h=":";e.exports=a},function(e,t,n){"use strict";e.exports=function(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})}},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}},function(e,t,n){e.exports=n(103)}])}); \ No newline at end of file diff --git a/lib/vendor/bezier.js b/lib/vendor/bezier.js new file mode 100644 index 00000000..2119e350 --- /dev/null +++ b/lib/vendor/bezier.js @@ -0,0 +1 @@ +var Bezier=function(t){function n(i){if(r[i])return r[i].exports;var e=r[i]={exports:{},id:i,loaded:!1};return t[i].call(e.exports,e,e.exports,n),e.loaded=!0,e.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){"use strict";t.exports=r(1)},function(t,n,r){"use strict";var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t};!function(){function n(t,n,r,i,e){"undefined"==typeof e&&(e=.5);var o=h.projectionratio(e,t),s=1-o,u={x:o*n.x+s*i.x,y:o*n.y+s*i.y},a=h.abcratio(e,t),f={x:r.x+(r.x-u.x)/a,y:r.y+(r.y-u.y)/a};return{A:f,B:r,C:u}}var e=Math.abs,o=Math.min,s=Math.max,u=Math.acos,a=Math.sqrt,f=Math.PI,c={x:0,y:0,z:0},h=r(2),x=r(3),y=function(t){var n=t&&t.forEach?t:[].slice.call(arguments),r=!1;if("object"===i(n[0])){r=n.length;var o=[];n.forEach(function(t){["x","y","z"].forEach(function(n){"undefined"!=typeof t[n]&&o.push(t[n])})}),n=o}var s=!1,u=n.length;if(r){if(r>4){if(1!==arguments.length)throw new Error("Only new Bezier(point[]) is accepted for 4th and higher order curves");s=!0}}else if(6!==u&&8!==u&&9!==u&&12!==u&&1!==arguments.length)throw new Error("Only new Bezier(point[]) is accepted for 4th and higher order curves");var a=!s&&(9===u||12===u)||t&&t[0]&&"undefined"!=typeof t[0].z;this._3d=a;for(var f=[],c=0,x=a?3:2;u>c;c+=x){var y={x:n[c],y:n[c+1]};a&&(y.z=n[c+2]),f.push(y)}this.order=f.length-1,this.points=f;var p=["x","y"];a&&p.push("z"),this.dims=p,this.dimlen=p.length,function(t){for(var n=t.order,r=t.points,i=h.align(r,{p1:r[0],p2:r[n]}),o=0;o<i.length;o++)if(e(i[o].y)>1e-4)return void(t._linear=!1);t._linear=!0}(this),this._t1=0,this._t2=1,this.update()};y.fromSVG=function(t){var n=t.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/g).map(parseFloat),r=/[cq]/.test(t);return r?(n=n.map(function(t,r){return 2>r?t:t+n[r%2]}),new y(n)):new y(n)},y.quadraticFromPoints=function(t,r,i,e){if("undefined"==typeof e&&(e=.5),0===e)return new y(r,r,i);if(1===e)return new y(t,r,r);var o=n(2,t,r,i,e);return new y(t,o.A,i)},y.cubicFromPoints=function(t,r,i,e,o){"undefined"==typeof e&&(e=.5);var s=n(3,t,r,i,e);"undefined"==typeof o&&(o=h.dist(r,s.C));var u=o*(1-e)/e,a=h.dist(t,i),f=(i.x-t.x)/a,c=(i.y-t.y)/a,x=o*f,p=o*c,l=u*f,v=u*c,d={x:r.x-x,y:r.y-p},m={x:r.x+l,y:r.y+v},g=s.A,z={x:g.x+(d.x-g.x)/(1-e),y:g.y+(d.y-g.y)/(1-e)},b={x:g.x+(m.x-g.x)/e,y:g.y+(m.y-g.y)/e},_={x:t.x+(z.x-t.x)/e,y:t.y+(z.y-t.y)/e},w={x:i.x+(b.x-i.x)/(1-e),y:i.y+(b.y-i.y)/(1-e)};return new y(t,_,w,i)};var p=function(){return h};y.getUtils=p,y.prototype={getUtils:p,valueOf:function(){return this.toString()},toString:function(){return h.pointsToString(this.points)},toSVG:function(t){if(this._3d)return!1;for(var n=this.points,r=n[0].x,i=n[0].y,e=["M",r,i,2===this.order?"Q":"C"],o=1,s=n.length;s>o;o++)e.push(n[o].x),e.push(n[o].y);return e.join(" ")},update:function(){this.dpoints=[];for(var t=this.points,n=t.length,r=n-1;n>1;n--,r--){for(var i,e=[],o=0;r>o;o++)i={x:r*(t[o+1].x-t[o].x),y:r*(t[o+1].y-t[o].y)},this._3d&&(i.z=r*(t[o+1].z-t[o].z)),e.push(i);this.dpoints.push(e),t=e}this.computedirection()},computedirection:function(){var t=this.points,n=h.angle(t[0],t[this.order],t[1]);this.clockwise=n>0},length:function(){return h.length(this.derivative.bind(this))},_lut:[],getLUT:function(t){if(t=t||100,this._lut.length===t)return this._lut;this._lut=[];for(var n=0;t>=n;n++)this._lut.push(this.compute(n/t));return this._lut},on:function(t,n){n=n||5;for(var r,i=this.getLUT(),e=[],o=0,s=0;s<i.length;s++)r=i[s],h.dist(r,t)<n&&(e.push(r),o+=s/i.length);return e.length?o/=e.length:!1},project:function(t){var n=this.getLUT(),r=n.length-1,i=h.closest(n,t),e=i.mdist,o=i.mpos;if(0===o||o===r){var s=o/r,u=this.compute(s);return u.t=s,u.d=e,u}var a,s,f,c,x=(o-1)/r,y=(o+1)/r,p=.1/r;for(e+=1,s=x,a=s;y+p>s;s+=p)f=this.compute(s),c=h.dist(t,f),e>c&&(e=c,a=s);return f=this.compute(a),f.t=a,f.d=e,f},get:function(t){return this.compute(t)},point:function(t){return this.points[t]},compute:function(t){if(0===t)return this.points[0];if(1===t)return this.points[this.order];var n=this.points,r=1-t;if(1===this.order)return f={x:r*n[0].x+t*n[1].x,y:r*n[0].y+t*n[1].y},this._3d&&(f.z=r*n[0].z+t*n[1].z),f;if(this.order<4){var i,e,o,s=r*r,u=t*t,a=0;2===this.order?(n=[n[0],n[1],n[2],c],i=s,e=r*t*2,o=u):3===this.order&&(i=s*r,e=s*t*3,o=r*u*3,a=t*u);var f={x:i*n[0].x+e*n[1].x+o*n[2].x+a*n[3].x,y:i*n[0].y+e*n[1].y+o*n[2].y+a*n[3].y};return this._3d&&(f.z=i*n[0].z+e*n[1].z+o*n[2].z+a*n[3].z),f}for(var h=JSON.parse(JSON.stringify(this.points));h.length>1;){for(var x=0;x<h.length-1;x++)h[x]={x:h[x].x+(h[x+1].x-h[x].x)*t,y:h[x].y+(h[x+1].y-h[x].y)*t},"undefined"!=typeof h[x].z&&(h[x]=h[x].z+(h[x+1].z-h[x].z)*t);h.splice(h.length-1,1)}return h[0]},raise:function(){for(var t,n,r,i=this.points,e=[i[0]],o=i.length,t=1;o>t;t++)n=i[t],r=i[t-1],e[t]={x:(o-t)/o*n.x+t/o*r.x,y:(o-t)/o*n.y+t/o*r.y};return e[o]=i[o-1],new y(e)},derivative:function(t){var n,r,i=1-t,e=0,o=this.dpoints[0];2===this.order&&(o=[o[0],o[1],c],n=i,r=t),3===this.order&&(n=i*i,r=i*t*2,e=t*t);var s={x:n*o[0].x+r*o[1].x+e*o[2].x,y:n*o[0].y+r*o[1].y+e*o[2].y};return this._3d&&(s.z=n*o[0].z+r*o[1].z+e*o[2].z),s},inflections:function(){return h.inflections(this.points)},normal:function(t){return this._3d?this.__normal3(t):this.__normal2(t)},__normal2:function(t){var n=this.derivative(t),r=a(n.x*n.x+n.y*n.y);return{x:-n.y/r,y:n.x/r}},__normal3:function(t){var n=this.derivative(t),r=this.derivative(t+.01),i=a(n.x*n.x+n.y*n.y+n.z*n.z),e=a(r.x*r.x+r.y*r.y+r.z*r.z);n.x/=i,n.y/=i,n.z/=i,r.x/=e,r.y/=e,r.z/=e;var o={x:r.y*n.z-r.z*n.y,y:r.z*n.x-r.x*n.z,z:r.x*n.y-r.y*n.x},s=a(o.x*o.x+o.y*o.y+o.z*o.z);o.x/=s,o.y/=s,o.z/=s;var u=[o.x*o.x,o.x*o.y-o.z,o.x*o.z+o.y,o.x*o.y+o.z,o.y*o.y,o.y*o.z-o.x,o.x*o.z-o.y,o.y*o.z+o.x,o.z*o.z],f={x:u[0]*n.x+u[1]*n.y+u[2]*n.z,y:u[3]*n.x+u[4]*n.y+u[5]*n.z,z:u[6]*n.x+u[7]*n.y+u[8]*n.z};return f},hull:function(t){var n,r=this.points,i=[],e=[],o=0,s=0,u=0;for(e[o++]=r[0],e[o++]=r[1],e[o++]=r[2],3===this.order&&(e[o++]=r[3]);r.length>1;){for(i=[],s=0,u=r.length-1;u>s;s++)n=h.lerp(t,r[s],r[s+1]),e[o++]=n,i.push(n);r=i}return e},split:function(t,n){if(0===t&&n)return this.split(n).left;if(1===n)return this.split(t).right;var r=this.hull(t),i={left:new y(2===this.order?[r[0],r[3],r[5]]:[r[0],r[4],r[7],r[9]]),right:new y(2===this.order?[r[5],r[4],r[2]]:[r[9],r[8],r[6],r[3]]),span:r};if(i.left._t1=h.map(0,0,1,this._t1,this._t2),i.left._t2=h.map(t,0,1,this._t1,this._t2),i.right._t1=h.map(t,0,1,this._t1,this._t2),i.right._t2=h.map(1,0,1,this._t1,this._t2),!n)return i;n=h.map(n,t,1,0,1);var e=i.right.split(n);return e.left},extrema:function(){var t,n,r=this.dims,i={},e=[];return r.forEach(function(r){n=function(t){return t[r]},t=this.dpoints[0].map(n),i[r]=h.droots(t),3===this.order&&(t=this.dpoints[1].map(n),i[r]=i[r].concat(h.droots(t))),i[r]=i[r].filter(function(t){return t>=0&&1>=t}),e=e.concat(i[r].sort())}.bind(this)),e=e.sort().filter(function(t,n){return e.indexOf(t)===n}),i.values=e,i},bbox:function(){var t=this.extrema(),n={};return this.dims.forEach(function(r){n[r]=h.getminmax(this,r,t[r])}.bind(this)),n},overlaps:function(t){var n=this.bbox(),r=t.bbox();return h.bboxoverlap(n,r)},offset:function(t,n){if("undefined"!=typeof n){var r=this.get(t),i=this.normal(t),e={c:r,n:i,x:r.x+i.x*n,y:r.y+i.y*n};return this._3d&&(e.z=r.z+i.z*n),e}if(this._linear){var o=this.normal(0),s=this.points.map(function(n){var r={x:n.x+t*o.x,y:n.y+t*o.y};return n.z&&i.z&&(r.z=n.z+t*o.z),r});return[new y(s)]}var u=this.reduce();return u.map(function(n){return n.scale(t)})},simple:function(){if(3===this.order){var t=h.angle(this.points[0],this.points[3],this.points[1]),n=h.angle(this.points[0],this.points[3],this.points[2]);if(t>0&&0>n||0>t&&n>0)return!1}var r=this.normal(0),i=this.normal(1),o=r.x*i.x+r.y*i.y;this._3d&&(o+=r.z*i.z);var s=e(u(o));return f/3>s},reduce:function(){var t,n,r=0,i=0,o=.01,s=[],u=[],a=this.extrema().values;for(-1===a.indexOf(0)&&(a=[0].concat(a)),-1===a.indexOf(1)&&a.push(1),r=a[0],t=1;t<a.length;t++)i=a[t],n=this.split(r,i),n._t1=r,n._t2=i,s.push(n),r=i;return s.forEach(function(t){for(r=0,i=0;1>=i;)for(i=r+o;1+o>=i;i+=o)if(n=t.split(r,i),!n.simple()){if(i-=o,e(r-i)<o)return[];n=t.split(r,i),n._t1=h.map(r,0,1,t._t1,t._t2),n._t2=h.map(i,0,1,t._t1,t._t2),u.push(n),r=i;break}1>r&&(n=t.split(r,1),n._t1=h.map(r,0,1,t._t1,t._t2),n._t2=t._t2,u.push(n))}),u},scale:function(t){var n=this.order,r=!1;if("function"==typeof t&&(r=t),r&&2===n)return this.raise().scale(r);var i=this.clockwise,e=r?r(0):t,o=r?r(1):t,s=[this.offset(0,10),this.offset(1,10)],u=h.lli4(s[0],s[0].c,s[1],s[1].c);if(!u)throw new Error("cannot scale this curve. Try reducing it first.");var f=this.points,c=[];return[0,1].forEach(function(t){var r=c[t*n]=h.copy(f[t*n]);r.x+=(t?o:e)*s[t].n.x,r.y+=(t?o:e)*s[t].n.y}.bind(this)),r?([0,1].forEach(function(e){if(2!==this.order||!e){var o=f[e+1],s={x:o.x-u.x,y:o.y-u.y},h=r?r((e+1)/n):t;r&&!i&&(h=-h);var x=a(s.x*s.x+s.y*s.y);s.x/=x,s.y/=x,c[e+1]={x:o.x+h*s.x,y:o.y+h*s.y}}}.bind(this)),new y(c)):([0,1].forEach(function(t){if(2!==this.order||!t){var r=c[t*n],i=this.derivative(t),e={x:r.x+i.x,y:r.y+i.y};c[t+1]=h.lli4(r,e,u,f[t+1])}}.bind(this)),new y(c))},outline:function(t,n,r,i){function e(t,n,r,i,e){return function(o){var s=i/r,u=(i+e)/r,a=n-t;return h.map(o,0,1,t+s*a,t+u*a)}}n="undefined"==typeof n?t:n;var o,s=this.reduce(),u=s.length,a=[],f=[],c=0,y=this.length(),p="undefined"!=typeof r&&"undefined"!=typeof i;s.forEach(function(o){_=o.length(),p?(a.push(o.scale(e(t,r,y,c,_))),f.push(o.scale(e(-n,-i,y,c,_)))):(a.push(o.scale(t)),f.push(o.scale(-n))),c+=_}),f=f.map(function(t){return o=t.points,o[3]?t.points=[o[3],o[2],o[1],o[0]]:t.points=[o[2],o[1],o[0]],t}).reverse();var l=a[0].points[0],v=a[u-1].points[a[u-1].points.length-1],d=f[u-1].points[f[u-1].points.length-1],m=f[0].points[0],g=h.makeline(d,l),z=h.makeline(v,m),b=[g].concat(a).concat([z]).concat(f),_=b.length;return new x(b)},outlineshapes:function(t,n,r){n=n||t;for(var i=this.outline(t,n).curves,e=[],o=1,s=i.length;s/2>o;o++){var u=h.makeshape(i[o],i[s-o],r);u.startcap.virtual=o>1,u.endcap.virtual=s/2-1>o,e.push(u)}return e},intersects:function(t,n){return t?t.p1&&t.p2?this.lineIntersects(t):(t instanceof y&&(t=t.reduce()),this.curveintersects(this.reduce(),t,n)):this.selfintersects(n)},lineIntersects:function(t){var n=o(t.p1.x,t.p2.x),r=o(t.p1.y,t.p2.y),i=s(t.p1.x,t.p2.x),e=s(t.p1.y,t.p2.y),u=this;return h.roots(this.points,t).filter(function(t){var o=u.get(t);return h.between(o.x,n,i)&&h.between(o.y,r,e)})},selfintersects:function(t){var n,r,i,e,o=this.reduce(),s=o.length-2,u=[];for(n=0;s>n;n++)i=o.slice(n,n+1),e=o.slice(n+2),r=this.curveintersects(i,e,t),u=u.concat(r);return u},curveintersects:function(t,n,r){var i=[];t.forEach(function(t){n.forEach(function(n){t.overlaps(n)&&i.push({left:t,right:n})})});var e=[];return i.forEach(function(t){var n=h.pairiteration(t.left,t.right,r);n.length>0&&(e=e.concat(n))}),e},arcs:function(t){t=t||.5;var n=[];return this._iterate(t,n)},_error:function(t,n,r,i){var o=(i-r)/4,s=this.get(r+o),u=this.get(i-o),a=h.dist(t,n),f=h.dist(t,s),c=h.dist(t,u);return e(f-a)+e(c-a)},_iterate:function(t,n){var r,i=0,e=1;do{r=0,e=1;var o,s,u,a,f,c=this.get(i),x=!1,y=!1,p=e,l=1,v=0;do{y=x,a=u,p=(i+e)/2,v++,o=this.get(p),s=this.get(e),u=h.getccenter(c,o,s),u.interval={start:i,end:e};var d=this._error(u,c,i,e);if(x=t>=d,f=y&&!x,f||(l=e),x){if(e>=1){l=1,a=u;break}e+=(e-i)/2}else e=p}while(!f&&r++<100);if(r>=100){console.error("arc abstraction somehow failed...");break}a=a?a:u,n.push(a),i=l}while(1>e);return n}},t.exports=y}()},function(t,n,r){"use strict";!function(){var n=Math.abs,i=Math.cos,e=Math.sin,o=Math.acos,s=Math.atan2,u=Math.sqrt,a=Math.pow,f=function(t){return 0>t?-a(-t,1/3):a(t,1/3)},c=Math.PI,h=2*c,x=c/2,y=1e-6,p={Tvalues:[-.06405689286260563,.06405689286260563,-.1911188674736163,.1911188674736163,-.3150426796961634,.3150426796961634,-.4337935076260451,.4337935076260451,-.5454214713888396,.5454214713888396,-.6480936519369755,.6480936519369755,-.7401241915785544,.7401241915785544,-.820001985973903,.820001985973903,-.8864155270044011,.8864155270044011,-.9382745520027328,.9382745520027328,-.9747285559713095,.9747285559713095,-.9951872199970213,.9951872199970213],Cvalues:[.12793819534675216,.12793819534675216,.1258374563468283,.1258374563468283,.12167047292780339,.12167047292780339,.1155056680537256,.1155056680537256,.10744427011596563,.10744427011596563,.09761865210411388,.09761865210411388,.08619016153195327,.08619016153195327,.0733464814110803,.0733464814110803,.05929858491543678,.05929858491543678,.04427743881741981,.04427743881741981,.028531388628933663,.028531388628933663,.0123412297999872,.0123412297999872],arcfn:function(t,n){var r=n(t),i=r.x*r.x+r.y*r.y;return"undefined"!=typeof r.z&&(i+=r.z*r.z),u(i)},between:function(t,n,r){return t>=n&&r>=t||p.approximately(t,n)||p.approximately(t,r)},approximately:function(t,r,i){return n(t-r)<=(i||y)},length:function(t){var n,r,i=.5,e=0,o=p.Tvalues.length;for(n=0;o>n;n++)r=i*p.Tvalues[n]+i,e+=p.Cvalues[n]*p.arcfn(r,t);return i*e},map:function(t,n,r,i,e){var o=r-n,s=e-i,u=t-n,a=u/o;return i+s*a},lerp:function(t,n,r){var i={x:n.x+t*(r.x-n.x),y:n.y+t*(r.y-n.y)};return n.z&&r.z&&(i.z=n.z+t*(r.z-n.z)),i},pointToString:function(t){var n=t.x+"/"+t.y;return"undefined"!=typeof t.z&&(n+="/"+t.z),n},pointsToString:function(t){return"["+t.map(p.pointToString).join(", ")+"]"},copy:function(t){return JSON.parse(JSON.stringify(t))},angle:function(t,n,r){var i,e=n.x-t.x,o=n.y-t.y,a=r.x-t.x,f=r.y-t.y,c=e*f-o*a,h=u(e*e+o*o),x=u(a*a+f*f);return e/=h,o/=h,a/=x,f/=x,i=e*a+o*f,s(c,i)},round:function(t,n){var r=""+t,i=r.indexOf(".");return parseFloat(r.substring(0,i+1+n))},dist:function(t,n){var r=t.x-n.x,i=t.y-n.y;return u(r*r+i*i)},closest:function(t,n){var r,i,e=a(2,63);return t.forEach(function(t,o){i=p.dist(n,t),e>i&&(e=i,r=o)}),{mdist:e,mpos:r}},abcratio:function(t,r){if(2!==r&&3!==r)return!1;if("undefined"==typeof t)t=.5;else if(0===t||1===t)return t;var i=a(t,r)+a(1-t,r),e=i-1;return n(e/i)},projectionratio:function(t,n){if(2!==n&&3!==n)return!1;if("undefined"==typeof t)t=.5;else if(0===t||1===t)return t;var r=a(1-t,n),i=a(t,n)+r;return r/i},lli8:function(t,n,r,i,e,o,s,u){var a=(t*i-n*r)*(e-s)-(t-r)*(e*u-o*s),f=(t*i-n*r)*(o-u)-(n-i)*(e*u-o*s),c=(t-r)*(o-u)-(n-i)*(e-s);return 0==c?!1:{x:a/c,y:f/c}},lli4:function(t,n,r,i){var e=t.x,o=t.y,s=n.x,u=n.y,a=r.x,f=r.y,c=i.x,h=i.y;return p.lli8(e,o,s,u,a,f,c,h)},lli:function(t,n){return p.lli4(t,t.c,n,n.c)},makeline:function(t,n){var i=r(1),e=t.x,o=t.y,s=n.x,u=n.y,a=(s-e)/3,f=(u-o)/3;return new i(e,o,e+a,o+f,e+2*a,o+2*f,s,u)},findbbox:function(t){var n=99999999,r=n,i=-n,e=i;return t.forEach(function(t){var o=t.bbox();n>o.x.min&&(n=o.x.min),r>o.y.min&&(r=o.y.min),i<o.x.max&&(i=o.x.max),e<o.y.max&&(e=o.y.max)}),{x:{min:n,mid:(n+i)/2,max:i,size:i-n},y:{min:r,mid:(r+e)/2,max:e,size:e-r}}},shapeintersections:function(t,n,r,i,e){if(!p.bboxoverlap(n,i))return[];var o=[],s=[t.startcap,t.forward,t.back,t.endcap],u=[r.startcap,r.forward,r.back,r.endcap];return s.forEach(function(n){n.virtual||u.forEach(function(i){if(!i.virtual){var s=n.intersects(i,e);s.length>0&&(s.c1=n,s.c2=i,s.s1=t,s.s2=r,o.push(s))}})}),o},makeshape:function(t,n,r){var i=n.points.length,e=t.points.length,o=p.makeline(n.points[i-1],t.points[0]),s=p.makeline(t.points[e-1],n.points[0]),u={startcap:o,forward:t,back:n,endcap:s,bbox:p.findbbox([o,t,n,s])},a=p;return u.intersections=function(t){return a.shapeintersections(u,u.bbox,t,t.bbox,r)},u},getminmax:function(t,n,r){if(!r)return{min:0,max:0};var i,e,o=0x10000000000000000,s=-o;-1===r.indexOf(0)&&(r=[0].concat(r)),-1===r.indexOf(1)&&r.push(1);for(var u=0,a=r.length;a>u;u++)i=r[u],e=t.get(i),e[n]<o&&(o=e[n]),e[n]>s&&(s=e[n]);return{min:o,mid:(o+s)/2,max:s,size:s-o}},align:function(t,n){var r=n.p1.x,o=n.p1.y,u=-s(n.p2.y-o,n.p2.x-r),a=function(t){return{x:(t.x-r)*i(u)-(t.y-o)*e(u),y:(t.x-r)*e(u)+(t.y-o)*i(u)}};return t.map(a)},roots:function(t,n){n=n||{p1:{x:0,y:0},p2:{x:1,y:0}};var r=t.length-1,e=p.align(t,n),s=function(t){return t>=0&&1>=t};if(2===r){var a=e[0].y,c=e[1].y,x=e[2].y,y=a-2*c+x;if(0!==y){var l=-u(c*c-a*x),v=-a+c,d=-(l+v)/y,m=-(-l+v)/y;return[d,m].filter(s)}return c!==x&&0===y?[(2*c-x)/2*(c-x)].filter(s):[]}var g,d,z,b,_,w=e[0].y,E=e[1].y,S=e[2].y,M=e[3].y,y=-w+3*E-3*S+M,a=(3*w-6*E+3*S)/y,c=(-3*w+3*E)/y,x=w/y,e=(3*c-a*a)/3,k=e/3,O=(2*a*a*a-9*a*c+27*x)/27,T=O/2,j=T*T+k*k*k;if(0>j){var C=-e/3,q=C*C*C,U=u(q),B=-O/(2*U),F=-1>B?-1:B>1?1:B,I=o(F),J=f(U),N=2*J;return z=N*i(I/3)-a/3,b=N*i((I+h)/3)-a/3,_=N*i((I+2*h)/3)-a/3,[z,b,_].filter(s)}if(0===j)return g=0>T?f(-T):-f(T),z=2*g-a/3,b=-g-a/3,[z,b].filter(s);var P=u(j);return g=f(-T+P),d=f(T+P),[g-d-a/3].filter(s)},droots:function(t){if(3===t.length){var n=t[0],r=t[1],i=t[2],e=n-2*r+i;if(0!==e){var o=-u(r*r-n*i),s=-n+r,a=-(o+s)/e,f=-(-o+s)/e;return[a,f]}return r!==i&&0===e?[(2*r-i)/(2*(r-i))]:[]}if(2===t.length){var n=t[0],r=t[1];return n!==r?[n/(n-r)]:[]}},inflections:function(t){if(t.length<4)return[];var n=p.align(t,{p1:t[0],p2:t.slice(-1)[0]}),r=n[2].x*n[1].y,i=n[3].x*n[1].y,e=n[1].x*n[2].y,o=n[3].x*n[2].y,s=18*(-3*r+2*i+3*e-o),u=18*(3*r-i-3*e),a=18*(e-r);if(p.approximately(s,0))return[];var f=u*u-4*s*a,c=Math.sqrt(f),o=2*s;return p.approximately(o,0)?[]:[(c-u)/o,-(u+c)/o].filter(function(t){return t>=0&&1>=t})},bboxoverlap:function(t,r){var i,e,o,s,u,a=["x","y"],f=a.length;for(i=0;f>i;i++)if(e=a[i],o=t[e].mid,s=r[e].mid,u=(t[e].size+r[e].size)/2,n(o-s)>=u)return!1;return!0},expandbox:function(t,n){n.x.min<t.x.min&&(t.x.min=n.x.min),n.y.min<t.y.min&&(t.y.min=n.y.min),n.z&&n.z.min<t.z.min&&(t.z.min=n.z.min),n.x.max>t.x.max&&(t.x.max=n.x.max),n.y.max>t.y.max&&(t.y.max=n.y.max),n.z&&n.z.max>t.z.max&&(t.z.max=n.z.max),t.x.mid=(t.x.min+t.x.max)/2,t.y.mid=(t.y.min+t.y.max)/2,t.z&&(t.z.mid=(t.z.min+t.z.max)/2),t.x.size=t.x.max-t.x.min,t.y.size=t.y.max-t.y.min,t.z&&(t.z.size=t.z.max-t.z.min)},pairiteration:function(t,n,r){var i=t.bbox(),e=n.bbox(),o=1e5,s=r||.5;if(i.x.size+i.y.size<s&&e.x.size+e.y.size<s)return[(o*(t._t1+t._t2)/2|0)/o+"/"+(o*(n._t1+n._t2)/2|0)/o];var u=t.split(.5),a=n.split(.5),f=[{left:u.left,right:a.left},{left:u.left,right:a.right},{left:u.right,right:a.right},{left:u.right,right:a.left}];f=f.filter(function(t){return p.bboxoverlap(t.left.bbox(),t.right.bbox())});var c=[];return 0===f.length?c:(f.forEach(function(t){c=c.concat(p.pairiteration(t.left,t.right,s))}),c=c.filter(function(t,n){return c.indexOf(t)===n}))},getccenter:function(t,n,r){var o,u=n.x-t.x,a=n.y-t.y,f=r.x-n.x,c=r.y-n.y,y=u*i(x)-a*e(x),l=u*e(x)+a*i(x),v=f*i(x)-c*e(x),d=f*e(x)+c*i(x),m=(t.x+n.x)/2,g=(t.y+n.y)/2,z=(n.x+r.x)/2,b=(n.y+r.y)/2,_=m+y,w=g+l,E=z+v,S=b+d,M=p.lli8(m,g,_,w,z,b,E,S),k=p.dist(M,t),O=s(t.y-M.y,t.x-M.x),T=s(n.y-M.y,n.x-M.x),j=s(r.y-M.y,r.x-M.x);return j>O?((O>T||T>j)&&(O+=h),O>j&&(o=j,j=O,O=o)):T>j&&O>T?(o=j,j=O,O=o):j+=h,M.s=O,M.e=j,M.r=k,M}};t.exports=p}()},function(t,n,r){"use strict";!function(){var n=r(2),i=function(t){this.curves=[],this._3d=!1,t&&(this.curves=t,this._3d=this.curves[0]._3d)};i.prototype={valueOf:function(){return this.toString()},toString:function(){return n.pointsToString(this.points)},addCurve:function(t){this.curves.push(t),this._3d=this._3d||t._3d},length:function(){return this.curves.map(function(t){return t.length()}).reduce(function(t,n){return t+n})},curve:function(t){return this.curves[t]},bbox:function e(){for(var t=this.curves,e=t[0].bbox(),r=1;r<t.length;r++)n.expandbox(e,t[r].bbox());return e},offset:function o(t){var o=[];return this.curves.forEach(function(n){o=o.concat(n.offset(t))}),new i(o)}},t.exports=i}()}]); \ No newline at end of file diff --git a/lib/vendor/chroma.min.js b/lib/vendor/chroma.min.js new file mode 100644 index 00000000..e81220c7 --- /dev/null +++ b/lib/vendor/chroma.min.js @@ -0,0 +1,33 @@ +/* +chroma.js - JavaScript library for color conversions + +Copyright (c) 2011-2015, Gregor Aisch +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. The name Gregor Aisch may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +(function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,aa,ba,ca,da,ea,fa,ga,ha,ia,ja,ka,la,ma,na,oa,pa,qa,ra,sa,ta,ua,va,wa,xa,ya,za=[].slice;ua=function(){var a,b,c,d,e;for(a={},e="Boolean Number String Function Array Date RegExp Undefined Null".split(" "),d=0,b=e.length;d<b;d++)c=e[d],a["[object "+c+"]"]=c.toLowerCase();return function(b){var c;return c=Object.prototype.toString.call(b),a[c]||"object"}}(),S=function(a,b,c){return null==b&&(b=0),null==c&&(c=1),a<b&&(a=b),a>c&&(a=c),a},va=function(a){return a.length>=3?[].slice.call(a):a[0]},t=function(a){var b;for(b in a)b<3?(a[b]<0&&(a[b]=0),a[b]>255&&(a[b]=255)):3===b&&(a[b]<0&&(a[b]=0),a[b]>1&&(a[b]=1));return a},d=Math.PI,pa=Math.round,w=Math.cos,B=Math.floor,_=Math.pow,T=Math.log,ra=Math.sin,sa=Math.sqrt,m=Math.atan2,W=Math.max,l=Math.abs,g=2*d,e=d/3,b=d/180,f=180/d,s=function(){return arguments[0]instanceof a?arguments[0]:function(a,b,c){c.prototype=a.prototype;var d=new c,e=a.apply(d,b);return Object(e)===e?e:d}(a,arguments,function(){})},k=[],"undefined"!=typeof module&&null!==module&&null!=module.exports&&(module.exports=s),"function"==typeof define&&define.amd?define([],function(){return s}):(oa="undefined"!=typeof exports&&null!==exports?exports:this,oa.chroma=s),s.version="1.1.1",j={},h=[],i=!1,a=function(){function a(){var a,b,c,d,e,f,g,k,l;for(f=this,b=[],k=0,d=arguments.length;k<d;k++)a=arguments[k],null!=a&&b.push(a);if(g=b[b.length-1],null!=j[g])f._rgb=t(j[g](va(b.slice(0,-1))));else{for(i||(h=h.sort(function(a,b){return b.p-a.p}),i=!0),l=0,e=h.length;l<e&&(c=h[l],!(g=c.test.apply(c,b)));l++);g&&(f._rgb=t(j[g].apply(j,b)))}null==f._rgb&&console.warn("unknown format: "+b),null==f._rgb&&(f._rgb=[0,0,0]),3===f._rgb.length&&f._rgb.push(1)}return a.prototype.alpha=function(a){return arguments.length?(this._rgb[3]=a,this):this._rgb[3]},a.prototype.toString=function(){return this.name()},a}(),s._input=j,s.brewer=q={OrRd:["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"],PuBu:["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"],BuPu:["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"],Oranges:["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"],BuGn:["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"],YlOrBr:["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"],YlGn:["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"],Reds:["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"],RdPu:["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"],Greens:["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"],YlGnBu:["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"],Purples:["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"],GnBu:["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"],Greys:["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"],YlOrRd:["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"],PuRd:["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"],Blues:["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"],PuBuGn:["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"],Spectral:["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"],RdYlGn:["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"],RdBu:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"],PiYG:["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"],PRGn:["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"],RdYlBu:["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"],BrBG:["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"],RdGy:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"],PuOr:["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"],Set2:["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"],Accent:["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"],Set1:["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"],Set3:["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"],Dark2:["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"],Paired:["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"],Pastel2:["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"],Pastel1:["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"]},wa={indigo:"#4b0082",gold:"#ffd700",hotpink:"#ff69b4",firebrick:"#b22222",indianred:"#cd5c5c",yellow:"#ffff00",mistyrose:"#ffe4e1",darkolivegreen:"#556b2f",olive:"#808000",darkseagreen:"#8fbc8f",pink:"#ffc0cb",tomato:"#ff6347",lightcoral:"#f08080",orangered:"#ff4500",navajowhite:"#ffdead",lime:"#00ff00",palegreen:"#98fb98",darkslategrey:"#2f4f4f",greenyellow:"#adff2f",burlywood:"#deb887",seashell:"#fff5ee",mediumspringgreen:"#00fa9a",fuchsia:"#ff00ff",papayawhip:"#ffefd5",blanchedalmond:"#ffebcd",chartreuse:"#7fff00",dimgray:"#696969",black:"#000000",peachpuff:"#ffdab9",springgreen:"#00ff7f",aquamarine:"#7fffd4",white:"#ffffff",orange:"#ffa500",lightsalmon:"#ffa07a",darkslategray:"#2f4f4f",brown:"#a52a2a",ivory:"#fffff0",dodgerblue:"#1e90ff",peru:"#cd853f",lawngreen:"#7cfc00",chocolate:"#d2691e",crimson:"#dc143c",forestgreen:"#228b22",darkgrey:"#a9a9a9",lightseagreen:"#20b2aa",cyan:"#00ffff",mintcream:"#f5fffa",silver:"#c0c0c0",antiquewhite:"#faebd7",mediumorchid:"#ba55d3",skyblue:"#87ceeb",gray:"#808080",darkturquoise:"#00ced1",goldenrod:"#daa520",darkgreen:"#006400",floralwhite:"#fffaf0",darkviolet:"#9400d3",darkgray:"#a9a9a9",moccasin:"#ffe4b5",saddlebrown:"#8b4513",grey:"#808080",darkslateblue:"#483d8b",lightskyblue:"#87cefa",lightpink:"#ffb6c1",mediumvioletred:"#c71585",slategrey:"#708090",red:"#ff0000",deeppink:"#ff1493",limegreen:"#32cd32",darkmagenta:"#8b008b",palegoldenrod:"#eee8aa",plum:"#dda0dd",turquoise:"#40e0d0",lightgrey:"#d3d3d3",lightgoldenrodyellow:"#fafad2",darkgoldenrod:"#b8860b",lavender:"#e6e6fa",maroon:"#800000",yellowgreen:"#9acd32",sandybrown:"#f4a460",thistle:"#d8bfd8",violet:"#ee82ee",navy:"#000080",magenta:"#ff00ff",dimgrey:"#696969",tan:"#d2b48c",rosybrown:"#bc8f8f",olivedrab:"#6b8e23",blue:"#0000ff",lightblue:"#add8e6",ghostwhite:"#f8f8ff",honeydew:"#f0fff0",cornflowerblue:"#6495ed",slateblue:"#6a5acd",linen:"#faf0e6",darkblue:"#00008b",powderblue:"#b0e0e6",seagreen:"#2e8b57",darkkhaki:"#bdb76b",snow:"#fffafa",sienna:"#a0522d",mediumblue:"#0000cd",royalblue:"#4169e1",lightcyan:"#e0ffff",green:"#008000",mediumpurple:"#9370db",midnightblue:"#191970",cornsilk:"#fff8dc",paleturquoise:"#afeeee",bisque:"#ffe4c4",slategray:"#708090",darkcyan:"#008b8b",khaki:"#f0e68c",wheat:"#f5deb3",teal:"#008080",darkorchid:"#9932cc",deepskyblue:"#00bfff",salmon:"#fa8072",darkred:"#8b0000",steelblue:"#4682b4",palevioletred:"#db7093",lightslategray:"#778899",aliceblue:"#f0f8ff",lightslategrey:"#778899",lightgreen:"#90ee90",orchid:"#da70d6",gainsboro:"#dcdcdc",mediumseagreen:"#3cb371",lightgray:"#d3d3d3",mediumturquoise:"#48d1cc",lemonchiffon:"#fffacd",cadetblue:"#5f9ea0",lightyellow:"#ffffe0",lavenderblush:"#fff0f5",coral:"#ff7f50",purple:"#800080",aqua:"#00ffff",whitesmoke:"#f5f5f5",mediumslateblue:"#7b68ee",darkorange:"#ff8c00",mediumaquamarine:"#66cdaa",darksalmon:"#e9967a",beige:"#f5f5dc",blueviolet:"#8a2be2",azure:"#f0ffff",lightsteelblue:"#b0c4de",oldlace:"#fdf5e6",rebeccapurple:"#663399"},s.colors=v=wa,N=function(){var a,b,d,e,f,g,h,i,j;return b=va(arguments),f=b[0],a=b[1],d=b[2],i=(f+16)/116,h=isNaN(a)?i:i+a/500,j=isNaN(d)?i:i-d/200,i=c.Yn*O(i),h=c.Xn*O(h),j=c.Zn*O(j),g=ya(3.2404542*h-1.5371385*i-.4985314*j),e=ya(-.969266*h+1.8760108*i+.041556*j),d=ya(.0556434*h-.2040259*i+1.0572252*j),g=S(g,0,255),e=S(e,0,255),d=S(d,0,255),[g,e,d,b.length>3?b[3]:1]},ya=function(a){return pa(255*(a<=.00304?12.92*a:1.055*_(a,1/2.4)-.055))},O=function(a){return a>c.t1?a*a*a:c.t2*(a-c.t0)},c={Kn:18,Xn:.95047,Yn:1,Zn:1.08883,t0:.137931034,t1:.206896552,t2:.12841855,t3:.008856452},ga=function(){var a,b,c,d,e,f,g,h;return d=va(arguments),c=d[0],b=d[1],a=d[2],e=la(c,b,a),f=e[0],g=e[1],h=e[2],[116*g-16,500*(f-g),200*(g-h)]},ma=function(a){return(a/=255)<=.04045?a/12.92:_((a+.055)/1.055,2.4)},xa=function(a){return a>c.t3?_(a,1/3):a/c.t2+c.t0},la=function(){var a,b,d,e,f,g,h;return e=va(arguments),d=e[0],b=e[1],a=e[2],d=ma(d),b=ma(b),a=ma(a),f=xa((.4124564*d+.3575761*b+.1804375*a)/c.Xn),g=xa((.2126729*d+.7151522*b+.072175*a)/c.Yn),h=xa((.0193339*d+.119192*b+.9503041*a)/c.Zn),[f,g,h]},s.lab=function(){return function(a,b,c){c.prototype=a.prototype;var d=new c,e=a.apply(d,b);return Object(e)===e?e:d}(a,za.call(arguments).concat(["lab"]),function(){})},j.lab=N,a.prototype.lab=function(){return ga(this._rgb)},n=function(a){var b,c,d,e,f,g,h,i,j,k,l;return a=function(){var b,c,d;for(d=[],c=0,b=a.length;c<b;c++)e=a[c],d.push(s(e));return d}(),2===a.length?(j=function(){var b,c,d;for(d=[],c=0,b=a.length;c<b;c++)e=a[c],d.push(e.lab());return d}(),f=j[0],g=j[1],b=function(a){var b,c;return c=function(){var c,d;for(d=[],b=c=0;c<=2;b=++c)d.push(f[b]+a*(g[b]-f[b]));return d}(),s.lab.apply(s,c)}):3===a.length?(k=function(){var b,c,d;for(d=[],c=0,b=a.length;c<b;c++)e=a[c],d.push(e.lab());return d}(),f=k[0],g=k[1],h=k[2],b=function(a){var b,c;return c=function(){var c,d;for(d=[],b=c=0;c<=2;b=++c)d.push((1-a)*(1-a)*f[b]+2*(1-a)*a*g[b]+a*a*h[b]);return d}(),s.lab.apply(s,c)}):4===a.length?(l=function(){var b,c,d;for(d=[],c=0,b=a.length;c<b;c++)e=a[c],d.push(e.lab());return d}(),f=l[0],g=l[1],h=l[2],i=l[3],b=function(a){var b,c;return c=function(){var c,d;for(d=[],b=c=0;c<=2;b=++c)d.push((1-a)*(1-a)*(1-a)*f[b]+3*(1-a)*(1-a)*a*g[b]+3*(1-a)*a*a*h[b]+a*a*a*i[b]);return d}(),s.lab.apply(s,c)}):5===a.length&&(c=n(a.slice(0,3)),d=n(a.slice(2,5)),b=function(a){return a<.5?c(2*a):d(2*(a-.5))}),b},s.bezier=function(a){var b;return b=n(a),b.scale=function(){return s.scale(b)},b},s.cubehelix=function(a,b,c,d,e){var f,h,i;return null==a&&(a=300),null==b&&(b=-1.5),null==c&&(c=1),null==d&&(d=1),null==e&&(e=[0,1]),h=e[1]-e[0],f=0,i=function(i){var j,k,l,m,n,o,p,q,r;return j=g*((a+120)/360+b*i),p=_(e[0]+h*i,d),o=0!==f?c[0]+i*f:c,k=o*p*(1-p)/2,m=w(j),r=ra(j),q=p+k*(-.14861*m+1.78277*r),n=p+k*(-.29227*m-.90649*r),l=p+k*(1.97294*m),s(t([255*q,255*n,255*l]))},i.start=function(b){return null==b?a:(a=b,i)},i.rotations=function(a){return null==a?b:(b=a,i)},i.gamma=function(a){return null==a?d:(d=a,i)},i.hue=function(a){return null==a?c:(c=a,"array"===ua(c)?(f=c[1]-c[0],0===f&&(c=c[1])):f=0,i)},i.lightness=function(a){return null==a?e:(e=a,"array"===ua(e)?(h=e[1]-e[0],0===h&&(e=e[1])):h=0,i)},i.scale=function(){return s.scale(i)},i.hue(c),i},s.random=function(){var b,c,d,e;for(c="0123456789abcdef",b="#",d=e=0;e<6;d=++e)b+=c.charAt(B(16*Math.random()));return new a(b)},s.average=function(b){var c,d,e,f,g,h,i,j,k;for(j=f=d=c=0,g=b.length,i=0,h=b.length;i<h;i++)e=b[i],k=s(e).rgba(),j+=k[0],f+=k[1],d+=k[2],c+=k[3];return new a(j/g,f/g,d/g,c/g)},j.rgb=function(){var a,b,c,d;b=va(arguments),c=[];for(a in b)d=b[a],c.push(d);return c},s.rgb=function(){return function(a,b,c){c.prototype=a.prototype;var d=new c,e=a.apply(d,b);return Object(e)===e?e:d}(a,za.call(arguments).concat(["rgb"]),function(){})},a.prototype.rgb=function(){return this._rgb.slice(0,3)},a.prototype.rgba=function(){return this._rgb},h.push({p:15,test:function(a){var b;return b=va(arguments),"array"===ua(b)&&3===b.length?"rgb":4===b.length&&"number"===ua(b[3])&&b[3]>=0&&b[3]<=1?"rgb":void 0}}),C=function(a){var b,c,d,e,f,g;if(a.match(/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/))return 4!==a.length&&7!==a.length||(a=a.substr(1)),3===a.length&&(a=a.split(""),a=a[0]+a[0]+a[1]+a[1]+a[2]+a[2]),g=parseInt(a,16),e=g>>16,d=g>>8&255,c=255&g,[e,d,c,1];if(a.match(/^#?([A-Fa-f0-9]{8})$/))return 9===a.length&&(a=a.substr(1)),g=parseInt(a,16),e=g>>24&255,d=g>>16&255,c=g>>8&255,b=pa((255&g)/255*100)/100,[e,d,c,b];if(null!=j.css&&(f=j.css(a)))return f;throw"unknown color: "+a},ca=function(a,b){var c,d,e,f,g,h,i;return null==b&&(b="rgb"),g=a[0],e=a[1],d=a[2],c=a[3],i=g<<16|e<<8|d,h="000000"+i.toString(16),h=h.substr(h.length-6),f="0"+pa(255*c).toString(16),f=f.substr(f.length-2),"#"+function(){switch(b.toLowerCase()){case"rgba":return h+f;case"argb":return f+h;default:return h}}()},j.hex=function(a){return C(a)},s.hex=function(){return function(a,b,c){c.prototype=a.prototype;var d=new c,e=a.apply(d,b);return Object(e)===e?e:d}(a,za.call(arguments).concat(["hex"]),function(){})},a.prototype.hex=function(a){return null==a&&(a="rgb"),ca(this._rgb,a)},h.push({p:10,test:function(a){if(1===arguments.length&&"string"===ua(a))return"hex"}}),F=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n;if(a=va(arguments),e=a[0],k=a[1],g=a[2],0===k)i=d=b=255*g;else{for(n=[0,0,0],c=[0,0,0],m=g<.5?g*(1+k):g+k-g*k,l=2*g-m,e/=360,n[0]=e+1/3,n[1]=e,n[2]=e-1/3,f=h=0;h<=2;f=++h)n[f]<0&&(n[f]+=1),n[f]>1&&(n[f]-=1),6*n[f]<1?c[f]=l+6*(m-l)*n[f]:2*n[f]<1?c[f]=m:3*n[f]<2?c[f]=l+(m-l)*(2/3-n[f])*6:c[f]=l;j=[pa(255*c[0]),pa(255*c[1]),pa(255*c[2])],i=j[0],d=j[1],b=j[2]}return a.length>3?[i,d,b,a[3]]:[i,d,b]},ea=function(a,b,c){var d,e,f,g,h;return void 0!==a&&a.length>=3&&(g=a,a=g[0],b=g[1],c=g[2]),a/=255,b/=255,c/=255,f=Math.min(a,b,c),W=Math.max(a,b,c),e=(W+f)/2,W===f?(h=0,d=Number.NaN):h=e<.5?(W-f)/(W+f):(W-f)/(2-W-f),a===W?d=(b-c)/(W-f):b===W?d=2+(c-a)/(W-f):c===W&&(d=4+(a-b)/(W-f)),d*=60,d<0&&(d+=360),[d,h,e]},s.hsl=function(){return function(a,b,c){c.prototype=a.prototype;var d=new c,e=a.apply(d,b);return Object(e)===e?e:d}(a,za.call(arguments).concat(["hsl"]),function(){})},j.hsl=F,a.prototype.hsl=function(){return ea(this._rgb)},G=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;if(a=va(arguments),e=a[0],p=a[1],r=a[2],r*=255,0===p)i=d=b=r;else switch(360===e&&(e=0),e>360&&(e-=360),e<0&&(e+=360),e/=60,f=B(e),c=e-f,g=r*(1-p),h=r*(1-p*c),q=r*(1-p*(1-c)),f){case 0:j=[r,q,g],i=j[0],d=j[1],b=j[2];break;case 1:k=[h,r,g],i=k[0],d=k[1],b=k[2];break;case 2:l=[g,r,q],i=l[0],d=l[1],b=l[2];break;case 3:m=[g,h,r],i=m[0],d=m[1],b=m[2];break;case 4:n=[q,g,r],i=n[0],d=n[1],b=n[2];break;case 5:o=[r,g,h],i=o[0],d=o[1],b=o[2]}return i=pa(i),d=pa(d),b=pa(b),[i,d,b,a.length>3?a[3]:1]},fa=function(){var a,b,c,d,e,f,g,h,i;return g=va(arguments),f=g[0],c=g[1],a=g[2],e=Math.min(f,c,a),W=Math.max(f,c,a),b=W-e,i=W/255,0===W?(d=Number.NaN,h=0):(h=b/W,f===W&&(d=(c-a)/b),c===W&&(d=2+(a-f)/b),a===W&&(d=4+(f-c)/b),d*=60,d<0&&(d+=360)),[d,h,i]},s.hsv=function(){return function(a,b,c){c.prototype=a.prototype;var d=new c,e=a.apply(d,b);return Object(e)===e?e:d}(a,za.call(arguments).concat(["hsv"]),function(){})},j.hsv=G,a.prototype.hsv=function(){return fa(this._rgb)},Z=function(a){var b,c,d;return"number"===ua(a)&&a>=0&&a<=16777215?(d=a>>16,c=a>>8&255,b=255&a,[d,c,b,1]):(console.warn("unknown num color: "+a),[0,0,0,1])},ja=function(){var a,b,c,d;return d=va(arguments),c=d[0],b=d[1],a=d[2],(c<<16)+(b<<8)+a},s.num=function(b){return new a(b,"num")},a.prototype.num=function(a){return null==a&&(a="rgb"),ja(this._rgb,a)},j.num=Z,h.push({p:10,test:function(a){if(1===arguments.length&&"number"===ua(a)&&a>=0&&a<=16777215)return"num"}}),x=function(a){var b,c,d,e,f,g,h,i;if(a=a.toLowerCase(),null!=s.colors&&s.colors[a])return C(s.colors[a]);if(f=a.match(/rgb\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*\)/)){for(h=f.slice(1,4),e=g=0;g<=2;e=++g)h[e]=+h[e];h[3]=1}else if(f=a.match(/rgba\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*,\s*([01]|[01]?\.\d+)\)/))for(h=f.slice(1,5),e=i=0;i<=3;e=++i)h[e]=+h[e];else if(f=a.match(/rgb\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/)){for(h=f.slice(1,4),e=b=0;b<=2;e=++b)h[e]=pa(2.55*h[e]);h[3]=1}else if(f=a.match(/rgba\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/)){for(h=f.slice(1,5),e=c=0;c<=2;e=++c)h[e]=pa(2.55*h[e]);h[3]=+h[3]}else(f=a.match(/hsl\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/))?(d=f.slice(1,4),d[1]*=.01,d[2]*=.01,h=F(d),h[3]=1):(f=a.match(/hsla\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/))&&(d=f.slice(1,4),d[1]*=.01,d[2]*=.01,h=F(d),h[3]=+f[4]);return h},ba=function(a){var b;return b=a[3]<1?"rgba":"rgb","rgb"===b?b+"("+a.slice(0,3).map(pa).join(",")+")":"rgba"===b?b+"("+a.slice(0,3).map(pa).join(",")+","+a[3]+")":void 0},na=function(a){return pa(100*a)/100},E=function(a,b){var c;return c=b<1?"hsla":"hsl",a[0]=na(a[0]||0),a[1]=na(100*a[1])+"%",a[2]=na(100*a[2])+"%","hsla"===c&&(a[3]=b),c+"("+a.join(",")+")"},j.css=function(a){return x(a)},s.css=function(){return function(a,b,c){c.prototype=a.prototype;var d=new c,e=a.apply(d,b);return Object(e)===e?e:d}(a,za.call(arguments).concat(["css"]),function(){})},a.prototype.css=function(a){return null==a&&(a="rgb"),"rgb"===a.slice(0,3)?ba(this._rgb):"hsl"===a.slice(0,3)?E(this.hsl(),this.alpha()):void 0},j.named=function(a){return C(wa[a])},h.push({p:20,test:function(a){if(1===arguments.length&&null!=wa[a])return"named"}}),a.prototype.name=function(a){var b,c;arguments.length&&(wa[a]&&(this._rgb=C(wa[a])),this._rgb[3]=1),b=this.hex();for(c in wa)if(b===wa[c])return c;return b},P=function(){var a,c,d,e;return e=va(arguments),d=e[0],a=e[1],c=e[2],c*=b,[d,w(c)*a,ra(c)*a]},Q=function(){var a,b,c,d,e,f,g,h,i,j,k;return c=va(arguments),h=c[0],e=c[1],g=c[2],j=P(h,e,g),a=j[0],b=j[1],d=j[2],k=N(a,b,d),i=k[0],f=k[1],d=k[2],[S(i,0,255),S(f,0,255),S(d,0,255),c.length>3?c[3]:1]},M=function(){var a,b,c,d,e,g;return g=va(arguments),e=g[0],a=g[1],b=g[2],c=sa(a*a+b*b),d=(m(b,a)*f+360)%360,0===pa(1e4*c)&&(d=Number.NaN),[e,c,d]},ha=function(){var a,b,c,d,e,f,g;return f=va(arguments),e=f[0],c=f[1],b=f[2],g=ga(e,c,b),d=g[0],a=g[1],b=g[2],M(d,a,b)},s.lch=function(){var b;return b=va(arguments),new a(b,"lch")},s.hcl=function(){var b;return b=va(arguments),new a(b,"hcl")},j.lch=Q,j.hcl=function(){var a,b,c,d;return d=va(arguments),b=d[0],a=d[1],c=d[2],Q([c,a,b])},a.prototype.lch=function(){return ha(this._rgb)},a.prototype.hcl=function(){return ha(this._rgb).reverse()},aa=function(a){var b,c,d,e,f,g,h,i,j;return null==a&&(a="rgb"),i=va(arguments),h=i[0],e=i[1],b=i[2],h/=255,e/=255,b/=255,f=1-Math.max(h,Math.max(e,b)),d=f<1?1/(1-f):0,c=(1-h-f)*d,g=(1-e-f)*d,j=(1-b-f)*d,[c,g,j,f]},u=function(){var a,b,c,d,e,f,g,h,i;return b=va(arguments),d=b[0],g=b[1],i=b[2],f=b[3],a=b.length>4?b[4]:1,1===f?[0,0,0,a]:(h=d>=1?0:pa(255*(1-d)*(1-f)),e=g>=1?0:pa(255*(1-g)*(1-f)),c=i>=1?0:pa(255*(1-i)*(1-f)),[h,e,c,a])},j.cmyk=function(){return u(va(arguments))},s.cmyk=function(){return function(a,b,c){c.prototype=a.prototype;var d=new c,e=a.apply(d,b);return Object(e)===e?e:d}(a,za.call(arguments).concat(["cmyk"]),function(){})},a.prototype.cmyk=function(){return aa(this._rgb)},j.gl=function(){var a,b,c,d,e;for(d=function(){var a,c;a=va(arguments),c=[];for(b in a)e=a[b],c.push(e);return c}.apply(this,arguments),a=c=0;c<=2;a=++c)d[a]*=255;return d},s.gl=function(){return function(a,b,c){c.prototype=a.prototype;var d=new c,e=a.apply(d,b);return Object(e)===e?e:d}(a,za.call(arguments).concat(["gl"]),function(){})},a.prototype.gl=function(){var a;return a=this._rgb,[a[0]/255,a[1]/255,a[2]/255,a[3]]},ia=function(a,b,c){var d;return d=va(arguments),a=d[0],b=d[1],c=d[2],a=U(a),b=U(b),c=U(c),.2126*a+.7152*b+.0722*c},U=function(a){return a/=255,a<=.03928?a/12.92:_((a+.055)/1.055,2.4)},k=[],H=function(a,b,c,d){var e,f,g,h;for(null==c&&(c=.5),null==d&&(d="rgb"),"object"!==ua(a)&&(a=s(a)),"object"!==ua(b)&&(b=s(b)),g=0,f=k.length;g<f;g++)if(e=k[g],d===e[0]){h=e[1](a,b,c,d);break}if(null==h)throw"color mode "+d+" is not supported";return h.alpha(a.alpha()+c*(b.alpha()-a.alpha())),h},s.interpolate=H,a.prototype.interpolate=function(a,b,c){return H(this,a,b,c)},s.mix=H,a.prototype.mix=a.prototype.interpolate,L=function(b,c,d,e){var f,g;return f=b._rgb,g=c._rgb,new a(f[0]+d*(g[0]-f[0]),f[1]+d*(g[1]-f[1]),f[2]+d*(g[2]-f[2]),e)},k.push(["rgb",L]),a.prototype.luminance=function(a,b){var c,d,e,f;return null==b&&(b="rgb"),arguments.length?(0===a?this._rgb=[0,0,0,this._rgb[3]]:1===a?this._rgb=[255,255,255,this._rgb[3]]:(d=1e-7,e=20,f=function(c,g){var h,i;return i=c.interpolate(g,.5,b),h=i.luminance(),Math.abs(a-h)<d||!e--?i:h>a?f(c,i):f(i,g)},c=ia(this._rgb),this._rgb=(c>a?f(s("black"),this):f(this,s("white"))).rgba()),this):ia(this._rgb)},ta=function(a){var b,c,d,e;return e=a/100,e<66?(d=255,c=-155.25485562709179-.44596950469579133*(c=e-2)+104.49216199393888*T(c),b=e<20?0:-254.76935184120902+.8274096064007395*(b=e-10)+115.67994401066147*T(b)):(d=351.97690566805693+.114206453784165*(d=e-55)-40.25366309332127*T(d),c=325.4494125711974+.07943456536662342*(c=e-50)-28.0852963507957*T(c),b=255),t([d,c,b])},ka=function(){var a,b,c,d,e,f,g,h,i;for(g=va(arguments),f=g[0],c=g[1],a=g[2],e=1e3,d=4e4,b=.4;d-e>b;)i=.5*(d+e),h=ta(i),h[2]/h[0]>=a/f?d=i:e=i;return pa(i)},s.temperature=s.kelvin=function(){return function(a,b,c){c.prototype=a.prototype;var d=new c,e=a.apply(d,b);return Object(e)===e?e:d}(a,za.call(arguments).concat(["temperature"]),function(){})},j.temperature=j.kelvin=j.K=ta,a.prototype.temperature=function(){return ka(this._rgb)},a.prototype.kelvin=a.prototype.temperature,s.contrast=function(b,c){var d,e,f,g;return"string"!==(f=ua(b))&&"number"!==f||(b=new a(b)),"string"!==(g=ua(c))&&"number"!==g||(c=new a(c)),d=b.luminance(),e=c.luminance(),d>e?(d+.05)/(e+.05):(e+.05)/(d+.05)},a.prototype.get=function(a){var b,c,d,e,f,g;return d=this,f=a.split("."),e=f[0],b=f[1],g=d[e](),b?(c=e.indexOf(b),c>-1?g[c]:console.warn("unknown channel "+b+" in mode "+e)):g},a.prototype.set=function(a,b){var c,d,e,f,g,h;if(e=this,g=a.split("."),f=g[0],c=g[1],c)if(h=e[f](),d=f.indexOf(c),d>-1)if("string"===ua(b))switch(b.charAt(0)){case"+":h[d]+=+b;break;case"-":h[d]+=+b;break;case"*":h[d]*=+b.substr(1);break;case"/":h[d]/=+b.substr(1);break;default:h[d]=+b}else h[d]=b;else console.warn("unknown channel "+c+" in mode "+f);else h=b;return e._rgb=s(h,f).alpha(e.alpha())._rgb,e},a.prototype.darken=function(a){var b,d;return null==a&&(a=1),d=this,b=d.lab(),b[0]-=c.Kn*a,s.lab(b).alpha(d.alpha())},a.prototype.brighten=function(a){return null==a&&(a=1),this.darken(-a)},a.prototype.darker=a.prototype.darken,a.prototype.brighter=a.prototype.brighten,a.prototype.saturate=function(a){var b,d;return null==a&&(a=1),d=this,b=d.lch(),b[1]+=a*c.Kn,b[1]<0&&(b[1]=0),s.lch(b).alpha(d.alpha())},a.prototype.desaturate=function(a){return null==a&&(a=1),this.saturate(-a)},a.prototype.premultiply=function(){var a,b;return b=this.rgb(),a=this.alpha(),s(b[0]*a,b[1]*a,b[2]*a,a)},o=function(a,b,c){if(!o[c])throw"unknown blend mode "+c;return o[c](a,b)},p=function(a){return function(b,c){var d,e;return d=s(c).rgb(),e=s(b).rgb(),s(a(d,e),"rgb")}},A=function(a){return function(b,c){var d,e,f;for(f=[],d=e=0;e<=3;d=++e)f[d]=a(b[d],c[d]);return f}},Y=function(a,b){return a},X=function(a,b){return a*b/255},y=function(a,b){return a>b?b:a},R=function(a,b){return a>b?a:b},qa=function(a,b){return 255*(1-(1-a/255)*(1-b/255))},$=function(a,b){return b<128?2*a*b/255:255*(1-2*(1-a/255)*(1-b/255))},r=function(a,b){return 255*(1-(1-b/255)/(a/255))},z=function(a,b){return 255===a?255:(a=255*(b/255)/(1-a/255),a>255?255:a)},o.normal=p(A(Y)),o.multiply=p(A(X)),o.screen=p(A(qa)),o.overlay=p(A($)),o.darken=p(A(y)),o.lighten=p(A(R)),o.dodge=p(A(z)),o.burn=p(A(r)),s.blend=o,s.analyze=function(a){var b,c,d,e;for(d={min:Number.MAX_VALUE,max:Number.MAX_VALUE*-1,sum:0,values:[],count:0},c=0,b=a.length;c<b;c++)e=a[c],null==e||isNaN(e)||(d.values.push(e),d.sum+=e,e<d.min&&(d.min=e),e>d.max&&(d.max=e),d.count+=1);return d.domain=[d.min,d.max],d.limits=function(a,b){return s.limits(d,a,b)},d},s.scale=function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t,u,v,w,x;return k="rgb",l=s("#ccc"),p=0,h=!1,g=[0,1],o=[],n=[0,0],c=!1,e=[],m=!1,j=0,i=1,f=!1,d={},w=function(a){var b,c,d,f,g,h,i;if(null==a&&(a=["#fff","#000"]),null!=a&&"string"===ua(a)&&null!=(null!=(f=s.brewer)?f[a]:void 0)&&(a=s.brewer[a]),"array"===ua(a)){for(a=a.slice(0),b=d=0,g=a.length-1;0<=g?d<=g:d>=g;b=0<=g?++d:--d)c=a[b],"string"===ua(c)&&(a[b]=s(c));for(o.length=0,b=i=0,h=a.length-1;0<=h?i<=h:i>=h;b=0<=h?++i:--i)o.push(b/(a.length-1))}return v(),e=a},t=function(a){var b,d;if(null!=c){for(d=c.length-1,b=0;b<d&&a>=c[b];)b++;return b-1}return 0},x=function(a){return a},q=function(a){var b,d,e,f,g;return g=a,c.length>2&&(f=c.length-1,b=t(a),e=c[0]+(c[1]-c[0])*(0+.5*p),d=c[f-1]+(c[f]-c[f-1])*(1-.5*p),g=j+(c[b]+.5*(c[b+1]-c[b])-e)/(d-e)*(i-j)),g},u=function(a,b){var f,g,h,m,p,q,r,u;if(null==b&&(b=!1),isNaN(a))return l;if(b?u=a:c&&c.length>2?(f=t(a),u=f/(c.length-2),u=n[0]+u*(1-n[0]-n[1])):i!==j?(u=(a-j)/(i-j),u=n[0]+u*(1-n[0]-n[1]),u=Math.min(1,Math.max(0,u))):u=1,b||(u=x(u)),m=Math.floor(1e4*u),d[m])g=d[m];else{if("array"===ua(e))for(h=p=0,r=o.length-1;0<=r?p<=r:p>=r;h=0<=r?++p:--p){if(q=o[h],u<=q){g=e[h];break}if(u>=q&&h===o.length-1){g=e[h];break}if(u>q&&u<o[h+1]){u=(u-q)/(o[h+1]-q),g=s.interpolate(e[h],e[h+1],u,k);break}}else"function"===ua(e)&&(g=e(u));d[m]=g}return g},v=function(){return d={}},w(a),r=function(a){var b;return b=s(u(a)),m&&b[m]?b[m]():b},r.classes=function(a){var b;return null!=a?("array"===ua(a)?(c=a,g=[a[0],a[a.length-1]]):(b=s.analyze(g),c=0===a?[b.min,b.max]:s.limits(b,"e",a)),r):c},r.domain=function(a){var b,c,d,f,h,k,l;if(!arguments.length)return g;if(j=a[0],i=a[a.length-1],o=[],d=e.length,a.length===d&&j!==i)for(h=0,f=a.length;h<f;h++)c=a[h],o.push((c-j)/(i-j));else for(b=l=0,k=d-1;0<=k?l<=k:l>=k;b=0<=k?++l:--l)o.push(b/(d-1));return g=[j,i],r},r.mode=function(a){return arguments.length?(k=a,v(),r):k},r.range=function(a,b){return w(a,b),r},r.out=function(a){return m=a,r},r.spread=function(a){return arguments.length?(p=a,r):p},r.correctLightness=function(a){return null==a&&(a=!0),f=a,v(),x=f?function(a){var b,c,d,e,f,g,h,i,j;for(b=u(0,!0).lab()[0],c=u(1,!0).lab()[0],h=b>c,d=u(a,!0).lab()[0],f=b+(c-b)*a,e=d-f,i=0,j=1,g=20;Math.abs(e)>.01&&g-- >0;)!function(){return h&&(e*=-1),e<0?(i=a,a+=.5*(j-a)):(j=a,a+=.5*(i-a)),d=u(a,!0).lab()[0],e=d-f}();return a}:function(a){return a},r},r.padding=function(a){return null!=a?("number"===ua(a)&&(a=[a,a]),n=a,r):n},r.colors=function(){var b,d,e,f,h,i,j,k,l;if(f=0,h="hex",1===arguments.length&&("string"===ua(arguments[0])?h=arguments[0]:f=arguments[0]),2===arguments.length&&(f=arguments[0],h=arguments[1]),f)return d=g[0],b=g[1]-d,function(){j=[];for(var a=0;0<=f?a<f:a>f;0<=f?a++:a--)j.push(a);return j}.apply(this).map(function(a){return r(d+a/(f-1)*b)[h]()});if(a=[],k=[],c&&c.length>2)for(e=l=1,i=c.length;1<=i?l<i:l>i;e=1<=i?++l:--l)k.push(.5*(c[e-1]+c[e]));else k=g;return k.map(function(a){return r(a)[h]()})},r},null==s.scales&&(s.scales={}),s.scales.cool=function(){return s.scale([s.hsl(180,1,.9),s.hsl(250,.7,.4)])},s.scales.hot=function(){return s.scale(["#000","#f00","#ff0","#fff"],[0,.25,.75,1]).mode("rgb")},s.analyze=function(a,b,c){var d,e,f,g,h,i,j;if(h={min:Number.MAX_VALUE,max:Number.MAX_VALUE*-1,sum:0,values:[],count:0},null==c&&(c=function(){return!0}),d=function(a){null==a||isNaN(a)||(h.values.push(a),h.sum+=a,a<h.min&&(h.min=a),a>h.max&&(h.max=a),h.count+=1)},j=function(a,e){if(c(a,e))return d(null!=b&&"function"===ua(b)?b(a):null!=b&&"string"===ua(b)||"number"===ua(b)?a[b]:a)},"array"===ua(a))for(g=0,f=a.length;g<f;g++)i=a[g],j(i);else for(e in a)i=a[e],j(i,e);return h.domain=[h.min,h.max],h.limits=function(a,b){return s.limits(h,a,b)},h},s.limits=function(a,b,c){var d,e,f,g,h,i,j,k,m,n,o,p,q,r,t,u,v,w,x,y,z,A,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,U,V,X,Y,Z,$,aa,ba,ca,da,ea,fa,ga,ha,ia,ja;if(null==b&&(b="equal"),null==c&&(c=7),"array"===ua(a)&&(a=s.analyze(a)),E=a.min,W=a.max,fa=a.sum,ia=a.values.sort(function(a,b){return a-b}),C=[],"c"===b.substr(0,1)&&(C.push(E),C.push(W)),"e"===b.substr(0,1)){for(C.push(E),y=K=1,O=c-1;1<=O?K<=O:K>=O;y=1<=O?++K:--K)C.push(E+y/c*(W-E));C.push(W)}else if("l"===b.substr(0,1)){if(E<=0)throw"Logarithmic scales are only possible for values > 0";for(F=Math.LOG10E*T(E),D=Math.LOG10E*T(W),C.push(E),y=ja=1,P=c-1;1<=P?ja<=P:ja>=P;y=1<=P?++ja:--ja)C.push(_(10,F+y/c*(D-F)));C.push(W)}else if("q"===b.substr(0,1)){for(C.push(E),y=d=1,X=c-1;1<=X?d<=X:d>=X;y=1<=X?++d:--d)L=ia.length*y/c,M=B(L),M===L?C.push(ia[M]):(N=L-M,C.push(ia[M]*N+ia[M+1]*(1-N)));C.push(W)}else if("k"===b.substr(0,1)){for(H=ia.length,r=new Array(H),w=new Array(c),ea=!0,I=0,u=null,u=[],u.push(E),y=e=1,Y=c-1;1<=Y?e<=Y:e>=Y;y=1<=Y?++e:--e)u.push(E+y/c*(W-E));for(u.push(W);ea;){for(z=f=0,Z=c-1;0<=Z?f<=Z:f>=Z;z=0<=Z?++f:--f)w[z]=0;for(y=g=0,$=H-1;0<=$?g<=$:g>=$;y=0<=$?++g:--g){for(ha=ia[y],G=Number.MAX_VALUE,z=h=0,aa=c-1;0<=aa?h<=aa:h>=aa;z=0<=aa?++h:--h)x=l(u[z]-ha),x<G&&(G=x,t=z);w[t]++,r[y]=t}for(J=new Array(c),z=i=0,ba=c-1;0<=ba?i<=ba:i>=ba;z=0<=ba?++i:--i)J[z]=null;for(y=j=0,ca=H-1;0<=ca?j<=ca:j>=ca;y=0<=ca?++j:--j)v=r[y],null===J[v]?J[v]=ia[y]:J[v]+=ia[y];for(z=k=0,da=c-1;0<=da?k<=da:k>=da;z=0<=da?++k:--k)J[z]*=1/w[z];for(ea=!1,z=m=0,Q=c-1;0<=Q?m<=Q:m>=Q;z=0<=Q?++m:--m)if(J[z]!==u[y]){ea=!0;break}u=J,I++,I>200&&(ea=!1)}for(A={},z=n=0,R=c-1;0<=R?n<=R:n>=R;z=0<=R?++n:--n)A[z]=[];for(y=o=0,S=H-1;0<=S?o<=S:o>=S;y=0<=S?++o:--o)v=r[y],A[v].push(ia[y]);for(ga=[],z=p=0,U=c-1;0<=U?p<=U:p>=U;z=0<=U?++p:--p)ga.push(A[z][0]),ga.push(A[z][A[z].length-1]);for(ga=ga.sort(function(a,b){return a-b}),C.push(ga[0]),y=q=1,V=ga.length-1;q<=V;y=q+=2)isNaN(ga[y])||C.push(ga[y])}return C},D=function(a,b,c){var d,f,h,i;return d=va(arguments),a=d[0],b=d[1],c=d[2],a/=360,a<1/3?(f=(1-b)/3,i=(1+b*w(g*a)/w(e-g*a))/3,h=1-(f+i)):a<2/3?(a-=1/3,i=(1-b)/3,h=(1+b*w(g*a)/w(e-g*a))/3,f=1-(i+h)):(a-=2/3,h=(1-b)/3,f=(1+b*w(g*a)/w(e-g*a))/3,i=1-(h+f)),i=S(c*i*3),h=S(c*h*3),f=S(c*f*3),[255*i,255*h,255*f,d.length>3?d[3]:1]},da=function(){var a,b,c,d,e,f,h,i;return h=va(arguments),f=h[0],b=h[1],a=h[2],g=2*Math.PI,f/=255,b/=255,a/=255,e=Math.min(f,b,a),d=(f+b+a)/3,i=1-e/d,0===i?c=0:(c=(f-b+(f-a))/2,c/=Math.sqrt((f-b)*(f-b)+(f-a)*(b-a)),c=Math.acos(c),a>b&&(c=g-c),c/=g),[360*c,i,d]},s.hsi=function(){return function(a,b,c){c.prototype=a.prototype;var d=new c,e=a.apply(d,b);return Object(e)===e?e:d}(a,za.call(arguments).concat(["hsi"]),function(){})},j.hsi=D,a.prototype.hsi=function(){return da(this._rgb)},I=function(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q;return"hsl"===d?(p=a.hsl(),q=b.hsl()):"hsv"===d?(p=a.hsv(),q=b.hsv()):"hsi"===d?(p=a.hsi(),q=b.hsi()):"lch"!==d&&"hcl"!==d||(d="hcl",p=a.hcl(),q=b.hcl()),"h"===d.substr(0,1)&&(g=p[0],n=p[1],j=p[2],h=q[0],o=q[1],k=q[2]),isNaN(g)||isNaN(h)?isNaN(g)?isNaN(h)?f=Number.NaN:(f=h,1!==j&&0!==j||"hsv"===d||(m=o)):(f=g,1!==k&&0!==k||"hsv"===d||(m=n)):(e=h>g&&h-g>180?h-(g+360):h<g&&g-h>180?h+360-g:h-g,f=g+c*e),null==m&&(m=n+c*(o-n)),i=j+c*(k-j),l=s[d](f,m,i)},k=k.concat(function(){var a,b,c,d;for(c=["hsv","hsl","hsi","hcl","lch"],d=[],b=0,a=c.length;b<a;b++)V=c[b],d.push([V,I]);return d}()),K=function(a,b,c,d){var e,f;return e=a.num(),f=b.num(),s.num(e+(f-e)*c,"num"); +},k.push(["num",K]),J=function(b,c,d,e){var f,g,h;return g=b.lab(),h=c.lab(),f=new a(g[0]+d*(h[0]-g[0]),g[1]+d*(h[1]-g[1]),g[2]+d*(h[2]-g[2]),e)},k.push(["lab",J])}).call(this); \ No newline at end of file diff --git a/package.json b/package.json index cb1c7bf4..2fc4f427 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,9 @@ "version": "2.0.0", "description": "pomax.github.io/bezierinfo", "scripts": { - "bootstrap": "run-s makeindex makehandlers localize", + "bootstrap": "run-s copy:** makeindex makehandlers localize", + "copy:bezier": "shx cp node_modules/bezier-js/bezier.js lib/vendor", + "copy:chroma": "shx cp node_modules/chroma-js/chroma.min.js lib/vendor", "localize": "node tools/make-locales", "prebuild": "node tools/buildmark -- set", "build": "run-s bootstrap less build:** default", @@ -11,7 +13,7 @@ "postbuild": "node tools/buildmark -- resolve", "makehandlers": "node tools/aggregate-js-handlers", "makeindex": "node tools/form-section-index-files", - "build:en-GB": "webpack", + "build:en-GB": "webpack -p", "build:zh-CN": "cross-env LOCALE=zh-CN webpack -p", "build:ja-JP": "cross-env LOCALE=ja-JP webpack -p", "dev": "npm run bootstrap && npm run less && webpack-dev-server --progress --colors --hot --inline", @@ -83,6 +85,7 @@ "react-router": "^1.0.3", "sha1": "^1.1.1", "showdown": "^1.6.4", + "shx": "^0.2.2", "style-loader": "^0.13.0", "svgo": "^0.6.6", "uglify-loader": "^1.3.0",