(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('react-dom'), require('prop-types')) : typeof define === 'function' && define.amd ? define(['exports', 'react', 'react-dom', 'prop-types'], factory) : (global = global || self, factory(global.ReactFlow = {}, global.React, global.ReactDOM, global.PropTypes)); }(this, function (exports, React, reactDom, PropTypes) { 'use strict'; var React__default = 'default' in React ? React['default'] : React; reactDom = reactDom && reactDom.hasOwnProperty('default') ? reactDom['default'] : reactDom; PropTypes = PropTypes && PropTypes.hasOwnProperty('default') ? PropTypes['default'] : PropTypes; var obj; var NOTHING = typeof Symbol !== "undefined" ? Symbol("immer-nothing") : ( obj = {}, obj["immer-nothing"] = true, obj ); var DRAFTABLE = typeof Symbol !== "undefined" && Symbol.for ? Symbol.for("immer-draftable") : "__$immer_draftable"; var DRAFT_STATE = typeof Symbol !== "undefined" && Symbol.for ? Symbol.for("immer-state") : "__$immer_state"; function isDraft(value) { return !!value && !!value[DRAFT_STATE]; } function isDraftable(value) { if (!value || typeof value !== "object") { return false; } if (Array.isArray(value)) { return true; } var proto = Object.getPrototypeOf(value); if (!proto || proto === Object.prototype) { return true; } return !!value[DRAFTABLE] || !!value.constructor[DRAFTABLE]; } var assign = Object.assign || function assign(target, value) { for (var key in value) { if (has(value, key)) { target[key] = value[key]; } } return target; }; var ownKeys = typeof Reflect !== "undefined" && Reflect.ownKeys ? Reflect.ownKeys : typeof Object.getOwnPropertySymbols !== "undefined" ? function (obj) { return Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj)); } : Object.getOwnPropertyNames; function shallowCopy(base, invokeGetters) { if ( invokeGetters === void 0 ) invokeGetters = false; if (Array.isArray(base)) { return base.slice(); } var clone = Object.create(Object.getPrototypeOf(base)); ownKeys(base).forEach(function (key) { if (key === DRAFT_STATE) { return; // Never copy over draft state. } var desc = Object.getOwnPropertyDescriptor(base, key); var value = desc.value; if (desc.get) { if (invokeGetters) { value = desc.get.call(base); } } if (desc.enumerable) { clone[key] = value; } else if (invokeGetters) { Object.defineProperty(clone, key, { value: value, writable: true, configurable: true }); } }); return clone; } function each(value, cb) { if (Array.isArray(value)) { for (var i = 0; i < value.length; i++) { cb(i, value[i], value); } } else { ownKeys(value).forEach(function (key) { return cb(key, value[key], value); }); } } function isEnumerable(base, prop) { var desc = Object.getOwnPropertyDescriptor(base, prop); return !!desc && desc.enumerable; } function has(thing, prop) { return Object.prototype.hasOwnProperty.call(thing, prop); } function is(x, y) { // From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js if (x === y) { return x !== 0 || 1 / x === 1 / y; } else { return x !== x && y !== y; } } /** Each scope represents a `produce` call. */ var ImmerScope = function ImmerScope(parent) { this.drafts = []; this.parent = parent; // Whenever the modified draft contains a draft from another scope, we // need to prevent auto-freezing so the unowned draft can be finalized. this.canAutoFreeze = true; // To avoid prototype lookups: this.patches = null; }; ImmerScope.prototype.usePatches = function usePatches (patchListener) { if (patchListener) { this.patches = []; this.inversePatches = []; this.patchListener = patchListener; } }; ImmerScope.prototype.revoke = function revoke$1 () { this.leave(); this.drafts.forEach(revoke); this.drafts = null; // Make draft-related methods throw. }; ImmerScope.prototype.leave = function leave () { if (this === ImmerScope.current) { ImmerScope.current = this.parent; } }; ImmerScope.current = null; ImmerScope.enter = function () { return this.current = new ImmerScope(this.current); }; function revoke(draft) { draft[DRAFT_STATE].revoke(); } // but share them all instead var descriptors = {}; function willFinalize(scope, result, isReplaced) { scope.drafts.forEach(function (draft) { draft[DRAFT_STATE].finalizing = true; }); if (!isReplaced) { if (scope.patches) { markChangesRecursively(scope.drafts[0]); } // This is faster when we don't care about which attributes changed. markChangesSweep(scope.drafts); } // When a child draft is returned, look for changes. else if (isDraft(result) && result[DRAFT_STATE].scope === scope) { markChangesSweep(scope.drafts); } } function createProxy(base, parent) { var isArray = Array.isArray(base); var draft = clonePotentialDraft(base); each(draft, function (prop) { proxyProperty(draft, prop, isArray || isEnumerable(base, prop)); }); // See "proxy.js" for property documentation. var scope = parent ? parent.scope : ImmerScope.current; var state = { scope: scope, modified: false, finalizing: false, // es5 only finalized: false, assigned: {}, parent: parent, base: base, draft: draft, copy: null, revoke: revoke$1, revoked: false // es5 only }; createHiddenProperty(draft, DRAFT_STATE, state); scope.drafts.push(draft); return draft; } function revoke$1() { this.revoked = true; } function source(state) { return state.copy || state.base; } // Access a property without creating an Immer draft. function peek(draft, prop) { var state = draft[DRAFT_STATE]; if (state && !state.finalizing) { state.finalizing = true; var value = draft[prop]; state.finalizing = false; return value; } return draft[prop]; } function get(state, prop) { assertUnrevoked(state); var value = peek(source(state), prop); if (state.finalizing) { return value; } // Create a draft if the value is unmodified. if (value === peek(state.base, prop) && isDraftable(value)) { prepareCopy(state); return state.copy[prop] = createProxy(value, state); } return value; } function set(state, prop, value) { assertUnrevoked(state); state.assigned[prop] = true; if (!state.modified) { if (is(value, peek(source(state), prop))) { return; } markChanged(state); prepareCopy(state); } state.copy[prop] = value; } function markChanged(state) { if (!state.modified) { state.modified = true; if (state.parent) { markChanged(state.parent); } } } function prepareCopy(state) { if (!state.copy) { state.copy = clonePotentialDraft(state.base); } } function clonePotentialDraft(base) { var state = base && base[DRAFT_STATE]; if (state) { state.finalizing = true; var draft = shallowCopy(state.draft, true); state.finalizing = false; return draft; } return shallowCopy(base); } function proxyProperty(draft, prop, enumerable) { var desc = descriptors[prop]; if (desc) { desc.enumerable = enumerable; } else { descriptors[prop] = desc = { configurable: true, enumerable: enumerable, get: function get$1() { return get(this[DRAFT_STATE], prop); }, set: function set$1(value) { set(this[DRAFT_STATE], prop, value); } }; } Object.defineProperty(draft, prop, desc); } function assertUnrevoked(state) { if (state.revoked === true) { throw new Error("Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? " + JSON.stringify(source(state))); } } // This looks expensive, but only proxies are visited, and only objects without known changes are scanned. function markChangesSweep(drafts) { // The natural order of drafts in the `scope` array is based on when they // were accessed. By processing drafts in reverse natural order, we have a // better chance of processing leaf nodes first. When a leaf node is known to // have changed, we can avoid any traversal of its ancestor nodes. for (var i = drafts.length - 1; i >= 0; i--) { var state = drafts[i][DRAFT_STATE]; if (!state.modified) { if (Array.isArray(state.base)) { if (hasArrayChanges(state)) { markChanged(state); } } else if (hasObjectChanges(state)) { markChanged(state); } } } } function markChangesRecursively(object) { if (!object || typeof object !== "object") { return; } var state = object[DRAFT_STATE]; if (!state) { return; } var base = state.base; var draft = state.draft; var assigned = state.assigned; if (!Array.isArray(object)) { // Look for added keys. Object.keys(draft).forEach(function (key) { // The `undefined` check is a fast path for pre-existing keys. if (base[key] === undefined && !has(base, key)) { assigned[key] = true; markChanged(state); } else if (!assigned[key]) { // Only untouched properties trigger recursion. markChangesRecursively(draft[key]); } }); // Look for removed keys. Object.keys(base).forEach(function (key) { // The `undefined` check is a fast path for pre-existing keys. if (draft[key] === undefined && !has(draft, key)) { assigned[key] = false; markChanged(state); } }); } else if (hasArrayChanges(state)) { markChanged(state); assigned.length = true; if (draft.length < base.length) { for (var i = draft.length; i < base.length; i++) { assigned[i] = false; } } else { for (var i$1 = base.length; i$1 < draft.length; i$1++) { assigned[i$1] = true; } } for (var i$2 = 0; i$2 < draft.length; i$2++) { // Only untouched indices trigger recursion. if (assigned[i$2] === undefined) { markChangesRecursively(draft[i$2]); } } } } function hasObjectChanges(state) { var base = state.base; var draft = state.draft; // Search for added keys and changed keys. Start at the back, because // non-numeric keys are ordered by time of definition on the object. var keys = Object.keys(draft); for (var i = keys.length - 1; i >= 0; i--) { var key = keys[i]; var baseValue = base[key]; // The `undefined` check is a fast path for pre-existing keys. if (baseValue === undefined && !has(base, key)) { return true; } // Once a base key is deleted, future changes go undetected, because its // descriptor is erased. This branch detects any missed changes. else { var value = draft[key]; var state$1 = value && value[DRAFT_STATE]; if (state$1 ? state$1.base !== baseValue : !is(value, baseValue)) { return true; } } } // At this point, no keys were added or changed. // Compare key count to determine if keys were deleted. return keys.length !== Object.keys(base).length; } function hasArrayChanges(state) { var draft = state.draft; if (draft.length !== state.base.length) { return true; } // See #116 // If we first shorten the length, our array interceptors will be removed. // If after that new items are added, result in the same original length, // those last items will have no intercepting property. // So if there is no own descriptor on the last position, we know that items were removed and added // N.B.: splice, unshift, etc only shift values around, but not prop descriptors, so we only have to check // the last one var descriptor = Object.getOwnPropertyDescriptor(draft, draft.length - 1); // descriptor can be null, but only for newly created sparse arrays, eg. new Array(10) if (descriptor && !descriptor.get) { return true; } // For all other cases, we don't have to compare, as they would have been picked up by the index setters return false; } function createHiddenProperty(target, prop, value) { Object.defineProperty(target, prop, { value: value, enumerable: false, writable: true }); } var legacyProxy = /*#__PURE__*/Object.freeze({ willFinalize: willFinalize, createProxy: createProxy }); function willFinalize$1() {} function createProxy$1(base, parent) { var scope = parent ? parent.scope : ImmerScope.current; var state = { // Track which produce call this is associated with. scope: scope, // True for both shallow and deep changes. modified: false, // Used during finalization. finalized: false, // Track which properties have been assigned (true) or deleted (false). assigned: {}, // The parent draft state. parent: parent, // The base state. base: base, // The base proxy. draft: null, // Any property proxies. drafts: {}, // The base copy with any updated values. copy: null, // Called by the `produce` function. revoke: null }; var ref = Array.isArray(base) ? // [state] is used for arrays, to make sure the proxy is array-ish and not violate invariants, // although state itself is an object Proxy.revocable([state], arrayTraps) : Proxy.revocable(state, objectTraps); var revoke = ref.revoke; var proxy = ref.proxy; state.draft = proxy; state.revoke = revoke; scope.drafts.push(proxy); return proxy; } var objectTraps = { get: get$1, has: function has(target, prop) { return prop in source$1(target); }, ownKeys: function ownKeys(target) { return Reflect.ownKeys(source$1(target)); }, set: set$1, deleteProperty: deleteProperty, getOwnPropertyDescriptor: getOwnPropertyDescriptor, defineProperty: function defineProperty() { throw new Error("Object.defineProperty() cannot be used on an Immer draft"); // prettier-ignore }, getPrototypeOf: function getPrototypeOf(target) { return Object.getPrototypeOf(target.base); }, setPrototypeOf: function setPrototypeOf() { throw new Error("Object.setPrototypeOf() cannot be used on an Immer draft"); // prettier-ignore } }; var arrayTraps = {}; each(objectTraps, function (key, fn) { arrayTraps[key] = function () { arguments[0] = arguments[0][0]; return fn.apply(this, arguments); }; }); arrayTraps.deleteProperty = function (state, prop) { if (isNaN(parseInt(prop))) { throw new Error("Immer only supports deleting array indices"); // prettier-ignore } return objectTraps.deleteProperty.call(this, state[0], prop); }; arrayTraps.set = function (state, prop, value) { if (prop !== "length" && isNaN(parseInt(prop))) { throw new Error("Immer only supports setting array indices and the 'length' property"); // prettier-ignore } return objectTraps.set.call(this, state[0], prop, value); }; // returns the object we should be reading the current value from, which is base, until some change has been made function source$1(state) { return state.copy || state.base; } // Access a property without creating an Immer draft. function peek$1(draft, prop) { var state = draft[DRAFT_STATE]; var desc = Reflect.getOwnPropertyDescriptor(state ? source$1(state) : draft, prop); return desc && desc.value; } function get$1(state, prop) { if (prop === DRAFT_STATE) { return state; } var drafts = state.drafts; // Check for existing draft in unmodified state. if (!state.modified && has(drafts, prop)) { return drafts[prop]; } var value = source$1(state)[prop]; if (state.finalized || !isDraftable(value)) { return value; } // Check for existing draft in modified state. if (state.modified) { // Assigned values are never drafted. This catches any drafts we created, too. if (value !== peek$1(state.base, prop)) { return value; } // Store drafts on the copy (when one exists). drafts = state.copy; } return drafts[prop] = createProxy$1(value, state); } function set$1(state, prop, value) { if (!state.modified) { var baseValue = peek$1(state.base, prop); // Optimize based on value's truthiness. Truthy values are guaranteed to // never be undefined, so we can avoid the `in` operator. Lastly, truthy // values may be drafts, but falsy values are never drafts. var isUnchanged = value ? is(baseValue, value) || value === state.drafts[prop] : is(baseValue, value) && prop in state.base; if (isUnchanged) { return true; } markChanged$1(state); } state.assigned[prop] = true; state.copy[prop] = value; return true; } function deleteProperty(state, prop) { // The `undefined` check is a fast path for pre-existing keys. if (peek$1(state.base, prop) !== undefined || prop in state.base) { state.assigned[prop] = false; markChanged$1(state); } if (state.copy) { delete state.copy[prop]; } return true; } // Note: We never coerce `desc.value` into an Immer draft, because we can't make // the same guarantee in ES5 mode. function getOwnPropertyDescriptor(state, prop) { var owner = source$1(state); var desc = Reflect.getOwnPropertyDescriptor(owner, prop); if (desc) { desc.writable = true; desc.configurable = !Array.isArray(owner) || prop !== "length"; } return desc; } function markChanged$1(state) { if (!state.modified) { state.modified = true; state.copy = assign(shallowCopy(state.base), state.drafts); state.drafts = null; if (state.parent) { markChanged$1(state.parent); } } } var modernProxy = /*#__PURE__*/Object.freeze({ willFinalize: willFinalize$1, createProxy: createProxy$1 }); function generatePatches(state, basePath, patches, inversePatches) { Array.isArray(state.base) ? generateArrayPatches(state, basePath, patches, inversePatches) : generateObjectPatches(state, basePath, patches, inversePatches); } function generateArrayPatches(state, basePath, patches, inversePatches) { var assign, assign$1; var base = state.base; var copy = state.copy; var assigned = state.assigned; // Reduce complexity by ensuring `base` is never longer. if (copy.length < base.length) { (assign = [copy, base], base = assign[0], copy = assign[1]); (assign$1 = [inversePatches, patches], patches = assign$1[0], inversePatches = assign$1[1]); } var delta = copy.length - base.length; // Find the first replaced index. var start = 0; while (base[start] === copy[start] && start < base.length) { ++start; } // Find the last replaced index. Search from the end to optimize splice patches. var end = base.length; while (end > start && base[end - 1] === copy[end + delta - 1]) { --end; } // Process replaced indices. for (var i = start; i < end; ++i) { if (assigned[i] && copy[i] !== base[i]) { var path = basePath.concat([i]); patches.push({ op: "replace", path: path, value: copy[i] }); inversePatches.push({ op: "replace", path: path, value: base[i] }); } } var useRemove = end != base.length; var replaceCount = patches.length; // Process added indices. for (var i$1 = end + delta - 1; i$1 >= end; --i$1) { var path$1 = basePath.concat([i$1]); patches[replaceCount + i$1 - end] = { op: "add", path: path$1, value: copy[i$1] }; if (useRemove) { inversePatches.push({ op: "remove", path: path$1 }); } } // One "replace" patch reverses all non-splicing "add" patches. if (!useRemove) { inversePatches.push({ op: "replace", path: basePath.concat(["length"]), value: base.length }); } } function generateObjectPatches(state, basePath, patches, inversePatches) { var base = state.base; var copy = state.copy; each(state.assigned, function (key, assignedValue) { var origValue = base[key]; var value = copy[key]; var op = !assignedValue ? "remove" : key in base ? "replace" : "add"; if (origValue === value && op === "replace") { return; } var path = basePath.concat(key); patches.push(op === "remove" ? { op: op, path: path } : { op: op, path: path, value: value }); inversePatches.push(op === "add" ? { op: "remove", path: path } : op === "remove" ? { op: "add", path: path, value: origValue } : { op: "replace", path: path, value: origValue }); }); } function applyPatches(draft, patches) { for (var i = 0; i < patches.length; i++) { var patch = patches[i]; var path = patch.path; if (path.length === 0 && patch.op === "replace") { draft = patch.value; } else { var base = draft; for (var i$1 = 0; i$1 < path.length - 1; i$1++) { base = base[path[i$1]]; if (!base || typeof base !== "object") { throw new Error("Cannot apply patch, path doesn't resolve: " + path.join("/")); } // prettier-ignore } var key = path[path.length - 1]; switch (patch.op) { case "replace": base[key] = patch.value; break; case "add": if (Array.isArray(base)) { // TODO: support "foo/-" paths for appending to an array base.splice(key, 0, patch.value); } else { base[key] = patch.value; } break; case "remove": if (Array.isArray(base)) { base.splice(key, 1); } else { delete base[key]; } break; default: throw new Error("Unsupported patch operation: " + patch.op); } } } return draft; } function verifyMinified() {} var configDefaults = { useProxies: typeof Proxy !== "undefined" && typeof Reflect !== "undefined", autoFreeze: typeof process !== "undefined" ? process.env.NODE_ENV !== "production" : verifyMinified.name === "verifyMinified", onAssign: null, onDelete: null, onCopy: null }; var Immer = function Immer(config) { assign(this, configDefaults, config); this.setUseProxies(this.useProxies); this.produce = this.produce.bind(this); }; Immer.prototype.produce = function produce (base, recipe, patchListener) { var this$1 = this; // curried invocation if (typeof base === "function" && typeof recipe !== "function") { var defaultBase = recipe; recipe = base; var self = this; return function curriedProduce(base) { var this$1 = this; if ( base === void 0 ) base = defaultBase; var args = [], len = arguments.length - 1; while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ]; return self.produce(base, function (draft) { return recipe.call.apply(recipe, [ this$1, draft ].concat( args )); }); // prettier-ignore }; } // prettier-ignore { if (typeof recipe !== "function") { throw new Error("The first or second argument to `produce` must be a function"); } if (patchListener !== undefined && typeof patchListener !== "function") { throw new Error("The third argument to `produce` must be a function or undefined"); } } var result; // Only plain objects, arrays, and "immerable classes" are drafted. if (isDraftable(base)) { var scope = ImmerScope.enter(); var proxy = this.createProxy(base); var hasError = true; try { result = recipe(proxy); hasError = false; } finally { // finally instead of catch + rethrow better preserves original stack if (hasError) { scope.revoke(); }else { scope.leave(); } } if (result instanceof Promise) { return result.then(function (result) { scope.usePatches(patchListener); return this$1.processResult(result, scope); }, function (error) { scope.revoke(); throw error; }); } scope.usePatches(patchListener); return this.processResult(result, scope); } else { result = recipe(base); if (result === undefined) { return base; } return result !== NOTHING ? result : undefined; } }; Immer.prototype.createDraft = function createDraft (base) { if (!isDraftable(base)) { throw new Error("First argument to `createDraft` must be a plain object, an array, or an immerable object"); // prettier-ignore } var scope = ImmerScope.enter(); var proxy = this.createProxy(base); proxy[DRAFT_STATE].isManual = true; scope.leave(); return proxy; }; Immer.prototype.finishDraft = function finishDraft (draft, patchListener) { var state = draft && draft[DRAFT_STATE]; if (!state || !state.isManual) { throw new Error("First argument to `finishDraft` must be a draft returned by `createDraft`"); // prettier-ignore } if (state.finalized) { throw new Error("The given draft is already finalized"); // prettier-ignore } var scope = state.scope; scope.usePatches(patchListener); return this.processResult(undefined, scope); }; Immer.prototype.setAutoFreeze = function setAutoFreeze (value) { this.autoFreeze = value; }; Immer.prototype.setUseProxies = function setUseProxies (value) { this.useProxies = value; assign(this, value ? modernProxy : legacyProxy); }; Immer.prototype.applyPatches = function applyPatches$1 (base, patches) { // Mutate the base state when a draft is passed. if (isDraft(base)) { return applyPatches(base, patches); } // Otherwise, produce a copy of the base state. return this.produce(base, function (draft) { return applyPatches(draft, patches); }); }; /** @internal */ Immer.prototype.processResult = function processResult (result, scope) { var baseDraft = scope.drafts[0]; var isReplaced = result !== undefined && result !== baseDraft; this.willFinalize(scope, result, isReplaced); if (isReplaced) { if (baseDraft[DRAFT_STATE].modified) { scope.revoke(); throw new Error("An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft."); // prettier-ignore } if (isDraftable(result)) { // Finalize the result in case it contains (or is) a subset of the draft. result = this.finalize(result, null, scope); } if (scope.patches) { scope.patches.push({ op: "replace", path: [], value: result }); scope.inversePatches.push({ op: "replace", path: [], value: baseDraft[DRAFT_STATE].base }); } } else { // Finalize the base draft. result = this.finalize(baseDraft, [], scope); } scope.revoke(); if (scope.patches) { scope.patchListener(scope.patches, scope.inversePatches); } return result !== NOTHING ? result : undefined; }; /** * @internal * Finalize a draft, returning either the unmodified base state or a modified * copy of the base state. */ Immer.prototype.finalize = function finalize (draft, path, scope) { var this$1 = this; var state = draft[DRAFT_STATE]; if (!state) { if (Object.isFrozen(draft)) { return draft; } return this.finalizeTree(draft, null, scope); } // Never finalize drafts owned by another scope. if (state.scope !== scope) { return draft; } if (!state.modified) { return state.base; } if (!state.finalized) { state.finalized = true; this.finalizeTree(state.draft, path, scope); if (this.onDelete) { // The `assigned` object is unreliable with ES5 drafts. if (this.useProxies) { var assigned = state.assigned; for (var prop in assigned) { if (!assigned[prop]) { this.onDelete(state, prop); } } } else { var base = state.base; var copy = state.copy; each(base, function (prop) { if (!has(copy, prop)) { this$1.onDelete(state, prop); } }); } } if (this.onCopy) { this.onCopy(state); } // At this point, all descendants of `state.copy` have been finalized, // so we can be sure that `scope.canAutoFreeze` is accurate. if (this.autoFreeze && scope.canAutoFreeze) { Object.freeze(state.copy); } if (path && scope.patches) { generatePatches(state, path, scope.patches, scope.inversePatches); } } return state.copy; }; /** * @internal * Finalize all drafts in the given state tree. */ Immer.prototype.finalizeTree = function finalizeTree (root, rootPath, scope) { var this$1 = this; var state = root[DRAFT_STATE]; if (state) { if (!this.useProxies) { // Create the final copy, with added keys and without deleted keys. state.copy = shallowCopy(state.draft, true); } root = state.copy; } var needPatches = !!rootPath && !!scope.patches; var finalizeProperty = function (prop, value, parent) { if (value === parent) { throw Error("Immer forbids circular references"); } // In the `finalizeTree` method, only the `root` object may be a draft. var isDraftProp = !!state && parent === root; if (isDraft(value)) { var path = isDraftProp && needPatches && !state.assigned[prop] ? rootPath.concat(prop) : null; // Drafts owned by `scope` are finalized here. value = this$1.finalize(value, path, scope); // Drafts from another scope must prevent auto-freezing. if (isDraft(value)) { scope.canAutoFreeze = false; } // Preserve non-enumerable properties. if (Array.isArray(parent) || isEnumerable(parent, prop)) { parent[prop] = value; } else { Object.defineProperty(parent, prop, { value: value }); } // Unchanged drafts are never passed to the `onAssign` hook. if (isDraftProp && value === state.base[prop]) { return; } } // Unchanged draft properties are ignored. else if (isDraftProp && is(value, state.base[prop])) { return; } // Search new objects for unfinalized drafts. Frozen objects should never contain drafts. else if (isDraftable(value) && !Object.isFrozen(value)) { each(value, finalizeProperty); } if (isDraftProp && this$1.onAssign) { this$1.onAssign(state, prop, value); } }; each(root, finalizeProperty); return root; }; var immer = new Immer(); /** * Pass true to automatically freeze all copies created by Immer. * * By default, auto-freezing is disabled in production. */ var setAutoFreeze = immer.setAutoFreeze.bind(immer); /** * Pass true to use the ES2015 `Proxy` class when creating drafts, which is * always faster than using ES5 proxies. * * By default, feature detection is used, so calling this is rarely necessary. */ var setUseProxies = immer.setUseProxies.bind(immer); /** * Apply an array of Immer patches to the first argument. * * This function is a producer, which means copy-on-write is in effect. */ var applyPatches$1 = immer.applyPatches.bind(immer); /** * Create an Immer draft from the given base state, which may be a draft itself. * The draft can be modified until you finalize it with the `finishDraft` function. */ var createDraft = immer.createDraft.bind(immer); /** * Finalize an Immer draft from a `createDraft` call, returning the base state * (if no changes were made) or a modified copy. The draft must *not* be * mutated afterwards. * * Pass a function as the 2nd argument to generate Immer patches based on the * changes that were made. */ var finishDraft = immer.finishDraft.bind(immer); function symbolObservablePonyfill(root) { var result; var Symbol = root.Symbol; if (typeof Symbol === 'function') { if (Symbol.observable) { result = Symbol.observable; } else { result = Symbol('observable'); Symbol.observable = result; } } else { result = '@@observable'; } return result; } /* global window */ var root; if (typeof self !== 'undefined') { root = self; } else if (typeof window !== 'undefined') { root = window; } else if (typeof global !== 'undefined') { root = global; } else if (typeof module !== 'undefined') { root = module; } else { root = Function('return this')(); } var result = symbolObservablePonyfill(root); /** * These are private action types reserved by Redux. * For any unknown actions, you must return the current state. * If the current state is undefined, you must return the initial state. * Do not reference these action types directly in your code. */ var randomString = function randomString() { return Math.random().toString(36).substring(7).split('').join('.'); }; var ActionTypes = { INIT: "@@redux/INIT" + randomString(), REPLACE: "@@redux/REPLACE" + randomString(), PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() { return "@@redux/PROBE_UNKNOWN_ACTION" + randomString(); } }; /** * @param {any} obj The object to inspect. * @returns {boolean} True if the argument appears to be a plain object. */ function isPlainObject(obj) { if (typeof obj !== 'object' || obj === null) return false; var proto = obj; while (Object.getPrototypeOf(proto) !== null) { proto = Object.getPrototypeOf(proto); } return Object.getPrototypeOf(obj) === proto; } /** * Creates a Redux store that holds the state tree. * The only way to change the data in the store is to call `dispatch()` on it. * * There should only be a single store in your app. To specify how different * parts of the state tree respond to actions, you may combine several reducers * into a single reducer function by using `combineReducers`. * * @param {Function} reducer A function that returns the next state tree, given * the current state tree and the action to handle. * * @param {any} [preloadedState] The initial state. You may optionally specify it * to hydrate the state from the server in universal apps, or to restore a * previously serialized user session. * If you use `combineReducers` to produce the root reducer function, this must be * an object with the same shape as `combineReducers` keys. * * @param {Function} [enhancer] The store enhancer. You may optionally specify it * to enhance the store with third-party capabilities such as middleware, * time travel, persistence, etc. The only store enhancer that ships with Redux * is `applyMiddleware()`. * * @returns {Store} A Redux store that lets you read the state, dispatch actions * and subscribe to changes. */ function createStore(reducer, preloadedState, enhancer) { var _ref2; if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') { throw new Error('It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function.'); } if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') { enhancer = preloadedState; preloadedState = undefined; } if (typeof enhancer !== 'undefined') { if (typeof enhancer !== 'function') { throw new Error('Expected the enhancer to be a function.'); } return enhancer(createStore)(reducer, preloadedState); } if (typeof reducer !== 'function') { throw new Error('Expected the reducer to be a function.'); } var currentReducer = reducer; var currentState = preloadedState; var currentListeners = []; var nextListeners = currentListeners; var isDispatching = false; /** * This makes a shallow copy of currentListeners so we can use * nextListeners as a temporary list while dispatching. * * This prevents any bugs around consumers calling * subscribe/unsubscribe in the middle of a dispatch. */ function ensureCanMutateNextListeners() { if (nextListeners === currentListeners) { nextListeners = currentListeners.slice(); } } /** * Reads the state tree managed by the store. * * @returns {any} The current state tree of your application. */ function getState() { if (isDispatching) { throw new Error('You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.'); } return currentState; } /** * Adds a change listener. It will be called any time an action is dispatched, * and some part of the state tree may potentially have changed. You may then * call `getState()` to read the current state tree inside the callback. * * You may call `dispatch()` from a change listener, with the following * caveats: * * 1. The subscriptions are snapshotted just before every `dispatch()` call. * If you subscribe or unsubscribe while the listeners are being invoked, this * will not have any effect on the `dispatch()` that is currently in progress. * However, the next `dispatch()` call, whether nested or not, will use a more * recent snapshot of the subscription list. * * 2. The listener should not expect to see all state changes, as the state * might have been updated multiple times during a nested `dispatch()` before * the listener is called. It is, however, guaranteed that all subscribers * registered before the `dispatch()` started will be called with the latest * state by the time it exits. * * @param {Function} listener A callback to be invoked on every dispatch. * @returns {Function} A function to remove this change listener. */ function subscribe(listener) { if (typeof listener !== 'function') { throw new Error('Expected the listener to be a function.'); } if (isDispatching) { throw new Error('You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api-reference/store#subscribe(listener) for more details.'); } var isSubscribed = true; ensureCanMutateNextListeners(); nextListeners.push(listener); return function unsubscribe() { if (!isSubscribed) { return; } if (isDispatching) { throw new Error('You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api-reference/store#subscribe(listener) for more details.'); } isSubscribed = false; ensureCanMutateNextListeners(); var index = nextListeners.indexOf(listener); nextListeners.splice(index, 1); }; } /** * Dispatches an action. It is the only way to trigger a state change. * * The `reducer` function, used to create the store, will be called with the * current state tree and the given `action`. Its return value will * be considered the **next** state of the tree, and the change listeners * will be notified. * * The base implementation only supports plain object actions. If you want to * dispatch a Promise, an Observable, a thunk, or something else, you need to * wrap your store creating function into the corresponding middleware. For * example, see the documentation for the `redux-thunk` package. Even the * middleware will eventually dispatch plain object actions using this method. * * @param {Object} action A plain object representing “what changed”. It is * a good idea to keep actions serializable so you can record and replay user * sessions, or use the time travelling `redux-devtools`. An action must have * a `type` property which may not be `undefined`. It is a good idea to use * string constants for action types. * * @returns {Object} For convenience, the same action object you dispatched. * * Note that, if you use a custom middleware, it may wrap `dispatch()` to * return something else (for example, a Promise you can await). */ function dispatch(action) { if (!isPlainObject(action)) { throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.'); } if (typeof action.type === 'undefined') { throw new Error('Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?'); } if (isDispatching) { throw new Error('Reducers may not dispatch actions.'); } try { isDispatching = true; currentState = currentReducer(currentState, action); } finally { isDispatching = false; } var listeners = currentListeners = nextListeners; for (var i = 0; i < listeners.length; i++) { var listener = listeners[i]; listener(); } return action; } /** * Replaces the reducer currently used by the store to calculate the state. * * You might need this if your app implements code splitting and you want to * load some of the reducers dynamically. You might also need this if you * implement a hot reloading mechanism for Redux. * * @param {Function} nextReducer The reducer for the store to use instead. * @returns {void} */ function replaceReducer(nextReducer) { if (typeof nextReducer !== 'function') { throw new Error('Expected the nextReducer to be a function.'); } currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT. // Any reducers that existed in both the new and old rootReducer // will receive the previous state. This effectively populates // the new state tree with any relevant data from the old one. dispatch({ type: ActionTypes.REPLACE }); } /** * Interoperability point for observable/reactive libraries. * @returns {observable} A minimal observable of state changes. * For more information, see the observable proposal: * https://github.com/tc39/proposal-observable */ function observable() { var _ref; var outerSubscribe = subscribe; return _ref = { /** * The minimal observable subscription method. * @param {Object} observer Any object that can be used as an observer. * The observer object should have a `next` method. * @returns {subscription} An object with an `unsubscribe` method that can * be used to unsubscribe the observable from the store, and prevent further * emission of values from the observable. */ subscribe: function subscribe(observer) { if (typeof observer !== 'object' || observer === null) { throw new TypeError('Expected the observer to be an object.'); } function observeState() { if (observer.next) { observer.next(getState()); } } observeState(); var unsubscribe = outerSubscribe(observeState); return { unsubscribe: unsubscribe }; } }, _ref[result] = function () { return this; }, _ref; } // When a store is created, an "INIT" action is dispatched so that every // reducer returns their initial state. This effectively populates // the initial state tree. dispatch({ type: ActionTypes.INIT }); return _ref2 = { dispatch: dispatch, subscribe: subscribe, getState: getState, replaceReducer: replaceReducer }, _ref2[result] = observable, _ref2; } /** * Prints a warning in the console if it exists. * * @param {String} message The warning message. * @returns {void} */ function warning(message) { /* eslint-disable no-console */ if (typeof console !== 'undefined' && typeof console.error === 'function') { console.error(message); } /* eslint-enable no-console */ try { // This error was thrown as a convenience so that if you enable // "break on all exceptions" in your console, // it would pause the execution at this line. throw new Error(message); } catch (e) {} // eslint-disable-line no-empty } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { keys.push.apply(keys, Object.getOwnPropertySymbols(object)); } if (enumerableOnly) keys = keys.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$1(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$1(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * Composes single-argument functions from right to left. The rightmost * function can take multiple arguments as it provides the signature for * the resulting composite function. * * @param {...Function} funcs The functions to compose. * @returns {Function} A function obtained by composing the argument functions * from right to left. For example, compose(f, g, h) is identical to doing * (...args) => f(g(h(...args))). */ function compose() { for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) { funcs[_key] = arguments[_key]; } if (funcs.length === 0) { return function (arg) { return arg; }; } if (funcs.length === 1) { return funcs[0]; } return funcs.reduce(function (a, b) { return function () { return a(b.apply(void 0, arguments)); }; }); } /** * Creates a store enhancer that applies middleware to the dispatch method * of the Redux store. This is handy for a variety of tasks, such as expressing * asynchronous actions in a concise manner, or logging every action payload. * * See `redux-thunk` package as an example of the Redux middleware. * * Because middleware is potentially asynchronous, this should be the first * store enhancer in the composition chain. * * Note that each middleware will be given the `dispatch` and `getState` functions * as named arguments. * * @param {...Function} middlewares The middleware chain to be applied. * @returns {Function} A store enhancer applying the middleware. */ function applyMiddleware() { for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) { middlewares[_key] = arguments[_key]; } return function (createStore) { return function () { var store = createStore.apply(void 0, arguments); var _dispatch = function dispatch() { throw new Error('Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.'); }; var middlewareAPI = { getState: store.getState, dispatch: function dispatch() { return _dispatch.apply(void 0, arguments); } }; var chain = middlewares.map(function (middleware) { return middleware(middlewareAPI); }); _dispatch = compose.apply(void 0, chain)(store.dispatch); return _objectSpread2({}, store, { dispatch: _dispatch }); }; }; } /* * This is a dummy function to check if the function name has been altered by minification. * If the function has been minified and NODE_ENV !== 'production', warn the user. */ function isCrushed() {} if (process.env.NODE_ENV !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') { warning('You are currently using minified code outside of NODE_ENV === "production". ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or setting mode to production in webpack (https://webpack.js.org/concepts/mode/) ' + 'to ensure you have the correct code for your production build.'); } function createThunkMiddleware(extraArgument) { return function (_ref) { var dispatch = _ref.dispatch, getState = _ref.getState; return function (next) { return function (action) { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }; }; }; } var thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; function Similar() { this.list = []; this.lastItem = undefined; this.size = 0; return this; } Similar.prototype.get = function(key) { var index; if (this.lastItem && this.isEqual(this.lastItem.key, key)) { return this.lastItem.val; } index = this.indexOf(key); if (index >= 0) { this.lastItem = this.list[index]; return this.list[index].val; } return undefined; }; Similar.prototype.set = function(key, val) { var index; if (this.lastItem && this.isEqual(this.lastItem.key, key)) { this.lastItem.val = val; return this; } index = this.indexOf(key); if (index >= 0) { this.lastItem = this.list[index]; this.list[index].val = val; return this; } this.lastItem = { key: key, val: val }; this.list.push(this.lastItem); this.size++; return this; }; Similar.prototype.delete = function(key) { var index; if (this.lastItem && this.isEqual(this.lastItem.key, key)) { this.lastItem = undefined; } index = this.indexOf(key); if (index >= 0) { this.size--; return this.list.splice(index, 1)[0]; } return undefined; }; // important that has() doesn't use get() in case an existing key has a falsy value, in which case has() would return false Similar.prototype.has = function(key) { var index; if (this.lastItem && this.isEqual(this.lastItem.key, key)) { return true; } index = this.indexOf(key); if (index >= 0) { this.lastItem = this.list[index]; return true; } return false; }; Similar.prototype.forEach = function(callback, thisArg) { var i; for (i = 0; i < this.size; i++) { callback.call(thisArg || this, this.list[i].val, this.list[i].key, this); } }; Similar.prototype.indexOf = function(key) { var i; for (i = 0; i < this.size; i++) { if (this.isEqual(this.list[i].key, key)) { return i; } } return -1; }; // check if the numbers are equal, or whether they are both precisely NaN (isNaN returns true for all non-numbers) Similar.prototype.isEqual = function(val1, val2) { return val1 === val2 || (val1 !== val1 && val2 !== val2); }; var similar = Similar; var mapOrSimilar = function(forceSimilar) { if (typeof Map !== 'function' || forceSimilar) { var Similar = similar; return new Similar(); } else { return new Map(); } }; var memoizerific = function (limit) { var cache = new mapOrSimilar(process.env.FORCE_SIMILAR_INSTEAD_OF_MAP === 'true'), lru = []; return function (fn) { var memoizerific = function () { var currentCache = cache, newMap, fnResult, argsLengthMinusOne = arguments.length - 1, lruPath = Array(argsLengthMinusOne + 1), isMemoized = true, i; if ((memoizerific.numArgs || memoizerific.numArgs === 0) && memoizerific.numArgs !== argsLengthMinusOne + 1) { throw new Error('Memoizerific functions should always be called with the same number of arguments'); } // loop through each argument to traverse the map tree for (i = 0; i < argsLengthMinusOne; i++) { lruPath[i] = { cacheItem: currentCache, arg: arguments[i] }; // climb through the hierarchical map tree until the second-last argument has been found, or an argument is missing. // if all arguments up to the second-last have been found, this will potentially be a cache hit (determined later) if (currentCache.has(arguments[i])) { currentCache = currentCache.get(arguments[i]); continue; } isMemoized = false; // make maps until last value newMap = new mapOrSimilar(process.env.FORCE_SIMILAR_INSTEAD_OF_MAP === 'true'); currentCache.set(arguments[i], newMap); currentCache = newMap; } // we are at the last arg, check if it is really memoized if (isMemoized) { if (currentCache.has(arguments[argsLengthMinusOne])) { fnResult = currentCache.get(arguments[argsLengthMinusOne]); } else { isMemoized = false; } } // if the result wasn't memoized, compute it and cache it if (!isMemoized) { fnResult = fn.apply(null, arguments); currentCache.set(arguments[argsLengthMinusOne], fnResult); } // if there is a cache limit, purge any extra results if (limit > 0) { lruPath[argsLengthMinusOne] = { cacheItem: currentCache, arg: arguments[argsLengthMinusOne] }; if (isMemoized) { moveToMostRecentLru(lru, lruPath); } else { lru.push(lruPath); } if (lru.length > limit) { removeCachedResult(lru.shift()); } } memoizerific.wasMemoized = isMemoized; memoizerific.numArgs = argsLengthMinusOne + 1; return fnResult; }; memoizerific.limit = limit; memoizerific.wasMemoized = false; memoizerific.cache = cache; memoizerific.lru = lru; return memoizerific; }; }; // move current args to most recent position function moveToMostRecentLru(lru, lruPath) { var lruLen = lru.length, lruPathLen = lruPath.length, isMatch, i, ii; for (i = 0; i < lruLen; i++) { isMatch = true; for (ii = 0; ii < lruPathLen; ii++) { if (!isEqual(lru[i][ii].arg, lruPath[ii].arg)) { isMatch = false; break; } } if (isMatch) { break; } } lru.push(lru.splice(i, 1)[0]); } // remove least recently used cache item and all dead branches function removeCachedResult(removedLru) { var removedLruLen = removedLru.length, currentLru = removedLru[removedLruLen - 1], tmp, i; currentLru.cacheItem.delete(currentLru.arg); // walk down the tree removing dead branches (size 0) along the way for (i = removedLruLen - 2; i >= 0; i--) { currentLru = removedLru[i]; tmp = currentLru.cacheItem.get(currentLru.arg); if (!tmp || !tmp.size) { currentLru.cacheItem.delete(currentLru.arg); } else { break; } } } // check if the numbers are equal, or whether they are both precisely NaN (isNaN returns true for all non-numbers) function isEqual(val1, val2) { return val1 === val2 || (val1 !== val1 && val2 !== val2); } var StoreContext = React.createContext(); // To get around it, we can conditionally useEffect on the server (no-op) and // useLayoutEffect in the browser. We need useLayoutEffect to ensure the store // subscription callback always has the selector from the latest render commit // available, otherwise a store update may happen between render and the effect, // which may cause missed updates; we also must ensure the store subscription // is created synchronously, otherwise a store update may occur before the // subscription is created and an inconsistent state may be observed var useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect; function createStoreStateHook(Context) { return function useStoreState(mapState) { var store = React.useContext(Context); var mapStateRef = React.useRef(mapState); var stateRef = React.useRef(); var mountedRef = React.useRef(true); var subscriptionMapStateError = React.useRef(); var _useReducer = React.useReducer(function (s) { return s + 1; }, 0), forceRender = _useReducer[1]; if (subscriptionMapStateError.current || mapStateRef.current !== mapState || stateRef.current === undefined) { try { stateRef.current = mapState(store.getState()); } catch (err) { var errorMessage = "An error occurred trying to map state in a useStoreState hook: " + err.message + "."; if (subscriptionMapStateError.current) { errorMessage += "\nThis error may be related to the following error:\n" + subscriptionMapStateError.current.stack + "\n\nOriginal stack trace:"; } throw new Error(errorMessage); } } useIsomorphicLayoutEffect(function () { mapStateRef.current = mapState; subscriptionMapStateError.current = undefined; }); useIsomorphicLayoutEffect(function () { var checkMapState = function checkMapState() { try { var newState = mapStateRef.current(store.getState()); if (newState === stateRef.current) { return; } stateRef.current = newState; } catch (err) { // see https://github.com/reduxjs/react-redux/issues/1179 // There is a possibility mapState will fail due to stale state or // props, therefore we will just track the error and force our // component to update. It should then receive the updated state subscriptionMapStateError.current = err; } if (mountedRef.current) { forceRender({}); } }; var unsubscribe = store.subscribe(checkMapState); checkMapState(); return function () { mountedRef.current = false; unsubscribe(); }; }, []); return stateRef.current; }; } var useStoreState = createStoreStateHook(StoreContext); function createStoreActionsHook(Context) { return function useStoreActions(mapActions) { var store = React.useContext(Context); return mapActions(store.getActions()); }; } var useStoreActions = createStoreActionsHook(StoreContext); function _extends() { _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; }; return _extends.apply(this, arguments); } var actionSymbol = '🙈action🙈'; var actionOnSymbol = '🙈actionOn🙈'; var computedSymbol = '🙈computedSymbol🙈'; var reducerSymbol = '🙈reducer🙈'; var thunkOnSymbol = '🙈thunkOn🙈'; var thunkSymbol = '🙈thunk🙈'; var action = function action(fn) { fn[actionSymbol] = {}; return fn; }; var isStateObject = function isStateObject(x) { return x !== null && typeof x === 'object' && !Array.isArray(x) && x.constructor === Object; }; var get$2 = function get(path, target) { return path.reduce(function (acc, cur) { return isStateObject(acc) ? acc[cur] : undefined; }, target); }; var set$2 = function set(path, target, value) { path.reduce(function (acc, cur, idx) { if (idx + 1 === path.length) { acc[cur] = value; } else { acc[cur] = acc[cur] || {}; } return acc[cur]; }, target); }; var newify = function newify(currentPath, currentState, finalValue) { if (currentPath.length === 0) { return finalValue; } var newState = _extends({}, currentState); var key = currentPath[0]; if (currentPath.length === 1) { newState[key] = finalValue; } else { newState[key] = newify(currentPath.slice(1), newState[key], finalValue); } return newState; }; function createStoreInternals(_ref) { var disableImmer = _ref.disableImmer, initialState = _ref.initialState, injections = _ref.injections, model = _ref.model, reducerEnhancer = _ref.reducerEnhancer, references = _ref.references; function simpleProduce(path, state, fn) { if (disableImmer) { var _current = get$2(path, state); var next = fn(_current); if (_current !== next) { return newify(path, state, next); } return state; } var draft = createDraft(state); var current = get$2(path, draft); fn(current); return finishDraft(draft); } var defaultState = initialState; var actionCreatorDict = {}; var actionCreators = {}; var actionReducersDict = {}; var actionThunks = {}; var computedProperties = []; var customReducers = []; var listenerActionCreators = {}; var listenerActionMap = {}; var listenerDefinitions = []; var computedState = { isInReducer: false, currentState: defaultState }; var recursiveExtractDefsFromModel = function recursiveExtractDefsFromModel(current, parentPath) { return Object.keys(current).forEach(function (key) { var value = current[key]; var path = [].concat(parentPath, [key]); var meta = { parent: parentPath, path: path }; var handleValueAsState = function handleValueAsState() { var initialParentRef = get$2(parentPath, initialState); if (initialParentRef && key in initialParentRef) { set$2(path, defaultState, initialParentRef[key]); } else { set$2(path, defaultState, value); } }; if (typeof value === 'function') { if (value[actionSymbol] || value[actionOnSymbol]) { var prefix = value[actionSymbol] ? '@action' : '@actionOn'; var type = prefix + "." + path.join('.'); var actionMeta = value[actionSymbol] || value[actionOnSymbol]; actionMeta.actionName = key; actionMeta.type = type; actionMeta.parent = meta.parent; actionMeta.path = meta.path; // Action Reducer actionReducersDict[type] = value; // Action Creator var actionCreator = function actionCreator(payload) { var actionDefinition = { type: type, payload: payload }; if (value[actionOnSymbol] && actionMeta.resolvedTargets) { payload.resolvedTargets = [].concat(actionMeta.resolvedTargets); } var result = references.dispatch(actionDefinition); return result; }; actionCreator.type = type; actionCreatorDict[type] = actionCreator; if (key !== 'easyPeasyReplaceState') { if (value[actionOnSymbol]) { listenerDefinitions.push(value); set$2(path, listenerActionCreators, actionCreator); } else { set$2(path, actionCreators, actionCreator); } } } else if (value[thunkSymbol] || value[thunkOnSymbol]) { var _prefix = value[thunkSymbol] ? '@thunk' : '@thunkOn'; var _type = _prefix + "." + path.join('.'); var thunkMeta = value[thunkSymbol] || value[thunkOnSymbol]; thunkMeta.actionName = key; thunkMeta.type = _type; thunkMeta.parent = meta.parent; thunkMeta.path = meta.path; // Thunk Action var thunkHandler = function thunkHandler(payload) { var helpers = { dispatch: references.dispatch, getState: function getState() { return get$2(parentPath, references.getState()); }, getStoreActions: function getStoreActions() { return actionCreators; }, getStoreState: references.getState, injections: injections, meta: meta }; if (value[thunkOnSymbol] && thunkMeta.resolvedTargets) { payload.resolvedTargets = [].concat(thunkMeta.resolvedTargets); } return value(get$2(parentPath, actionCreators), payload, helpers); }; set$2(path, actionThunks, thunkHandler); // Thunk Action Creator var startType = _type + "(start)"; var successType = _type + "(success)"; var failType = _type + "(fail)"; var _actionCreator = function _actionCreator(payload) { var dispatchError = function dispatchError(err) { references.dispatch({ type: failType, payload: payload, error: err }); references.dispatch({ type: _type, payload: payload, error: err }); }; var dispatchSuccess = function dispatchSuccess(result) { references.dispatch({ type: successType, payload: payload, result: result }); references.dispatch({ type: _type, payload: payload, result: result }); }; references.dispatch({ type: startType, payload: payload }); try { var result = references.dispatch(function () { return thunkHandler(payload); }); if (typeof result === 'object' && typeof result.then === 'function') { return result.then(function (resolved) { dispatchSuccess(resolved); return resolved; }).catch(function (err) { dispatchError(err); throw err; }); } dispatchSuccess(result); return result; } catch (err) { dispatchError(err); throw err; } }; _actionCreator.type = _type; _actionCreator.startType = startType; _actionCreator.successType = successType; _actionCreator.failType = failType; actionCreatorDict[_type] = _actionCreator; if (value[thunkOnSymbol]) { listenerDefinitions.push(value); set$2(path, listenerActionCreators, _actionCreator); } else { set$2(path, actionCreators, _actionCreator); } } else if (value[computedSymbol]) { var parent = get$2(parentPath, defaultState); var computedMeta = value[computedSymbol]; var memoisedResultFn = memoizerific(1)(value); var createComputedProperty = function createComputedProperty(o) { Object.defineProperty(o, key, { configurable: true, enumerable: true, get: function get$1() { var storeState; if (computedState.isInReducer) { storeState = computedState.currentState; } else if (references.getState == null) { return undefined; } else { try { storeState = references.getState(); } catch (err) { if (process.env.NODE_ENV !== 'production') { console.warn('Invalid access attempt to a computed property'); } return undefined; } } var state = get$2(parentPath, storeState); var inputs = computedMeta.stateResolvers.map(function (resolver) { return resolver(state, storeState); }); return memoisedResultFn.apply(void 0, inputs); } }); }; createComputedProperty(parent); computedProperties.push({ key: key, parentPath: parentPath, createComputedProperty: createComputedProperty }); } else if (value[reducerSymbol]) { customReducers.push({ key: key, parentPath: parentPath, reducer: value }); } else { handleValueAsState(); } } else if (isStateObject(value)) { var existing = get$2(path, defaultState); if (existing == null) { set$2(path, defaultState, {}); } recursiveExtractDefsFromModel(value, path); } else { handleValueAsState(); } }); }; recursiveExtractDefsFromModel(model, []); listenerDefinitions.forEach(function (listenerActionOrThunk) { var listenerMeta = listenerActionOrThunk[actionOnSymbol] || listenerActionOrThunk[thunkOnSymbol]; var targets = listenerMeta.targetResolver(get$2(listenerMeta.parent, actionCreators), actionCreators); var targetTypes = (Array.isArray(targets) ? targets : [targets]).reduce(function (acc, target) { if (typeof target === 'function' && target.type && actionCreatorDict[target.type]) { acc.push(target.type); } else if (typeof target === 'string') { acc.push(target); } return acc; }, []); listenerMeta.resolvedTargets = targetTypes; targetTypes.forEach(function (targetType) { var listenerReg = listenerActionMap[targetType] || []; listenerReg.push(actionCreatorDict[listenerMeta.type]); listenerActionMap[targetType] = listenerReg; }); }); var createReducer = function createReducer() { var runActionReducerAtPath = function runActionReducerAtPath(state, action, actionReducer, path) { return simpleProduce(path, state, function (draft) { return actionReducer(draft, action.payload); }); }; var reducerForActions = function reducerForActions(state, action) { var actionReducer = actionReducersDict[action.type]; if (actionReducer) { var actionMeta = actionReducer[actionSymbol] || actionReducer[actionOnSymbol]; return runActionReducerAtPath(state, action, actionReducer, actionMeta.parent); } return state; }; var reducerForCustomReducers = function reducerForCustomReducers(state, action) { return customReducers.reduce(function (acc, _ref2) { var parentPath = _ref2.parentPath, key = _ref2.key, red = _ref2.reducer; return simpleProduce(parentPath, acc, function (draft) { draft[key] = red(draft[key], action); return draft; }); }, state); }; var rootReducer = function rootReducer(state, action) { var stateAfterActions = reducerForActions(state, action); var next = customReducers.length > 0 ? reducerForCustomReducers(stateAfterActions, action) : stateAfterActions; if (state !== next) { computedProperties.forEach(function (_ref3) { var parentPath = _ref3.parentPath, createComputedProperty = _ref3.createComputedProperty; createComputedProperty(get$2(parentPath, next)); }); } return next; }; return rootReducer; }; return { actionCreatorDict: actionCreatorDict, actionCreators: actionCreators, computedProperties: computedProperties, computedState: computedState, defaultState: defaultState, listenerActionCreators: listenerActionCreators, listenerActionMap: listenerActionMap, reducer: reducerEnhancer(createReducer()) }; } function createStore$1(model, options) { if (options === void 0) { options = {}; } var _options = options, compose$1 = _options.compose, _options$devTools = _options.devTools, devTools = _options$devTools === void 0 ? true : _options$devTools, _options$disableImmer = _options.disableImmer, disableImmer = _options$disableImmer === void 0 ? false : _options$disableImmer, _options$enhancers = _options.enhancers, enhancers = _options$enhancers === void 0 ? [] : _options$enhancers, _options$initialState = _options.initialState, initialState = _options$initialState === void 0 ? {} : _options$initialState, injections = _options.injections, _options$middleware = _options.middleware, middleware = _options$middleware === void 0 ? [] : _options$middleware, _options$mockActions = _options.mockActions, mockActions = _options$mockActions === void 0 ? false : _options$mockActions, _options$name = _options.name, storeName = _options$name === void 0 ? "EasyPeasyStore" : _options$name, _options$reducerEnhan = _options.reducerEnhancer, reducerEnhancer = _options$reducerEnhan === void 0 ? function (rootReducer) { return rootReducer; } : _options$reducerEnhan; var bindReplaceState = function bindReplaceState(modelDef) { return _extends({}, modelDef, { easyPeasyReplaceState: action(function (state, payload) { return payload; }) }); }; var modelDefinition = bindReplaceState(model); var mockedActions = []; var references = {}; var bindStoreInternals = function bindStoreInternals(state) { if (state === void 0) { state = {}; } references.internals = createStoreInternals({ disableImmer: disableImmer, initialState: state, injections: injections, model: modelDefinition, reducerEnhancer: reducerEnhancer, references: references }); }; bindStoreInternals(initialState); var listenerActionsMiddleware = function listenerActionsMiddleware() { return function (next) { return function (action) { var result = next(action); if (action && references.internals.listenerActionMap[action.type] && references.internals.listenerActionMap[action.type].length > 0) { var sourceAction = references.internals.actionCreatorDict[action.type]; references.internals.listenerActionMap[action.type].forEach(function (actionCreator) { actionCreator({ type: sourceAction ? sourceAction.type : action.type, payload: action.payload, error: action.error, result: action.result }); }); } return result; }; }; }; var mockActionsMiddleware = function mockActionsMiddleware() { return function () { return function (action) { if (action != null) { mockedActions.push(action); } return undefined; }; }; }; var computedPropertiesMiddleware = function computedPropertiesMiddleware(store) { return function (next) { return function (action) { references.internals.computedState.currentState = store.getState(); references.internals.computedState.isInReducer = true; return next(action); }; }; }; var easyPeasyMiddleware = [computedPropertiesMiddleware, thunk].concat(middleware, [listenerActionsMiddleware]); if (mockActions) { easyPeasyMiddleware.push(mockActionsMiddleware); } var composeEnhancers = compose$1 || (devTools && typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ name: storeName }) : compose); var store = createStore(references.internals.reducer, references.internals.defaultState, composeEnhancers.apply(void 0, [applyMiddleware.apply(void 0, easyPeasyMiddleware)].concat(enhancers))); store.subscribe(function () { references.internals.computedState.isInReducer = false; }); references.dispatch = store.dispatch; references.getState = store.getState; var bindActionCreators = function bindActionCreators() { Object.keys(store.dispatch).forEach(function (actionsKey) { delete store.dispatch[actionsKey]; }); Object.keys(references.internals.actionCreators).forEach(function (key) { store.dispatch[key] = references.internals.actionCreators[key]; }); }; bindActionCreators(); var rebindStore = function rebindStore(removeKey) { var currentState = store.getState(); if (removeKey) { delete currentState[removeKey]; } bindStoreInternals(store.getState()); store.replaceReducer(references.internals.reducer); references.internals.actionCreatorDict['@action.easyPeasyReplaceState'](references.internals.defaultState); bindActionCreators(); }; return Object.assign(store, { addModel: function addModel(key, modelForKey) { if (modelDefinition[key] && process.env.NODE_ENV !== 'production') { // eslint-disable-next-line no-console console.warn("easy-peasy: The store model already contains a model definition for \"" + key + "\""); store.removeModel(key); } modelDefinition[key] = modelForKey; rebindStore(); }, clearMockedActions: function clearMockedActions() { mockedActions = []; }, getActions: function getActions() { return references.internals.actionCreators; }, getListeners: function getListeners() { return references.internals.listenerActionCreators; }, getMockedActions: function getMockedActions() { return [].concat(mockedActions); }, reconfigure: function reconfigure(newModel) { modelDefinition = bindReplaceState(newModel); rebindStore(); }, removeModel: function removeModel(key) { if (!modelDefinition[key]) { if (process.env.NODE_ENV !== 'production') { // eslint-disable-next-line no-console console.warn("easy-peasy: The store model does not contain a model definition for \"" + key + "\""); } return; } delete modelDefinition[key]; rebindStore(key); } }); } var StoreProvider = function StoreProvider(_ref) { var children = _ref.children, store = _ref.store; return React__default.createElement(StoreContext.Provider, { value: store }, children); }; /** * The auto freeze feature of immer doesn't seem to work in our testing. We have * explicitly disabled it to avoid perf issues. */ setAutoFreeze(false); function _defineProperty$1(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _extends$1() { _extends$1 = 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; }; return _extends$1.apply(this, arguments); } function ownKeys$2(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread2$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$2(source, true).forEach(function (key) { _defineProperty$1(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$2(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } var noop = {value: function() {}}; function dispatch() { for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t); _[t] = []; } return new Dispatch(_); } function Dispatch(_) { this._ = _; } function parseTypenames(typenames, types) { return typenames.trim().split(/^|\s+/).map(function(t) { var name = "", i = t.indexOf("."); if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); return {type: t, name: name}; }); } Dispatch.prototype = dispatch.prototype = { constructor: Dispatch, on: function(typename, callback) { var _ = this._, T = parseTypenames(typename + "", _), t, i = -1, n = T.length; // If no callback was specified, return the callback of the given type and name. if (arguments.length < 2) { while (++i < n) if ((t = (typename = T[i]).type) && (t = get$3(_[t], typename.name))) return t; return; } // If a type was specified, set the callback for the given type and name. // Otherwise, if a null callback was specified, remove callbacks of the given name. if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); while (++i < n) { if (t = (typename = T[i]).type) _[t] = set$3(_[t], typename.name, callback); else if (callback == null) for (t in _) _[t] = set$3(_[t], typename.name, null); } return this; }, copy: function() { var copy = {}, _ = this._; for (var t in _) copy[t] = _[t].slice(); return new Dispatch(copy); }, call: function(type, that) { if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); }, apply: function(type, that, args) { if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); } }; function get$3(type, name) { for (var i = 0, n = type.length, c; i < n; ++i) { if ((c = type[i]).name === name) { return c.value; } } } function set$3(type, name, callback) { for (var i = 0, n = type.length; i < n; ++i) { if (type[i].name === name) { type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1)); break; } } if (callback != null) type.push({name: name, value: callback}); return type; } var xhtml = "http://www.w3.org/1999/xhtml"; var namespaces = { svg: "http://www.w3.org/2000/svg", xhtml: xhtml, xlink: "http://www.w3.org/1999/xlink", xml: "http://www.w3.org/XML/1998/namespace", xmlns: "http://www.w3.org/2000/xmlns/" }; function namespace(name) { var prefix = name += "", i = prefix.indexOf(":"); if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; } function creatorInherit(name) { return function() { var document = this.ownerDocument, uri = this.namespaceURI; return uri === xhtml && document.documentElement.namespaceURI === xhtml ? document.createElement(name) : document.createElementNS(uri, name); }; } function creatorFixed(fullname) { return function() { return this.ownerDocument.createElementNS(fullname.space, fullname.local); }; } function creator(name) { var fullname = namespace(name); return (fullname.local ? creatorFixed : creatorInherit)(fullname); } function none() {} function selector(selector) { return selector == null ? none : function() { return this.querySelector(selector); }; } function selection_select(select) { if (typeof select !== "function") select = selector(select); for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { if ("__data__" in node) subnode.__data__ = node.__data__; subgroup[i] = subnode; } } } return new Selection(subgroups, this._parents); } function empty() { return []; } function selectorAll(selector) { return selector == null ? empty : function() { return this.querySelectorAll(selector); }; } function selection_selectAll(select) { if (typeof select !== "function") select = selectorAll(select); for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { if (node = group[i]) { subgroups.push(select.call(node, node.__data__, i, group)); parents.push(node); } } } return new Selection(subgroups, parents); } function matcher(selector) { return function() { return this.matches(selector); }; } function selection_filter(match) { if (typeof match !== "function") match = matcher(match); for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { if ((node = group[i]) && match.call(node, node.__data__, i, group)) { subgroup.push(node); } } } return new Selection(subgroups, this._parents); } function sparse(update) { return new Array(update.length); } function selection_enter() { return new Selection(this._enter || this._groups.map(sparse), this._parents); } function EnterNode(parent, datum) { this.ownerDocument = parent.ownerDocument; this.namespaceURI = parent.namespaceURI; this._next = null; this._parent = parent; this.__data__ = datum; } EnterNode.prototype = { constructor: EnterNode, appendChild: function(child) { return this._parent.insertBefore(child, this._next); }, insertBefore: function(child, next) { return this._parent.insertBefore(child, next); }, querySelector: function(selector) { return this._parent.querySelector(selector); }, querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); } }; function constant(x) { return function() { return x; }; } var keyPrefix = "$"; // Protect against keys like “__proto__”. function bindIndex(parent, group, enter, update, exit, data) { var i = 0, node, groupLength = group.length, dataLength = data.length; // Put any non-null nodes that fit into update. // Put any null nodes into enter. // Put any remaining data into enter. for (; i < dataLength; ++i) { if (node = group[i]) { node.__data__ = data[i]; update[i] = node; } else { enter[i] = new EnterNode(parent, data[i]); } } // Put any non-null nodes that don’t fit into exit. for (; i < groupLength; ++i) { if (node = group[i]) { exit[i] = node; } } } function bindKey(parent, group, enter, update, exit, data, key) { var i, node, nodeByKeyValue = {}, groupLength = group.length, dataLength = data.length, keyValues = new Array(groupLength), keyValue; // Compute the key for each node. // If multiple nodes have the same key, the duplicates are added to exit. for (i = 0; i < groupLength; ++i) { if (node = group[i]) { keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group); if (keyValue in nodeByKeyValue) { exit[i] = node; } else { nodeByKeyValue[keyValue] = node; } } } // Compute the key for each datum. // If there a node associated with this key, join and add it to update. // If there is not (or the key is a duplicate), add it to enter. for (i = 0; i < dataLength; ++i) { keyValue = keyPrefix + key.call(parent, data[i], i, data); if (node = nodeByKeyValue[keyValue]) { update[i] = node; node.__data__ = data[i]; nodeByKeyValue[keyValue] = null; } else { enter[i] = new EnterNode(parent, data[i]); } } // Add any remaining nodes that were not bound to data to exit. for (i = 0; i < groupLength; ++i) { if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) { exit[i] = node; } } } function selection_data(value, key) { if (!value) { data = new Array(this.size()), j = -1; this.each(function(d) { data[++j] = d; }); return data; } var bind = key ? bindKey : bindIndex, parents = this._parents, groups = this._groups; if (typeof value !== "function") value = constant(value); for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) { var parent = parents[j], group = groups[j], groupLength = group.length, data = value.call(parent, parent && parent.__data__, j, parents), dataLength = data.length, enterGroup = enter[j] = new Array(dataLength), updateGroup = update[j] = new Array(dataLength), exitGroup = exit[j] = new Array(groupLength); bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); // Now connect the enter nodes to their following update node, such that // appendChild can insert the materialized enter node before this node, // rather than at the end of the parent node. for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { if (previous = enterGroup[i0]) { if (i0 >= i1) i1 = i0 + 1; while (!(next = updateGroup[i1]) && ++i1 < dataLength); previous._next = next || null; } } } update = new Selection(update, parents); update._enter = enter; update._exit = exit; return update; } function selection_exit() { return new Selection(this._exit || this._groups.map(sparse), this._parents); } function selection_join(onenter, onupdate, onexit) { var enter = this.enter(), update = this, exit = this.exit(); enter = typeof onenter === "function" ? onenter(enter) : enter.append(onenter + ""); if (onupdate != null) update = onupdate(update); if (onexit == null) exit.remove(); else onexit(exit); return enter && update ? enter.merge(update).order() : update; } function selection_merge(selection) { for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { if (node = group0[i] || group1[i]) { merge[i] = node; } } } for (; j < m0; ++j) { merges[j] = groups0[j]; } return new Selection(merges, this._parents); } function selection_order() { for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) { for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) { if (node = group[i]) { if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next); next = node; } } } return this; } function selection_sort(compare) { if (!compare) compare = ascending; function compareNode(a, b) { return a && b ? compare(a.__data__, b.__data__) : !a - !b; } for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) { if (node = group[i]) { sortgroup[i] = node; } } sortgroup.sort(compareNode); } return new Selection(sortgroups, this._parents).order(); } function ascending(a, b) { return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; } function selection_call() { var callback = arguments[0]; arguments[0] = this; callback.apply(null, arguments); return this; } function selection_nodes() { var nodes = new Array(this.size()), i = -1; this.each(function() { nodes[++i] = this; }); return nodes; } function selection_node() { for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { var node = group[i]; if (node) return node; } } return null; } function selection_size() { var size = 0; this.each(function() { ++size; }); return size; } function selection_empty() { return !this.node(); } function selection_each(callback) { for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { if (node = group[i]) callback.call(node, node.__data__, i, group); } } return this; } function attrRemove(name) { return function() { this.removeAttribute(name); }; } function attrRemoveNS(fullname) { return function() { this.removeAttributeNS(fullname.space, fullname.local); }; } function attrConstant(name, value) { return function() { this.setAttribute(name, value); }; } function attrConstantNS(fullname, value) { return function() { this.setAttributeNS(fullname.space, fullname.local, value); }; } function attrFunction(name, value) { return function() { var v = value.apply(this, arguments); if (v == null) this.removeAttribute(name); else this.setAttribute(name, v); }; } function attrFunctionNS(fullname, value) { return function() { var v = value.apply(this, arguments); if (v == null) this.removeAttributeNS(fullname.space, fullname.local); else this.setAttributeNS(fullname.space, fullname.local, v); }; } function selection_attr(name, value) { var fullname = namespace(name); if (arguments.length < 2) { var node = this.node(); return fullname.local ? node.getAttributeNS(fullname.space, fullname.local) : node.getAttribute(fullname); } return this.each((value == null ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function" ? (fullname.local ? attrFunctionNS : attrFunction) : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value)); } function defaultView(node) { return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node || (node.document && node) // node is a Window || node.defaultView; // node is a Document } function styleRemove(name) { return function() { this.style.removeProperty(name); }; } function styleConstant(name, value, priority) { return function() { this.style.setProperty(name, value, priority); }; } function styleFunction(name, value, priority) { return function() { var v = value.apply(this, arguments); if (v == null) this.style.removeProperty(name); else this.style.setProperty(name, v, priority); }; } function selection_style(name, value, priority) { return arguments.length > 1 ? this.each((value == null ? styleRemove : typeof value === "function" ? styleFunction : styleConstant)(name, value, priority == null ? "" : priority)) : styleValue(this.node(), name); } function styleValue(node, name) { return node.style.getPropertyValue(name) || defaultView(node).getComputedStyle(node, null).getPropertyValue(name); } function propertyRemove(name) { return function() { delete this[name]; }; } function propertyConstant(name, value) { return function() { this[name] = value; }; } function propertyFunction(name, value) { return function() { var v = value.apply(this, arguments); if (v == null) delete this[name]; else this[name] = v; }; } function selection_property(name, value) { return arguments.length > 1 ? this.each((value == null ? propertyRemove : typeof value === "function" ? propertyFunction : propertyConstant)(name, value)) : this.node()[name]; } function classArray(string) { return string.trim().split(/^|\s+/); } function classList(node) { return node.classList || new ClassList(node); } function ClassList(node) { this._node = node; this._names = classArray(node.getAttribute("class") || ""); } ClassList.prototype = { add: function(name) { var i = this._names.indexOf(name); if (i < 0) { this._names.push(name); this._node.setAttribute("class", this._names.join(" ")); } }, remove: function(name) { var i = this._names.indexOf(name); if (i >= 0) { this._names.splice(i, 1); this._node.setAttribute("class", this._names.join(" ")); } }, contains: function(name) { return this._names.indexOf(name) >= 0; } }; function classedAdd(node, names) { var list = classList(node), i = -1, n = names.length; while (++i < n) list.add(names[i]); } function classedRemove(node, names) { var list = classList(node), i = -1, n = names.length; while (++i < n) list.remove(names[i]); } function classedTrue(names) { return function() { classedAdd(this, names); }; } function classedFalse(names) { return function() { classedRemove(this, names); }; } function classedFunction(names, value) { return function() { (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names); }; } function selection_classed(name, value) { var names = classArray(name + ""); if (arguments.length < 2) { var list = classList(this.node()), i = -1, n = names.length; while (++i < n) if (!list.contains(names[i])) return false; return true; } return this.each((typeof value === "function" ? classedFunction : value ? classedTrue : classedFalse)(names, value)); } function textRemove() { this.textContent = ""; } function textConstant(value) { return function() { this.textContent = value; }; } function textFunction(value) { return function() { var v = value.apply(this, arguments); this.textContent = v == null ? "" : v; }; } function selection_text(value) { return arguments.length ? this.each(value == null ? textRemove : (typeof value === "function" ? textFunction : textConstant)(value)) : this.node().textContent; } function htmlRemove() { this.innerHTML = ""; } function htmlConstant(value) { return function() { this.innerHTML = value; }; } function htmlFunction(value) { return function() { var v = value.apply(this, arguments); this.innerHTML = v == null ? "" : v; }; } function selection_html(value) { return arguments.length ? this.each(value == null ? htmlRemove : (typeof value === "function" ? htmlFunction : htmlConstant)(value)) : this.node().innerHTML; } function raise() { if (this.nextSibling) this.parentNode.appendChild(this); } function selection_raise() { return this.each(raise); } function lower() { if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); } function selection_lower() { return this.each(lower); } function selection_append(name) { var create = typeof name === "function" ? name : creator(name); return this.select(function() { return this.appendChild(create.apply(this, arguments)); }); } function constantNull() { return null; } function selection_insert(name, before) { var create = typeof name === "function" ? name : creator(name), select = before == null ? constantNull : typeof before === "function" ? before : selector(before); return this.select(function() { return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); }); } function remove() { var parent = this.parentNode; if (parent) parent.removeChild(this); } function selection_remove() { return this.each(remove); } function selection_cloneShallow() { return this.parentNode.insertBefore(this.cloneNode(false), this.nextSibling); } function selection_cloneDeep() { return this.parentNode.insertBefore(this.cloneNode(true), this.nextSibling); } function selection_clone(deep) { return this.select(deep ? selection_cloneDeep : selection_cloneShallow); } function selection_datum(value) { return arguments.length ? this.property("__data__", value) : this.node().__data__; } var filterEvents = {}; var event = null; if (typeof document !== "undefined") { var element = document.documentElement; if (!("onmouseenter" in element)) { filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"}; } } function filterContextListener(listener, index, group) { listener = contextListener(listener, index, group); return function(event) { var related = event.relatedTarget; if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) { listener.call(this, event); } }; } function contextListener(listener, index, group) { return function(event1) { var event0 = event; // Events can be reentrant (e.g., focus). event = event1; try { listener.call(this, this.__data__, index, group); } finally { event = event0; } }; } function parseTypenames$1(typenames) { return typenames.trim().split(/^|\s+/).map(function(t) { var name = "", i = t.indexOf("."); if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); return {type: t, name: name}; }); } function onRemove(typename) { return function() { var on = this.__on; if (!on) return; for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { this.removeEventListener(o.type, o.listener, o.capture); } else { on[++i] = o; } } if (++i) on.length = i; else delete this.__on; }; } function onAdd(typename, value, capture) { var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener; return function(d, i, group) { var on = this.__on, o, listener = wrap(value, i, group); if (on) for (var j = 0, m = on.length; j < m; ++j) { if ((o = on[j]).type === typename.type && o.name === typename.name) { this.removeEventListener(o.type, o.listener, o.capture); this.addEventListener(o.type, o.listener = listener, o.capture = capture); o.value = value; return; } } this.addEventListener(typename.type, listener, capture); o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture}; if (!on) this.__on = [o]; else on.push(o); }; } function selection_on(typename, value, capture) { var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t; if (arguments.length < 2) { var on = this.node().__on; if (on) for (var j = 0, m = on.length, o; j < m; ++j) { for (i = 0, o = on[j]; i < n; ++i) { if ((t = typenames[i]).type === o.type && t.name === o.name) { return o.value; } } } return; } on = value ? onAdd : onRemove; if (capture == null) capture = false; for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture)); return this; } function customEvent(event1, listener, that, args) { var event0 = event; event1.sourceEvent = event; event = event1; try { return listener.apply(that, args); } finally { event = event0; } } function dispatchEvent(node, type, params) { var window = defaultView(node), event = window.CustomEvent; if (typeof event === "function") { event = new event(type, params); } else { event = window.document.createEvent("Event"); if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail; else event.initEvent(type, false, false); } node.dispatchEvent(event); } function dispatchConstant(type, params) { return function() { return dispatchEvent(this, type, params); }; } function dispatchFunction(type, params) { return function() { return dispatchEvent(this, type, params.apply(this, arguments)); }; } function selection_dispatch(type, params) { return this.each((typeof params === "function" ? dispatchFunction : dispatchConstant)(type, params)); } var root$1 = [null]; function Selection(groups, parents) { this._groups = groups; this._parents = parents; } function selection() { return new Selection([[document.documentElement]], root$1); } Selection.prototype = selection.prototype = { constructor: Selection, select: selection_select, selectAll: selection_selectAll, filter: selection_filter, data: selection_data, enter: selection_enter, exit: selection_exit, join: selection_join, merge: selection_merge, order: selection_order, sort: selection_sort, call: selection_call, nodes: selection_nodes, node: selection_node, size: selection_size, empty: selection_empty, each: selection_each, attr: selection_attr, style: selection_style, property: selection_property, classed: selection_classed, text: selection_text, html: selection_html, raise: selection_raise, lower: selection_lower, append: selection_append, insert: selection_insert, remove: selection_remove, clone: selection_clone, datum: selection_datum, on: selection_on, dispatch: selection_dispatch }; function select(selector) { return typeof selector === "string" ? new Selection([[document.querySelector(selector)]], [document.documentElement]) : new Selection([[selector]], root$1); } function sourceEvent() { var current = event, source; while (source = current.sourceEvent) current = source; return current; } function point(node, event) { var svg = node.ownerSVGElement || node; if (svg.createSVGPoint) { var point = svg.createSVGPoint(); point.x = event.clientX, point.y = event.clientY; point = point.matrixTransform(node.getScreenCTM().inverse()); return [point.x, point.y]; } var rect = node.getBoundingClientRect(); return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop]; } function mouse(node) { var event = sourceEvent(); if (event.changedTouches) event = event.changedTouches[0]; return point(node, event); } function touch(node, touches, identifier) { if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches; for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) { if ((touch = touches[i]).identifier === identifier) { return point(node, touch); } } return null; } function noevent() { event.preventDefault(); event.stopImmediatePropagation(); } function dragDisable(view) { var root = view.document.documentElement, selection = select(view).on("dragstart.drag", noevent, true); if ("onselectstart" in root) { selection.on("selectstart.drag", noevent, true); } else { root.__noselect = root.style.MozUserSelect; root.style.MozUserSelect = "none"; } } function yesdrag(view, noclick) { var root = view.document.documentElement, selection = select(view).on("dragstart.drag", null); if (noclick) { selection.on("click.drag", noevent, true); setTimeout(function() { selection.on("click.drag", null); }, 0); } if ("onselectstart" in root) { selection.on("selectstart.drag", null); } else { root.style.MozUserSelect = root.__noselect; delete root.__noselect; } } function define(constructor, factory, prototype) { constructor.prototype = factory.prototype = prototype; prototype.constructor = constructor; } function extend(parent, definition) { var prototype = Object.create(parent.prototype); for (var key in definition) prototype[key] = definition[key]; return prototype; } function Color() {} var darker = 0.7; var brighter = 1 / darker; var reI = "\\s*([+-]?\\d+)\\s*", reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*", reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*", reHex = /^#([0-9a-f]{3,8})$/, reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"), reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"), reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"), reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"), reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"), reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); var named = { aliceblue: 0xf0f8ff, antiquewhite: 0xfaebd7, aqua: 0x00ffff, aquamarine: 0x7fffd4, azure: 0xf0ffff, beige: 0xf5f5dc, bisque: 0xffe4c4, black: 0x000000, blanchedalmond: 0xffebcd, blue: 0x0000ff, blueviolet: 0x8a2be2, brown: 0xa52a2a, burlywood: 0xdeb887, cadetblue: 0x5f9ea0, chartreuse: 0x7fff00, chocolate: 0xd2691e, coral: 0xff7f50, cornflowerblue: 0x6495ed, cornsilk: 0xfff8dc, crimson: 0xdc143c, cyan: 0x00ffff, darkblue: 0x00008b, darkcyan: 0x008b8b, darkgoldenrod: 0xb8860b, darkgray: 0xa9a9a9, darkgreen: 0x006400, darkgrey: 0xa9a9a9, darkkhaki: 0xbdb76b, darkmagenta: 0x8b008b, darkolivegreen: 0x556b2f, darkorange: 0xff8c00, darkorchid: 0x9932cc, darkred: 0x8b0000, darksalmon: 0xe9967a, darkseagreen: 0x8fbc8f, darkslateblue: 0x483d8b, darkslategray: 0x2f4f4f, darkslategrey: 0x2f4f4f, darkturquoise: 0x00ced1, darkviolet: 0x9400d3, deeppink: 0xff1493, deepskyblue: 0x00bfff, dimgray: 0x696969, dimgrey: 0x696969, dodgerblue: 0x1e90ff, firebrick: 0xb22222, floralwhite: 0xfffaf0, forestgreen: 0x228b22, fuchsia: 0xff00ff, gainsboro: 0xdcdcdc, ghostwhite: 0xf8f8ff, gold: 0xffd700, goldenrod: 0xdaa520, gray: 0x808080, green: 0x008000, greenyellow: 0xadff2f, grey: 0x808080, honeydew: 0xf0fff0, hotpink: 0xff69b4, indianred: 0xcd5c5c, indigo: 0x4b0082, ivory: 0xfffff0, khaki: 0xf0e68c, lavender: 0xe6e6fa, lavenderblush: 0xfff0f5, lawngreen: 0x7cfc00, lemonchiffon: 0xfffacd, lightblue: 0xadd8e6, lightcoral: 0xf08080, lightcyan: 0xe0ffff, lightgoldenrodyellow: 0xfafad2, lightgray: 0xd3d3d3, lightgreen: 0x90ee90, lightgrey: 0xd3d3d3, lightpink: 0xffb6c1, lightsalmon: 0xffa07a, lightseagreen: 0x20b2aa, lightskyblue: 0x87cefa, lightslategray: 0x778899, lightslategrey: 0x778899, lightsteelblue: 0xb0c4de, lightyellow: 0xffffe0, lime: 0x00ff00, limegreen: 0x32cd32, linen: 0xfaf0e6, magenta: 0xff00ff, maroon: 0x800000, mediumaquamarine: 0x66cdaa, mediumblue: 0x0000cd, mediumorchid: 0xba55d3, mediumpurple: 0x9370db, mediumseagreen: 0x3cb371, mediumslateblue: 0x7b68ee, mediumspringgreen: 0x00fa9a, mediumturquoise: 0x48d1cc, mediumvioletred: 0xc71585, midnightblue: 0x191970, mintcream: 0xf5fffa, mistyrose: 0xffe4e1, moccasin: 0xffe4b5, navajowhite: 0xffdead, navy: 0x000080, oldlace: 0xfdf5e6, olive: 0x808000, olivedrab: 0x6b8e23, orange: 0xffa500, orangered: 0xff4500, orchid: 0xda70d6, palegoldenrod: 0xeee8aa, palegreen: 0x98fb98, paleturquoise: 0xafeeee, palevioletred: 0xdb7093, papayawhip: 0xffefd5, peachpuff: 0xffdab9, peru: 0xcd853f, pink: 0xffc0cb, plum: 0xdda0dd, powderblue: 0xb0e0e6, purple: 0x800080, rebeccapurple: 0x663399, red: 0xff0000, rosybrown: 0xbc8f8f, royalblue: 0x4169e1, saddlebrown: 0x8b4513, salmon: 0xfa8072, sandybrown: 0xf4a460, seagreen: 0x2e8b57, seashell: 0xfff5ee, sienna: 0xa0522d, silver: 0xc0c0c0, skyblue: 0x87ceeb, slateblue: 0x6a5acd, slategray: 0x708090, slategrey: 0x708090, snow: 0xfffafa, springgreen: 0x00ff7f, steelblue: 0x4682b4, tan: 0xd2b48c, teal: 0x008080, thistle: 0xd8bfd8, tomato: 0xff6347, turquoise: 0x40e0d0, violet: 0xee82ee, wheat: 0xf5deb3, white: 0xffffff, whitesmoke: 0xf5f5f5, yellow: 0xffff00, yellowgreen: 0x9acd32 }; define(Color, color, { copy: function(channels) { return Object.assign(new this.constructor, this, channels); }, displayable: function() { return this.rgb().displayable(); }, hex: color_formatHex, // Deprecated! Use color.formatHex. formatHex: color_formatHex, formatHsl: color_formatHsl, formatRgb: color_formatRgb, toString: color_formatRgb }); function color_formatHex() { return this.rgb().formatHex(); } function color_formatHsl() { return hslConvert(this).formatHsl(); } function color_formatRgb() { return this.rgb().formatRgb(); } function color(format) { var m, l; format = (format + "").trim().toLowerCase(); return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000 : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00 : l === 8 ? new Rgb(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000 : l === 4 ? new Rgb((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000 : null) // invalid hex : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null; } function rgbn(n) { return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); } function rgba(r, g, b, a) { if (a <= 0) r = g = b = NaN; return new Rgb(r, g, b, a); } function rgbConvert(o) { if (!(o instanceof Color)) o = color(o); if (!o) return new Rgb; o = o.rgb(); return new Rgb(o.r, o.g, o.b, o.opacity); } function rgb(r, g, b, opacity) { return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); } function Rgb(r, g, b, opacity) { this.r = +r; this.g = +g; this.b = +b; this.opacity = +opacity; } define(Rgb, rgb, extend(Color, { brighter: function(k) { k = k == null ? brighter : Math.pow(brighter, k); return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); }, darker: function(k) { k = k == null ? darker : Math.pow(darker, k); return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); }, rgb: function() { return this; }, displayable: function() { return (-0.5 <= this.r && this.r < 255.5) && (-0.5 <= this.g && this.g < 255.5) && (-0.5 <= this.b && this.b < 255.5) && (0 <= this.opacity && this.opacity <= 1); }, hex: rgb_formatHex, // Deprecated! Use color.formatHex. formatHex: rgb_formatHex, formatRgb: rgb_formatRgb, toString: rgb_formatRgb })); function rgb_formatHex() { return "#" + hex(this.r) + hex(this.g) + hex(this.b); } function rgb_formatRgb() { var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); return (a === 1 ? "rgb(" : "rgba(") + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.b) || 0)) + (a === 1 ? ")" : ", " + a + ")"); } function hex(value) { value = Math.max(0, Math.min(255, Math.round(value) || 0)); return (value < 16 ? "0" : "") + value.toString(16); } function hsla(h, s, l, a) { if (a <= 0) h = s = l = NaN; else if (l <= 0 || l >= 1) h = s = NaN; else if (s <= 0) h = NaN; return new Hsl(h, s, l, a); } function hslConvert(o) { if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); if (!(o instanceof Color)) o = color(o); if (!o) return new Hsl; if (o instanceof Hsl) return o; o = o.rgb(); var r = o.r / 255, g = o.g / 255, b = o.b / 255, min = Math.min(r, g, b), max = Math.max(r, g, b), h = NaN, s = max - min, l = (max + min) / 2; if (s) { if (r === max) h = (g - b) / s + (g < b) * 6; else if (g === max) h = (b - r) / s + 2; else h = (r - g) / s + 4; s /= l < 0.5 ? max + min : 2 - max - min; h *= 60; } else { s = l > 0 && l < 1 ? 0 : h; } return new Hsl(h, s, l, o.opacity); } function hsl(h, s, l, opacity) { return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); } function Hsl(h, s, l, opacity) { this.h = +h; this.s = +s; this.l = +l; this.opacity = +opacity; } define(Hsl, hsl, extend(Color, { brighter: function(k) { k = k == null ? brighter : Math.pow(brighter, k); return new Hsl(this.h, this.s, this.l * k, this.opacity); }, darker: function(k) { k = k == null ? darker : Math.pow(darker, k); return new Hsl(this.h, this.s, this.l * k, this.opacity); }, rgb: function() { var h = this.h % 360 + (this.h < 0) * 360, s = isNaN(h) || isNaN(this.s) ? 0 : this.s, l = this.l, m2 = l + (l < 0.5 ? l : 1 - l) * s, m1 = 2 * l - m2; return new Rgb( hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), hsl2rgb(h, m1, m2), hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), this.opacity ); }, displayable: function() { return (0 <= this.s && this.s <= 1 || isNaN(this.s)) && (0 <= this.l && this.l <= 1) && (0 <= this.opacity && this.opacity <= 1); }, formatHsl: function() { var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); return (a === 1 ? "hsl(" : "hsla(") + (this.h || 0) + ", " + (this.s || 0) * 100 + "%, " + (this.l || 0) * 100 + "%" + (a === 1 ? ")" : ", " + a + ")"); } })); /* From FvD 13.37, CSS Color Module Level 3 */ function hsl2rgb(h, m1, m2) { return (h < 60 ? m1 + (m2 - m1) * h / 60 : h < 180 ? m2 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 : m1) * 255; } function constant$1(x) { return function() { return x; }; } function linear(a, d) { return function(t) { return a + t * d; }; } function exponential(a, b, y) { return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { return Math.pow(a + t * b, y); }; } function gamma(y) { return (y = +y) === 1 ? nogamma : function(a, b) { return b - a ? exponential(a, b, y) : constant$1(isNaN(a) ? b : a); }; } function nogamma(a, b) { var d = b - a; return d ? linear(a, d) : constant$1(isNaN(a) ? b : a); } var interpolateRgb = (function rgbGamma(y) { var color = gamma(y); function rgb$1(start, end) { var r = color((start = rgb(start)).r, (end = rgb(end)).r), g = color(start.g, end.g), b = color(start.b, end.b), opacity = nogamma(start.opacity, end.opacity); return function(t) { start.r = r(t); start.g = g(t); start.b = b(t); start.opacity = opacity(t); return start + ""; }; } rgb$1.gamma = rgbGamma; return rgb$1; })(1); function interpolateNumber(a, b) { return a = +a, b -= a, function(t) { return a + b * t; }; } var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, reB = new RegExp(reA.source, "g"); function zero(b) { return function() { return b; }; } function one(b) { return function(t) { return b(t) + ""; }; } function interpolateString(a, b) { var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b am, // current match in a bm, // current match in b bs, // string preceding current number in b, if any i = -1, // index in s s = [], // string constants and placeholders q = []; // number interpolators // Coerce inputs to strings. a = a + "", b = b + ""; // Interpolate pairs of numbers in a & b. while ((am = reA.exec(a)) && (bm = reB.exec(b))) { if ((bs = bm.index) > bi) { // a string precedes the next number in b bs = b.slice(bi, bs); if (s[i]) s[i] += bs; // coalesce with previous string else s[++i] = bs; } if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match if (s[i]) s[i] += bm; // coalesce with previous string else s[++i] = bm; } else { // interpolate non-matching numbers s[++i] = null; q.push({i: i, x: interpolateNumber(am, bm)}); } bi = reB.lastIndex; } // Add remains of b. if (bi < b.length) { bs = b.slice(bi); if (s[i]) s[i] += bs; // coalesce with previous string else s[++i] = bs; } // Special optimization for only a single match. // Otherwise, interpolate each of the numbers and rejoin the string. return s.length < 2 ? (q[0] ? one(q[0].x) : zero(b)) : (b = q.length, function(t) { for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); return s.join(""); }); } var degrees = 180 / Math.PI; var identity = { translateX: 0, translateY: 0, rotate: 0, skewX: 0, scaleX: 1, scaleY: 1 }; function decompose(a, b, c, d, e, f) { var scaleX, scaleY, skewX; if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; return { translateX: e, translateY: f, rotate: Math.atan2(b, a) * degrees, skewX: Math.atan(skewX) * degrees, scaleX: scaleX, scaleY: scaleY }; } var cssNode, cssRoot, cssView, svgNode; function parseCss(value) { if (value === "none") return identity; if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView; cssNode.style.transform = value; value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform"); cssRoot.removeChild(cssNode); value = value.slice(7, -1).split(","); return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]); } function parseSvg(value) { if (value == null) return identity; if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); svgNode.setAttribute("transform", value); if (!(value = svgNode.transform.baseVal.consolidate())) return identity; value = value.matrix; return decompose(value.a, value.b, value.c, value.d, value.e, value.f); } function interpolateTransform(parse, pxComma, pxParen, degParen) { function pop(s) { return s.length ? s.pop() + " " : ""; } function translate(xa, ya, xb, yb, s, q) { if (xa !== xb || ya !== yb) { var i = s.push("translate(", null, pxComma, null, pxParen); q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)}); } else if (xb || yb) { s.push("translate(" + xb + pxComma + yb + pxParen); } } function rotate(a, b, s, q) { if (a !== b) { if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: interpolateNumber(a, b)}); } else if (b) { s.push(pop(s) + "rotate(" + b + degParen); } } function skewX(a, b, s, q) { if (a !== b) { q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: interpolateNumber(a, b)}); } else if (b) { s.push(pop(s) + "skewX(" + b + degParen); } } function scale(xa, ya, xb, yb, s, q) { if (xa !== xb || ya !== yb) { var i = s.push(pop(s) + "scale(", null, ",", null, ")"); q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)}); } else if (xb !== 1 || yb !== 1) { s.push(pop(s) + "scale(" + xb + "," + yb + ")"); } } return function(a, b) { var s = [], // string constants and placeholders q = []; // number interpolators a = parse(a), b = parse(b); translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); rotate(a.rotate, b.rotate, s, q); skewX(a.skewX, b.skewX, s, q); scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); a = b = null; // gc return function(t) { var i = -1, n = q.length, o; while (++i < n) s[(o = q[i]).i] = o.x(t); return s.join(""); }; }; } var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); var rho = Math.SQRT2, rho2 = 2, rho4 = 4, epsilon2 = 1e-12; function cosh(x) { return ((x = Math.exp(x)) + 1 / x) / 2; } function sinh(x) { return ((x = Math.exp(x)) - 1 / x) / 2; } function tanh(x) { return ((x = Math.exp(2 * x)) - 1) / (x + 1); } // p0 = [ux0, uy0, w0] // p1 = [ux1, uy1, w1] function interpolateZoom(p0, p1) { var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2], dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, i, S; // Special case for u0 ≅ u1. if (d2 < epsilon2) { S = Math.log(w1 / w0) / rho; i = function(t) { return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(rho * t * S) ]; }; } // General case. else { var d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); S = (r1 - r0) / rho; i = function(t) { var s = t * S, coshr0 = cosh(r0), u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / cosh(rho * s + r0) ]; }; } i.duration = S * 1000; return i; } var frame = 0, // is an animation frame pending? timeout = 0, // is a timeout pending? interval = 0, // are any timers active? pokeDelay = 1000, // how frequently we check for clock skew taskHead, taskTail, clockLast = 0, clockNow = 0, clockSkew = 0, clock = typeof performance === "object" && performance.now ? performance : Date, setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); }; function now() { return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); } function clearNow() { clockNow = 0; } function Timer() { this._call = this._time = this._next = null; } Timer.prototype = timer.prototype = { constructor: Timer, restart: function(callback, delay, time) { if (typeof callback !== "function") throw new TypeError("callback is not a function"); time = (time == null ? now() : +time) + (delay == null ? 0 : +delay); if (!this._next && taskTail !== this) { if (taskTail) taskTail._next = this; else taskHead = this; taskTail = this; } this._call = callback; this._time = time; sleep(); }, stop: function() { if (this._call) { this._call = null; this._time = Infinity; sleep(); } } }; function timer(callback, delay, time) { var t = new Timer; t.restart(callback, delay, time); return t; } function timerFlush() { now(); // Get the current time, if not already set. ++frame; // Pretend we’ve set an alarm, if we haven’t already. var t = taskHead, e; while (t) { if ((e = clockNow - t._time) >= 0) t._call.call(null, e); t = t._next; } --frame; } function wake() { clockNow = (clockLast = clock.now()) + clockSkew; frame = timeout = 0; try { timerFlush(); } finally { frame = 0; nap(); clockNow = 0; } } function poke() { var now = clock.now(), delay = now - clockLast; if (delay > pokeDelay) clockSkew -= delay, clockLast = now; } function nap() { var t0, t1 = taskHead, t2, time = Infinity; while (t1) { if (t1._call) { if (time > t1._time) time = t1._time; t0 = t1, t1 = t1._next; } else { t2 = t1._next, t1._next = null; t1 = t0 ? t0._next = t2 : taskHead = t2; } } taskTail = t0; sleep(time); } function sleep(time) { if (frame) return; // Soonest alarm already set, or will be. if (timeout) timeout = clearTimeout(timeout); var delay = time - clockNow; // Strictly less than if we recomputed clockNow. if (delay > 24) { if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew); if (interval) interval = clearInterval(interval); } else { if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay); frame = 1, setFrame(wake); } } function timeout$1(callback, delay, time) { var t = new Timer; delay = delay == null ? 0 : +delay; t.restart(function(elapsed) { t.stop(); callback(elapsed + delay); }, delay, time); return t; } var emptyOn = dispatch("start", "end", "cancel", "interrupt"); var emptyTween = []; var CREATED = 0; var SCHEDULED = 1; var STARTING = 2; var STARTED = 3; var RUNNING = 4; var ENDING = 5; var ENDED = 6; function schedule(node, name, id, index, group, timing) { var schedules = node.__transition; if (!schedules) node.__transition = {}; else if (id in schedules) return; create(node, id, { name: name, index: index, // For context during callback. group: group, // For context during callback. on: emptyOn, tween: emptyTween, time: timing.time, delay: timing.delay, duration: timing.duration, ease: timing.ease, timer: null, state: CREATED }); } function init(node, id) { var schedule = get$4(node, id); if (schedule.state > CREATED) throw new Error("too late; already scheduled"); return schedule; } function set$4(node, id) { var schedule = get$4(node, id); if (schedule.state > STARTED) throw new Error("too late; already running"); return schedule; } function get$4(node, id) { var schedule = node.__transition; if (!schedule || !(schedule = schedule[id])) throw new Error("transition not found"); return schedule; } function create(node, id, self) { var schedules = node.__transition, tween; // Initialize the self timer when the transition is created. // Note the actual delay is not known until the first callback! schedules[id] = self; self.timer = timer(schedule, 0, self.time); function schedule(elapsed) { self.state = SCHEDULED; self.timer.restart(start, self.delay, self.time); // If the elapsed delay is less than our first sleep, start immediately. if (self.delay <= elapsed) start(elapsed - self.delay); } function start(elapsed) { var i, j, n, o; // If the state is not SCHEDULED, then we previously errored on start. if (self.state !== SCHEDULED) return stop(); for (i in schedules) { o = schedules[i]; if (o.name !== self.name) continue; // While this element already has a starting transition during this frame, // defer starting an interrupting transition until that transition has a // chance to tick (and possibly end); see d3/d3-transition#54! if (o.state === STARTED) return timeout$1(start); // Interrupt the active transition, if any. if (o.state === RUNNING) { o.state = ENDED; o.timer.stop(); o.on.call("interrupt", node, node.__data__, o.index, o.group); delete schedules[i]; } // Cancel any pre-empted transitions. else if (+i < id) { o.state = ENDED; o.timer.stop(); o.on.call("cancel", node, node.__data__, o.index, o.group); delete schedules[i]; } } // Defer the first tick to end of the current frame; see d3/d3#1576. // Note the transition may be canceled after start and before the first tick! // Note this must be scheduled before the start event; see d3/d3-transition#16! // Assuming this is successful, subsequent callbacks go straight to tick. timeout$1(function() { if (self.state === STARTED) { self.state = RUNNING; self.timer.restart(tick, self.delay, self.time); tick(elapsed); } }); // Dispatch the start event. // Note this must be done before the tween are initialized. self.state = STARTING; self.on.call("start", node, node.__data__, self.index, self.group); if (self.state !== STARTING) return; // interrupted self.state = STARTED; // Initialize the tween, deleting null tween. tween = new Array(n = self.tween.length); for (i = 0, j = -1; i < n; ++i) { if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) { tween[++j] = o; } } tween.length = j + 1; } function tick(elapsed) { var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), i = -1, n = tween.length; while (++i < n) { tween[i].call(node, t); } // Dispatch the end event. if (self.state === ENDING) { self.on.call("end", node, node.__data__, self.index, self.group); stop(); } } function stop() { self.state = ENDED; self.timer.stop(); delete schedules[id]; for (var i in schedules) return; // eslint-disable-line no-unused-vars delete node.__transition; } } function interrupt(node, name) { var schedules = node.__transition, schedule, active, empty = true, i; if (!schedules) return; name = name == null ? null : name + ""; for (i in schedules) { if ((schedule = schedules[i]).name !== name) { empty = false; continue; } active = schedule.state > STARTING && schedule.state < ENDING; schedule.state = ENDED; schedule.timer.stop(); schedule.on.call(active ? "interrupt" : "cancel", node, node.__data__, schedule.index, schedule.group); delete schedules[i]; } if (empty) delete node.__transition; } function selection_interrupt(name) { return this.each(function() { interrupt(this, name); }); } function tweenRemove(id, name) { var tween0, tween1; return function() { var schedule = set$4(this, id), tween = schedule.tween; // If this node shared tween with the previous node, // just assign the updated shared tween and we’re done! // Otherwise, copy-on-write. if (tween !== tween0) { tween1 = tween0 = tween; for (var i = 0, n = tween1.length; i < n; ++i) { if (tween1[i].name === name) { tween1 = tween1.slice(); tween1.splice(i, 1); break; } } } schedule.tween = tween1; }; } function tweenFunction(id, name, value) { var tween0, tween1; if (typeof value !== "function") throw new Error; return function() { var schedule = set$4(this, id), tween = schedule.tween; // If this node shared tween with the previous node, // just assign the updated shared tween and we’re done! // Otherwise, copy-on-write. if (tween !== tween0) { tween1 = (tween0 = tween).slice(); for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) { if (tween1[i].name === name) { tween1[i] = t; break; } } if (i === n) tween1.push(t); } schedule.tween = tween1; }; } function transition_tween(name, value) { var id = this._id; name += ""; if (arguments.length < 2) { var tween = get$4(this.node(), id).tween; for (var i = 0, n = tween.length, t; i < n; ++i) { if ((t = tween[i]).name === name) { return t.value; } } return null; } return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value)); } function tweenValue(transition, name, value) { var id = transition._id; transition.each(function() { var schedule = set$4(this, id); (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments); }); return function(node) { return get$4(node, id).value[name]; }; } function interpolate(a, b) { var c; return (typeof b === "number" ? interpolateNumber : b instanceof color ? interpolateRgb : (c = color(b)) ? (b = c, interpolateRgb) : interpolateString)(a, b); } function attrRemove$1(name) { return function() { this.removeAttribute(name); }; } function attrRemoveNS$1(fullname) { return function() { this.removeAttributeNS(fullname.space, fullname.local); }; } function attrConstant$1(name, interpolate, value1) { var string00, string1 = value1 + "", interpolate0; return function() { var string0 = this.getAttribute(name); return string0 === string1 ? null : string0 === string00 ? interpolate0 : interpolate0 = interpolate(string00 = string0, value1); }; } function attrConstantNS$1(fullname, interpolate, value1) { var string00, string1 = value1 + "", interpolate0; return function() { var string0 = this.getAttributeNS(fullname.space, fullname.local); return string0 === string1 ? null : string0 === string00 ? interpolate0 : interpolate0 = interpolate(string00 = string0, value1); }; } function attrFunction$1(name, interpolate, value) { var string00, string10, interpolate0; return function() { var string0, value1 = value(this), string1; if (value1 == null) return void this.removeAttribute(name); string0 = this.getAttribute(name); string1 = value1 + ""; return string0 === string1 ? null : string0 === string00 && string1 === string10 ? interpolate0 : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1)); }; } function attrFunctionNS$1(fullname, interpolate, value) { var string00, string10, interpolate0; return function() { var string0, value1 = value(this), string1; if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local); string0 = this.getAttributeNS(fullname.space, fullname.local); string1 = value1 + ""; return string0 === string1 ? null : string0 === string00 && string1 === string10 ? interpolate0 : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1)); }; } function transition_attr(name, value) { var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate; return this.attrTween(name, typeof value === "function" ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value)) : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname) : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value)); } function attrInterpolate(name, i) { return function(t) { this.setAttribute(name, i(t)); }; } function attrInterpolateNS(fullname, i) { return function(t) { this.setAttributeNS(fullname.space, fullname.local, i(t)); }; } function attrTweenNS(fullname, value) { var t0, i0; function tween() { var i = value.apply(this, arguments); if (i !== i0) t0 = (i0 = i) && attrInterpolateNS(fullname, i); return t0; } tween._value = value; return tween; } function attrTween(name, value) { var t0, i0; function tween() { var i = value.apply(this, arguments); if (i !== i0) t0 = (i0 = i) && attrInterpolate(name, i); return t0; } tween._value = value; return tween; } function transition_attrTween(name, value) { var key = "attr." + name; if (arguments.length < 2) return (key = this.tween(key)) && key._value; if (value == null) return this.tween(key, null); if (typeof value !== "function") throw new Error; var fullname = namespace(name); return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value)); } function delayFunction(id, value) { return function() { init(this, id).delay = +value.apply(this, arguments); }; } function delayConstant(id, value) { return value = +value, function() { init(this, id).delay = value; }; } function transition_delay(value) { var id = this._id; return arguments.length ? this.each((typeof value === "function" ? delayFunction : delayConstant)(id, value)) : get$4(this.node(), id).delay; } function durationFunction(id, value) { return function() { set$4(this, id).duration = +value.apply(this, arguments); }; } function durationConstant(id, value) { return value = +value, function() { set$4(this, id).duration = value; }; } function transition_duration(value) { var id = this._id; return arguments.length ? this.each((typeof value === "function" ? durationFunction : durationConstant)(id, value)) : get$4(this.node(), id).duration; } function easeConstant(id, value) { if (typeof value !== "function") throw new Error; return function() { set$4(this, id).ease = value; }; } function transition_ease(value) { var id = this._id; return arguments.length ? this.each(easeConstant(id, value)) : get$4(this.node(), id).ease; } function transition_filter(match) { if (typeof match !== "function") match = matcher(match); for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { if ((node = group[i]) && match.call(node, node.__data__, i, group)) { subgroup.push(node); } } } return new Transition(subgroups, this._parents, this._name, this._id); } function transition_merge(transition) { if (transition._id !== this._id) throw new Error; for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { if (node = group0[i] || group1[i]) { merge[i] = node; } } } for (; j < m0; ++j) { merges[j] = groups0[j]; } return new Transition(merges, this._parents, this._name, this._id); } function start(name) { return (name + "").trim().split(/^|\s+/).every(function(t) { var i = t.indexOf("."); if (i >= 0) t = t.slice(0, i); return !t || t === "start"; }); } function onFunction(id, name, listener) { var on0, on1, sit = start(name) ? init : set$4; return function() { var schedule = sit(this, id), on = schedule.on; // If this node shared a dispatch with the previous node, // just assign the updated shared dispatch and we’re done! // Otherwise, copy-on-write. if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener); schedule.on = on1; }; } function transition_on(name, listener) { var id = this._id; return arguments.length < 2 ? get$4(this.node(), id).on.on(name) : this.each(onFunction(id, name, listener)); } function removeFunction(id) { return function() { var parent = this.parentNode; for (var i in this.__transition) if (+i !== id) return; if (parent) parent.removeChild(this); }; } function transition_remove() { return this.on("end.remove", removeFunction(this._id)); } function transition_select(select) { var name = this._name, id = this._id; if (typeof select !== "function") select = selector(select); for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { if ("__data__" in node) subnode.__data__ = node.__data__; subgroup[i] = subnode; schedule(subgroup[i], name, id, i, subgroup, get$4(node, id)); } } } return new Transition(subgroups, this._parents, name, id); } function transition_selectAll(select) { var name = this._name, id = this._id; if (typeof select !== "function") select = selectorAll(select); for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { if (node = group[i]) { for (var children = select.call(node, node.__data__, i, group), child, inherit = get$4(node, id), k = 0, l = children.length; k < l; ++k) { if (child = children[k]) { schedule(child, name, id, k, children, inherit); } } subgroups.push(children); parents.push(node); } } } return new Transition(subgroups, parents, name, id); } var Selection$1 = selection.prototype.constructor; function transition_selection() { return new Selection$1(this._groups, this._parents); } function styleNull(name, interpolate) { var string00, string10, interpolate0; return function() { var string0 = styleValue(this, name), string1 = (this.style.removeProperty(name), styleValue(this, name)); return string0 === string1 ? null : string0 === string00 && string1 === string10 ? interpolate0 : interpolate0 = interpolate(string00 = string0, string10 = string1); }; } function styleRemove$1(name) { return function() { this.style.removeProperty(name); }; } function styleConstant$1(name, interpolate, value1) { var string00, string1 = value1 + "", interpolate0; return function() { var string0 = styleValue(this, name); return string0 === string1 ? null : string0 === string00 ? interpolate0 : interpolate0 = interpolate(string00 = string0, value1); }; } function styleFunction$1(name, interpolate, value) { var string00, string10, interpolate0; return function() { var string0 = styleValue(this, name), value1 = value(this), string1 = value1 + ""; if (value1 == null) string1 = value1 = (this.style.removeProperty(name), styleValue(this, name)); return string0 === string1 ? null : string0 === string00 && string1 === string10 ? interpolate0 : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1)); }; } function styleMaybeRemove(id, name) { var on0, on1, listener0, key = "style." + name, event = "end." + key, remove; return function() { var schedule = set$4(this, id), on = schedule.on, listener = schedule.value[key] == null ? remove || (remove = styleRemove$1(name)) : undefined; // If this node shared a dispatch with the previous node, // just assign the updated shared dispatch and we’re done! // Otherwise, copy-on-write. if (on !== on0 || listener0 !== listener) (on1 = (on0 = on).copy()).on(event, listener0 = listener); schedule.on = on1; }; } function transition_style(name, value, priority) { var i = (name += "") === "transform" ? interpolateTransformCss : interpolate; return value == null ? this .styleTween(name, styleNull(name, i)) .on("end.style." + name, styleRemove$1(name)) : typeof value === "function" ? this .styleTween(name, styleFunction$1(name, i, tweenValue(this, "style." + name, value))) .each(styleMaybeRemove(this._id, name)) : this .styleTween(name, styleConstant$1(name, i, value), priority) .on("end.style." + name, null); } function styleInterpolate(name, i, priority) { return function(t) { this.style.setProperty(name, i(t), priority); }; } function styleTween(name, value, priority) { var t, i0; function tween() { var i = value.apply(this, arguments); if (i !== i0) t = (i0 = i) && styleInterpolate(name, i, priority); return t; } tween._value = value; return tween; } function transition_styleTween(name, value, priority) { var key = "style." + (name += ""); if (arguments.length < 2) return (key = this.tween(key)) && key._value; if (value == null) return this.tween(key, null); if (typeof value !== "function") throw new Error; return this.tween(key, styleTween(name, value, priority == null ? "" : priority)); } function textConstant$1(value) { return function() { this.textContent = value; }; } function textFunction$1(value) { return function() { var value1 = value(this); this.textContent = value1 == null ? "" : value1; }; } function transition_text(value) { return this.tween("text", typeof value === "function" ? textFunction$1(tweenValue(this, "text", value)) : textConstant$1(value == null ? "" : value + "")); } function transition_transition() { var name = this._name, id0 = this._id, id1 = newId(); for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { if (node = group[i]) { var inherit = get$4(node, id0); schedule(node, name, id1, i, group, { time: inherit.time + inherit.delay + inherit.duration, delay: 0, duration: inherit.duration, ease: inherit.ease }); } } } return new Transition(groups, this._parents, name, id1); } function transition_end() { var on0, on1, that = this, id = that._id, size = that.size(); return new Promise(function(resolve, reject) { var cancel = {value: reject}, end = {value: function() { if (--size === 0) resolve(); }}; that.each(function() { var schedule = set$4(this, id), on = schedule.on; // If this node shared a dispatch with the previous node, // just assign the updated shared dispatch and we’re done! // Otherwise, copy-on-write. if (on !== on0) { on1 = (on0 = on).copy(); on1._.cancel.push(cancel); on1._.interrupt.push(cancel); on1._.end.push(end); } schedule.on = on1; }); }); } var id = 0; function Transition(groups, parents, name, id) { this._groups = groups; this._parents = parents; this._name = name; this._id = id; } function transition(name) { return selection().transition(name); } function newId() { return ++id; } var selection_prototype = selection.prototype; Transition.prototype = transition.prototype = { constructor: Transition, select: transition_select, selectAll: transition_selectAll, filter: transition_filter, merge: transition_merge, selection: transition_selection, transition: transition_transition, call: selection_prototype.call, nodes: selection_prototype.nodes, node: selection_prototype.node, size: selection_prototype.size, empty: selection_prototype.empty, each: selection_prototype.each, on: transition_on, attr: transition_attr, attrTween: transition_attrTween, style: transition_style, styleTween: transition_styleTween, text: transition_text, remove: transition_remove, tween: transition_tween, delay: transition_delay, duration: transition_duration, ease: transition_ease, end: transition_end }; function cubicInOut(t) { return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2; } var defaultTiming = { time: null, // Set on use. delay: 0, duration: 250, ease: cubicInOut }; function inherit(node, id) { var timing; while (!(timing = node.__transition) || !(timing = timing[id])) { if (!(node = node.parentNode)) { return defaultTiming.time = now(), defaultTiming; } } return timing; } function selection_transition(name) { var id, timing; if (name instanceof Transition) { id = name._id, name = name._name; } else { id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + ""; } for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { if (node = group[i]) { schedule(node, name, id, i, group, timing || inherit(node, id)); } } } return new Transition(groups, this._parents, name, id); } selection.prototype.interrupt = selection_interrupt; selection.prototype.transition = selection_transition; function constant$2(x) { return function() { return x; }; } function ZoomEvent(target, type, transform) { this.target = target; this.type = type; this.transform = transform; } function Transform(k, x, y) { this.k = k; this.x = x; this.y = y; } Transform.prototype = { constructor: Transform, scale: function(k) { return k === 1 ? this : new Transform(this.k * k, this.x, this.y); }, translate: function(x, y) { return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y); }, apply: function(point) { return [point[0] * this.k + this.x, point[1] * this.k + this.y]; }, applyX: function(x) { return x * this.k + this.x; }, applyY: function(y) { return y * this.k + this.y; }, invert: function(location) { return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k]; }, invertX: function(x) { return (x - this.x) / this.k; }, invertY: function(y) { return (y - this.y) / this.k; }, rescaleX: function(x) { return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x)); }, rescaleY: function(y) { return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y)); }, toString: function() { return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")"; } }; var identity$1 = new Transform(1, 0, 0); function nopropagation() { event.stopImmediatePropagation(); } function noevent$1() { event.preventDefault(); event.stopImmediatePropagation(); } // Ignore right-click, since that should open the context menu. function defaultFilter() { return !event.ctrlKey && !event.button; } function defaultExtent() { var e = this; if (e instanceof SVGElement) { e = e.ownerSVGElement || e; if (e.hasAttribute("viewBox")) { e = e.viewBox.baseVal; return [[e.x, e.y], [e.x + e.width, e.y + e.height]]; } return [[0, 0], [e.width.baseVal.value, e.height.baseVal.value]]; } return [[0, 0], [e.clientWidth, e.clientHeight]]; } function defaultTransform() { return this.__zoom || identity$1; } function defaultWheelDelta() { return -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002); } function defaultTouchable() { return navigator.maxTouchPoints || ("ontouchstart" in this); } function defaultConstrain(transform, extent, translateExtent) { var dx0 = transform.invertX(extent[0][0]) - translateExtent[0][0], dx1 = transform.invertX(extent[1][0]) - translateExtent[1][0], dy0 = transform.invertY(extent[0][1]) - translateExtent[0][1], dy1 = transform.invertY(extent[1][1]) - translateExtent[1][1]; return transform.translate( dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1), dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1) ); } function zoom() { var filter = defaultFilter, extent = defaultExtent, constrain = defaultConstrain, wheelDelta = defaultWheelDelta, touchable = defaultTouchable, scaleExtent = [0, Infinity], translateExtent = [[-Infinity, -Infinity], [Infinity, Infinity]], duration = 250, interpolate = interpolateZoom, listeners = dispatch("start", "zoom", "end"), touchstarting, touchending, touchDelay = 500, wheelDelay = 150, clickDistance2 = 0; function zoom(selection) { selection .property("__zoom", defaultTransform) .on("wheel.zoom", wheeled) .on("mousedown.zoom", mousedowned) .on("dblclick.zoom", dblclicked) .filter(touchable) .on("touchstart.zoom", touchstarted) .on("touchmove.zoom", touchmoved) .on("touchend.zoom touchcancel.zoom", touchended) .style("touch-action", "none") .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); } zoom.transform = function(collection, transform, point) { var selection = collection.selection ? collection.selection() : collection; selection.property("__zoom", defaultTransform); if (collection !== selection) { schedule(collection, transform, point); } else { selection.interrupt().each(function() { gesture(this, arguments) .start() .zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform) .end(); }); } }; zoom.scaleBy = function(selection, k, p) { zoom.scaleTo(selection, function() { var k0 = this.__zoom.k, k1 = typeof k === "function" ? k.apply(this, arguments) : k; return k0 * k1; }, p); }; zoom.scaleTo = function(selection, k, p) { zoom.transform(selection, function() { var e = extent.apply(this, arguments), t0 = this.__zoom, p0 = p == null ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p, p1 = t0.invert(p0), k1 = typeof k === "function" ? k.apply(this, arguments) : k; return constrain(translate(scale(t0, k1), p0, p1), e, translateExtent); }, p); }; zoom.translateBy = function(selection, x, y) { zoom.transform(selection, function() { return constrain(this.__zoom.translate( typeof x === "function" ? x.apply(this, arguments) : x, typeof y === "function" ? y.apply(this, arguments) : y ), extent.apply(this, arguments), translateExtent); }); }; zoom.translateTo = function(selection, x, y, p) { zoom.transform(selection, function() { var e = extent.apply(this, arguments), t = this.__zoom, p0 = p == null ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p; return constrain(identity$1.translate(p0[0], p0[1]).scale(t.k).translate( typeof x === "function" ? -x.apply(this, arguments) : -x, typeof y === "function" ? -y.apply(this, arguments) : -y ), e, translateExtent); }, p); }; function scale(transform, k) { k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k)); return k === transform.k ? transform : new Transform(k, transform.x, transform.y); } function translate(transform, p0, p1) { var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k; return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y); } function centroid(extent) { return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2]; } function schedule(transition, transform, point) { transition .on("start.zoom", function() { gesture(this, arguments).start(); }) .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); }) .tween("zoom", function() { var that = this, args = arguments, g = gesture(that, args), e = extent.apply(that, args), p = point == null ? centroid(e) : typeof point === "function" ? point.apply(that, args) : point, w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), a = that.__zoom, b = typeof transform === "function" ? transform.apply(that, args) : transform, i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); return function(t) { if (t === 1) t = b; // Avoid rounding error on end. else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); } g.zoom(null, t); }; }); } function gesture(that, args, clean) { return (!clean && that.__zooming) || new Gesture(that, args); } function Gesture(that, args) { this.that = that; this.args = args; this.active = 0; this.extent = extent.apply(that, args); this.taps = 0; } Gesture.prototype = { start: function() { if (++this.active === 1) { this.that.__zooming = this; this.emit("start"); } return this; }, zoom: function(key, transform) { if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]); if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]); if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]); this.that.__zoom = transform; this.emit("zoom"); return this; }, end: function() { if (--this.active === 0) { delete this.that.__zooming; this.emit("end"); } return this; }, emit: function(type) { customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]); } }; function wheeled() { if (!filter.apply(this, arguments)) return; var g = gesture(this, arguments), t = this.__zoom, k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))), p = mouse(this); // If the mouse is in the same location as before, reuse it. // If there were recent wheel events, reset the wheel idle timeout. if (g.wheel) { if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) { g.mouse[1] = t.invert(g.mouse[0] = p); } clearTimeout(g.wheel); } // If this wheel event won’t trigger a transform change, ignore it. else if (t.k === k) return; // Otherwise, capture the mouse point and location at the start. else { g.mouse = [p, t.invert(p)]; interrupt(this); g.start(); } noevent$1(); g.wheel = setTimeout(wheelidled, wheelDelay); g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent)); function wheelidled() { g.wheel = null; g.end(); } } function mousedowned() { if (touchending || !filter.apply(this, arguments)) return; var g = gesture(this, arguments, true), v = select(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true), p = mouse(this), x0 = event.clientX, y0 = event.clientY; dragDisable(event.view); nopropagation(); g.mouse = [p, this.__zoom.invert(p)]; interrupt(this); g.start(); function mousemoved() { noevent$1(); if (!g.moved) { var dx = event.clientX - x0, dy = event.clientY - y0; g.moved = dx * dx + dy * dy > clickDistance2; } g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent, translateExtent)); } function mouseupped() { v.on("mousemove.zoom mouseup.zoom", null); yesdrag(event.view, g.moved); noevent$1(); g.end(); } } function dblclicked() { if (!filter.apply(this, arguments)) return; var t0 = this.__zoom, p0 = mouse(this), p1 = t0.invert(p0), k1 = t0.k * (event.shiftKey ? 0.5 : 2), t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments), translateExtent); noevent$1(); if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0); else select(this).call(zoom.transform, t1); } function touchstarted() { if (!filter.apply(this, arguments)) return; var touches = event.touches, n = touches.length, g = gesture(this, arguments, event.changedTouches.length === n), started, i, t, p; nopropagation(); for (i = 0; i < n; ++i) { t = touches[i], p = touch(this, touches, t.identifier); p = [p, this.__zoom.invert(p), t.identifier]; if (!g.touch0) g.touch0 = p, started = true, g.taps = 1 + !!touchstarting; else if (!g.touch1 && g.touch0[2] !== p[2]) g.touch1 = p, g.taps = 0; } if (touchstarting) touchstarting = clearTimeout(touchstarting); if (started) { if (g.taps < 2) touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay); interrupt(this); g.start(); } } function touchmoved() { if (!this.__zooming) return; var g = gesture(this, arguments), touches = event.changedTouches, n = touches.length, i, t, p, l; noevent$1(); if (touchstarting) touchstarting = clearTimeout(touchstarting); g.taps = 0; for (i = 0; i < n; ++i) { t = touches[i], p = touch(this, touches, t.identifier); if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p; else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p; } t = g.that.__zoom; if (g.touch1) { var p0 = g.touch0[0], l0 = g.touch0[1], p1 = g.touch1[0], l1 = g.touch1[1], dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp, dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl; t = scale(t, Math.sqrt(dp / dl)); p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2]; l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2]; } else if (g.touch0) p = g.touch0[0], l = g.touch0[1]; else return; g.zoom("touch", constrain(translate(t, p, l), g.extent, translateExtent)); } function touchended() { if (!this.__zooming) return; var g = gesture(this, arguments), touches = event.changedTouches, n = touches.length, i, t; nopropagation(); if (touchending) clearTimeout(touchending); touchending = setTimeout(function() { touchending = null; }, touchDelay); for (i = 0; i < n; ++i) { t = touches[i]; if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0; else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1; } if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1; if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]); else { g.end(); // If this was a dbltap, reroute to the (optional) dblclick.zoom handler. if (g.taps === 2) { var p = select(this).on("dblclick.zoom"); if (p) p.apply(this, arguments); } } } zoom.wheelDelta = function(_) { return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant$2(+_), zoom) : wheelDelta; }; zoom.filter = function(_) { return arguments.length ? (filter = typeof _ === "function" ? _ : constant$2(!!_), zoom) : filter; }; zoom.touchable = function(_) { return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$2(!!_), zoom) : touchable; }; zoom.extent = function(_) { return arguments.length ? (extent = typeof _ === "function" ? _ : constant$2([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent; }; zoom.scaleExtent = function(_) { return arguments.length ? (scaleExtent[0] = +_[0], scaleExtent[1] = +_[1], zoom) : [scaleExtent[0], scaleExtent[1]]; }; zoom.translateExtent = function(_) { return arguments.length ? (translateExtent[0][0] = +_[0][0], translateExtent[1][0] = +_[1][0], translateExtent[0][1] = +_[0][1], translateExtent[1][1] = +_[1][1], zoom) : [[translateExtent[0][0], translateExtent[0][1]], [translateExtent[1][0], translateExtent[1][1]]]; }; zoom.constrain = function(_) { return arguments.length ? (constrain = _, zoom) : constrain; }; zoom.duration = function(_) { return arguments.length ? (duration = +_, zoom) : duration; }; zoom.interpolate = function(_) { return arguments.length ? (interpolate = _, zoom) : interpolate; }; zoom.on = function() { var value = listeners.on.apply(listeners, arguments); return value === listeners ? zoom : value; }; zoom.clickDistance = function(_) { return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2); }; return zoom; } // do not edit .js files directly - edit src/index.jst var fastDeepEqual = function equal(a, b) { if (a === b) return true; if (a && b && typeof a == 'object' && typeof b == 'object') { if (a.constructor !== b.constructor) return false; var length, i, keys; if (Array.isArray(a)) { length = a.length; if (length != b.length) return false; for (i = length; i-- !== 0;) if (!equal(a[i], b[i])) return false; return true; } if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); keys = Object.keys(a); length = keys.length; if (length !== Object.keys(b).length) return false; for (i = length; i-- !== 0;) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; for (i = length; i-- !== 0;) { var key = keys[i]; if (!equal(a[key], b[key])) return false; } return true; } // true if both NaN, false otherwise return a!==a && b!==b; }; var actions = { setOnConnect: action(function (state, onConnect) { state.onConnect = onConnect; }), setNodes: action(function (state, nodes) { state.nodes = nodes; }), setEdges: action(function (state, edges) { state.edges = edges; }), updateNodeData: action(function (state, _ref) { var id = _ref.id, data = _objectWithoutProperties(_ref, ["id"]); state.nodes.forEach(function (n) { if (n.id === id) { n.__rg = _objectSpread2$1({}, n.__rg, {}, data); } }); }), updateNodePos: action(function (state, _ref2) { var id = _ref2.id, pos = _ref2.pos; state.nodes.forEach(function (n) { if (n.id === id) { n.__rg = _objectSpread2$1({}, n.__rg, { position: pos }); } }); }), setSelection: action(function (state, isActive) { state.selectionActive = isActive; }), setNodesSelection: action(function (state, _ref3) { var isActive = _ref3.isActive, selection = _ref3.selection; if (!isActive) { state.nodesSelectionActive = false; state.selectedElements = []; return; } var selectedNodes = getNodesInside(state.nodes, selection, state.transform); var selectedNodesBbox = getBoundingBox(selectedNodes); state.selection = selection; state.nodesSelectionActive = true; state.selectedNodesBbox = selectedNodesBbox; state.nodesSelectionActive = true; }), setSelectedElements: action(function (state, elements) { var selectedElementsArr = Array.isArray(elements) ? elements : [elements]; var selectedElementsUpdated = !fastDeepEqual(selectedElementsArr, state.selectedElements); var selectedElements = selectedElementsUpdated ? selectedElementsArr : state.selectedElements; state.selectedElements = selectedElements; }), updateSelection: action(function (state, selection) { var selectedNodes = getNodesInside(state.nodes, selection, state.transform); var selectedEdges = getConnectedEdges(selectedNodes, state.edges); var nextSelectedElements = [].concat(_toConsumableArray(selectedNodes), _toConsumableArray(selectedEdges)); var selectedElementsUpdated = !fastDeepEqual(nextSelectedElements, state.selectedElements); state.selection = selection; state.selectedElements = selectedElementsUpdated ? nextSelectedElements : state.selectedElements; }), updateTransform: action(function (state, transform) { state.transform = [transform.x, transform.y, transform.k]; }), updateSize: action(function (state, size) { state.width = size.width; state.height = size.height; }), initD3: action(function (state, _ref4) { var zoom = _ref4.zoom, selection = _ref4.selection; state.d3Zoom = zoom; state.d3Selection = selection; state.d3Initialised = true; }), setConnectionPosition: action(function (state, position) { state.connectionPosition = position; }), setConnectionSourceId: action(function (state, sourceId) { state.connectionSourceId = sourceId; }) }; var store = createStore$1(_objectSpread2$1({ width: 0, height: 0, transform: [0, 0, 1], nodes: [], edges: [], selectedElements: [], selectedNodesBbox: { x: 0, y: 0, width: 0, height: 0 }, d3Zoom: null, d3Selection: null, d3Initialised: false, nodesSelectionActive: false, selectionActive: false, selection: {}, connectionSourceId: null, connectionPosition: { x: 0, y: 0 }, onConnect: function onConnect() {} }, actions)); var isEdge = function isEdge(element) { return element.source && element.target; }; var isNode = function isNode(element) { return !element.source && !element.target; }; var getOutgoers = function getOutgoers(node, elements) { if (!isNode(node)) { return []; } var outgoerIds = elements.filter(function (e) { return e.source === node.id; }).map(function (e) { return e.target; }); return elements.filter(function (e) { return outgoerIds.includes(e.id); }); }; var removeElements = function removeElements(elements, elementsToRemove) { var nodeIdsToRemove = elementsToRemove.map(function (n) { return n.id; }); return elements.filter(function (e) { return !nodeIdsToRemove.includes(e.id) && !nodeIdsToRemove.includes(e.target) && !nodeIdsToRemove.includes(e.source); }); }; var getEdgeId = function getEdgeId(e) { return "react-flow__edge-".concat(e.source, "-").concat(e.target); }; var pointToRendererPoint = function pointToRendererPoint(_ref, transform) { var x = _ref.x, y = _ref.y; var rendererX = (x - transform[0]) * (1 / [transform[2]]); var rendererY = (y - transform[1]) * (1 / [transform[2]]); return { x: rendererX, y: rendererY }; }; var parseElement = function parseElement(e, transform) { if (isEdge(e)) { return _objectSpread2$1({}, e, { type: e.type || 'default', id: e.id ? e.id.toString() : getEdgeId(e) }); } return _objectSpread2$1({}, e, { id: e.id.toString(), type: e.type || 'default', __rg: { position: pointToRendererPoint(e.position, transform), width: null, height: null, handleBounds: {} } }); }; var getBoundingBox = function getBoundingBox(nodes) { var bbox = nodes.reduce(function (res, node) { var position = node.__rg.position; var x2 = position.x + node.__rg.width; var y2 = position.y + node.__rg.height; if (position.x < res.minX) { res.minX = position.x; } if (x2 > res.maxX) { res.maxX = x2; } if (position.y < res.minY) { res.minY = position.y; } if (y2 > res.maxY) { res.maxY = y2; } return res; }, { minX: Number.MAX_VALUE, minY: Number.MAX_VALUE, maxX: 0, maxY: 0 }); return { x: bbox.minX, y: bbox.minY, width: bbox.maxX - bbox.minX, height: bbox.maxY - bbox.minY }; }; var getNodesInside = function getNodesInside(nodes, bbox) { var transform = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [0, 0, 1]; var partially = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; return nodes.filter(function (n) { var bboxPos = { x: (bbox.x - transform[0]) * (1 / transform[2]), y: (bbox.y - transform[1]) * (1 / transform[2]) }; var bboxWidth = bbox.width * (1 / transform[2]); var bboxHeight = bbox.height * (1 / transform[2]); var _n$__rg = n.__rg, position = _n$__rg.position, width = _n$__rg.width, height = _n$__rg.height; var nodeWidth = partially ? -width : width; var nodeHeight = partially ? 0 : height; var offsetX = partially ? width : 0; var offsetY = partially ? height : 0; return position.x + offsetX > bboxPos.x && position.x + nodeWidth < bboxPos.x + bboxWidth && position.y + offsetY > bboxPos.y && position.y + nodeHeight < bboxPos.y + bboxHeight; }); }; var getConnectedEdges = function getConnectedEdges(nodes, edges) { var nodeIds = nodes.map(function (n) { return n.id; }); return edges.filter(function (e) { var hasSourceHandleId = e.source.includes('__'); var hasTargetHandleId = e.target.includes('__'); var sourceId = hasSourceHandleId ? e.source.split('__')[0] : e.source; var targetId = hasTargetHandleId ? e.target.split('__')[0] : e.target; return nodeIds.includes(sourceId) || nodeIds.includes(targetId); }); }; var fitView = function fitView() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref2$padding = _ref2.padding, padding = _ref2$padding === void 0 ? 0 : _ref2$padding; var state = store.getState(); var bounds = getBoundingBox(state.nodes); var maxBoundsSize = Math.max(bounds.width, bounds.height); var k = Math.min(state.width, state.height) / (maxBoundsSize + maxBoundsSize * padding); var boundsCenterX = bounds.x + bounds.width / 2; var boundsCenterY = bounds.y + bounds.height / 2; var transform = [state.width / 2 - boundsCenterX * k, state.height / 2 - boundsCenterY * k]; var fittedTransform = identity$1.translate(transform[0], transform[1]).scale(k); state.d3Selection.call(state.d3Zoom.transform, fittedTransform); }; var zoomIn = function zoomIn() { var state = store.getState(); state.d3Zoom.scaleTo(state.d3Selection, state.transform[2] + 0.2); }; var zoomOut = function zoomOut() { var state = store.getState(); state.d3Zoom.scaleTo(state.d3Selection, state.transform[2] - 0.2); }; function renderNode(d, props, state) { var nodeType = d.type || 'default'; if (!props.nodeTypes[nodeType]) { console.warn("No node type found for type \"".concat(nodeType, "\". Using fallback type \"default\".")); } var NodeComponent = props.nodeTypes[nodeType] || props.nodeTypes["default"]; var selected = state.selectedElements.filter(isNode).map(function (e) { return e.id; }).includes(d.id); return React__default.createElement(NodeComponent, { key: d.id, id: d.id, type: d.type, data: d.data, xPos: d.__rg.position.x, yPos: d.__rg.position.y, onClick: props.onElementClick, onNodeDragStop: props.onNodeDragStop, transform: state.transform, selected: selected, style: d.style }); } var NodeRenderer = React.memo(function (props) { var state = useStoreState(function (s) { return { nodes: s.nodes, transform: s.transform, selectedElements: s.selectedElements }; }); var transform = state.transform, nodes = state.nodes; var transformStyle = { transform: "translate(".concat(transform[0], "px,").concat(transform[1], "px) scale(").concat(transform[2], ")") }; return React__default.createElement("div", { className: "react-flow__nodes", style: transformStyle }, nodes.map(function (d) { return renderNode(d, props, state); })); }); NodeRenderer.displayName = 'NodeRenderer'; NodeRenderer.whyDidYouRender = false; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var classnames = createCommonjsModule(function (module) { /*! Copyright (c) 2017 Jed Watson. Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames */ /* global define */ (function () { var hasOwn = {}.hasOwnProperty; function classNames () { var classes = []; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; if (!arg) continue; var argType = typeof arg; if (argType === 'string' || argType === 'number') { classes.push(arg); } else if (Array.isArray(arg) && arg.length) { var inner = classNames.apply(null, arg); if (inner) { classes.push(inner); } } else if (argType === 'object') { for (var key in arg) { if (hasOwn.call(arg, key) && arg[key]) { classes.push(key); } } } } return classes.join(' '); } if ( module.exports) { classNames.default = classNames; module.exports = classNames; } else { window.classNames = classNames; } }()); }); var ConnectionLine = (function (props) { var _useState = React.useState(null), _useState2 = _slicedToArray(_useState, 2), sourceNode = _useState2[0], setSourceNode = _useState2[1]; var hasHandleId = props.connectionSourceId.includes('__'); var sourceIdSplitted = props.connectionSourceId.split('__'); var nodeId = sourceIdSplitted[0]; var handleId = hasHandleId ? sourceIdSplitted[1] : null; React.useEffect(function () { setSourceNode(props.nodes.find(function (n) { return n.id === nodeId; })); }, []); if (!sourceNode) { return null; } var style = props.connectionLineStyle || {}; var className = classnames('react-flow__edge', 'connection', props.className); var sourceHandle = handleId ? sourceNode.__rg.handleBounds.source.find(function (d) { return d.id === handleId; }) : sourceNode.__rg.handleBounds.source[0]; var sourceHandleX = sourceHandle ? sourceHandle.x + sourceHandle.width / 2 : sourceNode.__rg.width / 2; var sourceHandleY = sourceHandle ? sourceHandle.y + sourceHandle.height / 2 : sourceNode.__rg.height; var sourceX = sourceNode.__rg.position.x + sourceHandleX; var sourceY = sourceNode.__rg.position.y + sourceHandleY; var targetX = (props.connectionPositionX - props.transform[0]) * (1 / props.transform[2]); var targetY = (props.connectionPositionY - props.transform[1]) * (1 / props.transform[2]); var dAttr = ''; if (props.connectionLineType === 'bezier') { var yOffset = Math.abs(targetY - sourceY) / 2; var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset; dAttr = "M".concat(sourceX, ",").concat(sourceY, " C").concat(sourceX, ",").concat(centerY, " ").concat(targetX, ",").concat(centerY, " ").concat(targetX, ",").concat(targetY); } else { dAttr = "M".concat(sourceX, ",").concat(sourceY, " ").concat(targetX, ",").concat(targetY); } return React__default.createElement("g", { className: className }, React__default.createElement("path", _extends$1({ d: dAttr }, style))); }); function getHandlePosition(position, node) { var handle = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; if (!handle) { switch (position) { case 'top': return { x: node.__rg.width / 2, y: 0 }; case 'right': return { x: node.__rg.width, y: node.__rg.height / 2 }; case 'bottom': return { x: node.__rg.width / 2, y: node.__rg.height }; case 'left': return { x: 0, y: node.__rg.height / 2 }; } } switch (position) { case 'top': return { x: handle.x + handle.width / 2, y: handle.y }; case 'right': return { x: handle.x + handle.width, y: handle.y + handle.height / 2 }; case 'bottom': return { x: handle.x + handle.width / 2, y: handle.y + handle.height }; case 'left': return { x: handle.x, y: handle.y + handle.height / 2 }; } } function getHandle(bounds, handleId) { var handle = null; if (!bounds) { return null; } // there is no handleId when there are no multiple handles/ handles with ids // so we just pick the first one if (bounds.length === 1 || !handleId) { handle = bounds[0]; } else if (handleId) { handle = bounds.find(function (d) { return d.id === handleId; }); } return handle; } function getEdgePositions(_ref) { var sourceNode = _ref.sourceNode, sourceHandle = _ref.sourceHandle, sourcePosition = _ref.sourcePosition, targetNode = _ref.targetNode, targetHandle = _ref.targetHandle, targetPosition = _ref.targetPosition; var sourceHandlePos = getHandlePosition(sourcePosition, sourceNode, sourceHandle); var sourceX = sourceNode.__rg.position.x + sourceHandlePos.x; var sourceY = sourceNode.__rg.position.y + sourceHandlePos.y; var targetHandlePos = getHandlePosition(targetPosition, targetNode, targetHandle); var targetX = targetNode.__rg.position.x + targetHandlePos.x; var targetY = targetNode.__rg.position.y + targetHandlePos.y; return { sourceX: sourceX, sourceY: sourceY, targetX: targetX, targetY: targetY }; } function renderEdge(e, props, state) { var edgeType = e.type || 'default'; var hasSourceHandleId = e.source.includes('__'); var hasTargetHandleId = e.target.includes('__'); var sourceId = hasSourceHandleId ? e.source.split('__')[0] : e.source; var targetId = hasTargetHandleId ? e.target.split('__')[0] : e.target; var sourceHandleId = hasSourceHandleId ? e.source.split('__')[1] : null; var targetHandleId = hasTargetHandleId ? e.target.split('__')[1] : null; var sourceNode = state.nodes.find(function (n) { return n.id === sourceId; }); var targetNode = state.nodes.find(function (n) { return n.id === targetId; }); if (!sourceNode) { throw new Error("couldn't create edge for source id: ".concat(sourceId)); } if (!targetNode) { throw new Error("couldn't create edge for target id: ".concat(targetId)); } var EdgeComponent = props.edgeTypes[edgeType] || props.edgeTypes["default"]; var sourceHandle = getHandle(sourceNode.__rg.handleBounds.source, sourceHandleId); var targetHandle = getHandle(targetNode.__rg.handleBounds.target, targetHandleId); var sourcePosition = sourceHandle ? sourceHandle.position : 'bottom'; var targetPosition = targetHandle ? targetHandle.position : 'top'; var _getEdgePositions = getEdgePositions({ sourceNode: sourceNode, sourceHandle: sourceHandle, sourcePosition: sourcePosition, targetNode: targetNode, targetHandle: targetHandle, targetPosition: targetPosition }), sourceX = _getEdgePositions.sourceX, sourceY = _getEdgePositions.sourceY, targetX = _getEdgePositions.targetX, targetY = _getEdgePositions.targetY; var selected = state.selectedElements.filter(isEdge).find(function (elm) { return elm.source === sourceId && elm.target === targetId; }); return React__default.createElement(EdgeComponent, { key: e.id, id: e.id, type: e.type, onClick: props.onElementClick, selected: selected, animated: e.animated, style: e.style, source: sourceId, target: targetId, sourceHandleId: sourceHandleId, targetHandleId: targetHandleId, sourceX: sourceX, sourceY: sourceY, targetX: targetX, targetY: targetY, sourcePosition: sourcePosition, targetPosition: targetPosition }); } var EdgeRenderer = React.memo(function (props) { var state = useStoreState(function (s) { return { nodes: s.nodes, edges: s.edges, transform: s.transform, selectedElements: s.selectedElements, connectionSourceId: s.connectionSourceId, position: s.connectionPosition }; }); var width = props.width, height = props.height, connectionLineStyle = props.connectionLineStyle, connectionLineType = props.connectionLineType; if (!width) { return null; } var transform = state.transform, edges = state.edges, nodes = state.nodes, connectionSourceId = state.connectionSourceId, position = state.position; var transformStyle = "translate(".concat(transform[0], ",").concat(transform[1], ") scale(").concat(transform[2], ")"); return React__default.createElement("svg", { width: width, height: height, className: "react-flow__edges" }, React__default.createElement("g", { transform: transformStyle }, edges.map(function (e) { return renderEdge(e, props, state); }), connectionSourceId && React__default.createElement(ConnectionLine, { nodes: nodes, connectionSourceId: connectionSourceId, connectionPositionX: position.x, connectionPositionY: position.y, transform: transform, connectionLineStyle: connectionLineStyle, connectionLineType: connectionLineType }))); }); EdgeRenderer.displayName = 'EdgeRenderer'; var baseStyles = { position: 'absolute', top: 0, left: 0 }; var GridRenderer = React.memo(function (_ref) { var _ref$gap = _ref.gap, gap = _ref$gap === void 0 ? 24 : _ref$gap, _ref$strokeColor = _ref.strokeColor, strokeColor = _ref$strokeColor === void 0 ? '#999' : _ref$strokeColor, _ref$strokeWidth = _ref.strokeWidth, strokeWidth = _ref$strokeWidth === void 0 ? 0.1 : _ref$strokeWidth, style = _ref.style, className = _ref.className; var _useStoreState = useStoreState(function (s) { return s; }), width = _useStoreState.width, height = _useStoreState.height, _useStoreState$transf = _slicedToArray(_useStoreState.transform, 3), x = _useStoreState$transf[0], y = _useStoreState$transf[1], scale = _useStoreState$transf[2]; var gridClasses = classnames('react-flow__grid', className); var scaledGap = gap * scale; var xStart = x % scaledGap; var yStart = y % scaledGap; var lineCountX = Math.ceil(width / scaledGap) + 1; var lineCountY = Math.ceil(height / scaledGap) + 1; var xValues = Array.from({ length: lineCountX }, function (_, index) { return "M".concat(index * scaledGap + xStart, " 0 V").concat(height); }); var yValues = Array.from({ length: lineCountY }, function (_, index) { return "M0 ".concat(index * scaledGap + yStart, " H").concat(width); }); var path = [].concat(_toConsumableArray(xValues), _toConsumableArray(yValues)).join(' '); return React__default.createElement("svg", { width: width, height: height, style: _objectSpread2$1({}, baseStyles, {}, style), className: gridClasses }, React__default.createElement("path", { fill: "none", stroke: strokeColor, strokeWidth: strokeWidth, d: path })); }); GridRenderer.displayName = 'GridRenderer'; var initialRect = { startX: 0, startY: 0, x: 0, y: 0, width: 0, height: 0, draw: false }; function getMousePosition(evt) { var containerBounds = document.querySelector('.react-flow').getBoundingClientRect(); return { x: evt.clientX - containerBounds.left, y: evt.clientY - containerBounds.top }; } var UserSelection = React.memo(function () { var selectionPane = React.useRef(null); var _useState = React.useState(initialRect), _useState2 = _slicedToArray(_useState, 2), rect = _useState2[0], setRect = _useState2[1]; var setSelection = useStoreActions(function (a) { return a.setSelection; }); var updateSelection = useStoreActions(function (a) { return a.updateSelection; }); var setNodesSelection = useStoreActions(function (a) { return a.setNodesSelection; }); React.useEffect(function () { function onMouseDown(evt) { var mousePos = getMousePosition(evt); setRect(function (currentRect) { return _objectSpread2$1({}, currentRect, { startX: mousePos.x, startY: mousePos.y, x: mousePos.x, y: mousePos.y, draw: true }); }); setSelection(true); } function onMouseMove(evt) { setRect(function (currentRect) { if (!currentRect.draw) { return currentRect; } var mousePos = getMousePosition(evt); var negativeX = mousePos.x < currentRect.startX; var negativeY = mousePos.y < currentRect.startY; var nextRect = _objectSpread2$1({}, currentRect, { x: negativeX ? mousePos.x : currentRect.x, y: negativeY ? mousePos.y : currentRect.y, width: negativeX ? currentRect.startX - mousePos.x : mousePos.x - currentRect.startX, height: negativeY ? currentRect.startY - mousePos.y : mousePos.y - currentRect.startY }); updateSelection(nextRect); return nextRect; }); } function onMouseUp() { setRect(function (currentRect) { setNodesSelection({ isActive: true, selection: currentRect }); setSelection(false); return _objectSpread2$1({}, currentRect, { draw: false }); }); } selectionPane.current.addEventListener('mousedown', onMouseDown); selectionPane.current.addEventListener('mousemove', onMouseMove); selectionPane.current.addEventListener('mouseup', onMouseUp); return function () { selectionPane.current.removeEventListener('mousedown', onMouseDown); selectionPane.current.removeEventListener('mousemove', onMouseMove); selectionPane.current.removeEventListener('mouseup', onMouseUp); }; }, []); return React__default.createElement("div", { className: "react-flow__selectionpane", ref: selectionPane }, (rect.draw || rect.fixed) && React__default.createElement("div", { className: "react-flow__selection", style: { width: rect.width, height: rect.height, transform: "translate(".concat(rect.x, "px, ").concat(rect.y, "px)") } })); }); var reactDraggable = createCommonjsModule(function (module, exports) { (function (global, factory) { module.exports = factory(reactDom, React__default) ; }(commonjsGlobal, (function (ReactDOM,React) { ReactDOM = ReactDOM && ReactDOM.hasOwnProperty('default') ? ReactDOM['default'] : ReactDOM; React = React && React.hasOwnProperty('default') ? React['default'] : React; function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ 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; }; var emptyFunction_1 = emptyFunction; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ /** * 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) {}; { 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; } } var invariant_1 = invariant; /** * 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_1; { 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)); } }; } var warning_1 = warning; /* object-assign (c) Sindre Sorhus @license MIT */ /* eslint-disable no-unused-vars */ var getOwnPropertySymbols = Object.getOwnPropertySymbols; 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 no-new-wrappers 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 (err) { // We don't expect any of the above to throw, but better to be safe. return false; } } var objectAssign = 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 (getOwnPropertySymbols) { symbols = getOwnPropertySymbols(from); for (var i = 0; i < symbols.length; i++) { if (propIsEnumerable.call(from, symbols[i])) { to[symbols[i]] = from[symbols[i]]; } } } } return to; }; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; var ReactPropTypesSecret_1 = ReactPropTypesSecret; { var invariant$1 = invariant_1; var warning$1 = warning_1; var ReactPropTypesSecret$1 = ReactPropTypesSecret_1; 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 {?Function} getStack Returns the component stack. * @private */ function checkPropTypes(typeSpecs, values, location, componentName, getStack) { { 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. invariant$1(typeof typeSpecs[typeSpecName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'the `prop-types` package, but received `%s`.', componentName || 'React class', location, typeSpecName, typeof typeSpecs[typeSpecName]); error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret$1); } catch (ex) { error = ex; } warning$1(!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', location, typeSpecName, typeof error); 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 stack = getStack ? getStack() : ''; warning$1(false, 'Failed %s type: %s%s', location, error.message, stack != null ? stack : ''); } } } } } var checkPropTypes_1 = checkPropTypes; var factoryWithTypeCheckers = function(isValidElement, throwOnDirectAccess) { /* 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; } } /** * 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 = '<>'; // Important! // Keep this list in sync with production version in `./factoryWithThrowingShims.js`. 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, exact: createStrictShapeTypeChecker, }; /** * 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) { { var manualPropTypeCallCache = {}; var manualPropTypeWarningCount = 0; } function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { componentName = componentName || ANONYMOUS; propFullName = propFullName || propName; if (secret !== ReactPropTypesSecret_1) { if (throwOnDirectAccess) { // New behavior only for users of `prop-types` package invariant_1( false, 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + 'Use `PropTypes.checkPropTypes()` to call them. ' + 'Read more at http://fb.me/use-check-prop-types' ); } else if ( typeof console !== 'undefined') { // Old behavior for people using React.PropTypes var cacheKey = componentName + ':' + propName; if ( !manualPropTypeCallCache[cacheKey] && // Avoid spamming the console because they are often not actionable except for lib authors manualPropTypeWarningCount < 3 ) { warning_1( false, 'You are manually calling a React.PropTypes validation ' + 'function for the `%s` prop on `%s`. This is deprecated ' + 'and will throw in the standalone `prop-types` package. ' + '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 ); manualPropTypeCallCache[cacheKey] = true; manualPropTypeWarningCount++; } } } if (props[propName] == null) { if (isRequired) { if (props[propName] === null) { return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); } return new PropTypeError('The ' + location + ' `' + 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) { // `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 ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.')); } return null; } return createChainableTypeChecker(validate); } function createAnyTypeChecker() { return createChainableTypeChecker(emptyFunction_1.thatReturnsNull); } 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 propType = getPropType(propValue); return new PropTypeError('Invalid ' + location + ' `' + 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_1); 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 (!isValidElement(propValue)) { var propType = getPropType(propValue); return new PropTypeError('Invalid ' + location + ' `' + 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 expectedClassName = expectedClass.name || ANONYMOUS; var actualClassName = getClassName(props[propName]); return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); } return null; } return createChainableTypeChecker(validate); } function createEnumTypeChecker(expectedValues) { if (!Array.isArray(expectedValues)) { warning_1(false, 'Invalid argument supplied to oneOf, expected an instance of array.'); return emptyFunction_1.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 valuesString = JSON.stringify(expectedValues); return new PropTypeError('Invalid ' + location + ' `' + 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') { return new PropTypeError('Invalid ' + location + ' `' + 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_1); if (error instanceof Error) { return error; } } } return null; } return createChainableTypeChecker(validate); } function createUnionTypeChecker(arrayOfTypeCheckers) { if (!Array.isArray(arrayOfTypeCheckers)) { warning_1(false, 'Invalid argument supplied to oneOfType, expected an instance of array.'); return emptyFunction_1.thatReturnsNull; } for (var i = 0; i < arrayOfTypeCheckers.length; i++) { var checker = arrayOfTypeCheckers[i]; if (typeof checker !== 'function') { warning_1( false, 'Invalid argument supplied to oneOfType. Expected an array of check functions, but ' + 'received %s at index %s.', getPostfixForTypeWarning(checker), i ); return emptyFunction_1.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_1) == null) { return null; } } return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.')); } return createChainableTypeChecker(validate); } function createNodeChecker() { function validate(props, propName, componentName, location, propFullName) { if (!isNode(props[propName])) { return new PropTypeError('Invalid ' + location + ' `' + 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') { return new PropTypeError('Invalid ' + location + ' `' + 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_1); if (error) { return error; } } return null; } return createChainableTypeChecker(validate); } function createStrictShapeTypeChecker(shapeTypes) { function validate(props, propName, componentName, location, propFullName) { var propValue = props[propName]; var propType = getPropType(propValue); if (propType !== 'object') { return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); } // We need to check all keys in case some are required but missing from // props. var allKeys = objectAssign({}, props[propName], shapeTypes); for (var key in allKeys) { var checker = shapeTypes[key]; if (!checker) { return new PropTypeError( 'Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' + '\nBad object: ' + JSON.stringify(props[propName], null, ' ') + '\nValid keys: ' + JSON.stringify(Object.keys(shapeTypes), null, ' ') ); } var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret_1); 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 || 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) { if (typeof propValue === 'undefined' || propValue === null) { return '' + propValue; } var propType = getPropType(propValue); if (propType === 'object') { if (propValue instanceof Date) { return 'date'; } else if (propValue instanceof RegExp) { return 'regexp'; } } return propType; } // Returns a string that is postfixed to a warning about an invalid type. // For example, "undefined" or "of type array" function getPostfixForTypeWarning(value) { var type = getPreciseType(value); switch (type) { case 'array': case 'object': return 'an ' + type; case 'boolean': case 'date': case 'regexp': return 'a ' + type; default: return type; } } // Returns class name of the object, if any. function getClassName(propValue) { if (!propValue.constructor || !propValue.constructor.name) { return ANONYMOUS; } return propValue.constructor.name; } ReactPropTypes.checkPropTypes = checkPropTypes_1; ReactPropTypes.PropTypes = ReactPropTypes; return ReactPropTypes; }; var propTypes = createCommonjsModule(function (module) { /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ { var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element')) || 0xeac7; var isValidElement = function(object) { return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; }; // By explicitly using `prop-types` you are opting into new development behavior. // http://fb.me/prop-types-in-prod var throwOnDirectAccess = true; module.exports = factoryWithTypeCheckers(isValidElement, throwOnDirectAccess); } }); var classnames = createCommonjsModule(function (module) { /*! Copyright (c) 2016 Jed Watson. Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames */ /* global define */ (function () { var hasOwn = {}.hasOwnProperty; function classNames () { var classes = []; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; if (!arg) continue; var argType = typeof arg; if (argType === 'string' || argType === 'number') { classes.push(arg); } else if (Array.isArray(arg)) { classes.push(classNames.apply(null, arg)); } else if (argType === 'object') { for (var key in arg) { if (hasOwn.call(arg, key) && arg[key]) { classes.push(key); } } } } return classes.join(' '); } if ( module.exports) { module.exports = classNames; } else { window.classNames = classNames; } }()); }); // @credits https://gist.github.com/rogozhnikoff/a43cfed27c41e4e68cdc function findInArray(array /*: Array | TouchList*/, callback /*: Function*/) /*: any*/ { for (var i = 0, length = array.length; i < length; i++) { if (callback.apply(callback, [array[i], i, array])) return array[i]; } } function isFunction(func /*: any*/) /*: boolean*/ { return typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]'; } function isNum(num /*: any*/) /*: boolean*/ { return typeof num === 'number' && !isNaN(num); } function int(a /*: string*/) /*: number*/ { return parseInt(a, 10); } function dontSetMe(props /*: Object*/, propName /*: string*/, componentName /*: string*/) { if (props[propName]) { return new Error('Invalid prop ' + propName + ' passed to ' + componentName + ' - do not set this, set it on the child.'); } } var prefixes = ['Moz', 'Webkit', 'O', 'ms']; function getPrefix() /*: string*/ { var prop /*: string*/ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'transform'; // Checking specifically for 'window.document' is for pseudo-browser server-side // environments that define 'window' as the global context. // E.g. React-rails (see https://github.com/reactjs/react-rails/pull/84) if (typeof window === 'undefined' || typeof window.document === 'undefined') return ''; var style = window.document.documentElement.style; if (prop in style) return ''; for (var i = 0; i < prefixes.length; i++) { if (browserPrefixToKey(prop, prefixes[i]) in style) return prefixes[i]; } return ''; } function browserPrefixToKey(prop /*: string*/, prefix /*: string*/) /*: string*/ { return prefix ? '' + prefix + kebabToTitleCase(prop) : prop; } function kebabToTitleCase(str /*: string*/) /*: string*/ { var out = ''; var shouldCapitalize = true; for (var i = 0; i < str.length; i++) { if (shouldCapitalize) { out += str[i].toUpperCase(); shouldCapitalize = false; } else if (str[i] === '-') { shouldCapitalize = true; } else { out += str[i]; } } return out; } // Default export is the prefix itself, like 'Moz', 'Webkit', etc // Note that you may have to re-test for certain things; for instance, Chrome 50 // can handle unprefixed `transform`, but not unprefixed `user-select` var browserPrefix = getPrefix(); var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var defineProperty = function (obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }; 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 inherits = function (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 possibleConstructorReturn = function (self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }; var slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /*:: import type {ControlPosition, PositionOffsetControlPosition, MouseTouchEvent} from './types';*/ var matchesSelectorFunc = ''; function matchesSelector(el /*: Node*/, selector /*: string*/) /*: boolean*/ { if (!matchesSelectorFunc) { matchesSelectorFunc = findInArray(['matches', 'webkitMatchesSelector', 'mozMatchesSelector', 'msMatchesSelector', 'oMatchesSelector'], function (method) { // $FlowIgnore: Doesn't think elements are indexable return isFunction(el[method]); }); } // Might not be found entirely (not an Element?) - in that case, bail // $FlowIgnore: Doesn't think elements are indexable if (!isFunction(el[matchesSelectorFunc])) return false; // $FlowIgnore: Doesn't think elements are indexable return el[matchesSelectorFunc](selector); } // Works up the tree to the draggable itself attempting to match selector. function matchesSelectorAndParentsTo(el /*: Node*/, selector /*: string*/, baseNode /*: Node*/) /*: boolean*/ { var node = el; do { if (matchesSelector(node, selector)) return true; if (node === baseNode) return false; node = node.parentNode; } while (node); return false; } function addEvent(el /*: ?Node*/, event /*: string*/, handler /*: Function*/) /*: void*/ { if (!el) { return; } if (el.attachEvent) { el.attachEvent('on' + event, handler); } else if (el.addEventListener) { el.addEventListener(event, handler, true); } else { // $FlowIgnore: Doesn't think elements are indexable el['on' + event] = handler; } } function removeEvent(el /*: ?Node*/, event /*: string*/, handler /*: Function*/) /*: void*/ { if (!el) { return; } if (el.detachEvent) { el.detachEvent('on' + event, handler); } else if (el.removeEventListener) { el.removeEventListener(event, handler, true); } else { // $FlowIgnore: Doesn't think elements are indexable el['on' + event] = null; } } function outerHeight(node /*: HTMLElement*/) /*: number*/ { // This is deliberately excluding margin for our calculations, since we are using // offsetTop which is including margin. See getBoundPosition var height = node.clientHeight; var computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); height += int(computedStyle.borderTopWidth); height += int(computedStyle.borderBottomWidth); return height; } function outerWidth(node /*: HTMLElement*/) /*: number*/ { // This is deliberately excluding margin for our calculations, since we are using // offsetLeft which is including margin. See getBoundPosition var width = node.clientWidth; var computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); width += int(computedStyle.borderLeftWidth); width += int(computedStyle.borderRightWidth); return width; } function innerHeight(node /*: HTMLElement*/) /*: number*/ { var height = node.clientHeight; var computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); height -= int(computedStyle.paddingTop); height -= int(computedStyle.paddingBottom); return height; } function innerWidth(node /*: HTMLElement*/) /*: number*/ { var width = node.clientWidth; var computedStyle = node.ownerDocument.defaultView.getComputedStyle(node); width -= int(computedStyle.paddingLeft); width -= int(computedStyle.paddingRight); return width; } // Get from offsetParent function offsetXYFromParent(evt /*: {clientX: number, clientY: number}*/, offsetParent /*: HTMLElement*/) /*: ControlPosition*/ { var isBody = offsetParent === offsetParent.ownerDocument.body; var offsetParentRect = isBody ? { left: 0, top: 0 } : offsetParent.getBoundingClientRect(); var x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left; var y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top; return { x: x, y: y }; } function createCSSTransform(controlPos /*: ControlPosition*/, positionOffset /*: PositionOffsetControlPosition*/) /*: Object*/ { var translation = getTranslation(controlPos, positionOffset, 'px'); return defineProperty({}, browserPrefixToKey('transform', browserPrefix), translation); } function createSVGTransform(controlPos /*: ControlPosition*/, positionOffset /*: PositionOffsetControlPosition*/) /*: string*/ { var translation = getTranslation(controlPos, positionOffset, ''); return translation; } function getTranslation(_ref2, positionOffset /*: PositionOffsetControlPosition*/, unitSuffix /*: string*/) /*: string*/ { var x = _ref2.x, y = _ref2.y; var translation = 'translate(' + x + unitSuffix + ',' + y + unitSuffix + ')'; if (positionOffset) { var defaultX = '' + (typeof positionOffset.x === 'string' ? positionOffset.x : positionOffset.x + unitSuffix); var defaultY = '' + (typeof positionOffset.y === 'string' ? positionOffset.y : positionOffset.y + unitSuffix); translation = 'translate(' + defaultX + ', ' + defaultY + ')' + translation; } return translation; } function getTouch(e /*: MouseTouchEvent*/, identifier /*: number*/) /*: ?{clientX: number, clientY: number}*/ { return e.targetTouches && findInArray(e.targetTouches, function (t) { return identifier === t.identifier; }) || e.changedTouches && findInArray(e.changedTouches, function (t) { return identifier === t.identifier; }); } function getTouchIdentifier(e /*: MouseTouchEvent*/) /*: ?number*/ { if (e.targetTouches && e.targetTouches[0]) return e.targetTouches[0].identifier; if (e.changedTouches && e.changedTouches[0]) return e.changedTouches[0].identifier; } // User-select Hacks: // // Useful for preventing blue highlights all over everything when dragging. // Note we're passing `document` b/c we could be iframed function addUserSelectStyles(doc /*: ?Document*/) { if (!doc) return; var styleEl = doc.getElementById('react-draggable-style-el'); if (!styleEl) { styleEl = doc.createElement('style'); styleEl.type = 'text/css'; styleEl.id = 'react-draggable-style-el'; styleEl.innerHTML = '.react-draggable-transparent-selection *::-moz-selection {all: inherit;}\n'; styleEl.innerHTML += '.react-draggable-transparent-selection *::selection {all: inherit;}\n'; doc.getElementsByTagName('head')[0].appendChild(styleEl); } if (doc.body) addClassName(doc.body, 'react-draggable-transparent-selection'); } function removeUserSelectStyles(doc /*: ?Document*/) { try { if (doc && doc.body) removeClassName(doc.body, 'react-draggable-transparent-selection'); // $FlowIgnore: IE if (doc.selection) { // $FlowIgnore: IE doc.selection.empty(); } else { window.getSelection().removeAllRanges(); // remove selection caused by scroll } } catch (e) { // probably IE } } function styleHacks() /*: Object*/ { var childStyle /*: Object*/ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; // Workaround IE pointer events; see #51 // https://github.com/mzabriskie/react-draggable/issues/51#issuecomment-103488278 return _extends({ touchAction: 'none' }, childStyle); } function addClassName(el /*: HTMLElement*/, className /*: string*/) { if (el.classList) { el.classList.add(className); } else { if (!el.className.match(new RegExp('(?:^|\\s)' + className + '(?!\\S)'))) { el.className += ' ' + className; } } } function removeClassName(el /*: HTMLElement*/, className /*: string*/) { if (el.classList) { el.classList.remove(className); } else { el.className = el.className.replace(new RegExp('(?:^|\\s)' + className + '(?!\\S)', 'g'), ''); } } /*:: import type Draggable from '../Draggable';*/ /*:: import type {Bounds, ControlPosition, DraggableData, MouseTouchEvent} from './types';*/ /*:: import type DraggableCore from '../DraggableCore';*/ function getBoundPosition(draggable /*: Draggable*/, x /*: number*/, y /*: number*/) /*: [number, number]*/ { // If no bounds, short-circuit and move on if (!draggable.props.bounds) return [x, y]; // Clone new bounds var bounds = draggable.props.bounds; bounds = typeof bounds === 'string' ? bounds : cloneBounds(bounds); var node = findDOMNode(draggable); if (typeof bounds === 'string') { var ownerDocument = node.ownerDocument; var ownerWindow = ownerDocument.defaultView; var boundNode = void 0; if (bounds === 'parent') { boundNode = node.parentNode; } else { boundNode = ownerDocument.querySelector(bounds); } if (!(boundNode instanceof ownerWindow.HTMLElement)) { throw new Error('Bounds selector "' + bounds + '" could not find an element.'); } var nodeStyle = ownerWindow.getComputedStyle(node); var boundNodeStyle = ownerWindow.getComputedStyle(boundNode); // Compute bounds. This is a pain with padding and offsets but this gets it exactly right. bounds = { left: -node.offsetLeft + int(boundNodeStyle.paddingLeft) + int(nodeStyle.marginLeft), top: -node.offsetTop + int(boundNodeStyle.paddingTop) + int(nodeStyle.marginTop), right: innerWidth(boundNode) - outerWidth(node) - node.offsetLeft + int(boundNodeStyle.paddingRight) - int(nodeStyle.marginRight), bottom: innerHeight(boundNode) - outerHeight(node) - node.offsetTop + int(boundNodeStyle.paddingBottom) - int(nodeStyle.marginBottom) }; } // Keep x and y below right and bottom limits... if (isNum(bounds.right)) x = Math.min(x, bounds.right); if (isNum(bounds.bottom)) y = Math.min(y, bounds.bottom); // But above left and top limits. if (isNum(bounds.left)) x = Math.max(x, bounds.left); if (isNum(bounds.top)) y = Math.max(y, bounds.top); return [x, y]; } function snapToGrid(grid /*: [number, number]*/, pendingX /*: number*/, pendingY /*: number*/) /*: [number, number]*/ { var x = Math.round(pendingX / grid[0]) * grid[0]; var y = Math.round(pendingY / grid[1]) * grid[1]; return [x, y]; } function canDragX(draggable /*: Draggable*/) /*: boolean*/ { return draggable.props.axis === 'both' || draggable.props.axis === 'x'; } function canDragY(draggable /*: Draggable*/) /*: boolean*/ { return draggable.props.axis === 'both' || draggable.props.axis === 'y'; } // Get {x, y} positions from event. function getControlPosition(e /*: MouseTouchEvent*/, touchIdentifier /*: ?number*/, draggableCore /*: DraggableCore*/) /*: ?ControlPosition*/ { var touchObj = typeof touchIdentifier === 'number' ? getTouch(e, touchIdentifier) : null; if (typeof touchIdentifier === 'number' && !touchObj) return null; // not the right touch var node = findDOMNode(draggableCore); // User can provide an offsetParent if desired. var offsetParent = draggableCore.props.offsetParent || node.offsetParent || node.ownerDocument.body; return offsetXYFromParent(touchObj || e, offsetParent); } // Create an data object exposed by 's events function createCoreData(draggable /*: DraggableCore*/, x /*: number*/, y /*: number*/) /*: DraggableData*/ { var state = draggable.state; var isStart = !isNum(state.lastX); var node = findDOMNode(draggable); if (isStart) { // If this is our first move, use the x and y as last coords. return { node: node, deltaX: 0, deltaY: 0, lastX: x, lastY: y, x: x, y: y }; } else { // Otherwise calculate proper values. return { node: node, deltaX: x - state.lastX, deltaY: y - state.lastY, lastX: state.lastX, lastY: state.lastY, x: x, y: y }; } } // Create an data exposed by 's events function createDraggableData(draggable /*: Draggable*/, coreData /*: DraggableData*/) /*: DraggableData*/ { var scale = draggable.props.scale; return { node: coreData.node, x: draggable.state.x + coreData.deltaX / scale, y: draggable.state.y + coreData.deltaY / scale, deltaX: coreData.deltaX / scale, deltaY: coreData.deltaY / scale, lastX: draggable.state.x, lastY: draggable.state.y }; } // A lot faster than stringify/parse function cloneBounds(bounds /*: Bounds*/) /*: Bounds*/ { return { left: bounds.left, top: bounds.top, right: bounds.right, bottom: bounds.bottom }; } function findDOMNode(draggable /*: Draggable | DraggableCore*/) /*: HTMLElement*/ { var node = ReactDOM.findDOMNode(draggable); if (!node) { throw new Error(': Unmounted during event!'); } // $FlowIgnore we can't assert on HTMLElement due to tests... FIXME return node; } /*eslint no-console:0*/ function log() { } /*:: import type {EventHandler, MouseTouchEvent} from './utils/types';*/ // Simple abstraction for dragging events names. /*:: import type {Element as ReactElement} from 'react';*/ var eventsFor = { touch: { start: 'touchstart', move: 'touchmove', stop: 'touchend' }, mouse: { start: 'mousedown', move: 'mousemove', stop: 'mouseup' } }; // Default to mouse events. var dragEventFor = eventsFor.mouse; /*:: type DraggableCoreState = { dragging: boolean, lastX: number, lastY: number, touchIdentifier: ?number };*/ /*:: export type DraggableBounds = { left: number, right: number, top: number, bottom: number, };*/ /*:: export type DraggableData = { node: HTMLElement, x: number, y: number, deltaX: number, deltaY: number, lastX: number, lastY: number, };*/ /*:: export type DraggableEventHandler = (e: MouseEvent, data: DraggableData) => void;*/ /*:: export type ControlPosition = {x: number, y: number};*/ /*:: export type PositionOffsetControlPosition = {x: number|string, y: number|string};*/ // // Define . // // is for advanced usage of . It maintains minimal internal state so it can // work well with libraries that require more control over the element. // /*:: export type DraggableCoreProps = { allowAnyClick: boolean, cancel: string, children: ReactElement, disabled: boolean, enableUserSelectHack: boolean, offsetParent: HTMLElement, grid: [number, number], handle: string, onStart: DraggableEventHandler, onDrag: DraggableEventHandler, onStop: DraggableEventHandler, onMouseDown: (e: MouseEvent) => void, };*/ var DraggableCore = function (_React$Component) { inherits(DraggableCore, _React$Component); function DraggableCore() { var _ref; var _temp, _this, _ret; classCallCheck(this, DraggableCore); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = DraggableCore.__proto__ || Object.getPrototypeOf(DraggableCore)).call.apply(_ref, [this].concat(args))), _this), _this.state = { dragging: false, // Used while dragging to determine deltas. lastX: NaN, lastY: NaN, touchIdentifier: null }, _this.handleDragStart = function (e) { // Make it possible to attach event handlers on top of this one. _this.props.onMouseDown(e); // Only accept left-clicks. if (!_this.props.allowAnyClick && typeof e.button === 'number' && e.button !== 0) return false; // Get nodes. Be sure to grab relative document (could be iframed) var thisNode = ReactDOM.findDOMNode(_this); if (!thisNode || !thisNode.ownerDocument || !thisNode.ownerDocument.body) { throw new Error(' not mounted on DragStart!'); } var ownerDocument = thisNode.ownerDocument; // Short circuit if handle or cancel prop was provided and selector doesn't match. if (_this.props.disabled || !(e.target instanceof ownerDocument.defaultView.Node) || _this.props.handle && !matchesSelectorAndParentsTo(e.target, _this.props.handle, thisNode) || _this.props.cancel && matchesSelectorAndParentsTo(e.target, _this.props.cancel, thisNode)) { return; } // Set touch identifier in component state if this is a touch event. This allows us to // distinguish between individual touches on multitouch screens by identifying which // touchpoint was set to this element. var touchIdentifier = getTouchIdentifier(e); _this.setState({ touchIdentifier: touchIdentifier }); // Get the current drag point from the event. This is used as the offset. var position = getControlPosition(e, touchIdentifier, _this); if (position == null) return; // not possible but satisfies flow var x = position.x, y = position.y; // Create an event object with all the data parents need to make a decision here. var coreEvent = createCoreData(_this, x, y); // Call event handler. If it returns explicit false, cancel. log('calling', _this.props.onStart); var shouldUpdate = _this.props.onStart(e, coreEvent); if (shouldUpdate === false) return; // Add a style to the body to disable user-select. This prevents text from // being selected all over the page. if (_this.props.enableUserSelectHack) addUserSelectStyles(ownerDocument); // Initiate dragging. Set the current x and y as offsets // so we know how much we've moved during the drag. This allows us // to drag elements around even if they have been moved, without issue. _this.setState({ dragging: true, lastX: x, lastY: y }); // Add events to the document directly so we catch when the user's mouse/touch moves outside of // this element. We use different events depending on whether or not we have detected that this // is a touch-capable device. addEvent(ownerDocument, dragEventFor.move, _this.handleDrag); addEvent(ownerDocument, dragEventFor.stop, _this.handleDragStop); }, _this.handleDrag = function (e) { // Prevent scrolling on mobile devices, like ipad/iphone. if (e.type === 'touchmove') e.preventDefault(); // Get the current drag point from the event. This is used as the offset. var position = getControlPosition(e, _this.state.touchIdentifier, _this); if (position == null) return; var x = position.x, y = position.y; // Snap to grid if prop has been provided if (Array.isArray(_this.props.grid)) { var _deltaX = x - _this.state.lastX, _deltaY = y - _this.state.lastY; var _snapToGrid = snapToGrid(_this.props.grid, _deltaX, _deltaY); var _snapToGrid2 = slicedToArray(_snapToGrid, 2); _deltaX = _snapToGrid2[0]; _deltaY = _snapToGrid2[1]; if (!_deltaX && !_deltaY) return; // skip useless drag x = _this.state.lastX + _deltaX, y = _this.state.lastY + _deltaY; } var coreEvent = createCoreData(_this, x, y); // Call event handler. If it returns explicit false, trigger end. var shouldUpdate = _this.props.onDrag(e, coreEvent); if (shouldUpdate === false) { try { // $FlowIgnore _this.handleDragStop(new MouseEvent('mouseup')); } catch (err) { // Old browsers var event = ((document.createEvent('MouseEvents') /*: any*/) /*: MouseTouchEvent*/); // I see why this insanity was deprecated // $FlowIgnore event.initMouseEvent('mouseup', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); _this.handleDragStop(event); } return; } _this.setState({ lastX: x, lastY: y }); }, _this.handleDragStop = function (e) { if (!_this.state.dragging) return; var position = getControlPosition(e, _this.state.touchIdentifier, _this); if (position == null) return; var x = position.x, y = position.y; var coreEvent = createCoreData(_this, x, y); var thisNode = ReactDOM.findDOMNode(_this); if (thisNode) { // Remove user-select hack if (_this.props.enableUserSelectHack) removeUserSelectStyles(thisNode.ownerDocument); } // Reset the el. _this.setState({ dragging: false, lastX: NaN, lastY: NaN }); // Call event handler _this.props.onStop(e, coreEvent); if (thisNode) { removeEvent(thisNode.ownerDocument, dragEventFor.move, _this.handleDrag); removeEvent(thisNode.ownerDocument, dragEventFor.stop, _this.handleDragStop); } }, _this.onMouseDown = function (e) { dragEventFor = eventsFor.mouse; // on touchscreen laptops we could switch back to mouse return _this.handleDragStart(e); }, _this.onMouseUp = function (e) { dragEventFor = eventsFor.mouse; return _this.handleDragStop(e); }, _this.onTouchStart = function (e) { // We're on a touch device now, so change the event handlers dragEventFor = eventsFor.touch; return _this.handleDragStart(e); }, _this.onTouchEnd = function (e) { // We're on a touch device now, so change the event handlers dragEventFor = eventsFor.touch; return _this.handleDragStop(e); }, _temp), possibleConstructorReturn(_this, _ret); } createClass(DraggableCore, [{ key: 'componentWillUnmount', value: function componentWillUnmount() { // Remove any leftover event handlers. Remove both touch and mouse handlers in case // some browser quirk caused a touch event to fire during a mouse move, or vice versa. var thisNode = ReactDOM.findDOMNode(this); if (thisNode) { var ownerDocument = thisNode.ownerDocument; removeEvent(ownerDocument, eventsFor.mouse.move, this.handleDrag); removeEvent(ownerDocument, eventsFor.touch.move, this.handleDrag); removeEvent(ownerDocument, eventsFor.mouse.stop, this.handleDragStop); removeEvent(ownerDocument, eventsFor.touch.stop, this.handleDragStop); if (this.props.enableUserSelectHack) removeUserSelectStyles(ownerDocument); } } // Same as onMouseDown (start drag), but now consider this a touch device. }, { key: 'render', value: function render() { // Reuse the child provided // This makes it flexible to use whatever element is wanted (div, ul, etc) return React.cloneElement(React.Children.only(this.props.children), { style: styleHacks(this.props.children.props.style), // Note: mouseMove handler is attached to document so it will still function // when the user drags quickly and leaves the bounds of the element. onMouseDown: this.onMouseDown, onTouchStart: this.onTouchStart, onMouseUp: this.onMouseUp, onTouchEnd: this.onTouchEnd }); } }]); return DraggableCore; }(React.Component); DraggableCore.displayName = 'DraggableCore'; DraggableCore.propTypes = { /** * `allowAnyClick` allows dragging using any mouse button. * By default, we only accept the left button. * * Defaults to `false`. */ allowAnyClick: propTypes.bool, /** * `disabled`, if true, stops the from dragging. All handlers, * with the exception of `onMouseDown`, will not fire. */ disabled: propTypes.bool, /** * By default, we add 'user-select:none' attributes to the document body * to prevent ugly text selection during drag. If this is causing problems * for your app, set this to `false`. */ enableUserSelectHack: propTypes.bool, /** * `offsetParent`, if set, uses the passed DOM node to compute drag offsets * instead of using the parent node. */ offsetParent: function offsetParent(props /*: DraggableCoreProps*/, propName /*: $Keys*/) { if (props[propName] && props[propName].nodeType !== 1) { throw new Error('Draggable\'s offsetParent must be a DOM Node.'); } }, /** * `grid` specifies the x and y that dragging should snap to. */ grid: propTypes.arrayOf(propTypes.number), /** * `scale` specifies the scale of the area you are dragging inside of. It allows * the drag deltas to scale correctly with how far zoomed in/out you are. */ scale: propTypes.number, /** * `handle` specifies a selector to be used as the handle that initiates drag. * * Example: * * ```jsx * let App = React.createClass({ * render: function () { * return ( * *
*
Click me to drag
*
This is some other content
*
*
* ); * } * }); * ``` */ handle: propTypes.string, /** * `cancel` specifies a selector to be used to prevent drag initialization. * * Example: * * ```jsx * let App = React.createClass({ * render: function () { * return( * *
*
You can't drag from here
*
Dragging here works fine
*
*
* ); * } * }); * ``` */ cancel: propTypes.string, /** * Called when dragging starts. * If this function returns the boolean false, dragging will be canceled. */ onStart: propTypes.func, /** * Called while dragging. * If this function returns the boolean false, dragging will be canceled. */ onDrag: propTypes.func, /** * Called when dragging stops. * If this function returns the boolean false, the drag will remain active. */ onStop: propTypes.func, /** * A workaround option which can be passed if onMouseDown needs to be accessed, * since it'll always be blocked (as there is internal use of onMouseDown) */ onMouseDown: propTypes.func, /** * These properties should be defined on the child, not here. */ className: dontSetMe, style: dontSetMe, transform: dontSetMe }; DraggableCore.defaultProps = { allowAnyClick: false, // by default only accept left click cancel: null, disabled: false, enableUserSelectHack: true, offsetParent: null, handle: null, grid: null, transform: null, onStart: function onStart() {}, onDrag: function onDrag() {}, onStop: function onStop() {}, onMouseDown: function onMouseDown() {} }; /*:: import type {DraggableEventHandler} from './utils/types';*/ /*:: import type {Element as ReactElement} from 'react';*/ /*:: type DraggableState = { dragging: boolean, dragged: boolean, x: number, y: number, slackX: number, slackY: number, isElementSVG: boolean };*/ // // Define // /*:: export type DraggableProps = { ...$Exact, axis: 'both' | 'x' | 'y' | 'none', bounds: DraggableBounds | string | false, defaultClassName: string, defaultClassNameDragging: string, defaultClassNameDragged: string, defaultPosition: ControlPosition, positionOffset: PositionOffsetControlPosition, position: ControlPosition, scale: number };*/ var Draggable = function (_React$Component) { inherits(Draggable, _React$Component); function Draggable(props /*: DraggableProps*/) { classCallCheck(this, Draggable); var _this = possibleConstructorReturn(this, (Draggable.__proto__ || Object.getPrototypeOf(Draggable)).call(this, props)); _this.onDragStart = function (e, coreData) { // Short-circuit if user's callback killed it. var shouldStart = _this.props.onStart(e, createDraggableData(_this, coreData)); // Kills start event on core as well, so move handlers are never bound. if (shouldStart === false) return false; _this.setState({ dragging: true, dragged: true }); }; _this.onDrag = function (e, coreData) { if (!_this.state.dragging) return false; var uiData = createDraggableData(_this, coreData); var newState /*: $Shape*/ = { x: uiData.x, y: uiData.y }; // Keep within bounds. if (_this.props.bounds) { // Save original x and y. var _x = newState.x, _y = newState.y; // Add slack to the values used to calculate bound position. This will ensure that if // we start removing slack, the element won't react to it right away until it's been // completely removed. newState.x += _this.state.slackX; newState.y += _this.state.slackY; // Get bound position. This will ceil/floor the x and y within the boundaries. var _getBoundPosition = getBoundPosition(_this, newState.x, newState.y), _getBoundPosition2 = slicedToArray(_getBoundPosition, 2), newStateX = _getBoundPosition2[0], newStateY = _getBoundPosition2[1]; newState.x = newStateX; newState.y = newStateY; // Recalculate slack by noting how much was shaved by the boundPosition handler. newState.slackX = _this.state.slackX + (_x - newState.x); newState.slackY = _this.state.slackY + (_y - newState.y); // Update the event we fire to reflect what really happened after bounds took effect. uiData.x = newState.x; uiData.y = newState.y; uiData.deltaX = newState.x - _this.state.x; uiData.deltaY = newState.y - _this.state.y; } // Short-circuit if user's callback killed it. var shouldUpdate = _this.props.onDrag(e, uiData); if (shouldUpdate === false) return false; _this.setState(newState); }; _this.onDragStop = function (e, coreData) { if (!_this.state.dragging) return false; // Short-circuit if user's callback killed it. var shouldStop = _this.props.onStop(e, createDraggableData(_this, coreData)); if (shouldStop === false) return false; var newState /*: $Shape*/ = { dragging: false, slackX: 0, slackY: 0 }; // If this is a controlled component, the result of this operation will be to // revert back to the old position. We expect a handler on `onDragStop`, at the least. var controlled = Boolean(_this.props.position); if (controlled) { var _this$props$position = _this.props.position, _x2 = _this$props$position.x, _y2 = _this$props$position.y; newState.x = _x2; newState.y = _y2; } _this.setState(newState); }; _this.state = { // Whether or not we are currently dragging. dragging: false, // Whether or not we have been dragged before. dragged: false, // Current transform x and y. x: props.position ? props.position.x : props.defaultPosition.x, y: props.position ? props.position.y : props.defaultPosition.y, // Used for compensating for out-of-bounds drags slackX: 0, slackY: 0, // Can only determine if SVG after mounting isElementSVG: false }; if (props.position && !(props.onDrag || props.onStop)) { // eslint-disable-next-line no-console console.warn('A `position` was applied to this , without drag handlers. This will make this ' + 'component effectively undraggable. Please attach `onDrag` or `onStop` handlers so you can adjust the ' + '`position` of this element.'); } return _this; } createClass(Draggable, [{ key: 'componentDidMount', value: function componentDidMount() { // Check to see if the element passed is an instanceof SVGElement if (typeof window.SVGElement !== 'undefined' && ReactDOM.findDOMNode(this) instanceof window.SVGElement) { this.setState({ isElementSVG: true }); } } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps /*: Object*/) { // Set x/y if position has changed if (nextProps.position && (!this.props.position || nextProps.position.x !== this.props.position.x || nextProps.position.y !== this.props.position.y)) { this.setState({ x: nextProps.position.x, y: nextProps.position.y }); } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { this.setState({ dragging: false }); // prevents invariant if unmounted while dragging } }, { key: 'render', value: function render() /*: ReactElement*/ { var _classNames; var style = {}, svgTransform = null; // If this is controlled, we don't want to move it - unless it's dragging. var controlled = Boolean(this.props.position); var draggable = !controlled || this.state.dragging; var position = this.props.position || this.props.defaultPosition; var transformOpts = { // Set left if horizontal drag is enabled x: canDragX(this) && draggable ? this.state.x : position.x, // Set top if vertical drag is enabled y: canDragY(this) && draggable ? this.state.y : position.y }; // If this element was SVG, we use the `transform` attribute. if (this.state.isElementSVG) { svgTransform = createSVGTransform(transformOpts, this.props.positionOffset); } else { // Add a CSS transform to move the element around. This allows us to move the element around // without worrying about whether or not it is relatively or absolutely positioned. // If the item you are dragging already has a transform set, wrap it in a so // has a clean slate. style = createCSSTransform(transformOpts, this.props.positionOffset); } var _props = this.props, defaultClassName = _props.defaultClassName, defaultClassNameDragging = _props.defaultClassNameDragging, defaultClassNameDragged = _props.defaultClassNameDragged; var children = React.Children.only(this.props.children); // Mark with class while dragging var className = classnames(children.props.className || '', defaultClassName, (_classNames = {}, defineProperty(_classNames, defaultClassNameDragging, this.state.dragging), defineProperty(_classNames, defaultClassNameDragged, this.state.dragged), _classNames)); // Reuse the child provided // This makes it flexible to use whatever element is wanted (div, ul, etc) return React.createElement( DraggableCore, _extends({}, this.props, { onStart: this.onDragStart, onDrag: this.onDrag, onStop: this.onDragStop }), React.cloneElement(children, { className: className, style: _extends({}, children.props.style, style), transform: svgTransform }) ); } }]); return Draggable; }(React.Component); Draggable.displayName = 'Draggable'; Draggable.propTypes = _extends({}, DraggableCore.propTypes, { /** * `axis` determines which axis the draggable can move. * * Note that all callbacks will still return data as normal. This only * controls flushing to the DOM. * * 'both' allows movement horizontally and vertically. * 'x' limits movement to horizontal axis. * 'y' limits movement to vertical axis. * 'none' limits all movement. * * Defaults to 'both'. */ axis: propTypes.oneOf(['both', 'x', 'y', 'none']), /** * `bounds` determines the range of movement available to the element. * Available values are: * * 'parent' restricts movement within the Draggable's parent node. * * Alternatively, pass an object with the following properties, all of which are optional: * * {left: LEFT_BOUND, right: RIGHT_BOUND, bottom: BOTTOM_BOUND, top: TOP_BOUND} * * All values are in px. * * Example: * * ```jsx * let App = React.createClass({ * render: function () { * return ( * *
Content
*
* ); * } * }); * ``` */ bounds: propTypes.oneOfType([propTypes.shape({ left: propTypes.number, right: propTypes.number, top: propTypes.number, bottom: propTypes.number }), propTypes.string, propTypes.oneOf([false])]), defaultClassName: propTypes.string, defaultClassNameDragging: propTypes.string, defaultClassNameDragged: propTypes.string, /** * `defaultPosition` specifies the x and y that the dragged item should start at * * Example: * * ```jsx * let App = React.createClass({ * render: function () { * return ( * *
I start with transformX: 25px and transformY: 25px;
*
* ); * } * }); * ``` */ defaultPosition: propTypes.shape({ x: propTypes.number, y: propTypes.number }), positionOffset: propTypes.shape({ x: propTypes.oneOfType([propTypes.number, propTypes.string]), y: propTypes.oneOfType([propTypes.number, propTypes.string]) }), /** * `position`, if present, defines the current position of the element. * * This is similar to how form elements in React work - if no `position` is supplied, the component * is uncontrolled. * * Example: * * ```jsx * let App = React.createClass({ * render: function () { * return ( * *
I start with transformX: 25px and transformY: 25px;
*
* ); * } * }); * ``` */ position: propTypes.shape({ x: propTypes.number, y: propTypes.number }), /** * These properties should be defined on the child, not here. */ className: dontSetMe, style: dontSetMe, transform: dontSetMe }); Draggable.defaultProps = _extends({}, DraggableCore.defaultProps, { axis: 'both', bounds: false, defaultClassName: 'react-draggable', defaultClassNameDragging: 'react-draggable-dragging', defaultClassNameDragged: 'react-draggable-dragged', defaultPosition: { x: 0, y: 0 }, position: null, scale: 1 }); // Previous versions of this lib exported as the root export. As to not break // them, or TypeScript, we export *both* as the root and as 'default'. // See https://github.com/mzabriskie/react-draggable/pull/254 // and https://github.com/mzabriskie/react-draggable/issues/266 Draggable.default = Draggable; Draggable.DraggableCore = DraggableCore; return Draggable; }))); }); function getStartPositions(elements) { return elements.filter(isNode).reduce(function (res, node) { var startPosition = { x: node.__rg.position.x || node.position.x, y: node.__rg.position.y || node.position.x }; res[node.id] = startPosition; return res; }, {}); } var NodesSelection = React.memo(function () { var _useState = React.useState({ x: 0, y: 0 }), _useState2 = _slicedToArray(_useState, 2), offset = _useState2[0], setOffset = _useState2[1]; var _useState3 = React.useState({}), _useState4 = _slicedToArray(_useState3, 2), startPositions = _useState4[0], setStartPositions = _useState4[1]; var state = useStoreState(function (s) { return { transform: s.transform, selectedNodesBbox: s.selectedNodesBbox, selectedElements: s.selectedElements }; }); var updateNodePos = useStoreActions(function (a) { return a.updateNodePos; }); var _state$transform = _slicedToArray(state.transform, 3), x = _state$transform[0], y = _state$transform[1], k = _state$transform[2]; var position = state.selectedNodesBbox; var onStart = function onStart(evt) { var scaledClient = { x: evt.clientX * (1 / k), y: evt.clientY * (1 / k) }; var offsetX = scaledClient.x - position.x - x; var offsetY = scaledClient.y - position.y - y; var startPositions = getStartPositions(state.selectedElements); setOffset({ x: offsetX, y: offsetY }); setStartPositions(startPositions); }; var onDrag = function onDrag(evt) { var scaledClient = { x: evt.clientX * (1 / k), y: evt.clientY * (1 / k) }; state.selectedElements.filter(isNode).forEach(function (node) { updateNodePos({ id: node.id, pos: { x: startPositions[node.id].x + scaledClient.x - position.x - offset.x - x, y: startPositions[node.id].y + scaledClient.y - position.y - offset.y - y } }); }); }; return React__default.createElement("div", { className: "react-flow__nodesselection", style: { transform: "translate(".concat(x, "px,").concat(y, "px) scale(").concat(k, ")") } }, React__default.createElement(reactDraggable, { scale: k, onStart: onStart, onDrag: onDrag }, React__default.createElement("div", { className: "react-flow__nodesselection-rect", style: { width: state.selectedNodesBbox.width, height: state.selectedNodesBbox.height, top: state.selectedNodesBbox.y, left: state.selectedNodesBbox.x } }))); }); var isFunction = function isFunction(obj) { return !!(obj && obj.constructor && obj.call && obj.apply); }; var inInputDOMNode = function inInputDOMNode(e) { return e && e.target && ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName); }; var getDimensions = function getDimensions() { var node = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return { width: node.offsetWidth, height: node.offsetHeight }; }; function useKeyPress(keyCode) { var _useState = React.useState(false), _useState2 = _slicedToArray(_useState, 2), keyPressed = _useState2[0], setKeyPressed = _useState2[1]; function downHandler(evt) { if (evt.keyCode === keyCode && !inInputDOMNode(evt.target)) { setKeyPressed(true); } } var upHandler = function upHandler(evt) { if (evt.keyCode === keyCode && !inInputDOMNode(evt.target)) { setKeyPressed(false); } }; React.useEffect(function () { window.addEventListener('keydown', downHandler); window.addEventListener('keyup', upHandler); return function () { window.removeEventListener('keydown', downHandler); window.removeEventListener('keyup', upHandler); }; }, []); return keyPressed; } var d3ZoomInstance = zoom().scaleExtent([0.5, 2]); function useD3Zoom(zoomPane, onMove, shiftPressed) { var state = useStoreState(function (s) { return { transform: s.transform, d3Selection: s.d3Selection, d3Zoom: s.d3Zoom, edges: s.edged, d3Initialised: s.d3Initialised, nodesSelectionActive: s.nodesSelectionActive }; }); var initD3 = useStoreActions(function (actions) { return actions.initD3; }); var updateTransform = useStoreActions(function (actions) { return actions.updateTransform; }); React.useEffect(function () { var selection = select(zoomPane.current).call(d3ZoomInstance); initD3({ zoom: d3ZoomInstance, selection: selection }); }, []); React.useEffect(function () { if (shiftPressed) { d3ZoomInstance.on('zoom', null); } else { d3ZoomInstance.on('zoom', function () { if (event.sourceEvent && event.sourceEvent.target !== zoomPane.current) { return false; } updateTransform(event.transform); onMove(); }); if (state.d3Selection) { // we need to restore the graph transform otherwise d3 zoom transform and graph transform are not synced var graphTransform = identity$1.translate(state.transform[0], state.transform[1]).scale(state.transform[2]); state.d3Selection.call(state.d3Zoom.transform, graphTransform); } } return function () { d3ZoomInstance.on('zoom', null); }; }, [shiftPressed]); } var useGlobalKeyHandler = (function (_ref) { var deleteKeyCode = _ref.deleteKeyCode, onElementsRemove = _ref.onElementsRemove; var state = useStoreState(function (s) { return { selectedElements: s.selectedElements, edges: s.edges }; }); var setNodesSelection = useStoreActions(function (a) { return a.setNodesSelection; }); var deleteKeyPressed = useKeyPress(deleteKeyCode); React.useEffect(function () { if (deleteKeyPressed && state.selectedElements.length) { var elementsToRemove = state.selectedElements; // we also want to remove the edges if only one node is selected if (state.selectedElements.length === 1 && !isEdge(state.selectedElements[0])) { var connectedEdges = getConnectedEdges(state.selectedElements, state.edges); elementsToRemove = [].concat(_toConsumableArray(state.selectedElements), _toConsumableArray(connectedEdges)); } onElementsRemove(elementsToRemove); setNodesSelection({ isActive: false }); } }, [deleteKeyPressed]); return null; }); var useElementUpdater = function useElementUpdater(_ref) { var elements = _ref.elements; var state = useStoreState(function (s) { return { nodes: s.nodes, edges: s.edges, transform: s.transform }; }); var setNodes = useStoreActions(function (a) { return a.setNodes; }); var setEdges = useStoreActions(function (a) { return a.setEdges; }); React.useEffect(function () { var nodes = elements.filter(isNode); var edges = elements.filter(isEdge).map(parseElement); var nextNodes = nodes.map(function (propNode) { var existingNode = state.nodes.find(function (n) { return n.id === propNode.id; }); if (existingNode) { var data = !fastDeepEqual(existingNode.data, propNode.data) ? _objectSpread2$1({}, existingNode.data, {}, propNode.data) : existingNode.data; return _objectSpread2$1({}, existingNode, { data: data }); } return parseElement(propNode, state.transform); }); var nodesChanged = !fastDeepEqual(state.nodes, nextNodes); var edgesChanged = !fastDeepEqual(state.edges, edges); if (nodesChanged) { setNodes(nextNodes); } if (edgesChanged) { setEdges(edges); } }); return null; }; var GraphView = React.memo(function (_ref) { var nodeTypes = _ref.nodeTypes, edgeTypes = _ref.edgeTypes, onMove = _ref.onMove, onLoad = _ref.onLoad, onElementClick = _ref.onElementClick, onNodeDragStop = _ref.onNodeDragStop, connectionLineType = _ref.connectionLineType, connectionLineStyle = _ref.connectionLineStyle, selectionKeyCode = _ref.selectionKeyCode, onElementsRemove = _ref.onElementsRemove, deleteKeyCode = _ref.deleteKeyCode, elements = _ref.elements, onConnect = _ref.onConnect, gridColor = _ref.gridColor, showGrid = _ref.showGrid, gridGap = _ref.gridGap; var zoomPane = React.useRef(); var rendererNode = React.useRef(); var state = useStoreState(function (s) { return { width: s.width, height: s.height, nodes: s.nodes, edges: s.edges, d3Initialised: s.d3Initialised, nodesSelectionActive: s.nodesSelectionActive }; }); var updateSize = useStoreActions(function (actions) { return actions.updateSize; }); var setNodesSelection = useStoreActions(function (actions) { return actions.setNodesSelection; }); var setOnConnect = useStoreActions(function (a) { return a.setOnConnect; }); var selectionKeyPressed = useKeyPress(selectionKeyCode); var onZoomPaneClick = function onZoomPaneClick() { return setNodesSelection({ isActive: false }); }; var updateDimensions = function updateDimensions() { var size = getDimensions(rendererNode.current); updateSize(size); }; React.useEffect(function () { updateDimensions(); setOnConnect(onConnect); window.onresize = updateDimensions; return function () { window.onresize = null; }; }, []); useD3Zoom(zoomPane, onMove, selectionKeyPressed); React.useEffect(function () { if (state.d3Initialised) { onLoad({ fitView: fitView, zoomIn: zoomIn, zoomOut: zoomOut }); } }, [state.d3Initialised]); useGlobalKeyHandler({ onElementsRemove: onElementsRemove, deleteKeyCode: deleteKeyCode }); useElementUpdater({ elements: elements }); return React__default.createElement("div", { className: "react-flow__renderer", ref: rendererNode }, showGrid && React__default.createElement(GridRenderer, { gap: gridGap, strokeColor: gridColor }), React__default.createElement(NodeRenderer, { nodeTypes: nodeTypes, onElementClick: onElementClick, onNodeDragStop: onNodeDragStop }), React__default.createElement(EdgeRenderer, { width: state.width, height: state.height, edgeTypes: edgeTypes, onElementClick: onElementClick, connectionLineType: connectionLineType, connectionLineStyle: connectionLineStyle }), selectionKeyPressed && React__default.createElement(UserSelection, null), state.nodesSelectionActive && React__default.createElement(NodesSelection, null), React__default.createElement("div", { className: "react-flow__zoompane", onClick: onZoomPaneClick, ref: zoomPane })); }); GraphView.displayName = 'GraphView'; function _onMouseDown(evt, _ref) { var nodeId = _ref.nodeId, setSourceId = _ref.setSourceId, setPosition = _ref.setPosition, onConnect = _ref.onConnect, isTarget = _ref.isTarget, isValidConnection = _ref.isValidConnection; var containerBounds = document.querySelector('.react-flow').getBoundingClientRect(); var recentHoveredHandle = null; setPosition({ x: evt.clientX - containerBounds.x, y: evt.clientY - containerBounds.y }); setSourceId(nodeId); function resetRecentHandle() { if (recentHoveredHandle) { recentHoveredHandle.classList.remove('valid'); recentHoveredHandle.classList.remove('connecting'); } } // checks if element below mouse is a handle and returns connection in form of an object { source: 123, target: 312 } function checkElementBelowIsValid(evt) { var elementBelow = document.elementFromPoint(evt.clientX, evt.clientY); var result = { elementBelow: elementBelow, isValid: false, connection: null, isHoveringHandle: false }; if (elementBelow && (elementBelow.classList.contains('target') || elementBelow.classList.contains('source'))) { var connection = null; if (isTarget) { var sourceId = elementBelow.getAttribute('data-nodeid'); connection = { source: sourceId, target: nodeId }; } else { var targetId = elementBelow.getAttribute('data-nodeid'); connection = { source: nodeId, target: targetId }; } var isValid = isValidConnection(connection); result.connection = connection; result.isValid = isValid; result.isHoveringHandle = true; } return result; } function onMouseMove(evt) { setPosition({ x: evt.clientX - containerBounds.x, y: evt.clientY - containerBounds.y }); var _checkElementBelowIsV = checkElementBelowIsValid(evt), connection = _checkElementBelowIsV.connection, elementBelow = _checkElementBelowIsV.elementBelow, isValid = _checkElementBelowIsV.isValid, isHoveringHandle = _checkElementBelowIsV.isHoveringHandle; if (!isHoveringHandle) { return resetRecentHandle(); } var isOwnHandle = connection.source === connection.target; if (!isOwnHandle) { recentHoveredHandle = elementBelow; elementBelow.classList.add('connecting'); elementBelow.classList.toggle('valid', isValid); } } function onMouseUp(evt) { var _checkElementBelowIsV2 = checkElementBelowIsValid(evt), connection = _checkElementBelowIsV2.connection, isValid = _checkElementBelowIsV2.isValid; if (isValid) { onConnect(connection); } resetRecentHandle(); setSourceId(null); document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); } document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); } var BaseHandle = React.memo(function (_ref2) { var type = _ref2.type, nodeId = _ref2.nodeId, onConnect = _ref2.onConnect, position = _ref2.position, setSourceId = _ref2.setSourceId, setPosition = _ref2.setPosition, className = _ref2.className, _ref2$id = _ref2.id, id = _ref2$id === void 0 ? false : _ref2$id, isValidConnection = _ref2.isValidConnection, rest = _objectWithoutProperties(_ref2, ["type", "nodeId", "onConnect", "position", "setSourceId", "setPosition", "className", "id", "isValidConnection"]); var isTarget = type === 'target'; var handleClasses = classnames('react-flow__handle', className, position, { source: !isTarget, target: isTarget }); var nodeIdWithHandleId = id ? "".concat(nodeId, "__").concat(id) : nodeId; return React__default.createElement("div", _extends$1({ "data-nodeid": nodeIdWithHandleId, "data-handlepos": position, className: handleClasses, onMouseDown: function onMouseDown(evt) { return _onMouseDown(evt, { nodeId: nodeIdWithHandleId, setSourceId: setSourceId, setPosition: setPosition, onConnect: onConnect, isTarget: isTarget, isValidConnection: isValidConnection }); } }, rest)); }); BaseHandle.displayName = 'BaseHandle'; BaseHandle.whyDidYouRender = false; var NodeIdContext = React.createContext(null); var Provider = NodeIdContext.Provider; var Consumer = NodeIdContext.Consumer; Provider.displayName = 'NodeIdProvider'; var Handle = React.memo(function (_ref) { var onConnect = _ref.onConnect, rest = _objectWithoutProperties(_ref, ["onConnect"]); var nodeId = React.useContext(NodeIdContext); var _useStoreActions = useStoreActions(function (a) { return { setPosition: a.setConnectionPosition, setSourceId: a.setConnectionSourceId }; }), setPosition = _useStoreActions.setPosition, setSourceId = _useStoreActions.setSourceId; var onConnectAction = useStoreState(function (s) { return s.onConnect; }); var onConnectExtended = function onConnectExtended(params) { onConnectAction(params); onConnect(params); }; return React__default.createElement(BaseHandle, _extends$1({ nodeId: nodeId, setPosition: setPosition, setSourceId: setSourceId, onConnect: onConnectExtended }, rest)); }); Handle.displayName = 'Handle'; Handle.propTypes = { type: PropTypes.oneOf(['source', 'target']), position: PropTypes.oneOf(['top', 'right', 'bottom', 'left']), onConnect: PropTypes.func, isValidConnection: PropTypes.func }; Handle.defaultProps = { type: 'source', position: 'top', onConnect: function onConnect() {}, isValidConnection: function isValidConnection() { return true; } }; var nodeStyles = { background: '#ff6060', padding: 10, borderRadius: 5, width: 150 }; var DefaultNode = (function (_ref) { var data = _ref.data, style = _ref.style; return React__default.createElement("div", { style: _objectSpread2$1({}, nodeStyles, {}, style) }, React__default.createElement(Handle, { type: "target", position: "top" }), data.label, React__default.createElement(Handle, { type: "source", position: "bottom" })); }); var nodeStyles$1 = { background: '#9999ff', padding: 10, borderRadius: 5, width: 150 }; var InputNode = (function (_ref) { var data = _ref.data, style = _ref.style; return React__default.createElement("div", { style: _objectSpread2$1({}, nodeStyles$1, {}, style) }, data.label, React__default.createElement(Handle, { type: "source", position: "bottom" })); }); var nodeStyles$2 = { background: '#55dd99', padding: 10, borderRadius: 5, width: 150 }; var OutputNode = (function (_ref) { var data = _ref.data, style = _ref.style; return React__default.createElement("div", { style: _objectSpread2$1({}, nodeStyles$2, {}, style) }, React__default.createElement(Handle, { type: "target", position: "top" }), data.label); }); var isHandle = function isHandle(e) { return e.target.className && e.target.className.includes && (e.target.className.includes('source') || e.target.className.includes('target')); }; var hasResizeObserver = !!window.ResizeObserver; var getHandleBounds = function getHandleBounds(sel, nodeElement, parentBounds, k) { var handles = nodeElement.querySelectorAll(sel); if (!handles || !handles.length) { return null; } return [].map.call(handles, function (handle) { var bounds = handle.getBoundingClientRect(); var dimensions = getDimensions(handle); var nodeIdAttr = handle.getAttribute('data-nodeid'); var handlePosition = handle.getAttribute('data-handlepos'); var nodeIdSplitted = nodeIdAttr.split('__'); var handleId = null; if (nodeIdSplitted) { handleId = nodeIdSplitted.length ? nodeIdSplitted[1] : nodeIdSplitted; } return _objectSpread2$1({ id: handleId, position: handlePosition, x: (bounds.x - parentBounds.x) * (1 / k), y: (bounds.y - parentBounds.y) * (1 / k) }, dimensions); }); }; var _onStart = function onStart(evt, _ref) { var setOffset = _ref.setOffset, onClick = _ref.onClick, id = _ref.id, type = _ref.type, data = _ref.data, position = _ref.position, transform = _ref.transform; if (inInputDOMNode(evt) || isHandle(evt)) { return false; } var scaledClient = { x: evt.clientX * (1 / [transform[2]]), y: evt.clientY * (1 / [transform[2]]) }; var offsetX = scaledClient.x - position.x - transform[0]; var offsetY = scaledClient.y - position.y - transform[1]; var node = { id: id, type: type, position: position, data: data }; store.dispatch.setSelectedElements({ id: id, type: type }); setOffset({ x: offsetX, y: offsetY }); onClick(node); }; var _onDrag = function onDrag(evt, _ref2) { var setDragging = _ref2.setDragging, id = _ref2.id, offset = _ref2.offset, transform = _ref2.transform; var scaledClient = { x: evt.clientX * (1 / transform[2]), y: evt.clientY * (1 / transform[2]) }; setDragging(true); store.dispatch.updateNodePos({ id: id, pos: { x: scaledClient.x - transform[0] - offset.x, y: scaledClient.y - transform[1] - offset.y } }); }; var _onStop = function onStop(_ref3) { var onNodeDragStop = _ref3.onNodeDragStop, setDragging = _ref3.setDragging, isDragging = _ref3.isDragging, id = _ref3.id, type = _ref3.type, position = _ref3.position, data = _ref3.data; if (!isDragging) { return false; } setDragging(false); onNodeDragStop({ id: id, type: type, position: position, data: data }); }; var wrapNode = (function (NodeComponent) { var NodeWrapper = React.memo(function (props) { var nodeElement = React.useRef(null); var _useState = React.useState({ x: 0, y: 0 }), _useState2 = _slicedToArray(_useState, 2), offset = _useState2[0], setOffset = _useState2[1]; var _useState3 = React.useState(false), _useState4 = _slicedToArray(_useState3, 2), isDragging = _useState4[0], setDragging = _useState4[1]; var id = props.id, type = props.type, data = props.data, transform = props.transform, xPos = props.xPos, yPos = props.yPos, selected = props.selected, onClick = props.onClick, onNodeDragStop = props.onNodeDragStop, style = props.style; var position = { x: xPos, y: yPos }; var nodeClasses = classnames('react-flow__node', { selected: selected }); var nodeStyle = { zIndex: selected ? 10 : 3, transform: "translate(".concat(xPos, "px,").concat(yPos, "px)") }; var updateNode = function updateNode() { var storeState = store.getState(); var bounds = nodeElement.current.getBoundingClientRect(); var dimensions = getDimensions(nodeElement.current); var handleBounds = { source: getHandleBounds('.source', nodeElement.current, bounds, storeState.transform[2]), target: getHandleBounds('.target', nodeElement.current, bounds, storeState.transform[2]) }; store.dispatch.updateNodeData(_objectSpread2$1({ id: id }, dimensions, { handleBounds: handleBounds })); }; React.useEffect(function () { updateNode(); var resizeObserver = null; if (hasResizeObserver) { resizeObserver = new ResizeObserver(function (entries) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var entry = _step.value; updateNode(); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator["return"] != null) { _iterator["return"](); } } finally { if (_didIteratorError) { throw _iteratorError; } } } }); resizeObserver.observe(nodeElement.current); } return function () { if (hasResizeObserver && resizeObserver) { resizeObserver.unobserve(nodeElement.current); } }; }, []); return React__default.createElement(reactDraggable.DraggableCore, { onStart: function onStart(evt) { return _onStart(evt, { onClick: onClick, id: id, type: type, data: data, setOffset: setOffset, transform: transform, position: position }); }, onDrag: function onDrag(evt) { return _onDrag(evt, { setDragging: setDragging, id: id, offset: offset, transform: transform }); }, onStop: function onStop() { return _onStop({ onNodeDragStop: onNodeDragStop, isDragging: isDragging, setDragging: setDragging, id: id, type: type, position: position, data: data }); }, scale: transform[2] }, React__default.createElement("div", { className: nodeClasses, ref: nodeElement, style: nodeStyle }, React__default.createElement(Provider, { value: id }, React__default.createElement(NodeComponent, { id: id, data: data, type: type, style: style, selected: selected })))); }); NodeWrapper.displayName = 'NodeWrapper'; NodeWrapper.whyDidYouRender = false; return NodeWrapper; }); function createNodeTypes(nodeTypes) { var standardTypes = { input: wrapNode(nodeTypes.input || InputNode), "default": wrapNode(nodeTypes["default"] || DefaultNode), output: wrapNode(nodeTypes.output || OutputNode) }; var specialTypes = Object.keys(nodeTypes).filter(function (k) { return !['input', 'default', 'output'].includes(k); }).reduce(function (res, key) { res[key] = wrapNode(nodeTypes[key] || DefaultNode); return res; }, {}); return _objectSpread2$1({}, standardTypes, {}, specialTypes); } var BezierEdge = React.memo(function (_ref) { var sourceX = _ref.sourceX, sourceY = _ref.sourceY, targetX = _ref.targetX, targetY = _ref.targetY, sourcePosition = _ref.sourcePosition, targetPosition = _ref.targetPosition, _ref$style = _ref.style, style = _ref$style === void 0 ? {} : _ref$style; var yOffset = Math.abs(targetY - sourceY) / 2; var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset; var dAttr = "M".concat(sourceX, ",").concat(sourceY, " C").concat(sourceX, ",").concat(centerY, " ").concat(targetX, ",").concat(centerY, " ").concat(targetX, ",").concat(targetY); if (['left', 'right'].includes(sourcePosition) && ['left', 'right'].includes(targetPosition)) { var xOffset = Math.abs(targetX - sourceX) / 2; var centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset; dAttr = "M".concat(sourceX, ",").concat(sourceY, " C").concat(centerX, ",").concat(sourceY, " ").concat(centerX, ",").concat(targetY, " ").concat(targetX, ",").concat(targetY); } else if (['left', 'right'].includes(sourcePosition) || ['left', 'right'].includes(targetPosition)) { dAttr = "M".concat(sourceX, ",").concat(sourceY, " C").concat(sourceX, ",").concat(targetY, " ").concat(sourceX, ",").concat(targetY, " ").concat(targetX, ",").concat(targetY); } return React__default.createElement("path", _extends$1({}, style, { d: dAttr })); }); var StraightEdge = React.memo(function (props) { var sourceX = props.sourceX, sourceY = props.sourceY, targetX = props.targetX, targetY = props.targetY, _props$style = props.style, style = _props$style === void 0 ? {} : _props$style; return React__default.createElement("path", _extends$1({}, style, { d: "M ".concat(sourceX, ",").concat(sourceY, "L ").concat(targetX, ",").concat(targetY) })); }); var StepEdge = React.memo(function (props) { var sourceX = props.sourceX, sourceY = props.sourceY, targetX = props.targetX, targetY = props.targetY, _props$style = props.style, style = _props$style === void 0 ? {} : _props$style; var yOffset = Math.abs(targetY - sourceY) / 2; var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset; return React__default.createElement("path", _extends$1({}, style, { d: "M ".concat(sourceX, ",").concat(sourceY, "L ").concat(sourceX, ",").concat(centerY, "L ").concat(targetX, ",").concat(centerY, "L ").concat(targetX, ",").concat(targetY) })); }); var wrapEdge = (function (EdgeComponent) { var EdgeWrapper = React.memo(function (props) { var id = props.id, source = props.source, target = props.target, type = props.type, animated = props.animated, selected = props.selected, onClick = props.onClick; var edgeClasses = classnames('react-flow__edge', { selected: selected, animated: animated }); var onEdgeClick = function onEdgeClick(evt) { if (inInputDOMNode(evt)) { return false; } store.dispatch.setSelectedElements({ id: id, source: source, target: target }); onClick({ id: id, source: source, target: target, type: type }); }; return React__default.createElement("g", { className: edgeClasses, onClick: onEdgeClick }, React__default.createElement(EdgeComponent, props)); }); EdgeWrapper.displayName = 'EdgeWrapper'; EdgeWrapper.whyDidYouRender = false; return EdgeWrapper; }); function createEdgeTypes(edgeTypes) { var standardTypes = { "default": wrapEdge(edgeTypes["default"] || BezierEdge), straight: wrapEdge(edgeTypes.bezier || StraightEdge) }; var specialTypes = Object.keys(edgeTypes).filter(function (k) { return !['default', 'bezier'].includes(k); }).reduce(function (res, key) { res[key] = wrapEdge(edgeTypes[key] || BezierEdge); return res; }, {}); return _objectSpread2$1({}, standardTypes, {}, specialTypes); } function styleInject(css, ref) { if ( ref === void 0 ) ref = {}; var insertAt = ref.insertAt; if (!css || typeof document === 'undefined') { return; } var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (insertAt === 'top') { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css = ".react-flow {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.react-flow__renderer {\n width: 100%;\n height: 100%;\n position: absolute;\n}\n\n.react-flow__zoompane {\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1;\n}\n\n.react-flow__selectionpane {\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n}\n\n.react-flow__selection {\n position: absolute;\n top: 0;\n left: 0;\n background: rgba(0, 89, 220, 0.08);\n border: 1px dotted rgba(0, 89, 220, 0.8);\n}\n\n.react-flow__edges {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: none;\n z-index: 2;\n}\n\n.react-flow__edge {\n fill: none;\n stroke: #bbb;\n stroke-width: 2;\n pointer-events: all;\n}\n\n.react-flow__edge.selected {\n stroke: #555;\n }\n\n.react-flow__edge.animated {\n stroke-dasharray: 5;\n -webkit-animation: dashdraw 0.5s linear infinite;\n animation: dashdraw 0.5s linear infinite;\n }\n\n.react-flow__edge.connection {\n stroke: '#ddd';\n pointer-events: none;\n }\n\n@-webkit-keyframes dashdraw {\n from {stroke-dashoffset: 10}\n}\n\n@keyframes dashdraw {\n from {stroke-dashoffset: 10}\n}\n\n.react-flow__nodes {\n width: 100%;\n height: 100%;\n position: absolute;\n z-index: 3;\n pointer-events: none;\n transform-origin: 0 0;\n}\n\n.react-flow__node {\n position: absolute;\n color: #222;\n font-family: sans-serif;\n font-size: 12px;\n text-align: center;\n cursor: -webkit-grab;\n cursor: grab;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n pointer-events: all;\n transform-origin: 0 0;\n}\n\n.react-flow__node:hover > * {\n box-shadow: 0 1px 5px 2px rgba(0, 0, 0, 0.08);\n }\n\n.react-flow__node.selected > * {\n box-shadow: 0 0 0 2px #555;\n }\n\n.react-flow__handle {\n position: absolute;\n width: 10px;\n height: 8px;\n background: rgba(255, 255, 255, 0.4);\n cursor: crosshair;\n}\n\n.react-flow__handle.bottom {\n top: auto;\n left: 50%;\n bottom: 0;\n transform: translate(-50%, 0);\n }\n\n.react-flow__handle.top {\n left: 50%;\n top: 0;\n transform: translate(-50%, 0);\n }\n\n.react-flow__handle.left {\n top: 50%;\n left: 0;\n transform: translate(0, -50%);\n\n }\n\n.react-flow__handle.right {\n right: 0;\n top: 50%;\n transform: translate(0, -50%);\n }\n\n.react-flow__nodesselection {\n z-index: 3;\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n transform-origin: left top;\n pointer-events: none;\n}\n\n.react-flow__nodesselection-rect {\n position: absolute;\n background: rgba(0, 89, 220, 0.08);\n border: 1px dotted rgba(0, 89, 220, 0.8);\n pointer-events: all;\n }\n\n.react-flow__controls-button {\n background: #f8f8f8;\n border: 1px solid #eee;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 24px;\n height: 24px;\n cursor: pointer;\n}\n\n.react-flow__controls-button:hover {\n background: #eee;\n}"; styleInject(css); if (process.env.NODE_ENV !== 'production') { var whyDidYouRender = require('@welldone-software/why-did-you-render'); whyDidYouRender(React__default); } var ReactFlow = function ReactFlow(_ref) { var style = _ref.style, onElementClick = _ref.onElementClick, elements = _ref.elements, children = _ref.children, nodeTypes = _ref.nodeTypes, edgeTypes = _ref.edgeTypes, onLoad = _ref.onLoad, onMove = _ref.onMove, onElementsRemove = _ref.onElementsRemove, onConnect = _ref.onConnect, onNodeDragStop = _ref.onNodeDragStop, connectionLineType = _ref.connectionLineType, connectionLineStyle = _ref.connectionLineStyle, deleteKeyCode = _ref.deleteKeyCode, selectionKeyCode = _ref.selectionKeyCode, gridColor = _ref.gridColor, showGrid = _ref.showGrid, gridGap = _ref.gridGap; var nodeTypesParsed = React.useMemo(function () { return createNodeTypes(nodeTypes); }, []); var edgeTypesParsed = React.useMemo(function () { return createEdgeTypes(edgeTypes); }, []); return React__default.createElement("div", { style: style, className: "react-flow" }, React__default.createElement(StoreProvider, { store: store }, React__default.createElement(GraphView, { onLoad: onLoad, onMove: onMove, onElementClick: onElementClick, onNodeDragStop: onNodeDragStop, nodeTypes: nodeTypesParsed, edgeTypes: edgeTypesParsed, connectionLineType: connectionLineType, connectionLineStyle: connectionLineStyle, selectionKeyCode: selectionKeyCode, onElementsRemove: onElementsRemove, deleteKeyCode: deleteKeyCode, elements: elements, onConnect: onConnect, gridColor: gridColor, gridGap: gridGap, showGrid: showGrid }), children)); }; ReactFlow.displayName = 'ReactFlow'; ReactFlow.defaultProps = { onElementClick: function onElementClick() {}, onElementsRemove: function onElementsRemove() {}, onNodeDragStop: function onNodeDragStop() {}, onConnect: function onConnect() {}, onLoad: function onLoad() {}, onMove: function onMove() {}, nodeTypes: { input: InputNode, "default": DefaultNode, output: OutputNode }, edgeTypes: { "default": BezierEdge, straight: StraightEdge, step: StepEdge }, connectionLineType: 'bezier', connectionLineStyle: {}, deleteKeyCode: 8, selectionKeyCode: 16, gridColor: '#999', gridGap: 24, showGrid: true }; var baseStyle = { position: 'absolute', zIndex: 5, bottom: 10, right: 10, width: 200 }; var index = (function (_ref) { var _ref$style = _ref.style, style = _ref$style === void 0 ? {} : _ref$style, className = _ref.className, _ref$bgColor = _ref.bgColor, bgColor = _ref$bgColor === void 0 ? '#f8f8f8' : _ref$bgColor, _ref$nodeColor = _ref.nodeColor, nodeColor = _ref$nodeColor === void 0 ? '#ddd' : _ref$nodeColor; var canvasNode = React.useRef(null); var state = useStoreState(function (s) { return { width: s.width, height: s.height, nodes: s.nodes, transform: s.transform }; }); var mapClasses = classnames('react-flow__minimap', className); var nodePositions = state.nodes.map(function (n) { return n.__rg.position; }); var width = style.width || baseStyle.width; var height = state.height / (state.width || 1) * width; var bbox = { x: 0, y: 0, width: state.width, height: state.height }; var scaleFactor = width / state.width; var nodeColorFunc = isFunction(nodeColor) ? nodeColor : function () { return nodeColor; }; React.useEffect(function () { if (canvasNode) { var ctx = canvasNode.current.getContext('2d'); var nodesInside = getNodesInside(state.nodes, bbox, state.transform, true); ctx.fillStyle = bgColor; ctx.fillRect(0, 0, width, height); nodesInside.forEach(function (n) { var pos = n.__rg.position; var transformX = state.transform[0]; var transformY = state.transform[1]; var x = pos.x * state.transform[2] + transformX; var y = pos.y * state.transform[2] + transformY; ctx.fillStyle = nodeColorFunc(n); ctx.fillRect(x * scaleFactor, y * scaleFactor, n.__rg.width * scaleFactor * state.transform[2], n.__rg.height * scaleFactor * state.transform[2]); }); } }, [nodePositions, state.transform, height]); return React__default.createElement("canvas", { style: _objectSpread2$1({}, baseStyle, {}, style, { height: height }), width: width, height: height, className: mapClasses, ref: canvasNode }); }); var baseStyle$1 = { position: 'absolute', zIndex: 5, bottom: 10, left: 10 }; var index$1 = (function (_ref) { var style = _ref.style, className = _ref.className; var mapClasses = classnames('react-flow__controls', className); return React__default.createElement("div", { className: mapClasses, style: _objectSpread2$1({}, baseStyle$1, {}, style) }, React__default.createElement("div", { className: "react-flow__controls-button react-flow__controls-zoomin", onClick: zoomIn }, "+"), React__default.createElement("div", { className: "react-flow__controls-button react-flow__controls-zoomout", onClick: zoomOut }, "-"), React__default.createElement("div", { className: "react-flow__controls-button react-flow__controls-fitview", onClick: fitView }, "@")); }); exports.Controls = index$1; exports.Handle = Handle; exports.MiniMap = index; exports.default = ReactFlow; exports.getOutgoers = getOutgoers; exports.isEdge = isEdge; exports.isNode = isNode; exports.removeElements = removeElements; Object.defineProperty(exports, '__esModule', { value: true }); }));