\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]';\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\n/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\n/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = overArg(Object.keys, Object),\n nativeMax = Math.max;\n\n/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */\nvar nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n // Safari 9 makes `arguments.length` enumerable in strict mode.\n var result = (isArray(value) || isArguments(value))\n ? baseTimes(value.length, String)\n : [];\n\n var length = result.length,\n skipIndexes = !!length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (key == 'length' || isIndex(key, length)))) {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n object[key] = value;\n }\n}\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = array;\n return apply(func, this, otherArgs);\n };\n}\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n assignValue(object, key, newValue === undefined ? source[key] : newValue);\n }\n return object;\n}\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n return baseRest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8-9 which returns 'object' for typed array and other constructors.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Assigns own enumerable string keyed properties of source objects to the\n * destination object. Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object` and is loosely based on\n * [`Object.assign`](https://mdn.io/Object/assign).\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assignIn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * function Bar() {\n * this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assign({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'c': 3 }\n */\nvar assign = createAssigner(function(object, source) {\n if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {\n copyObject(source, keys(source), object);\n return;\n }\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n assignValue(object, key, source[key]);\n }\n }\n});\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nmodule.exports = assign;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/lodash.assign/index.js\n// module id = 66\n// module chunks = 0","import ascending from \"./ascending\";\nimport bisector from \"./bisector\";\n\nvar ascendingBisect = bisector(ascending);\nexport var bisectRight = ascendingBisect.right;\nexport var bisectLeft = ascendingBisect.left;\nexport default bisectRight;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/bisect.js\n// module id = 67\n// module chunks = 0","import ascending from \"./ascending\";\n\nexport default function(compare) {\n if (compare.length === 1) compare = ascendingComparator(compare);\n return {\n left: function(a, x, lo, hi) {\n if (lo == null) lo = 0;\n if (hi == null) hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (compare(a[mid], x) < 0) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n },\n right: function(a, x, lo, hi) {\n if (lo == null) lo = 0;\n if (hi == null) hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (compare(a[mid], x) > 0) hi = mid;\n else lo = mid + 1;\n }\n return lo;\n }\n };\n}\n\nfunction ascendingComparator(f) {\n return function(d, x) {\n return ascending(f(d), x);\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/bisector.js\n// module id = 68\n// module chunks = 0","export default function(array, f) {\n if (f == null) f = pair;\n var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);\n while (i < n) pairs[i] = f(p, p = array[++i]);\n return pairs;\n}\n\nexport function pair(a, b) {\n return [a, b];\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/pairs.js\n// module id = 69\n// module chunks = 0","import variance from \"./variance\";\n\nexport default function(array, f) {\n var v = variance(array, f);\n return v ? Math.sqrt(v) : v;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/deviation.js\n// module id = 70\n// module chunks = 0","import number from \"./number\";\n\nexport default function(values, valueof) {\n var n = values.length,\n m = 0,\n i = -1,\n mean = 0,\n value,\n delta,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) {\n delta = value - mean;\n mean += delta / ++m;\n sum += delta * (value - mean);\n }\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) {\n delta = value - mean;\n mean += delta / ++m;\n sum += delta * (value - mean);\n }\n }\n }\n\n if (m > 1) return sum / (m - 1);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/variance.js\n// module id = 71\n// module chunks = 0","export default function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n min,\n max;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n min = max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null) {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n min = max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null) {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n }\n }\n\n return [min, max];\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/extent.js\n// module id = 72\n// module chunks = 0","var array = Array.prototype;\n\nexport var slice = array.slice;\nexport var map = array.map;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/array.js\n// module id = 73\n// module chunks = 0","export default function(start, stop, step) {\n start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;\n\n var i = -1,\n n = Math.max(0, Math.ceil((stop - start) / step)) | 0,\n range = new Array(n);\n\n while (++i < n) {\n range[i] = start + i * step;\n }\n\n return range;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/range.js\n// module id = 74\n// module chunks = 0","var e10 = Math.sqrt(50),\n e5 = Math.sqrt(10),\n e2 = Math.sqrt(2);\n\nexport default function(start, stop, count) {\n var reverse = stop < start,\n i = -1,\n n,\n ticks,\n step;\n\n if (reverse) n = start, start = stop, stop = n;\n\n if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];\n\n if (step > 0) {\n start = Math.ceil(start / step);\n stop = Math.floor(stop / step);\n ticks = new Array(n = Math.ceil(stop - start + 1));\n while (++i < n) ticks[i] = (start + i) * step;\n } else {\n start = Math.floor(start * step);\n stop = Math.ceil(stop * step);\n ticks = new Array(n = Math.ceil(start - stop + 1));\n while (++i < n) ticks[i] = (start - i) / step;\n }\n\n if (reverse) ticks.reverse();\n\n return ticks;\n}\n\nexport function tickIncrement(start, stop, count) {\n var step = (stop - start) / Math.max(0, count),\n power = Math.floor(Math.log(step) / Math.LN10),\n error = step / Math.pow(10, power);\n return power >= 0\n ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)\n : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);\n}\n\nexport function tickStep(start, stop, count) {\n var step0 = Math.abs(stop - start) / Math.max(0, count),\n step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),\n error = step0 / step1;\n if (error >= e10) step1 *= 10;\n else if (error >= e5) step1 *= 5;\n else if (error >= e2) step1 *= 2;\n return stop < start ? -step1 : step1;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/ticks.js\n// module id = 75\n// module chunks = 0","export default function(values) {\n return Math.ceil(Math.log(values.length) / Math.LN2) + 1;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/threshold/sturges.js\n// module id = 76\n// module chunks = 0","export default function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n min;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n min = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null && min > value) {\n min = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n min = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null && min > value) {\n min = value;\n }\n }\n }\n }\n }\n\n return min;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/min.js\n// module id = 77\n// module chunks = 0","import min from \"./min\";\n\nexport default function(matrix) {\n if (!(n = matrix.length)) return [];\n for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) {\n for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {\n row[j] = matrix[j][i];\n }\n }\n return transpose;\n}\n\nfunction length(d) {\n return d.length;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/transpose.js\n// module id = 78\n// module chunks = 0","export var deg2rad = Math.PI / 180;\nexport var rad2deg = 180 / Math.PI;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-color/src/math.js\n// module id = 79\n// module chunks = 0","import exponent from \"./exponent\";\nimport formatGroup from \"./formatGroup\";\nimport formatNumerals from \"./formatNumerals\";\nimport formatSpecifier from \"./formatSpecifier\";\nimport formatTypes from \"./formatTypes\";\nimport {prefixExponent} from \"./formatPrefixAuto\";\nimport identity from \"./identity\";\n\nvar prefixes = [\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"µ\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"];\n\nexport default function(locale) {\n var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity,\n currency = locale.currency,\n decimal = locale.decimal,\n numerals = locale.numerals ? formatNumerals(locale.numerals) : identity,\n percent = locale.percent || \"%\";\n\n function newFormat(specifier) {\n specifier = formatSpecifier(specifier);\n\n var fill = specifier.fill,\n align = specifier.align,\n sign = specifier.sign,\n symbol = specifier.symbol,\n zero = specifier.zero,\n width = specifier.width,\n comma = specifier.comma,\n precision = specifier.precision,\n type = specifier.type;\n\n // Compute the prefix and suffix.\n // For SI-prefix, the suffix is lazily computed.\n var prefix = symbol === \"$\" ? currency[0] : symbol === \"#\" && /[boxX]/.test(type) ? \"0\" + type.toLowerCase() : \"\",\n suffix = symbol === \"$\" ? currency[1] : /[%p]/.test(type) ? percent : \"\";\n\n // What format function should we use?\n // Is this an integer type?\n // Can this type generate exponential notation?\n var formatType = formatTypes[type],\n maybeSuffix = !type || /[defgprs%]/.test(type);\n\n // Set the default precision if not specified,\n // or clamp the specified precision to the supported range.\n // For significant precision, it must be in [1, 21].\n // For fixed precision, it must be in [0, 20].\n precision = precision == null ? (type ? 6 : 12)\n : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))\n : Math.max(0, Math.min(20, precision));\n\n function format(value) {\n var valuePrefix = prefix,\n valueSuffix = suffix,\n i, n, c;\n\n if (type === \"c\") {\n valueSuffix = formatType(value) + valueSuffix;\n value = \"\";\n } else {\n value = +value;\n\n // Perform the initial formatting.\n var valueNegative = value < 0;\n value = formatType(Math.abs(value), precision);\n\n // If a negative value rounds to zero during formatting, treat as positive.\n if (valueNegative && +value === 0) valueNegative = false;\n\n // Compute the prefix and suffix.\n valuePrefix = (valueNegative ? (sign === \"(\" ? sign : \"-\") : sign === \"-\" || sign === \"(\" ? \"\" : sign) + valuePrefix;\n valueSuffix = valueSuffix + (type === \"s\" ? prefixes[8 + prefixExponent / 3] : \"\") + (valueNegative && sign === \"(\" ? \")\" : \"\");\n\n // Break the formatted value into the integer “value” part that can be\n // grouped, and fractional or exponential “suffix” part that is not.\n if (maybeSuffix) {\n i = -1, n = value.length;\n while (++i < n) {\n if (c = value.charCodeAt(i), 48 > c || c > 57) {\n valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;\n value = value.slice(0, i);\n break;\n }\n }\n }\n }\n\n // If the fill character is not \"0\", grouping is applied before padding.\n if (comma && !zero) value = group(value, Infinity);\n\n // Compute the padding.\n var length = valuePrefix.length + value.length + valueSuffix.length,\n padding = length < width ? new Array(width - length + 1).join(fill) : \"\";\n\n // If the fill character is \"0\", grouping is applied after padding.\n if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = \"\";\n\n // Reconstruct the final output based on the desired alignment.\n switch (align) {\n case \"<\": value = valuePrefix + value + valueSuffix + padding; break;\n case \"=\": value = valuePrefix + padding + value + valueSuffix; break;\n case \"^\": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;\n default: value = padding + valuePrefix + value + valueSuffix; break;\n }\n\n return numerals(value);\n }\n\n format.toString = function() {\n return specifier + \"\";\n };\n\n return format;\n }\n\n function formatPrefix(specifier, value) {\n var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = \"f\", specifier)),\n e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,\n k = Math.pow(10, -e),\n prefix = prefixes[8 + e / 3];\n return function(value) {\n return f(k * value) + prefix;\n };\n }\n\n return {\n format: newFormat,\n formatPrefix: formatPrefix\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/locale.js\n// module id = 80\n// module chunks = 0","import formatTypes from \"./formatTypes\";\n\n// [[fill]align][sign][symbol][0][width][,][.precision][type]\nvar re = /^(?:(.)?([<>=^]))?([+\\-\\( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?([a-z%])?$/i;\n\nexport default function formatSpecifier(specifier) {\n return new FormatSpecifier(specifier);\n}\n\nformatSpecifier.prototype = FormatSpecifier.prototype; // instanceof\n\nfunction FormatSpecifier(specifier) {\n if (!(match = re.exec(specifier))) throw new Error(\"invalid format: \" + specifier);\n\n var match,\n fill = match[1] || \" \",\n align = match[2] || \">\",\n sign = match[3] || \"-\",\n symbol = match[4] || \"\",\n zero = !!match[5],\n width = match[6] && +match[6],\n comma = !!match[7],\n precision = match[8] && +match[8].slice(1),\n type = match[9] || \"\";\n\n // The \"n\" type is an alias for \",g\".\n if (type === \"n\") comma = true, type = \"g\";\n\n // Map invalid types to the default format.\n else if (!formatTypes[type]) type = \"\";\n\n // If zero fill is specified, padding goes after sign and before digits.\n if (zero || (fill === \"0\" && align === \"=\")) zero = true, fill = \"0\", align = \"=\";\n\n this.fill = fill;\n this.align = align;\n this.sign = sign;\n this.symbol = symbol;\n this.zero = zero;\n this.width = width;\n this.comma = comma;\n this.precision = precision;\n this.type = type;\n}\n\nFormatSpecifier.prototype.toString = function() {\n return this.fill\n + this.align\n + this.sign\n + this.symbol\n + (this.zero ? \"0\" : \"\")\n + (this.width == null ? \"\" : Math.max(1, this.width | 0))\n + (this.comma ? \",\" : \"\")\n + (this.precision == null ? \"\" : \".\" + Math.max(0, this.precision | 0))\n + this.type;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/formatSpecifier.js\n// module id = 81\n// module chunks = 0","import formatDefault from \"./formatDefault\";\nimport formatPrefixAuto from \"./formatPrefixAuto\";\nimport formatRounded from \"./formatRounded\";\n\nexport default {\n \"\": formatDefault,\n \"%\": function(x, p) { return (x * 100).toFixed(p); },\n \"b\": function(x) { return Math.round(x).toString(2); },\n \"c\": function(x) { return x + \"\"; },\n \"d\": function(x) { return Math.round(x).toString(10); },\n \"e\": function(x, p) { return x.toExponential(p); },\n \"f\": function(x, p) { return x.toFixed(p); },\n \"g\": function(x, p) { return x.toPrecision(p); },\n \"o\": function(x) { return Math.round(x).toString(8); },\n \"p\": function(x, p) { return formatRounded(x * 100, p); },\n \"r\": formatRounded,\n \"s\": formatPrefixAuto,\n \"X\": function(x) { return Math.round(x).toString(16).toUpperCase(); },\n \"x\": function(x) { return Math.round(x).toString(16); }\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/formatTypes.js\n// module id = 82\n// module chunks = 0","import formatDecimal from \"./formatDecimal\";\n\nexport var prefixExponent;\n\nexport default function(x, p) {\n var d = formatDecimal(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1],\n i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,\n n = coefficient.length;\n return i === n ? coefficient\n : i > n ? coefficient + new Array(i - n + 1).join(\"0\")\n : i > 0 ? coefficient.slice(0, i) + \".\" + coefficient.slice(i)\n : \"0.\" + new Array(1 - i).join(\"0\") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/formatPrefixAuto.js\n// module id = 83\n// module chunks = 0","import {map} from \"d3-collection\";\nimport {slice} from \"./array\";\n\nexport var implicit = {name: \"implicit\"};\n\nexport default function ordinal(range) {\n var index = map(),\n domain = [],\n unknown = implicit;\n\n range = range == null ? [] : slice.call(range);\n\n function scale(d) {\n var key = d + \"\", i = index.get(key);\n if (!i) {\n if (unknown !== implicit) return unknown;\n index.set(key, i = domain.push(d));\n }\n return range[(i - 1) % range.length];\n }\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [], index = map();\n var i = -1, n = _.length, d, key;\n while (++i < n) if (!index.has(key = (d = _[i]) + \"\")) index.set(key, domain.push(d));\n return scale;\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice.call(_), scale) : range.slice();\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n scale.copy = function() {\n return ordinal()\n .domain(domain)\n .range(range)\n .unknown(unknown);\n };\n\n return scale;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/ordinal.js\n// module id = 84\n// module chunks = 0","import {rgb as colorRgb} from \"d3-color\";\nimport basis from \"./basis\";\nimport basisClosed from \"./basisClosed\";\nimport nogamma, {gamma} from \"./color\";\n\nexport default (function rgbGamma(y) {\n var color = gamma(y);\n\n function rgb(start, end) {\n var r = color((start = colorRgb(start)).r, (end = colorRgb(end)).r),\n g = color(start.g, end.g),\n b = color(start.b, end.b),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.r = r(t);\n start.g = g(t);\n start.b = b(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n\n rgb.gamma = rgbGamma;\n\n return rgb;\n})(1);\n\nfunction rgbSpline(spline) {\n return function(colors) {\n var n = colors.length,\n r = new Array(n),\n g = new Array(n),\n b = new Array(n),\n i, color;\n for (i = 0; i < n; ++i) {\n color = colorRgb(colors[i]);\n r[i] = color.r || 0;\n g[i] = color.g || 0;\n b[i] = color.b || 0;\n }\n r = spline(r);\n g = spline(g);\n b = spline(b);\n color.opacity = 1;\n return function(t) {\n color.r = r(t);\n color.g = g(t);\n color.b = b(t);\n return color + \"\";\n };\n };\n}\n\nexport var rgbBasis = rgbSpline(basis);\nexport var rgbBasisClosed = rgbSpline(basisClosed);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/rgb.js\n// module id = 85\n// module chunks = 0","import {basis} from \"./basis\";\n\nexport default function(values) {\n var n = values.length;\n return function(t) {\n var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),\n v0 = values[(i + n - 1) % n],\n v1 = values[i % n],\n v2 = values[(i + 1) % n],\n v3 = values[(i + 2) % n];\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/basisClosed.js\n// module id = 86\n// module chunks = 0","export default function(x) {\n return function() {\n return x;\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/constant.js\n// module id = 87\n// module chunks = 0","import value from \"./value\";\n\nexport default function(a, b) {\n var nb = b ? b.length : 0,\n na = a ? Math.min(nb, a.length) : 0,\n x = new Array(nb),\n c = new Array(nb),\n i;\n\n for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]);\n for (; i < nb; ++i) c[i] = b[i];\n\n return function(t) {\n for (i = 0; i < na; ++i) c[i] = x[i](t);\n return c;\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/array.js\n// module id = 88\n// module chunks = 0","export default function(a, b) {\n var d = new Date;\n return a = +a, b -= a, function(t) {\n return d.setTime(a + b * t), d;\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/date.js\n// module id = 89\n// module chunks = 0","import value from \"./value\";\n\nexport default function(a, b) {\n var i = {},\n c = {},\n k;\n\n if (a === null || typeof a !== \"object\") a = {};\n if (b === null || typeof b !== \"object\") b = {};\n\n for (k in b) {\n if (k in a) {\n i[k] = value(a[k], b[k]);\n } else {\n c[k] = b[k];\n }\n }\n\n return function(t) {\n for (k in i) c[k] = i[k](t);\n return c;\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/object.js\n// module id = 90\n// module chunks = 0","import number from \"./number\";\n\nvar reA = /[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g,\n reB = new RegExp(reA.source, \"g\");\n\nfunction zero(b) {\n return function() {\n return b;\n };\n}\n\nfunction one(b) {\n return function(t) {\n return b(t) + \"\";\n };\n}\n\nexport default function(a, b) {\n var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b\n am, // current match in a\n bm, // current match in b\n bs, // string preceding current number in b, if any\n i = -1, // index in s\n s = [], // string constants and placeholders\n q = []; // number interpolators\n\n // Coerce inputs to strings.\n a = a + \"\", b = b + \"\";\n\n // Interpolate pairs of numbers in a & b.\n while ((am = reA.exec(a))\n && (bm = reB.exec(b))) {\n if ((bs = bm.index) > bi) { // a string precedes the next number in b\n bs = b.slice(bi, bs);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match\n if (s[i]) s[i] += bm; // coalesce with previous string\n else s[++i] = bm;\n } else { // interpolate non-matching numbers\n s[++i] = null;\n q.push({i: i, x: number(am, bm)});\n }\n bi = reB.lastIndex;\n }\n\n // Add remains of b.\n if (bi < b.length) {\n bs = b.slice(bi);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n\n // Special optimization for only a single match.\n // Otherwise, interpolate each of the numbers and rejoin the string.\n return s.length < 2 ? (q[0]\n ? one(q[0].x)\n : zero(b))\n : (b = q.length, function(t) {\n for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);\n return s.join(\"\");\n });\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/string.js\n// module id = 91\n// module chunks = 0","export default function(x) {\n return +x;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/number.js\n// module id = 92\n// module chunks = 0","export default function(domain, interval) {\n domain = domain.slice();\n\n var i0 = 0,\n i1 = domain.length - 1,\n x0 = domain[i0],\n x1 = domain[i1],\n t;\n\n if (x1 < x0) {\n t = i0, i0 = i1, i1 = t;\n t = x0, x0 = x1, x1 = t;\n }\n\n domain[i0] = interval.floor(x0);\n domain[i1] = interval.ceil(x1);\n return domain;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/nice.js\n// module id = 93\n// module chunks = 0","import {bisector, tickStep} from \"d3-array\";\nimport {interpolateNumber as reinterpolate} from \"d3-interpolate\";\nimport {timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeMillisecond} from \"d3-time\";\nimport {timeFormat} from \"d3-time-format\";\nimport {map} from \"./array\";\nimport {default as continuous, copy, deinterpolateLinear as deinterpolate} from \"./continuous\";\nimport nice from \"./nice\";\n\nvar durationSecond = 1000,\n durationMinute = durationSecond * 60,\n durationHour = durationMinute * 60,\n durationDay = durationHour * 24,\n durationWeek = durationDay * 7,\n durationMonth = durationDay * 30,\n durationYear = durationDay * 365;\n\nfunction date(t) {\n return new Date(t);\n}\n\nfunction number(t) {\n return t instanceof Date ? +t : +new Date(+t);\n}\n\nexport function calendar(year, month, week, day, hour, minute, second, millisecond, format) {\n var scale = continuous(deinterpolate, reinterpolate),\n invert = scale.invert,\n domain = scale.domain;\n\n var formatMillisecond = format(\".%L\"),\n formatSecond = format(\":%S\"),\n formatMinute = format(\"%I:%M\"),\n formatHour = format(\"%I %p\"),\n formatDay = format(\"%a %d\"),\n formatWeek = format(\"%b %d\"),\n formatMonth = format(\"%B\"),\n formatYear = format(\"%Y\");\n\n var tickIntervals = [\n [second, 1, durationSecond],\n [second, 5, 5 * durationSecond],\n [second, 15, 15 * durationSecond],\n [second, 30, 30 * durationSecond],\n [minute, 1, durationMinute],\n [minute, 5, 5 * durationMinute],\n [minute, 15, 15 * durationMinute],\n [minute, 30, 30 * durationMinute],\n [ hour, 1, durationHour ],\n [ hour, 3, 3 * durationHour ],\n [ hour, 6, 6 * durationHour ],\n [ hour, 12, 12 * durationHour ],\n [ day, 1, durationDay ],\n [ day, 2, 2 * durationDay ],\n [ week, 1, durationWeek ],\n [ month, 1, durationMonth ],\n [ month, 3, 3 * durationMonth ],\n [ year, 1, durationYear ]\n ];\n\n function tickFormat(date) {\n return (second(date) < date ? formatMillisecond\n : minute(date) < date ? formatSecond\n : hour(date) < date ? formatMinute\n : day(date) < date ? formatHour\n : month(date) < date ? (week(date) < date ? formatDay : formatWeek)\n : year(date) < date ? formatMonth\n : formatYear)(date);\n }\n\n function tickInterval(interval, start, stop, step) {\n if (interval == null) interval = 10;\n\n // If a desired tick count is specified, pick a reasonable tick interval\n // based on the extent of the domain and a rough estimate of tick size.\n // Otherwise, assume interval is already a time interval and use it.\n if (typeof interval === \"number\") {\n var target = Math.abs(stop - start) / interval,\n i = bisector(function(i) { return i[2]; }).right(tickIntervals, target);\n if (i === tickIntervals.length) {\n step = tickStep(start / durationYear, stop / durationYear, interval);\n interval = year;\n } else if (i) {\n i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];\n step = i[1];\n interval = i[0];\n } else {\n step = Math.max(tickStep(start, stop, interval), 1);\n interval = millisecond;\n }\n }\n\n return step == null ? interval : interval.every(step);\n }\n\n scale.invert = function(y) {\n return new Date(invert(y));\n };\n\n scale.domain = function(_) {\n return arguments.length ? domain(map.call(_, number)) : domain().map(date);\n };\n\n scale.ticks = function(interval, step) {\n var d = domain(),\n t0 = d[0],\n t1 = d[d.length - 1],\n r = t1 < t0,\n t;\n if (r) t = t0, t0 = t1, t1 = t;\n t = tickInterval(interval, t0, t1, step);\n t = t ? t.range(t0, t1 + 1) : []; // inclusive stop\n return r ? t.reverse() : t;\n };\n\n scale.tickFormat = function(count, specifier) {\n return specifier == null ? tickFormat : format(specifier);\n };\n\n scale.nice = function(interval, step) {\n var d = domain();\n return (interval = tickInterval(interval, d[0], d[d.length - 1], step))\n ? domain(nice(d, interval))\n : scale;\n };\n\n scale.copy = function() {\n return copy(scale, calendar(year, month, week, day, hour, minute, second, millisecond, format));\n };\n\n return scale;\n}\n\nexport default function() {\n return calendar(timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeMillisecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/time.js\n// module id = 94\n// module chunks = 0","import {timeDay, timeSunday, timeMonday, timeYear, utcDay, utcSunday, utcMonday, utcYear} from \"d3-time\";\n\nfunction localDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);\n date.setFullYear(d.y);\n return date;\n }\n return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);\n}\n\nfunction utcDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));\n date.setUTCFullYear(d.y);\n return date;\n }\n return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));\n}\n\nfunction newYear(y) {\n return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};\n}\n\nexport default function formatLocale(locale) {\n var locale_dateTime = locale.dateTime,\n locale_date = locale.date,\n locale_time = locale.time,\n locale_periods = locale.periods,\n locale_weekdays = locale.days,\n locale_shortWeekdays = locale.shortDays,\n locale_months = locale.months,\n locale_shortMonths = locale.shortMonths;\n\n var periodRe = formatRe(locale_periods),\n periodLookup = formatLookup(locale_periods),\n weekdayRe = formatRe(locale_weekdays),\n weekdayLookup = formatLookup(locale_weekdays),\n shortWeekdayRe = formatRe(locale_shortWeekdays),\n shortWeekdayLookup = formatLookup(locale_shortWeekdays),\n monthRe = formatRe(locale_months),\n monthLookup = formatLookup(locale_months),\n shortMonthRe = formatRe(locale_shortMonths),\n shortMonthLookup = formatLookup(locale_shortMonths);\n\n var formats = {\n \"a\": formatShortWeekday,\n \"A\": formatWeekday,\n \"b\": formatShortMonth,\n \"B\": formatMonth,\n \"c\": null,\n \"d\": formatDayOfMonth,\n \"e\": formatDayOfMonth,\n \"H\": formatHour24,\n \"I\": formatHour12,\n \"j\": formatDayOfYear,\n \"L\": formatMilliseconds,\n \"m\": formatMonthNumber,\n \"M\": formatMinutes,\n \"p\": formatPeriod,\n \"S\": formatSeconds,\n \"U\": formatWeekNumberSunday,\n \"w\": formatWeekdayNumber,\n \"W\": formatWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatYear,\n \"Y\": formatFullYear,\n \"Z\": formatZone,\n \"%\": formatLiteralPercent\n };\n\n var utcFormats = {\n \"a\": formatUTCShortWeekday,\n \"A\": formatUTCWeekday,\n \"b\": formatUTCShortMonth,\n \"B\": formatUTCMonth,\n \"c\": null,\n \"d\": formatUTCDayOfMonth,\n \"e\": formatUTCDayOfMonth,\n \"H\": formatUTCHour24,\n \"I\": formatUTCHour12,\n \"j\": formatUTCDayOfYear,\n \"L\": formatUTCMilliseconds,\n \"m\": formatUTCMonthNumber,\n \"M\": formatUTCMinutes,\n \"p\": formatUTCPeriod,\n \"S\": formatUTCSeconds,\n \"U\": formatUTCWeekNumberSunday,\n \"w\": formatUTCWeekdayNumber,\n \"W\": formatUTCWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatUTCYear,\n \"Y\": formatUTCFullYear,\n \"Z\": formatUTCZone,\n \"%\": formatLiteralPercent\n };\n\n var parses = {\n \"a\": parseShortWeekday,\n \"A\": parseWeekday,\n \"b\": parseShortMonth,\n \"B\": parseMonth,\n \"c\": parseLocaleDateTime,\n \"d\": parseDayOfMonth,\n \"e\": parseDayOfMonth,\n \"H\": parseHour24,\n \"I\": parseHour24,\n \"j\": parseDayOfYear,\n \"L\": parseMilliseconds,\n \"m\": parseMonthNumber,\n \"M\": parseMinutes,\n \"p\": parsePeriod,\n \"S\": parseSeconds,\n \"U\": parseWeekNumberSunday,\n \"w\": parseWeekdayNumber,\n \"W\": parseWeekNumberMonday,\n \"x\": parseLocaleDate,\n \"X\": parseLocaleTime,\n \"y\": parseYear,\n \"Y\": parseFullYear,\n \"Z\": parseZone,\n \"%\": parseLiteralPercent\n };\n\n // These recursive directive definitions must be deferred.\n formats.x = newFormat(locale_date, formats);\n formats.X = newFormat(locale_time, formats);\n formats.c = newFormat(locale_dateTime, formats);\n utcFormats.x = newFormat(locale_date, utcFormats);\n utcFormats.X = newFormat(locale_time, utcFormats);\n utcFormats.c = newFormat(locale_dateTime, utcFormats);\n\n function newFormat(specifier, formats) {\n return function(date) {\n var string = [],\n i = -1,\n j = 0,\n n = specifier.length,\n c,\n pad,\n format;\n\n if (!(date instanceof Date)) date = new Date(+date);\n\n while (++i < n) {\n if (specifier.charCodeAt(i) === 37) {\n string.push(specifier.slice(j, i));\n if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);\n else pad = c === \"e\" ? \" \" : \"0\";\n if (format = formats[c]) c = format(date, pad);\n string.push(c);\n j = i + 1;\n }\n }\n\n string.push(specifier.slice(j, i));\n return string.join(\"\");\n };\n }\n\n function newParse(specifier, newDate) {\n return function(string) {\n var d = newYear(1900),\n i = parseSpecifier(d, specifier, string += \"\", 0);\n if (i != string.length) return null;\n\n // The am-pm flag is 0 for AM, and 1 for PM.\n if (\"p\" in d) d.H = d.H % 12 + d.p * 12;\n\n // Convert day-of-week and week-of-year to day-of-year.\n if (\"W\" in d || \"U\" in d) {\n if (!(\"w\" in d)) d.w = \"W\" in d ? 1 : 0;\n var day = \"Z\" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();\n d.m = 0;\n d.d = \"W\" in d ? (d.w + 6) % 7 + d.W * 7 - (day + 5) % 7 : d.w + d.U * 7 - (day + 6) % 7;\n }\n\n // If a time zone is specified, all fields are interpreted as UTC and then\n // offset according to the specified time zone.\n if (\"Z\" in d) {\n d.H += d.Z / 100 | 0;\n d.M += d.Z % 100;\n return utcDate(d);\n }\n\n // Otherwise, all fields are in local time.\n return newDate(d);\n };\n }\n\n function parseSpecifier(d, specifier, string, j) {\n var i = 0,\n n = specifier.length,\n m = string.length,\n c,\n parse;\n\n while (i < n) {\n if (j >= m) return -1;\n c = specifier.charCodeAt(i++);\n if (c === 37) {\n c = specifier.charAt(i++);\n parse = parses[c in pads ? specifier.charAt(i++) : c];\n if (!parse || ((j = parse(d, string, j)) < 0)) return -1;\n } else if (c != string.charCodeAt(j++)) {\n return -1;\n }\n }\n\n return j;\n }\n\n function parsePeriod(d, string, i) {\n var n = periodRe.exec(string.slice(i));\n return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseShortWeekday(d, string, i) {\n var n = shortWeekdayRe.exec(string.slice(i));\n return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseWeekday(d, string, i) {\n var n = weekdayRe.exec(string.slice(i));\n return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseShortMonth(d, string, i) {\n var n = shortMonthRe.exec(string.slice(i));\n return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseMonth(d, string, i) {\n var n = monthRe.exec(string.slice(i));\n return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseLocaleDateTime(d, string, i) {\n return parseSpecifier(d, locale_dateTime, string, i);\n }\n\n function parseLocaleDate(d, string, i) {\n return parseSpecifier(d, locale_date, string, i);\n }\n\n function parseLocaleTime(d, string, i) {\n return parseSpecifier(d, locale_time, string, i);\n }\n\n function formatShortWeekday(d) {\n return locale_shortWeekdays[d.getDay()];\n }\n\n function formatWeekday(d) {\n return locale_weekdays[d.getDay()];\n }\n\n function formatShortMonth(d) {\n return locale_shortMonths[d.getMonth()];\n }\n\n function formatMonth(d) {\n return locale_months[d.getMonth()];\n }\n\n function formatPeriod(d) {\n return locale_periods[+(d.getHours() >= 12)];\n }\n\n function formatUTCShortWeekday(d) {\n return locale_shortWeekdays[d.getUTCDay()];\n }\n\n function formatUTCWeekday(d) {\n return locale_weekdays[d.getUTCDay()];\n }\n\n function formatUTCShortMonth(d) {\n return locale_shortMonths[d.getUTCMonth()];\n }\n\n function formatUTCMonth(d) {\n return locale_months[d.getUTCMonth()];\n }\n\n function formatUTCPeriod(d) {\n return locale_periods[+(d.getUTCHours() >= 12)];\n }\n\n return {\n format: function(specifier) {\n var f = newFormat(specifier += \"\", formats);\n f.toString = function() { return specifier; };\n return f;\n },\n parse: function(specifier) {\n var p = newParse(specifier += \"\", localDate);\n p.toString = function() { return specifier; };\n return p;\n },\n utcFormat: function(specifier) {\n var f = newFormat(specifier += \"\", utcFormats);\n f.toString = function() { return specifier; };\n return f;\n },\n utcParse: function(specifier) {\n var p = newParse(specifier, utcDate);\n p.toString = function() { return specifier; };\n return p;\n }\n };\n}\n\nvar pads = {\"-\": \"\", \"_\": \" \", \"0\": \"0\"},\n numberRe = /^\\s*\\d+/, // note: ignores next directive\n percentRe = /^%/,\n requoteRe = /[\\\\\\^\\$\\*\\+\\?\\|\\[\\]\\(\\)\\.\\{\\}]/g;\n\nfunction pad(value, fill, width) {\n var sign = value < 0 ? \"-\" : \"\",\n string = (sign ? -value : value) + \"\",\n length = string.length;\n return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);\n}\n\nfunction requote(s) {\n return s.replace(requoteRe, \"\\\\$&\");\n}\n\nfunction formatRe(names) {\n return new RegExp(\"^(?:\" + names.map(requote).join(\"|\") + \")\", \"i\");\n}\n\nfunction formatLookup(names) {\n var map = {}, i = -1, n = names.length;\n while (++i < n) map[names[i].toLowerCase()] = i;\n return map;\n}\n\nfunction parseWeekdayNumber(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.w = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.U = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.W = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseFullYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 4));\n return n ? (d.y = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;\n}\n\nfunction parseZone(d, string, i) {\n var n = /^(Z)|([+-]\\d\\d)(?:\\:?(\\d\\d))?/.exec(string.slice(i, i + 6));\n return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || \"00\")), i + n[0].length) : -1;\n}\n\nfunction parseMonthNumber(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.m = n[0] - 1, i + n[0].length) : -1;\n}\n\nfunction parseDayOfMonth(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseDayOfYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseHour24(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.H = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMinutes(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.M = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.S = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMilliseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.L = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseLiteralPercent(d, string, i) {\n var n = percentRe.exec(string.slice(i, i + 1));\n return n ? i + n[0].length : -1;\n}\n\nfunction formatDayOfMonth(d, p) {\n return pad(d.getDate(), p, 2);\n}\n\nfunction formatHour24(d, p) {\n return pad(d.getHours(), p, 2);\n}\n\nfunction formatHour12(d, p) {\n return pad(d.getHours() % 12 || 12, p, 2);\n}\n\nfunction formatDayOfYear(d, p) {\n return pad(1 + timeDay.count(timeYear(d), d), p, 3);\n}\n\nfunction formatMilliseconds(d, p) {\n return pad(d.getMilliseconds(), p, 3);\n}\n\nfunction formatMonthNumber(d, p) {\n return pad(d.getMonth() + 1, p, 2);\n}\n\nfunction formatMinutes(d, p) {\n return pad(d.getMinutes(), p, 2);\n}\n\nfunction formatSeconds(d, p) {\n return pad(d.getSeconds(), p, 2);\n}\n\nfunction formatWeekNumberSunday(d, p) {\n return pad(timeSunday.count(timeYear(d), d), p, 2);\n}\n\nfunction formatWeekdayNumber(d) {\n return d.getDay();\n}\n\nfunction formatWeekNumberMonday(d, p) {\n return pad(timeMonday.count(timeYear(d), d), p, 2);\n}\n\nfunction formatYear(d, p) {\n return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatFullYear(d, p) {\n return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatZone(d) {\n var z = d.getTimezoneOffset();\n return (z > 0 ? \"-\" : (z *= -1, \"+\"))\n + pad(z / 60 | 0, \"0\", 2)\n + pad(z % 60, \"0\", 2);\n}\n\nfunction formatUTCDayOfMonth(d, p) {\n return pad(d.getUTCDate(), p, 2);\n}\n\nfunction formatUTCHour24(d, p) {\n return pad(d.getUTCHours(), p, 2);\n}\n\nfunction formatUTCHour12(d, p) {\n return pad(d.getUTCHours() % 12 || 12, p, 2);\n}\n\nfunction formatUTCDayOfYear(d, p) {\n return pad(1 + utcDay.count(utcYear(d), d), p, 3);\n}\n\nfunction formatUTCMilliseconds(d, p) {\n return pad(d.getUTCMilliseconds(), p, 3);\n}\n\nfunction formatUTCMonthNumber(d, p) {\n return pad(d.getUTCMonth() + 1, p, 2);\n}\n\nfunction formatUTCMinutes(d, p) {\n return pad(d.getUTCMinutes(), p, 2);\n}\n\nfunction formatUTCSeconds(d, p) {\n return pad(d.getUTCSeconds(), p, 2);\n}\n\nfunction formatUTCWeekNumberSunday(d, p) {\n return pad(utcSunday.count(utcYear(d), d), p, 2);\n}\n\nfunction formatUTCWeekdayNumber(d) {\n return d.getUTCDay();\n}\n\nfunction formatUTCWeekNumberMonday(d, p) {\n return pad(utcMonday.count(utcYear(d), d), p, 2);\n}\n\nfunction formatUTCYear(d, p) {\n return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCFullYear(d, p) {\n return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCZone() {\n return \"+0000\";\n}\n\nfunction formatLiteralPercent() {\n return \"%\";\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time-format/src/locale.js\n// module id = 95\n// module chunks = 0","import {utcFormat} from \"./defaultLocale\";\n\nexport var isoSpecifier = \"%Y-%m-%dT%H:%M:%S.%LZ\";\n\nfunction formatIsoNative(date) {\n return date.toISOString();\n}\n\nvar formatIso = Date.prototype.toISOString\n ? formatIsoNative\n : utcFormat(isoSpecifier);\n\nexport default formatIso;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time-format/src/isoFormat.js\n// module id = 96\n// module chunks = 0","var matcher = function(selector) {\n return function() {\n return this.matches(selector);\n };\n};\n\nif (typeof document !== \"undefined\") {\n var element = document.documentElement;\n if (!element.matches) {\n var vendorMatches = element.webkitMatchesSelector\n || element.msMatchesSelector\n || element.mozMatchesSelector\n || element.oMatchesSelector;\n matcher = function(selector) {\n return function() {\n return vendorMatches.call(this, selector);\n };\n };\n }\n}\n\nexport default matcher;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/matcher.js\n// module id = 97\n// module chunks = 0","function empty() {\n return [];\n}\n\nexport default function(selector) {\n return selector == null ? empty : function() {\n return this.querySelectorAll(selector);\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selectorAll.js\n// module id = 98\n// module chunks = 0","import sparse from \"./sparse\";\nimport {Selection} from \"./index\";\n\nexport default function() {\n return new Selection(this._enter || this._groups.map(sparse), this._parents);\n}\n\nexport function EnterNode(parent, datum) {\n this.ownerDocument = parent.ownerDocument;\n this.namespaceURI = parent.namespaceURI;\n this._next = null;\n this._parent = parent;\n this.__data__ = datum;\n}\n\nEnterNode.prototype = {\n constructor: EnterNode,\n appendChild: function(child) { return this._parent.insertBefore(child, this._next); },\n insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },\n querySelector: function(selector) { return this._parent.querySelector(selector); },\n querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/enter.js\n// module id = 99\n// module chunks = 0","export default function(update) {\n return new Array(update.length);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/sparse.js\n// module id = 100\n// module chunks = 0","import defaultView from \"../window\";\n\nfunction styleRemove(name) {\n return function() {\n this.style.removeProperty(name);\n };\n}\n\nfunction styleConstant(name, value, priority) {\n return function() {\n this.style.setProperty(name, value, priority);\n };\n}\n\nfunction styleFunction(name, value, priority) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) this.style.removeProperty(name);\n else this.style.setProperty(name, v, priority);\n };\n}\n\nexport default function(name, value, priority) {\n return arguments.length > 1\n ? this.each((value == null\n ? styleRemove : typeof value === \"function\"\n ? styleFunction\n : styleConstant)(name, value, priority == null ? \"\" : priority))\n : styleValue(this.node(), name);\n}\n\nexport function styleValue(node, name) {\n return node.style.getPropertyValue(name)\n || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/style.js\n// module id = 101\n// module chunks = 0","import {STARTING, ENDING, ENDED} from \"./transition/schedule\";\n\nexport default function(node, name) {\n var schedules = node.__transition,\n schedule,\n active,\n empty = true,\n i;\n\n if (!schedules) return;\n\n name = name == null ? null : name + \"\";\n\n for (i in schedules) {\n if ((schedule = schedules[i]).name !== name) { empty = false; continue; }\n active = schedule.state > STARTING && schedule.state < ENDING;\n schedule.state = ENDED;\n schedule.timer.stop();\n if (active) schedule.on.call(\"interrupt\", node, node.__data__, schedule.index, schedule.group);\n delete schedules[i];\n }\n\n if (empty) delete node.__transition;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/interrupt.js\n// module id = 102\n// module chunks = 0","export {\n now,\n timer,\n timerFlush\n} from \"./src/timer\";\n\nexport {\n default as timeout\n} from \"./src/timeout\";\n\nexport {\n default as interval\n} from \"./src/interval\";\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-timer/index.js\n// module id = 103\n// module chunks = 0","import {color} from \"d3-color\";\nimport {interpolateNumber, interpolateRgb, interpolateString} from \"d3-interpolate\";\n\nexport default function(a, b) {\n var c;\n return (typeof b === \"number\" ? interpolateNumber\n : b instanceof color ? interpolateRgb\n : (c = color(b)) ? (b = c, interpolateRgb)\n : interpolateString)(a, b);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/interpolate.js\n// module id = 104\n// module chunks = 0","import {path} from \"d3-path\";\nimport constant from \"./constant\";\nimport curveLinear from \"./curve/linear\";\nimport line from \"./line\";\nimport {x as pointX, y as pointY} from \"./point\";\n\nexport default function() {\n var x0 = pointX,\n x1 = null,\n y0 = constant(0),\n y1 = pointY,\n defined = constant(true),\n context = null,\n curve = curveLinear,\n output = null;\n\n function area(data) {\n var i,\n j,\n k,\n n = data.length,\n d,\n defined0 = false,\n buffer,\n x0z = new Array(n),\n y0z = new Array(n);\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) {\n j = i;\n output.areaStart();\n output.lineStart();\n } else {\n output.lineEnd();\n output.lineStart();\n for (k = i - 1; k >= j; --k) {\n output.point(x0z[k], y0z[k]);\n }\n output.lineEnd();\n output.areaEnd();\n }\n }\n if (defined0) {\n x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);\n output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);\n }\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n function arealine() {\n return line().defined(defined).curve(curve).context(context);\n }\n\n area.x = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant(+_), x1 = null, area) : x0;\n };\n\n area.x0 = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant(+_), area) : x0;\n };\n\n area.x1 = function(_) {\n return arguments.length ? (x1 = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), area) : x1;\n };\n\n area.y = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant(+_), y1 = null, area) : y0;\n };\n\n area.y0 = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant(+_), area) : y0;\n };\n\n area.y1 = function(_) {\n return arguments.length ? (y1 = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), area) : y1;\n };\n\n area.lineX0 =\n area.lineY0 = function() {\n return arealine().x(x0).y(y0);\n };\n\n area.lineY1 = function() {\n return arealine().x(x0).y(y1);\n };\n\n area.lineX1 = function() {\n return arealine().x(x1).y(y0);\n };\n\n area.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant(!!_), area) : defined;\n };\n\n area.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;\n };\n\n area.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;\n };\n\n return area;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/area.js\n// module id = 105\n// module chunks = 0","import curveLinear from \"./linear\";\n\nexport var curveRadialLinear = curveRadial(curveLinear);\n\nfunction Radial(curve) {\n this._curve = curve;\n}\n\nRadial.prototype = {\n areaStart: function() {\n this._curve.areaStart();\n },\n areaEnd: function() {\n this._curve.areaEnd();\n },\n lineStart: function() {\n this._curve.lineStart();\n },\n lineEnd: function() {\n this._curve.lineEnd();\n },\n point: function(a, r) {\n this._curve.point(r * Math.sin(a), r * -Math.cos(a));\n }\n};\n\nexport default function curveRadial(curve) {\n\n function radial(context) {\n return new Radial(curve(context));\n }\n\n radial._curve = curve;\n\n return radial;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/curve/radial.js\n// module id = 106\n// module chunks = 0","import curveRadial, {curveRadialLinear} from \"./curve/radial\";\nimport line from \"./line\";\n\nexport function lineRadial(l) {\n var c = l.curve;\n\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n\n l.curve = function(_) {\n return arguments.length ? c(curveRadial(_)) : c()._curve;\n };\n\n return l;\n}\n\nexport default function() {\n return lineRadial(line().curve(curveRadialLinear));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/lineRadial.js\n// module id = 107\n// module chunks = 0","export default function(x, y) {\n return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/pointRadial.js\n// module id = 108\n// module chunks = 0","export var slice = Array.prototype.slice;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/array.js\n// module id = 109\n// module chunks = 0","import {pi, tau} from \"../math\";\n\nexport default {\n draw: function(context, size) {\n var r = Math.sqrt(size / pi);\n context.moveTo(r, 0);\n context.arc(0, 0, r, 0, tau);\n }\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/symbol/circle.js\n// module id = 110\n// module chunks = 0","export default {\n draw: function(context, size) {\n var r = Math.sqrt(size / 5) / 2;\n context.moveTo(-3 * r, -r);\n context.lineTo(-r, -r);\n context.lineTo(-r, -3 * r);\n context.lineTo(r, -3 * r);\n context.lineTo(r, -r);\n context.lineTo(3 * r, -r);\n context.lineTo(3 * r, r);\n context.lineTo(r, r);\n context.lineTo(r, 3 * r);\n context.lineTo(-r, 3 * r);\n context.lineTo(-r, r);\n context.lineTo(-3 * r, r);\n context.closePath();\n }\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/symbol/cross.js\n// module id = 111\n// module chunks = 0","var tan30 = Math.sqrt(1 / 3),\n tan30_2 = tan30 * 2;\n\nexport default {\n draw: function(context, size) {\n var y = Math.sqrt(size / tan30_2),\n x = y * tan30;\n context.moveTo(0, -y);\n context.lineTo(x, 0);\n context.lineTo(0, y);\n context.lineTo(-x, 0);\n context.closePath();\n }\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/symbol/diamond.js\n// module id = 112\n// module chunks = 0","import {pi, tau} from \"../math\";\n\nvar ka = 0.89081309152928522810,\n kr = Math.sin(pi / 10) / Math.sin(7 * pi / 10),\n kx = Math.sin(tau / 10) * kr,\n ky = -Math.cos(tau / 10) * kr;\n\nexport default {\n draw: function(context, size) {\n var r = Math.sqrt(size * ka),\n x = kx * r,\n y = ky * r;\n context.moveTo(0, -r);\n context.lineTo(x, y);\n for (var i = 1; i < 5; ++i) {\n var a = tau * i / 5,\n c = Math.cos(a),\n s = Math.sin(a);\n context.lineTo(s * r, -c * r);\n context.lineTo(c * x - s * y, s * x + c * y);\n }\n context.closePath();\n }\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/symbol/star.js\n// module id = 113\n// module chunks = 0","export default {\n draw: function(context, size) {\n var w = Math.sqrt(size),\n x = -w / 2;\n context.rect(x, x, w, w);\n }\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/symbol/square.js\n// module id = 114\n// module chunks = 0","var sqrt3 = Math.sqrt(3);\n\nexport default {\n draw: function(context, size) {\n var y = -Math.sqrt(size / (sqrt3 * 3));\n context.moveTo(0, y * 2);\n context.lineTo(-sqrt3 * y, -y);\n context.lineTo(sqrt3 * y, -y);\n context.closePath();\n }\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/symbol/triangle.js\n// module id = 115\n// module chunks = 0","var c = -0.5,\n s = Math.sqrt(3) / 2,\n k = 1 / Math.sqrt(12),\n a = (k / 2 + 1) * 3;\n\nexport default {\n draw: function(context, size) {\n var r = Math.sqrt(size / a),\n x0 = r / 2,\n y0 = r * k,\n x1 = x0,\n y1 = r * k + r,\n x2 = -x1,\n y2 = y1;\n context.moveTo(x0, y0);\n context.lineTo(x1, y1);\n context.lineTo(x2, y2);\n context.lineTo(c * x0 - s * y0, s * x0 + c * y0);\n context.lineTo(c * x1 - s * y1, s * x1 + c * y1);\n context.lineTo(c * x2 - s * y2, s * x2 + c * y2);\n context.lineTo(c * x0 + s * y0, c * y0 - s * x0);\n context.lineTo(c * x1 + s * y1, c * y1 - s * x1);\n context.lineTo(c * x2 + s * y2, c * y2 - s * x2);\n context.closePath();\n }\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/symbol/wye.js\n// module id = 116\n// module chunks = 0","import noop from \"../noop\";\nimport {point} from \"./cardinal\";\n\nexport function CardinalClosed(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new CardinalClosed(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/curve/cardinalClosed.js\n// module id = 117\n// module chunks = 0","import {point} from \"./cardinal\";\n\nexport function CardinalOpen(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new CardinalOpen(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/curve/cardinalOpen.js\n// module id = 118\n// module chunks = 0","define(function (require) {\n 'use strict';\n\n const d3Format = require('d3-format');\n let idCounter = 0;\n\n /**\n * Calculates percentage of value from total\n * @param {String} date Date\n * @param {Number} days Number of days to add\n * @return {String} Date\n */\n const addDays = (date, days) => {\n const result = new Date(date);\n\n result.setDate(result.getDate() + days);\n\n return String(result);\n }\n\n /**\n * Calculates difference between dates in days\n * @param {String} date1 Date in string form\n * @param {String} date2 Date in string form\n * @return {Number} Number of days between dates\n */\n const diffDays = (date1, date2) => {\n const oneDay = 24 * 60 * 60 * 1000;\n\n return Math.ceil(Math.abs((new Date(date1).getTime() - new Date(date2).getTime()) / (oneDay)));\n }\n\n /**\n * Takes a number representing milliseconds and convert to days\n * @param {Number} milliseconds Any number\n * @return {Number} Number of days that the input represents\n */\n const convertMillisecondsToDays = (milliseconds) => Math.ceil(milliseconds/(24*60*60*1000));\n\n /**\n * Takes a locale (string) and the format to return and returns a function to format dates\n * @param {String} locale locale tag eg. en-US, fr-FR, ru-RU\n * @param {string} timeUnit minute, hour, day, dayMonth, month, year\n * @return {function} function that formats dates in the proper locale\n */\n const getLocaleDateFormatter = (locale, timeUnit='day') => {\n let options = localeTimeMap[timeUnit];\n let formatter = new Intl.DateTimeFormat(locale, options);\n\n return (date) => formatter.format(date);\n }\n\n return {\n addDays,\n convertMillisecondsToDays,\n diffDays,\n getLocaleDateFormatter\n };\n\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/helpers/date.js","define(function (require) {\n\n const d3Selection = require('d3-selection');\n const filterId = 'highlight-filter';\n\n\n const createFilterContainer = (metadataSelection) => {\n let highlightFilter = metadataSelection\n .append('defs')\n .append('filter')\n .attr('id', filterId);\n\n return highlightFilter;\n };\n\n const createGausianBlur = (filterSelector) => {\n filterSelector\n .append('feGaussianBlur')\n .attr('stdDeviation', 1)\n .attr('result', 'coloredBlur');\n\n return filterId;\n };\n\n const createGlow = (filterSelector) => {\n filterSelector\n .attr('x', '-30%')\n .attr('y', '-30%')\n .attr('width', '160%')\n .attr('height', '160%');\n\n filterSelector\n .append('feGaussianBlur')\n .attr('stdDeviation', '0.9 0.9')\n .attr('result', 'glow');\n\n let merge = filterSelector\n .append('feMerge');\n\n merge\n .append('feMergeNode')\n .attr('in', 'glow');\n\n merge\n .append('feMergeNode')\n .attr('in', 'glow');\n\n merge\n .append('feMergeNode')\n .attr('in', 'glow');\n\n return filterId;\n };\n\n const createGlowWithMatrix = (filterSelector) => {\n let colorMatrix = '0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0';\n\n filterSelector\n .attr('x', '-500%')\n .attr('y', '-500%')\n .attr('width', '1800%')\n .attr('height', '1800%');\n\n filterSelector\n .append('feColorMatrix')\n .attr('type', 'matrix')\n .attr('values', colorMatrix);\n\n filterSelector\n .append('feGaussianBlur')\n .attr('stdDeviation', '1')\n .attr('result', 'coloredBlur')\n .attr('in', 'SourceGraphic');\n\n let merge = filterSelector\n .append('feMerge');\n\n merge\n .append('feMergeNode')\n .attr('in', 'coloredBlur');\n\n merge\n .append('feMergeNode')\n .attr('in', 'SourceGraphic');\n\n return filterId;\n }\n\n const createWhiteGlow = (filterSelector) => {\n filterSelector\n .attr('x', '-5000%')\n .attr('y', '-5000%')\n .attr('width', '10000%')\n .attr('height', '10000%');\n\n filterSelector\n .append('feFlood')\n .attr('result', 'flood')\n .attr('flood-color', '#ffffff')\n .attr('flood-opacity', '1');\n\n filterSelector\n .append('feComposite')\n .attr('result', 'mask')\n .attr('in2', 'SourceGraphic')\n .attr('operator', 'in')\n .attr('in', 'flood');\n\n filterSelector\n .append('feMorphology')\n .attr('result', 'dilated')\n .attr('operator', 'dilate')\n .attr('radius', '2')\n .attr('in', 'mask');\n\n filterSelector\n .append('feGaussianBlur')\n .attr('result', 'blurred')\n .attr('stdDeviation', '5')\n .attr('in', 'dilated');\n\n let merge = filterSelector\n .append('feMerge');\n\n merge\n .append('feMergeNode')\n .attr('in', 'blurred');\n\n merge\n .append('feMergeNode')\n .attr('in', 'SourceGraphic');\n\n return filterId;\n };\n\n return {\n createFilterContainer,\n createGausianBlur,\n createWhiteGlow,\n createGlow,\n createGlowWithMatrix,\n };\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/helpers/filter.js","import {select} from \"d3-selection\";\nimport noevent from \"./noevent\";\n\nexport default function(view) {\n var root = view.document.documentElement,\n selection = select(view).on(\"dragstart.drag\", noevent, true);\n if (\"onselectstart\" in root) {\n selection.on(\"selectstart.drag\", noevent, true);\n } else {\n root.__noselect = root.style.MozUserSelect;\n root.style.MozUserSelect = \"none\";\n }\n}\n\nexport function yesdrag(view, noclick) {\n var root = view.document.documentElement,\n selection = select(view).on(\"dragstart.drag\", null);\n if (noclick) {\n selection.on(\"click.drag\", noevent, true);\n setTimeout(function() { selection.on(\"click.drag\", null); }, 0);\n }\n if (\"onselectstart\" in root) {\n selection.on(\"selectstart.drag\", null);\n } else {\n root.style.MozUserSelect = root.__noselect;\n delete root.__noselect;\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-drag/src/nodrag.js\n// module id = 121\n// module chunks = 0","import {event} from \"d3-selection\";\n\nexport function nopropagation() {\n event.stopImmediatePropagation();\n}\n\nexport default function() {\n event.preventDefault();\n event.stopImmediatePropagation();\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-drag/src/noevent.js\n// module id = 122\n// module chunks = 0","import bar from './charts/bar.js';\nimport donut from './charts/donut.js';\nimport legend from './charts/legend.js';\nimport line from './charts/line.js';\nimport loadingStates from './charts/helpers/load.js';\nimport tooltip from './charts/tooltip.js';\nimport miniTooltip from './charts/mini-tooltip.js';\nimport sparkline from './charts/sparkline.js';\nimport stackedArea from './charts/stacked-area.js';\nimport groupedBar from './charts/grouped-bar.js';\nimport stackedBar from './charts/stacked-bar.js';\nimport step from './charts/step.js';\nimport brush from './charts/brush.js';\nimport colors from './charts/helpers/color.js';\n\nexport {\n bar,\n donut,\n legend,\n line,\n loadingStates,\n tooltip,\n miniTooltip,\n sparkline,\n stackedArea,\n groupedBar,\n stackedBar,\n step,\n brush,\n colors\n };\n\n\n\n// WEBPACK FOOTER //\n// ./src/bundle.js","define(function(require) {\n 'use strict';\n\n const d3Array = require('d3-array');\n const d3Ease = require('d3-ease');\n const d3Axis = require('d3-axis');\n const d3Color = require('d3-color');\n const d3Dispatch = require('d3-dispatch');\n const d3Format = require('d3-format');\n const d3Scale = require('d3-scale');\n const d3Selection = require('d3-selection');\n const d3Transition = require('d3-transition');\n\n const textHelper = require('./helpers/text');\n const {exportChart} = require('./helpers/export');\n const colorHelper = require('./helpers/color');\n const {bar} = require('./helpers/load');\n\n const PERCENTAGE_FORMAT = '%';\n const NUMBER_FORMAT = ',f';\n\n\n /**\n * @typedef BarChartData\n * @type {Object[]}\n * @property {Number} value Value of the group (required)\n * @property {String} name Name of the group (required)\n *\n * @example\n * [\n * {\n * value: 1,\n * name: 'glittering'\n * },\n * {\n * value: 1,\n * name: 'luminous'\n * }\n * ]\n */\n\n /**\n * Bar Chart reusable API class that renders a\n * simple and configurable bar chart.\n *\n * @module Bar\n * @tutorial bar\n * @requires d3-array, d3-axis, d3-dispatch, d3-scale, d3-selection\n *\n * @example\n * var barChart = bar();\n *\n * barChart\n * .height(500)\n * .width(800);\n *\n * d3Selection.select('.css-selector')\n * .datum(dataset)\n * .call(barChart);\n *\n */\n return function module() {\n\n let margin = {\n top: 20,\n right: 20,\n bottom: 30,\n left: 40\n },\n width = 960,\n height = 500,\n loadingState = bar,\n data,\n dataZeroed,\n chartWidth, chartHeight,\n xScale, yScale,\n colorSchema = colorHelper.singleColors.aloeGreen,\n colorList,\n colorMap,\n yTicks = 5,\n xTicks = 5,\n percentageAxisToMaxRatio = 1,\n numberFormat = NUMBER_FORMAT,\n enableLabels = false,\n labelsMargin = 7,\n labelsNumberFormat = NUMBER_FORMAT,\n labelsSize = 12,\n betweenBarsPadding = 0.1,\n xAxis, yAxis,\n xAxisPadding = {\n top: 0,\n left: 0,\n bottom: 0,\n right: 0\n },\n yAxisPaddingBetweenChart = 10,\n yAxisLineWrapLimit = 1,\n isHorizontal = false,\n svg,\n\n hasSingleBarHighlight = true,\n isAnimated = false,\n ease = d3Ease.easeQuadInOut,\n animationDuration = 800,\n animationStepRatio = 70,\n interBarDelay = (d, i) => animationStepRatio * i,\n\n highlightBarFunction = (barSelection) => barSelection.attr('fill', ({name}) => d3Color.color(colorMap(name)).darker()),\n orderingFunction,\n\n valueLabel = 'value',\n nameLabel = 'name',\n labelEl,\n\n baseLine,\n maskGridLines,\n shouldReverseColorList = true,\n\n // Dispatcher object to broadcast the mouse events\n // Ref: https://github.com/mbostock/d3/wiki/Internals#d3_dispatch\n dispatcher = d3Dispatch.dispatch(\n 'customMouseOver',\n 'customMouseOut',\n 'customMouseMove',\n 'customClick'\n ),\n\n // extractors\n getName = ({name}) => name,\n getValue = ({value}) => value,\n\n _labelsFormatValue = ({value}) => d3Format.format(labelsNumberFormat)(value),\n\n _labelsHorizontalX = ({value}) => xScale(value) + labelsMargin,\n _labelsHorizontalY= ({name}) => yScale(name) + (yScale.bandwidth() / 2) + (labelsSize * (3/8)),\n\n _labelsVerticalX = ({name}) => xScale(name),\n _labelsVerticalY = ({value}) => yScale(value) - labelsMargin;\n\n /**\n * This function creates the graph using the selection as container\n * @param {D3Selection} _selection A d3 selection that represents\n * the container(s) where the chart(s) will be rendered\n * @param {BarChartData} _data The data to attach and generate the chart\n */\n function exports(_selection) {\n _selection.each(function(_data) {\n chartWidth = width - margin.left - margin.right - (yAxisPaddingBetweenChart * 1.2);\n chartHeight = height - margin.top - margin.bottom;\n ({data, dataZeroed} = sortData(cleanData(_data)));\n\n buildScales();\n buildAxis();\n buildSVG(this);\n drawGridLines();\n drawBars();\n drawAxis();\n if (enableLabels) {\n drawLabels();\n }\n });\n }\n\n /**\n * Creates the d3 x and y axis, setting orientations\n * @private\n */\n function buildAxis() {\n if (isHorizontal) {\n xAxis = d3Axis.axisBottom(xScale)\n .ticks(xTicks, numberFormat)\n .tickSizeInner([-chartHeight]);\n\n yAxis = d3Axis.axisLeft(yScale);\n } else {\n xAxis = d3Axis.axisBottom(xScale);\n\n yAxis = d3Axis.axisLeft(yScale)\n .ticks(yTicks, numberFormat)\n }\n }\n\n /**\n * Builds containers for the chart, the axis and a wrapper for all of them\n * Also applies the Margin convention\n * @private\n */\n function buildContainerGroups() {\n let container = svg\n .append('g')\n .classed('container-group', true)\n .attr('transform', `translate(${margin.left + yAxisPaddingBetweenChart}, ${margin.top})`);\n\n container\n .append('g').classed('grid-lines-group', true);\n container\n .append('g').classed('chart-group', true);\n container\n .append('g').classed('x-axis-group axis', true);\n container\n .append('g')\n .attr('transform', `translate(${-1 * (yAxisPaddingBetweenChart)}, 0)`)\n .classed('y-axis-group axis', true);\n container\n .append('g').classed('metadata-group', true);\n }\n\n /**\n * Creates the x and y scales of the graph\n * @private\n */\n function buildScales() {\n let percentageAxis = Math.min(percentageAxisToMaxRatio * d3Array.max(data, getValue))\n\n if (isHorizontal) {\n xScale = d3Scale.scaleLinear()\n .domain([0, percentageAxis])\n .rangeRound([0, chartWidth]);\n\n yScale = d3Scale.scaleBand()\n .domain(data.map(getName))\n .rangeRound([chartHeight, 0])\n .padding(betweenBarsPadding);\n } else {\n xScale = d3Scale.scaleBand()\n .domain(data.map(getName))\n .rangeRound([0, chartWidth])\n .padding(betweenBarsPadding);\n\n yScale = d3Scale.scaleLinear()\n .domain([0, percentageAxis])\n .rangeRound([chartHeight, 0]);\n }\n\n if (shouldReverseColorList) {\n colorList = data.map(d => d)\n .reverse()\n .map(({name}, i) => ({\n name,\n color: colorSchema[i % colorSchema.length]}\n ));\n } else {\n colorList = data.map(d => d)\n .map(({name}, i) => ({\n name,\n color: colorSchema[i % colorSchema.length]}\n ));\n }\n\n colorMap = (item) => colorList.filter(({name}) => name === item)[0].color;\n }\n\n /**\n * Builds the SVG element that will contain the chart\n * @param {HTMLElement} container DOM element that will work as the container of the graph\n * @private\n */\n function buildSVG(container) {\n if (!svg) {\n svg = d3Selection.select(container)\n .append('svg')\n .classed('britechart bar-chart', true);\n\n buildContainerGroups();\n }\n\n svg\n .attr('width', width)\n .attr('height', height);\n }\n\n /**\n * Cleaning data casting the values and names to the proper type while keeping\n * the rest of properties on the data\n * It also creates a set of zeroed data (for animation purposes)\n * @param {BarChartData} originalData Raw data as passed to the container\n * @return {BarChartData} Clean data\n * @private\n */\n function cleanData(originalData) {\n let data = originalData.reduce((acc, d) => {\n d.value = +d[valueLabel];\n d.name = String(d[nameLabel]);\n\n return [...acc, d];\n }, []);\n\n let dataZeroed = data.map((d) => ({\n value: 0,\n name: String(d[nameLabel])\n }));\n\n return { data, dataZeroed };\n }\n\n /**\n * Sorts data if orderingFunction is specified\n * @param {BarChartData} clean unordered data\n * @return {BarChartData} clean ordered data\n * @private\n */\n function sortData(unorderedData) {\n let {data, dataZeroed} = unorderedData;\n\n if (orderingFunction) {\n data.sort(orderingFunction);\n dataZeroed.sort(orderingFunction)\n }\n\n return { data, dataZeroed };\n }\n\n /**\n * Utility function that wraps a text into the given width\n * @param {D3Selection} text Text to write\n * @param {Number} containerWidth\n * @private\n */\n function wrapText(text, containerWidth) {\n textHelper.wrapTextWithEllipses(text, containerWidth, 0, yAxisLineWrapLimit)\n }\n\n /**\n * Draws the x and y axis on the svg object within their\n * respective groups\n * @private\n */\n function drawAxis() {\n svg.select('.x-axis-group.axis')\n .attr('transform', `translate(0, ${chartHeight})`)\n .call(xAxis);\n\n svg.select('.y-axis-group.axis')\n .call(yAxis);\n\n svg.selectAll('.y-axis-group .tick text')\n .call(wrapText, margin.left - yAxisPaddingBetweenChart)\n }\n\n /**\n * Draws the bars along the x axis\n * @param {D3Selection} bars Selection of bars\n * @return {void}\n */\n function drawHorizontalBars(bars) {\n // Enter + Update\n bars.enter()\n .append('rect')\n .classed('bar', true)\n .attr('y', chartHeight)\n .attr('x', 0)\n .attr('height', yScale.bandwidth())\n .attr('width', ({value}) => xScale(value))\n .on('mouseover', function(d, index, barList) {\n handleMouseOver(this, d, barList, chartWidth, chartHeight);\n })\n .on('mousemove', function(d) {\n handleMouseMove(this, d, chartWidth, chartHeight);\n })\n .on('mouseout', function(d, index, barList) {\n handleMouseOut(this, d, barList, chartWidth, chartHeight);\n })\n .on('click', function(d) {\n handleClick(this, d, chartWidth, chartHeight);\n })\n .merge(bars)\n .attr('x', 0)\n .attr('y', ({name}) => yScale(name))\n .attr('height', yScale.bandwidth())\n .attr('width', ({value}) => xScale(value))\n .attr('fill', ({name}) => colorMap(name));\n }\n\n /**\n * Draws and animates the bars along the x axis\n * @param {D3Selection} bars Selection of bars\n * @return {void}\n */\n function drawAnimatedHorizontalBars(bars) {\n // Enter + Update\n bars.enter()\n .append('rect')\n .classed('bar', true)\n .attr('x', 0)\n .attr('y', chartHeight)\n .attr('height', yScale.bandwidth())\n .attr('width', ({value}) => xScale(value))\n .on('mouseover', function(d, index, barList) {\n handleMouseOver(this, d, barList, chartWidth, chartHeight);\n })\n .on('mousemove', function(d) {\n handleMouseMove(this, d, chartWidth, chartHeight);\n })\n .on('mouseout', function(d, index, barList) {\n handleMouseOut(this, d, barList, chartWidth, chartHeight);\n })\n .on('click', function(d) {\n handleClick(this, d, chartWidth, chartHeight);\n });\n\n bars\n .attr('x', 0)\n .attr('y', ({name}) => yScale(name))\n .attr('height', yScale.bandwidth())\n .attr('fill', ({name}) => colorMap(name))\n .transition()\n .duration(animationDuration)\n .delay(interBarDelay)\n .ease(ease)\n .attr('width', ({value}) => xScale(value));\n }\n\n /**\n * Draws and animates the bars along the y axis\n * @param {D3Selection} bars Selection of bars\n * @return {void}\n */\n function drawAnimatedVerticalBars(bars) {\n // Enter + Update\n bars.enter()\n .append('rect')\n .classed('bar', true)\n .attr('x', chartWidth)\n .attr('y', ({value}) => yScale(value))\n .attr('width', xScale.bandwidth())\n .attr('height', ({value}) => chartHeight - yScale(value))\n .on('mouseover', function(d, index, barList) {\n handleMouseOver(this, d, barList, chartWidth, chartHeight);\n })\n .on('mousemove', function(d) {\n handleMouseMove(this, d, chartWidth, chartHeight);\n })\n .on('mouseout', function(d, index, barList) {\n handleMouseOut(this, d, barList, chartWidth, chartHeight);\n })\n .on('click', function(d) {\n handleClick(this, d, chartWidth, chartHeight);\n })\n .merge(bars)\n .attr('x', ({name}) => xScale(name))\n .attr('width', xScale.bandwidth())\n .attr('fill', ({name}) => colorMap(name))\n .transition()\n .duration(animationDuration)\n .delay(interBarDelay)\n .ease(ease)\n .attr('y', ({value}) => yScale(value))\n .attr('height', ({value}) => chartHeight - yScale(value));\n }\n\n /**\n * Draws the bars along the y axis\n * @param {D3Selection} bars Selection of bars\n * @return {void}\n */\n function drawVerticalBars(bars) {\n // Enter + Update\n bars.enter()\n .append('rect')\n .classed('bar', true)\n .attr('x', chartWidth)\n .attr('y', ({value}) => yScale(value))\n .attr('width', xScale.bandwidth())\n .attr('height', ({value}) => chartHeight - yScale(value))\n .on('mouseover', function(d, index, barList) {\n handleMouseOver(this, d, barList, chartWidth, chartHeight);\n })\n .on('mousemove', function(d) {\n handleMouseMove(this, d, chartWidth, chartHeight);\n })\n .on('mouseout', function(d, index, barList) {\n handleMouseOut(this, d, barList, chartWidth, chartHeight);\n })\n .on('click', function(d) {\n handleClick(this, d, chartWidth, chartHeight);\n })\n .merge(bars)\n .attr('x', ({name}) => xScale(name))\n .attr('y', ({value}) => yScale(value))\n .attr('width', xScale.bandwidth())\n .attr('height', ({value}) => chartHeight - yScale(value))\n .attr('fill', ({name}) => colorMap(name));\n }\n\n /**\n * Draws labels at the end of each bar\n * @private\n * @return {void}\n */\n function drawLabels() {\n let labelXPosition = isHorizontal ? _labelsHorizontalX : _labelsVerticalX;\n let labelYPosition = isHorizontal ? _labelsHorizontalY : _labelsVerticalY;\n let text = _labelsFormatValue\n\n if (labelEl) {\n svg.selectAll('.percentage-label-group').remove();\n }\n\n labelEl = svg.select('.metadata-group')\n .append('g')\n .classed('percentage-label-group', true)\n .selectAll('text')\n .data(data.reverse())\n .enter()\n .append('text');\n\n labelEl\n .classed('percentage-label', true)\n .attr('x', labelXPosition)\n .attr('y', labelYPosition)\n .text(text)\n .attr('font-size', labelsSize + 'px')\n }\n\n /**\n * Draws the bar elements within the chart group\n * @private\n */\n function drawBars() {\n let bars;\n\n if (isAnimated) {\n bars = svg.select('.chart-group').selectAll('.bar')\n .data(dataZeroed);\n\n if (isHorizontal) {\n drawHorizontalBars(bars);\n } else {\n drawVerticalBars(bars);\n }\n\n bars = svg.select('.chart-group').selectAll('.bar')\n .data(data);\n\n if (isHorizontal) {\n drawAnimatedHorizontalBars(bars);\n } else {\n drawAnimatedVerticalBars(bars);\n }\n } else {\n bars = svg.select('.chart-group').selectAll('.bar')\n .data(data);\n\n if (isHorizontal) {\n drawHorizontalBars(bars);\n } else {\n drawVerticalBars(bars);\n }\n }\n\n // Exit\n bars.exit()\n .transition()\n .style('opacity', 0)\n .remove();\n }\n\n /**\n * Draws grid lines on the background of the chart\n * @return void\n */\n function drawGridLines() {\n svg.select('.grid-lines-group')\n .selectAll('line')\n .remove();\n\n if (isHorizontal) {\n drawHorizontalGridLines();\n } else {\n drawVerticalGridLines();\n }\n }\n\n /**\n * Draws the grid lines for an horizontal bar chart\n * @return {void}\n */\n function drawHorizontalGridLines() {\n maskGridLines = svg.select('.grid-lines-group')\n .selectAll('line.vertical-grid-line')\n .data(xScale.ticks(4))\n .enter()\n .append('line')\n .attr('class', 'vertical-grid-line')\n .attr('y1', (xAxisPadding.left))\n .attr('y2', chartHeight)\n .attr('x1', (d) => xScale(d))\n .attr('x2', (d) => xScale(d))\n\n drawVerticalExtendedLine();\n }\n\n /**\n * Draws a vertical line to extend y-axis till the edges\n * @return {void}\n */\n function drawVerticalExtendedLine() {\n baseLine = svg.select('.grid-lines-group')\n .selectAll('line.extended-y-line')\n .data([0])\n .enter()\n .append('line')\n .attr('class', 'extended-y-line')\n .attr('y1', (xAxisPadding.bottom))\n .attr('y2', chartHeight)\n .attr('x1', 0)\n .attr('x2', 0);\n }\n\n /**\n * Draws the grid lines for a vertical bar chart\n * @return {void}\n */\n function drawVerticalGridLines() {\n maskGridLines = svg.select('.grid-lines-group')\n .selectAll('line.horizontal-grid-line')\n .data(yScale.ticks(4))\n .enter()\n .append('line')\n .attr('class', 'horizontal-grid-line')\n .attr('x1', (xAxisPadding.left))\n .attr('x2', chartWidth)\n .attr('y1', (d) => yScale(d))\n .attr('y2', (d) => yScale(d))\n\n drawHorizontalExtendedLine();\n }\n\n /**\n * Draws a vertical line to extend x-axis till the edges\n * @return {void}\n */\n function drawHorizontalExtendedLine() {\n baseLine = svg.select('.grid-lines-group')\n .selectAll('line.extended-x-line')\n .data([0])\n .enter()\n .append('line')\n .attr('class', 'extended-x-line')\n .attr('x1', (xAxisPadding.left))\n .attr('x2', chartWidth)\n .attr('y1', chartHeight)\n .attr('y2', chartHeight);\n }\n\n /**\n * Custom OnMouseOver event handler\n * @return {void}\n * @private\n */\n function handleMouseOver(e, d, barList, chartWidth, chartHeight) {\n dispatcher.call('customMouseOver', e, d, d3Selection.mouse(e), [chartWidth, chartHeight]);\n highlightBarFunction = highlightBarFunction || function() {};\n\n if (hasSingleBarHighlight) {\n highlightBarFunction(d3Selection.select(e));\n return;\n }\n\n barList.forEach(barRect => {\n if (barRect === e) {\n return;\n }\n highlightBarFunction(d3Selection.select(barRect));\n });\n }\n\n /**\n * Custom OnMouseMove event handler\n * @return {void}\n * @private\n */\n function handleMouseMove(e, d, chartWidth, chartHeight) {\n dispatcher.call('customMouseMove', e, d, d3Selection.mouse(e), [chartWidth, chartHeight]);\n }\n\n /**\n * Custom OnMouseOver event handler\n * @return {void}\n * @private\n */\n function handleMouseOut(e, d, barList, chartWidth, chartHeight) {\n dispatcher.call('customMouseOut', e, d, d3Selection.mouse(e), [chartWidth, chartHeight]);\n\n barList.forEach((barRect) => {\n d3Selection.select(barRect).attr('fill', ({name}) => colorMap(name));\n });\n }\n\n /**\n * Custom onClick event handler\n * @return {void}\n * @private\n */\n function handleClick(e, d, chartWidth, chartHeight) {\n dispatcher.call('customClick', e, d, d3Selection.mouse(e), [chartWidth, chartHeight]);\n }\n\n // API\n\n /**\n * Gets or Sets the padding of the chart (Default is 0.1)\n * @param { Number | module } _x Padding value to get/set\n * @return { padding | module} Current padding or Chart module to chain calls\n * @public\n */\n exports.betweenBarsPadding = function(_x) {\n if (!arguments.length) {\n return betweenBarsPadding;\n }\n betweenBarsPadding = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the colorSchema of the chart\n * @param {String[]} _x Desired colorSchema for the graph\n * @return { colorSchema | module} Current colorSchema or Chart module to chain calls\n * @public\n */\n exports.colorSchema = function(_x) {\n if (!arguments.length) {\n return colorSchema;\n }\n colorSchema = _x;\n\n return this;\n };\n\n /**\n * If true, adds labels at the end of the bars\n * @param {Boolean} [_x=false]\n * @return {Boolean | module} Current value of enableLabels or Chart module to chain calls\n * @public\n */\n exports.enableLabels = function(_x) {\n if (!arguments.length) {\n return enableLabels;\n }\n enableLabels = _x;\n\n return this;\n };\n\n /**\n * Chart exported to png and a download action is fired\n * @param {String} filename File title for the resulting picture\n * @param {String} title Title to add at the top of the exported picture\n * @public\n */\n exports.exportChart = function(filename, title) {\n exportChart.call(exports, svg, filename, title);\n };\n\n /**\n * Gets or Sets the hasPercentage status\n * @param {boolean} _x Should use percentage as value format\n * @return {boolean | module} Is percentage used or Chart module to chain calls\n * @public\n */\n exports.hasPercentage = function(_x) {\n if (!arguments.length) {\n return numberFormat === PERCENTAGE_FORMAT;\n }\n if (_x) {\n numberFormat = PERCENTAGE_FORMAT;\n } else {\n numberFormat = NUMBER_FORMAT;\n }\n\n return this;\n };\n\n /**\n * Gets or Sets the hasSingleBarHighlight status.\n * If the value is true (default), only the hovered bar is considered to\n * be highlighted and will be darkened by default. If the value is false,\n * all the bars but the hovered bar are considered to be highlighted\n * and will be darkened (by default). To customize the bar highlight or\n * remove it completely, use highlightBarFunction instead.\n * @param {boolean} _x Should highlight the hovered bar\n * @return {boolean | module} Is hasSingleBarHighlight used or Chart module to chain calls\n * @public\n */\n exports.hasSingleBarHighlight = function(_x) {\n if (!arguments.length) {\n return hasSingleBarHighlight;\n }\n hasSingleBarHighlight = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets the height of the chart\n * @param {number} _x Desired width for the graph\n * @return {height | module} Current height or Chart module to chain calls\n * @public\n */\n exports.height = function(_x) {\n if (!arguments.length) {\n return height;\n }\n height = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the highlightBarFunction function. The callback passed to\n * this function returns a bar selection from the bar chart. Use this function\n * if you want to apply a custom behavior to the highlighted bar on hover.\n * When hasSingleBarHighlight is true the highlighted bar will be the\n * one that was hovered by the user. When hasSingleBarHighlight is false\n * the highlighted bars are all the bars but the hovered one. The default\n * highlight effect on a bar is darkening the highlighted bar(s) color.\n * @param {Function} _x Desired operation operation on a hovered bar passed through callback\n * @return {highlightBarFunction | module} Is highlightBarFunction used or Chart module to chain calls\n * @public\n * @example barChart.highlightBarFunction(bar => bar.attr('fill', 'blue'))\n * barChart.highlightBarFunction(null) // will disable the default highlight effect\n */\n exports.highlightBarFunction = function(_x) {\n if (!arguments.length) {\n return highlightBarFunction;\n }\n highlightBarFunction = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets the isAnimated property of the chart, making it to animate when render.\n * By default this is 'false'\n *\n * @param {Boolean} _x Desired animation flag\n * @return {isAnimated | module} Current isAnimated flag or Chart module\n * @public\n */\n exports.isAnimated = function(_x) {\n if (!arguments.length) {\n return isAnimated;\n }\n isAnimated = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the horizontal direction of the chart\n * @param {number} _x Desired horizontal direction for the graph\n * @return { isHorizontal | module} If it is horizontal or Chart module to chain calls\n * @public\n */\n exports.isHorizontal = function(_x) {\n if (!arguments.length) {\n return isHorizontal;\n }\n isHorizontal = _x;\n\n return this;\n };\n\n /**\n * Offset between end of bar and start of the percentage bars\n * @param {number} [_x=7] margin offset from end of bar\n * @return {number | module} Current offset or Chart module to chain calls\n * @public\n */\n exports.labelsMargin = function(_x) {\n if (!arguments.length) {\n return labelsMargin;\n }\n labelsMargin = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets the labels number format\n * @param {string} [_x=\",f\"] desired label number format for the bar chart\n * @return {string | module} Current labelsNumberFormat or Chart module to chain calls\n * @public\n */\n exports.labelsNumberFormat = function(_x) {\n if (!arguments.length) {\n return labelsNumberFormat;\n }\n labelsNumberFormat = _x;\n\n return this;\n }\n\n /**\n * Get or Sets the labels text size\n * @param {number} [_x=12] label font size\n * @return {number | module} Current text size or Chart module to chain calls\n * @public\n */\n exports.labelsSize = function(_x) {\n if (!arguments.length) {\n return labelsSize;\n }\n labelsSize = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets the loading state of the chart\n * @param {string} markup Desired markup to show when null data\n * @return {loadingState | module} Current loading state markup or Chart module to chain calls\n * @public\n */\n exports.loadingState = function(_markup) {\n if (!arguments.length) {\n return loadingState;\n }\n loadingState = _markup;\n\n return this;\n };\n\n /**\n * Gets or Sets the margin of the chart\n * @param {object} _x Margin object to get/set\n * @return {margin | module} Current margin or Chart module to chain calls\n * @public\n */\n exports.margin = function(_x) {\n if (!arguments.length) {\n return margin;\n }\n margin = {\n ...margin,\n ..._x\n };\n\n return this;\n };\n\n /**\n * Gets or Sets the nameLabel of the chart\n * @param {Number} _x Desired nameLabel for the graph\n * @return {nameLabel | module} Current nameLabel or Chart module to chain calls\n * @public\n */\n exports.nameLabel = function(_x) {\n if (!arguments.length) {\n return nameLabel;\n }\n nameLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the number format of the bar chart\n * @param {string} _x Desired number format for the bar chart\n * @return {numberFormat | module} Current numberFormat or Chart module to chain calls\n * @public\n */\n exports.numberFormat = function(_x) {\n if (!arguments.length) {\n return numberFormat;\n }\n numberFormat = _x;\n\n return this;\n }\n\n /**\n * Exposes an 'on' method that acts as a bridge with the event dispatcher\n * We are going to expose this events:\n * customMouseOver, customMouseMove, customMouseOut, and customClick\n *\n * @return {module} Bar Chart\n * @public\n */\n exports.on = function() {\n let value = dispatcher.on.apply(dispatcher, arguments);\n\n return value === dispatcher ? exports : value;\n };\n\n /**\n * Configurable extension of the x axis\n * if your max point was 50% you might want to show x axis to 60%, pass 1.2\n * @param {number} _x ratio to max data point to add to the x axis\n * @return {ratio | module} Current ratio or Chart module to chain calls\n * @public\n */\n exports.percentageAxisToMaxRatio = function(_x) {\n if (!arguments.length) {\n return percentageAxisToMaxRatio;\n }\n percentageAxisToMaxRatio = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets whether the color list should be reversed or not\n * @param {boolean} _x Should reverse the color list\n * @return {boolean | module} Is color list being reversed or Chart module to chain calls\n * @public\n */\n exports.shouldReverseColorList = function(_x) {\n if (!arguments.length) {\n return shouldReverseColorList;\n }\n shouldReverseColorList = _x;\n\n return this;\n };\n\n\n /**\n * Changes the order of items given the custom function\n * @param {Function} _x A custom function that sets logic for ordering\n * @return {(Function | Module)} A custom ordering function or Chart module to chain calls\n * @public\n */\n exports.orderingFunction = function(_x) {\n if (!arguments.length) {\n return orderingFunction;\n }\n orderingFunction = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets the valueLabel of the chart\n * @param {Number} _x Desired valueLabel for the graph\n * @return { valueLabel | module} Current valueLabel or Chart module to chain calls\n * @public\n */\n exports.valueLabel = function(_x) {\n if (!arguments.length) {\n return valueLabel;\n }\n valueLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the width of the chart\n * @param {number} _x Desired width for the graph\n * @return {width | module} Current width or Chart module to chain calls\n * @public\n */\n exports.width = function(_x) {\n if (!arguments.length) {\n return width;\n }\n width = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the number of ticks of the x axis on the chart\n * (Default is 5)\n * @param {Number} _x Desired horizontal ticks\n * @return {Number | module} Current xTicks or Chart module to chain calls\n * @public\n */\n exports.xTicks = function (_x) {\n if (!arguments.length) {\n return xTicks;\n }\n xTicks = _x;\n\n return this;\n };\n\n /**\n * Space between y axis and chart\n * (Default 10)\n * @param {Number} _x Space between y axis and chart\n * @return {Number| module} Current value of yAxisPaddingBetweenChart or Chart module to chain calls\n * @public\n */\n exports.yAxisPaddingBetweenChart = function(_x) {\n if (!arguments.length) {\n return yAxisPaddingBetweenChart;\n }\n yAxisPaddingBetweenChart = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the number of vertical ticks on the chart\n * (Default is 6)\n * @param {Number} _x Desired number of vertical ticks for the graph\n * @return {Number | module} Current yTicks or Chart module to chain calls\n * @public\n */\n exports.yTicks = function(_x) {\n if (!arguments.length) {\n return yTicks;\n }\n yTicks = _x;\n\n return this;\n };\n\n return exports;\n };\n\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/bar.js","import {pair} from \"./pairs\";\n\nexport default function(values0, values1, reduce) {\n var n0 = values0.length,\n n1 = values1.length,\n values = new Array(n0 * n1),\n i0,\n i1,\n i,\n value0;\n\n if (reduce == null) reduce = pair;\n\n for (i0 = i = 0; i0 < n0; ++i0) {\n for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) {\n values[i] = reduce(value0, values1[i1]);\n }\n }\n\n return values;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/cross.js\n// module id = 125\n// module chunks = 0","export default function(a, b) {\n return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/descending.js\n// module id = 126\n// module chunks = 0","import {slice} from \"./array\";\nimport bisect from \"./bisect\";\nimport constant from \"./constant\";\nimport extent from \"./extent\";\nimport identity from \"./identity\";\nimport range from \"./range\";\nimport {tickStep} from \"./ticks\";\nimport sturges from \"./threshold/sturges\";\n\nexport default function() {\n var value = identity,\n domain = extent,\n threshold = sturges;\n\n function histogram(data) {\n var i,\n n = data.length,\n x,\n values = new Array(n);\n\n for (i = 0; i < n; ++i) {\n values[i] = value(data[i], i, data);\n }\n\n var xz = domain(values),\n x0 = xz[0],\n x1 = xz[1],\n tz = threshold(values, x0, x1);\n\n // Convert number of thresholds into uniform thresholds.\n if (!Array.isArray(tz)) {\n tz = tickStep(x0, x1, tz);\n tz = range(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive\n }\n\n // Remove any thresholds outside the domain.\n var m = tz.length;\n while (tz[0] <= x0) tz.shift(), --m;\n while (tz[m - 1] > x1) tz.pop(), --m;\n\n var bins = new Array(m + 1),\n bin;\n\n // Initialize bins.\n for (i = 0; i <= m; ++i) {\n bin = bins[i] = [];\n bin.x0 = i > 0 ? tz[i - 1] : x0;\n bin.x1 = i < m ? tz[i] : x1;\n }\n\n // Assign data to bins by value, ignoring any outside the domain.\n for (i = 0; i < n; ++i) {\n x = values[i];\n if (x0 <= x && x <= x1) {\n bins[bisect(tz, x, 0, m)].push(data[i]);\n }\n }\n\n return bins;\n }\n\n histogram.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : constant(_), histogram) : value;\n };\n\n histogram.domain = function(_) {\n return arguments.length ? (domain = typeof _ === \"function\" ? _ : constant([_[0], _[1]]), histogram) : domain;\n };\n\n histogram.thresholds = function(_) {\n return arguments.length ? (threshold = typeof _ === \"function\" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold;\n };\n\n return histogram;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/histogram.js\n// module id = 127\n// module chunks = 0","export default function(x) {\n return function() {\n return x;\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/constant.js\n// module id = 128\n// module chunks = 0","export default function(x) {\n return x;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/identity.js\n// module id = 129\n// module chunks = 0","import {map} from \"../array\";\nimport ascending from \"../ascending\";\nimport number from \"../number\";\nimport quantile from \"../quantile\";\n\nexport default function(values, min, max) {\n values = map.call(values, number).sort(ascending);\n return Math.ceil((max - min) / (2 * (quantile(values, 0.75) - quantile(values, 0.25)) * Math.pow(values.length, -1 / 3)));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/threshold/freedmanDiaconis.js\n// module id = 130\n// module chunks = 0","import deviation from \"../deviation\";\n\nexport default function(values, min, max) {\n return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/threshold/scott.js\n// module id = 131\n// module chunks = 0","export default function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n max;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null && value > max) {\n max = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null && value > max) {\n max = value;\n }\n }\n }\n }\n }\n\n return max;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/max.js\n// module id = 132\n// module chunks = 0","import number from \"./number\";\n\nexport default function(values, valueof) {\n var n = values.length,\n m = n,\n i = -1,\n value,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) sum += value;\n else --m;\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value;\n else --m;\n }\n }\n\n if (m) return sum / m;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/mean.js\n// module id = 133\n// module chunks = 0","import ascending from \"./ascending\";\nimport number from \"./number\";\nimport quantile from \"./quantile\";\n\nexport default function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n numbers = [];\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) {\n numbers.push(value);\n }\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) {\n numbers.push(value);\n }\n }\n }\n\n return quantile(numbers.sort(ascending), 0.5);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/median.js\n// module id = 134\n// module chunks = 0","export default function(arrays) {\n var n = arrays.length,\n m,\n i = -1,\n j = 0,\n merged,\n array;\n\n while (++i < n) j += arrays[i].length;\n merged = new Array(j);\n\n while (--n >= 0) {\n array = arrays[n];\n m = array.length;\n while (--m >= 0) {\n merged[--j] = array[m];\n }\n }\n\n return merged;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/merge.js\n// module id = 135\n// module chunks = 0","export default function(array, indexes) {\n var i = indexes.length, permutes = new Array(i);\n while (i--) permutes[i] = array[indexes[i]];\n return permutes;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/permute.js\n// module id = 136\n// module chunks = 0","import ascending from \"./ascending\";\n\nexport default function(values, compare) {\n if (!(n = values.length)) return;\n var n,\n i = 0,\n j = 0,\n xi,\n xj = values[j];\n\n if (compare == null) compare = ascending;\n\n while (++i < n) {\n if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) {\n xj = xi, j = i;\n }\n }\n\n if (compare(xj, xj) === 0) return j;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/scan.js\n// module id = 137\n// module chunks = 0","export default function(array, i0, i1) {\n var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),\n t,\n i;\n\n while (m) {\n i = Math.random() * m-- | 0;\n t = array[m + i0];\n array[m + i0] = array[i + i0];\n array[i + i0] = t;\n }\n\n return array;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/shuffle.js\n// module id = 138\n// module chunks = 0","export default function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (value = +values[i]) sum += value; // Note: zero and null are equivalent.\n }\n }\n\n else {\n while (++i < n) {\n if (value = +valueof(values[i], i, values)) sum += value;\n }\n }\n\n return sum;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/sum.js\n// module id = 139\n// module chunks = 0","import transpose from \"./transpose\";\n\nexport default function() {\n return transpose(arguments);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-array/src/zip.js\n// module id = 140\n// module chunks = 0","export function linear(t) {\n return +t;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-ease/src/linear.js\n// module id = 141\n// module chunks = 0","export function quadIn(t) {\n return t * t;\n}\n\nexport function quadOut(t) {\n return t * (2 - t);\n}\n\nexport function quadInOut(t) {\n return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-ease/src/quad.js\n// module id = 142\n// module chunks = 0","export function cubicIn(t) {\n return t * t * t;\n}\n\nexport function cubicOut(t) {\n return --t * t * t + 1;\n}\n\nexport function cubicInOut(t) {\n return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-ease/src/cubic.js\n// module id = 143\n// module chunks = 0","var exponent = 3;\n\nexport var polyIn = (function custom(e) {\n e = +e;\n\n function polyIn(t) {\n return Math.pow(t, e);\n }\n\n polyIn.exponent = custom;\n\n return polyIn;\n})(exponent);\n\nexport var polyOut = (function custom(e) {\n e = +e;\n\n function polyOut(t) {\n return 1 - Math.pow(1 - t, e);\n }\n\n polyOut.exponent = custom;\n\n return polyOut;\n})(exponent);\n\nexport var polyInOut = (function custom(e) {\n e = +e;\n\n function polyInOut(t) {\n return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;\n }\n\n polyInOut.exponent = custom;\n\n return polyInOut;\n})(exponent);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-ease/src/poly.js\n// module id = 144\n// module chunks = 0","var pi = Math.PI,\n halfPi = pi / 2;\n\nexport function sinIn(t) {\n return 1 - Math.cos(t * halfPi);\n}\n\nexport function sinOut(t) {\n return Math.sin(t * halfPi);\n}\n\nexport function sinInOut(t) {\n return (1 - Math.cos(pi * t)) / 2;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-ease/src/sin.js\n// module id = 145\n// module chunks = 0","export function expIn(t) {\n return Math.pow(2, 10 * t - 10);\n}\n\nexport function expOut(t) {\n return 1 - Math.pow(2, -10 * t);\n}\n\nexport function expInOut(t) {\n return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-ease/src/exp.js\n// module id = 146\n// module chunks = 0","export function circleIn(t) {\n return 1 - Math.sqrt(1 - t * t);\n}\n\nexport function circleOut(t) {\n return Math.sqrt(1 - --t * t);\n}\n\nexport function circleInOut(t) {\n return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-ease/src/circle.js\n// module id = 147\n// module chunks = 0","var b1 = 4 / 11,\n b2 = 6 / 11,\n b3 = 8 / 11,\n b4 = 3 / 4,\n b5 = 9 / 11,\n b6 = 10 / 11,\n b7 = 15 / 16,\n b8 = 21 / 22,\n b9 = 63 / 64,\n b0 = 1 / b1 / b1;\n\nexport function bounceIn(t) {\n return 1 - bounceOut(1 - t);\n}\n\nexport function bounceOut(t) {\n return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9;\n}\n\nexport function bounceInOut(t) {\n return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-ease/src/bounce.js\n// module id = 148\n// module chunks = 0","var overshoot = 1.70158;\n\nexport var backIn = (function custom(s) {\n s = +s;\n\n function backIn(t) {\n return t * t * ((s + 1) * t - s);\n }\n\n backIn.overshoot = custom;\n\n return backIn;\n})(overshoot);\n\nexport var backOut = (function custom(s) {\n s = +s;\n\n function backOut(t) {\n return --t * t * ((s + 1) * t + s) + 1;\n }\n\n backOut.overshoot = custom;\n\n return backOut;\n})(overshoot);\n\nexport var backInOut = (function custom(s) {\n s = +s;\n\n function backInOut(t) {\n return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;\n }\n\n backInOut.overshoot = custom;\n\n return backInOut;\n})(overshoot);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-ease/src/back.js\n// module id = 149\n// module chunks = 0","var tau = 2 * Math.PI,\n amplitude = 1,\n period = 0.3;\n\nexport var elasticIn = (function custom(a, p) {\n var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);\n\n function elasticIn(t) {\n return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);\n }\n\n elasticIn.amplitude = function(a) { return custom(a, p * tau); };\n elasticIn.period = function(p) { return custom(a, p); };\n\n return elasticIn;\n})(amplitude, period);\n\nexport var elasticOut = (function custom(a, p) {\n var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);\n\n function elasticOut(t) {\n return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p);\n }\n\n elasticOut.amplitude = function(a) { return custom(a, p * tau); };\n elasticOut.period = function(p) { return custom(a, p); };\n\n return elasticOut;\n})(amplitude, period);\n\nexport var elasticInOut = (function custom(a, p) {\n var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);\n\n function elasticInOut(t) {\n return ((t = t * 2 - 1) < 0\n ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)\n : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;\n }\n\n elasticInOut.amplitude = function(a) { return custom(a, p * tau); };\n elasticInOut.period = function(p) { return custom(a, p); };\n\n return elasticInOut;\n})(amplitude, period);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-ease/src/elastic.js\n// module id = 150\n// module chunks = 0","import {slice} from \"./array\";\nimport identity from \"./identity\";\n\nvar top = 1,\n right = 2,\n bottom = 3,\n left = 4,\n epsilon = 1e-6;\n\nfunction translateX(x) {\n return \"translate(\" + (x + 0.5) + \",0)\";\n}\n\nfunction translateY(y) {\n return \"translate(0,\" + (y + 0.5) + \")\";\n}\n\nfunction number(scale) {\n return function(d) {\n return +scale(d);\n };\n}\n\nfunction center(scale) {\n var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset.\n if (scale.round()) offset = Math.round(offset);\n return function(d) {\n return +scale(d) + offset;\n };\n}\n\nfunction entering() {\n return !this.__axis;\n}\n\nfunction axis(orient, scale) {\n var tickArguments = [],\n tickValues = null,\n tickFormat = null,\n tickSizeInner = 6,\n tickSizeOuter = 6,\n tickPadding = 3,\n k = orient === top || orient === left ? -1 : 1,\n x = orient === left || orient === right ? \"x\" : \"y\",\n transform = orient === top || orient === bottom ? translateX : translateY;\n\n function axis(context) {\n var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,\n format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity) : tickFormat,\n spacing = Math.max(tickSizeInner, 0) + tickPadding,\n range = scale.range(),\n range0 = +range[0] + 0.5,\n range1 = +range[range.length - 1] + 0.5,\n position = (scale.bandwidth ? center : number)(scale.copy()),\n selection = context.selection ? context.selection() : context,\n path = selection.selectAll(\".domain\").data([null]),\n tick = selection.selectAll(\".tick\").data(values, scale).order(),\n tickExit = tick.exit(),\n tickEnter = tick.enter().append(\"g\").attr(\"class\", \"tick\"),\n line = tick.select(\"line\"),\n text = tick.select(\"text\");\n\n path = path.merge(path.enter().insert(\"path\", \".tick\")\n .attr(\"class\", \"domain\")\n .attr(\"stroke\", \"#000\"));\n\n tick = tick.merge(tickEnter);\n\n line = line.merge(tickEnter.append(\"line\")\n .attr(\"stroke\", \"#000\")\n .attr(x + \"2\", k * tickSizeInner));\n\n text = text.merge(tickEnter.append(\"text\")\n .attr(\"fill\", \"#000\")\n .attr(x, k * spacing)\n .attr(\"dy\", orient === top ? \"0em\" : orient === bottom ? \"0.71em\" : \"0.32em\"));\n\n if (context !== selection) {\n path = path.transition(context);\n tick = tick.transition(context);\n line = line.transition(context);\n text = text.transition(context);\n\n tickExit = tickExit.transition(context)\n .attr(\"opacity\", epsilon)\n .attr(\"transform\", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute(\"transform\"); });\n\n tickEnter\n .attr(\"opacity\", epsilon)\n .attr(\"transform\", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); });\n }\n\n tickExit.remove();\n\n path\n .attr(\"d\", orient === left || orient == right\n ? \"M\" + k * tickSizeOuter + \",\" + range0 + \"H0.5V\" + range1 + \"H\" + k * tickSizeOuter\n : \"M\" + range0 + \",\" + k * tickSizeOuter + \"V0.5H\" + range1 + \"V\" + k * tickSizeOuter);\n\n tick\n .attr(\"opacity\", 1)\n .attr(\"transform\", function(d) { return transform(position(d)); });\n\n line\n .attr(x + \"2\", k * tickSizeInner);\n\n text\n .attr(x, k * spacing)\n .text(format);\n\n selection.filter(entering)\n .attr(\"fill\", \"none\")\n .attr(\"font-size\", 10)\n .attr(\"font-family\", \"sans-serif\")\n .attr(\"text-anchor\", orient === right ? \"start\" : orient === left ? \"end\" : \"middle\");\n\n selection\n .each(function() { this.__axis = position; });\n }\n\n axis.scale = function(_) {\n return arguments.length ? (scale = _, axis) : scale;\n };\n\n axis.ticks = function() {\n return tickArguments = slice.call(arguments), axis;\n };\n\n axis.tickArguments = function(_) {\n return arguments.length ? (tickArguments = _ == null ? [] : slice.call(_), axis) : tickArguments.slice();\n };\n\n axis.tickValues = function(_) {\n return arguments.length ? (tickValues = _ == null ? null : slice.call(_), axis) : tickValues && tickValues.slice();\n };\n\n axis.tickFormat = function(_) {\n return arguments.length ? (tickFormat = _, axis) : tickFormat;\n };\n\n axis.tickSize = function(_) {\n return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;\n };\n\n axis.tickSizeInner = function(_) {\n return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;\n };\n\n axis.tickSizeOuter = function(_) {\n return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;\n };\n\n axis.tickPadding = function(_) {\n return arguments.length ? (tickPadding = +_, axis) : tickPadding;\n };\n\n return axis;\n}\n\nexport function axisTop(scale) {\n return axis(top, scale);\n}\n\nexport function axisRight(scale) {\n return axis(right, scale);\n}\n\nexport function axisBottom(scale) {\n return axis(bottom, scale);\n}\n\nexport function axisLeft(scale) {\n return axis(left, scale);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-axis/src/axis.js\n// module id = 151\n// module chunks = 0","export var slice = Array.prototype.slice;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-axis/src/array.js\n// module id = 152\n// module chunks = 0","export default function(x) {\n return x;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-axis/src/identity.js\n// module id = 153\n// module chunks = 0","import define, {extend} from \"./define\";\nimport {Color, rgbConvert, Rgb} from \"./color\";\nimport {deg2rad, rad2deg} from \"./math\";\n\nvar Kn = 18,\n Xn = 0.950470, // D65 standard referent\n Yn = 1,\n Zn = 1.088830,\n t0 = 4 / 29,\n t1 = 6 / 29,\n t2 = 3 * t1 * t1,\n t3 = t1 * t1 * t1;\n\nfunction labConvert(o) {\n if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);\n if (o instanceof Hcl) {\n var h = o.h * deg2rad;\n return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);\n }\n if (!(o instanceof Rgb)) o = rgbConvert(o);\n var b = rgb2xyz(o.r),\n a = rgb2xyz(o.g),\n l = rgb2xyz(o.b),\n x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),\n y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),\n z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);\n return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);\n}\n\nexport default function lab(l, a, b, opacity) {\n return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);\n}\n\nexport function Lab(l, a, b, opacity) {\n this.l = +l;\n this.a = +a;\n this.b = +b;\n this.opacity = +opacity;\n}\n\ndefine(Lab, lab, extend(Color, {\n brighter: function(k) {\n return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);\n },\n darker: function(k) {\n return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);\n },\n rgb: function() {\n var y = (this.l + 16) / 116,\n x = isNaN(this.a) ? y : y + this.a / 500,\n z = isNaN(this.b) ? y : y - this.b / 200;\n y = Yn * lab2xyz(y);\n x = Xn * lab2xyz(x);\n z = Zn * lab2xyz(z);\n return new Rgb(\n xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB\n xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),\n xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z),\n this.opacity\n );\n }\n}));\n\nfunction xyz2lab(t) {\n return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;\n}\n\nfunction lab2xyz(t) {\n return t > t1 ? t * t * t : t2 * (t - t0);\n}\n\nfunction xyz2rgb(x) {\n return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);\n}\n\nfunction rgb2xyz(x) {\n return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);\n}\n\nfunction hclConvert(o) {\n if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);\n if (!(o instanceof Lab)) o = labConvert(o);\n var h = Math.atan2(o.b, o.a) * rad2deg;\n return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);\n}\n\nexport function hcl(h, c, l, opacity) {\n return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);\n}\n\nexport function Hcl(h, c, l, opacity) {\n this.h = +h;\n this.c = +c;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Hcl, hcl, extend(Color, {\n brighter: function(k) {\n return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity);\n },\n darker: function(k) {\n return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity);\n },\n rgb: function() {\n return labConvert(this).rgb();\n }\n}));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-color/src/lab.js\n// module id = 154\n// module chunks = 0","import define, {extend} from \"./define\";\nimport {Color, rgbConvert, Rgb, darker, brighter} from \"./color\";\nimport {deg2rad, rad2deg} from \"./math\";\n\nvar A = -0.14861,\n B = +1.78277,\n C = -0.29227,\n D = -0.90649,\n E = +1.97294,\n ED = E * D,\n EB = E * B,\n BC_DA = B * C - D * A;\n\nfunction cubehelixConvert(o) {\n if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);\n if (!(o instanceof Rgb)) o = rgbConvert(o);\n var r = o.r / 255,\n g = o.g / 255,\n b = o.b / 255,\n l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),\n bl = b - l,\n k = (E * (g - l) - C * bl) / D,\n s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1\n h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;\n return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);\n}\n\nexport default function cubehelix(h, s, l, opacity) {\n return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);\n}\n\nexport function Cubehelix(h, s, l, opacity) {\n this.h = +h;\n this.s = +s;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Cubehelix, cubehelix, extend(Color, {\n brighter: function(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Cubehelix(this.h, this.s, this.l * k, this.opacity);\n },\n darker: function(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Cubehelix(this.h, this.s, this.l * k, this.opacity);\n },\n rgb: function() {\n var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,\n l = +this.l,\n a = isNaN(this.s) ? 0 : this.s * l * (1 - l),\n cosh = Math.cos(h),\n sinh = Math.sin(h);\n return new Rgb(\n 255 * (l + a * (A * cosh + B * sinh)),\n 255 * (l + a * (C * cosh + D * sinh)),\n 255 * (l + a * (E * cosh)),\n this.opacity\n );\n }\n}));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-color/src/cubehelix.js\n// module id = 155\n// module chunks = 0","var noop = {value: function() {}};\n\nfunction dispatch() {\n for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {\n if (!(t = arguments[i] + \"\") || (t in _)) throw new Error(\"illegal type: \" + t);\n _[t] = [];\n }\n return new Dispatch(_);\n}\n\nfunction Dispatch(_) {\n this._ = _;\n}\n\nfunction parseTypenames(typenames, types) {\n return typenames.trim().split(/^|\\s+/).map(function(t) {\n var name = \"\", i = t.indexOf(\".\");\n if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n if (t && !types.hasOwnProperty(t)) throw new Error(\"unknown type: \" + t);\n return {type: t, name: name};\n });\n}\n\nDispatch.prototype = dispatch.prototype = {\n constructor: Dispatch,\n on: function(typename, callback) {\n var _ = this._,\n T = parseTypenames(typename + \"\", _),\n t,\n i = -1,\n n = T.length;\n\n // If no callback was specified, return the callback of the given type and name.\n if (arguments.length < 2) {\n while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;\n return;\n }\n\n // If a type was specified, set the callback for the given type and name.\n // Otherwise, if a null callback was specified, remove callbacks of the given name.\n if (callback != null && typeof callback !== \"function\") throw new Error(\"invalid callback: \" + callback);\n while (++i < n) {\n if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);\n else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);\n }\n\n return this;\n },\n copy: function() {\n var copy = {}, _ = this._;\n for (var t in _) copy[t] = _[t].slice();\n return new Dispatch(copy);\n },\n call: function(type, that) {\n if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];\n if (!this._.hasOwnProperty(type)) throw new Error(\"unknown type: \" + type);\n for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);\n },\n apply: function(type, that, args) {\n if (!this._.hasOwnProperty(type)) throw new Error(\"unknown type: \" + type);\n for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);\n }\n};\n\nfunction get(type, name) {\n for (var i = 0, n = type.length, c; i < n; ++i) {\n if ((c = type[i]).name === name) {\n return c.value;\n }\n }\n}\n\nfunction set(type, name, callback) {\n for (var i = 0, n = type.length; i < n; ++i) {\n if (type[i].name === name) {\n type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));\n break;\n }\n }\n if (callback != null) type.push({name: name, value: callback});\n return type;\n}\n\nexport default dispatch;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-dispatch/src/dispatch.js\n// module id = 156\n// module chunks = 0","import formatLocale from \"./locale\";\n\nvar locale;\nexport var format;\nexport var formatPrefix;\n\ndefaultLocale({\n decimal: \".\",\n thousands: \",\",\n grouping: [3],\n currency: [\"$\", \"\"]\n});\n\nexport default function defaultLocale(definition) {\n locale = formatLocale(definition);\n format = locale.format;\n formatPrefix = locale.formatPrefix;\n return locale;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/defaultLocale.js\n// module id = 157\n// module chunks = 0","export default function(grouping, thousands) {\n return function(value, width) {\n var i = value.length,\n t = [],\n j = 0,\n g = grouping[0],\n length = 0;\n\n while (i > 0 && g > 0) {\n if (length + g + 1 > width) g = Math.max(1, width - length);\n t.push(value.substring(i -= g, i + g));\n if ((length += g + 1) > width) break;\n g = grouping[j = (j + 1) % grouping.length];\n }\n\n return t.reverse().join(thousands);\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/formatGroup.js\n// module id = 158\n// module chunks = 0","export default function(numerals) {\n return function(value) {\n return value.replace(/[0-9]/g, function(i) {\n return numerals[+i];\n });\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/formatNumerals.js\n// module id = 159\n// module chunks = 0","export default function(x, p) {\n x = x.toPrecision(p);\n\n out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {\n switch (x[i]) {\n case \".\": i0 = i1 = i; break;\n case \"0\": if (i0 === 0) i0 = i; i1 = i; break;\n case \"e\": break out;\n default: if (i0 > 0) i0 = 0; break;\n }\n }\n\n return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/formatDefault.js\n// module id = 160\n// module chunks = 0","import formatDecimal from \"./formatDecimal\";\n\nexport default function(x, p) {\n var d = formatDecimal(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1];\n return exponent < 0 ? \"0.\" + new Array(-exponent).join(\"0\") + coefficient\n : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + \".\" + coefficient.slice(exponent + 1)\n : coefficient + new Array(exponent - coefficient.length + 2).join(\"0\");\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/formatRounded.js\n// module id = 161\n// module chunks = 0","export default function(x) {\n return x;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/identity.js\n// module id = 162\n// module chunks = 0","import exponent from \"./exponent\";\n\nexport default function(step) {\n return Math.max(0, -exponent(Math.abs(step)));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/precisionFixed.js\n// module id = 163\n// module chunks = 0","import exponent from \"./exponent\";\n\nexport default function(step, value) {\n return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step)));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/precisionPrefix.js\n// module id = 164\n// module chunks = 0","import exponent from \"./exponent\";\n\nexport default function(step, max) {\n step = Math.abs(step), max = Math.abs(max) - step;\n return Math.max(0, exponent(max) - exponent(step)) + 1;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-format/src/precisionRound.js\n// module id = 165\n// module chunks = 0","import {range as sequence} from \"d3-array\";\nimport ordinal from \"./ordinal\";\n\nexport default function band() {\n var scale = ordinal().unknown(undefined),\n domain = scale.domain,\n ordinalRange = scale.range,\n range = [0, 1],\n step,\n bandwidth,\n round = false,\n paddingInner = 0,\n paddingOuter = 0,\n align = 0.5;\n\n delete scale.unknown;\n\n function rescale() {\n var n = domain().length,\n reverse = range[1] < range[0],\n start = range[reverse - 0],\n stop = range[1 - reverse];\n step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);\n if (round) step = Math.floor(step);\n start += (stop - start - step * (n - paddingInner)) * align;\n bandwidth = step * (1 - paddingInner);\n if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);\n var values = sequence(n).map(function(i) { return start + step * i; });\n return ordinalRange(reverse ? values.reverse() : values);\n }\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = [+_[0], +_[1]], rescale()) : range.slice();\n };\n\n scale.rangeRound = function(_) {\n return range = [+_[0], +_[1]], round = true, rescale();\n };\n\n scale.bandwidth = function() {\n return bandwidth;\n };\n\n scale.step = function() {\n return step;\n };\n\n scale.round = function(_) {\n return arguments.length ? (round = !!_, rescale()) : round;\n };\n\n scale.padding = function(_) {\n return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;\n };\n\n scale.paddingInner = function(_) {\n return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;\n };\n\n scale.paddingOuter = function(_) {\n return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;\n };\n\n scale.align = function(_) {\n return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;\n };\n\n scale.copy = function() {\n return band()\n .domain(domain())\n .range(range)\n .round(round)\n .paddingInner(paddingInner)\n .paddingOuter(paddingOuter)\n .align(align);\n };\n\n return rescale();\n}\n\nfunction pointish(scale) {\n var copy = scale.copy;\n\n scale.padding = scale.paddingOuter;\n delete scale.paddingInner;\n delete scale.paddingOuter;\n\n scale.copy = function() {\n return pointish(copy());\n };\n\n return scale;\n}\n\nexport function point() {\n return pointish(band().paddingInner(1));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/band.js\n// module id = 166\n// module chunks = 0","import map from \"./map\";\n\nexport default function() {\n var keys = [],\n sortKeys = [],\n sortValues,\n rollup,\n nest;\n\n function apply(array, depth, createResult, setResult) {\n if (depth >= keys.length) {\n if (sortValues != null) array.sort(sortValues);\n return rollup != null ? rollup(array) : array;\n }\n\n var i = -1,\n n = array.length,\n key = keys[depth++],\n keyValue,\n value,\n valuesByKey = map(),\n values,\n result = createResult();\n\n while (++i < n) {\n if (values = valuesByKey.get(keyValue = key(value = array[i]) + \"\")) {\n values.push(value);\n } else {\n valuesByKey.set(keyValue, [value]);\n }\n }\n\n valuesByKey.each(function(values, key) {\n setResult(result, key, apply(values, depth, createResult, setResult));\n });\n\n return result;\n }\n\n function entries(map, depth) {\n if (++depth > keys.length) return map;\n var array, sortKey = sortKeys[depth - 1];\n if (rollup != null && depth >= keys.length) array = map.entries();\n else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });\n return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;\n }\n\n return nest = {\n object: function(array) { return apply(array, 0, createObject, setObject); },\n map: function(array) { return apply(array, 0, createMap, setMap); },\n entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },\n key: function(d) { keys.push(d); return nest; },\n sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },\n sortValues: function(order) { sortValues = order; return nest; },\n rollup: function(f) { rollup = f; return nest; }\n };\n}\n\nfunction createObject() {\n return {};\n}\n\nfunction setObject(object, key, value) {\n object[key] = value;\n}\n\nfunction createMap() {\n return map();\n}\n\nfunction setMap(map, key, value) {\n map.set(key, value);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-collection/src/nest.js\n// module id = 167\n// module chunks = 0","import {default as map, prefix} from \"./map\";\n\nfunction Set() {}\n\nvar proto = map.prototype;\n\nSet.prototype = set.prototype = {\n constructor: Set,\n has: proto.has,\n add: function(value) {\n value += \"\";\n this[prefix + value] = value;\n return this;\n },\n remove: proto.remove,\n clear: proto.clear,\n values: proto.keys,\n size: proto.size,\n empty: proto.empty,\n each: proto.each\n};\n\nfunction set(object, f) {\n var set = new Set;\n\n // Copy constructor.\n if (object instanceof Set) object.each(function(value) { set.add(value); });\n\n // Otherwise, assume it’s an array.\n else if (object) {\n var i = -1, n = object.length;\n if (f == null) while (++i < n) set.add(object[i]);\n else while (++i < n) set.add(f(object[i], i, object));\n }\n\n return set;\n}\n\nexport default set;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-collection/src/set.js\n// module id = 168\n// module chunks = 0","export default function(map) {\n var keys = [];\n for (var key in map) keys.push(key);\n return keys;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-collection/src/keys.js\n// module id = 169\n// module chunks = 0","export default function(map) {\n var values = [];\n for (var key in map) values.push(map[key]);\n return values;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-collection/src/values.js\n// module id = 170\n// module chunks = 0","export default function(map) {\n var entries = [];\n for (var key in map) entries.push({key: key, value: map[key]});\n return entries;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-collection/src/entries.js\n// module id = 171\n// module chunks = 0","import {map} from \"./array\";\nimport {linearish} from \"./linear\";\nimport number from \"./number\";\n\nexport default function identity() {\n var domain = [0, 1];\n\n function scale(x) {\n return +x;\n }\n\n scale.invert = scale;\n\n scale.domain = scale.range = function(_) {\n return arguments.length ? (domain = map.call(_, number), scale) : domain.slice();\n };\n\n scale.copy = function() {\n return identity().domain(domain);\n };\n\n return linearish(scale);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/identity.js\n// module id = 172\n// module chunks = 0","export default function(a, b) {\n return a = +a, b -= a, function(t) {\n return Math.round(a + b * t);\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/round.js\n// module id = 173\n// module chunks = 0","import number from \"../number\";\nimport {parseCss, parseSvg} from \"./parse\";\n\nfunction interpolateTransform(parse, pxComma, pxParen, degParen) {\n\n function pop(s) {\n return s.length ? s.pop() + \" \" : \"\";\n }\n\n function translate(xa, ya, xb, yb, s, q) {\n if (xa !== xb || ya !== yb) {\n var i = s.push(\"translate(\", null, pxComma, null, pxParen);\n q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});\n } else if (xb || yb) {\n s.push(\"translate(\" + xb + pxComma + yb + pxParen);\n }\n }\n\n function rotate(a, b, s, q) {\n if (a !== b) {\n if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path\n q.push({i: s.push(pop(s) + \"rotate(\", null, degParen) - 2, x: number(a, b)});\n } else if (b) {\n s.push(pop(s) + \"rotate(\" + b + degParen);\n }\n }\n\n function skewX(a, b, s, q) {\n if (a !== b) {\n q.push({i: s.push(pop(s) + \"skewX(\", null, degParen) - 2, x: number(a, b)});\n } else if (b) {\n s.push(pop(s) + \"skewX(\" + b + degParen);\n }\n }\n\n function scale(xa, ya, xb, yb, s, q) {\n if (xa !== xb || ya !== yb) {\n var i = s.push(pop(s) + \"scale(\", null, \",\", null, \")\");\n q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});\n } else if (xb !== 1 || yb !== 1) {\n s.push(pop(s) + \"scale(\" + xb + \",\" + yb + \")\");\n }\n }\n\n return function(a, b) {\n var s = [], // string constants and placeholders\n q = []; // number interpolators\n a = parse(a), b = parse(b);\n translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);\n rotate(a.rotate, b.rotate, s, q);\n skewX(a.skewX, b.skewX, s, q);\n scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);\n a = b = null; // gc\n return function(t) {\n var i = -1, n = q.length, o;\n while (++i < n) s[(o = q[i]).i] = o.x(t);\n return s.join(\"\");\n };\n };\n}\n\nexport var interpolateTransformCss = interpolateTransform(parseCss, \"px, \", \"px)\", \"deg)\");\nexport var interpolateTransformSvg = interpolateTransform(parseSvg, \", \", \")\", \")\");\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/transform/index.js\n// module id = 174\n// module chunks = 0","import decompose, {identity} from \"./decompose\";\n\nvar cssNode,\n cssRoot,\n cssView,\n svgNode;\n\nexport function parseCss(value) {\n if (value === \"none\") return identity;\n if (!cssNode) cssNode = document.createElement(\"DIV\"), cssRoot = document.documentElement, cssView = document.defaultView;\n cssNode.style.transform = value;\n value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue(\"transform\");\n cssRoot.removeChild(cssNode);\n value = value.slice(7, -1).split(\",\");\n return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);\n}\n\nexport function parseSvg(value) {\n if (value == null) return identity;\n if (!svgNode) svgNode = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n svgNode.setAttribute(\"transform\", value);\n if (!(value = svgNode.transform.baseVal.consolidate())) return identity;\n value = value.matrix;\n return decompose(value.a, value.b, value.c, value.d, value.e, value.f);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/transform/parse.js\n// module id = 175\n// module chunks = 0","var degrees = 180 / Math.PI;\n\nexport var identity = {\n translateX: 0,\n translateY: 0,\n rotate: 0,\n skewX: 0,\n scaleX: 1,\n scaleY: 1\n};\n\nexport default function(a, b, c, d, e, f) {\n var scaleX, scaleY, skewX;\n if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;\n if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;\n if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;\n if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;\n return {\n translateX: e,\n translateY: f,\n rotate: Math.atan2(b, a) * degrees,\n skewX: Math.atan(skewX) * degrees,\n scaleX: scaleX,\n scaleY: scaleY\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/transform/decompose.js\n// module id = 176\n// module chunks = 0","var rho = Math.SQRT2,\n rho2 = 2,\n rho4 = 4,\n epsilon2 = 1e-12;\n\nfunction cosh(x) {\n return ((x = Math.exp(x)) + 1 / x) / 2;\n}\n\nfunction sinh(x) {\n return ((x = Math.exp(x)) - 1 / x) / 2;\n}\n\nfunction tanh(x) {\n return ((x = Math.exp(2 * x)) - 1) / (x + 1);\n}\n\n// p0 = [ux0, uy0, w0]\n// p1 = [ux1, uy1, w1]\nexport default function(p0, p1) {\n var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],\n ux1 = p1[0], uy1 = p1[1], w1 = p1[2],\n dx = ux1 - ux0,\n dy = uy1 - uy0,\n d2 = dx * dx + dy * dy,\n i,\n S;\n\n // Special case for u0 ≅ u1.\n if (d2 < epsilon2) {\n S = Math.log(w1 / w0) / rho;\n i = function(t) {\n return [\n ux0 + t * dx,\n uy0 + t * dy,\n w0 * Math.exp(rho * t * S)\n ];\n }\n }\n\n // General case.\n else {\n var d1 = Math.sqrt(d2),\n b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),\n b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),\n r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),\n r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);\n S = (r1 - r0) / rho;\n i = function(t) {\n var s = t * S,\n coshr0 = cosh(r0),\n u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));\n return [\n ux0 + u * dx,\n uy0 + u * dy,\n w0 * coshr0 / cosh(rho * s + r0)\n ];\n }\n }\n\n i.duration = S * 1000;\n\n return i;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/zoom.js\n// module id = 177\n// module chunks = 0","import {hsl as colorHsl} from \"d3-color\";\nimport color, {hue} from \"./color\";\n\nfunction hsl(hue) {\n return function(start, end) {\n var h = hue((start = colorHsl(start)).h, (end = colorHsl(end)).h),\n s = color(start.s, end.s),\n l = color(start.l, end.l),\n opacity = color(start.opacity, end.opacity);\n return function(t) {\n start.h = h(t);\n start.s = s(t);\n start.l = l(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n}\n\nexport default hsl(hue);\nexport var hslLong = hsl(color);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/hsl.js\n// module id = 178\n// module chunks = 0","import {lab as colorLab} from \"d3-color\";\nimport color from \"./color\";\n\nexport default function lab(start, end) {\n var l = color((start = colorLab(start)).l, (end = colorLab(end)).l),\n a = color(start.a, end.a),\n b = color(start.b, end.b),\n opacity = color(start.opacity, end.opacity);\n return function(t) {\n start.l = l(t);\n start.a = a(t);\n start.b = b(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/lab.js\n// module id = 179\n// module chunks = 0","import {hcl as colorHcl} from \"d3-color\";\nimport color, {hue} from \"./color\";\n\nfunction hcl(hue) {\n return function(start, end) {\n var h = hue((start = colorHcl(start)).h, (end = colorHcl(end)).h),\n c = color(start.c, end.c),\n l = color(start.l, end.l),\n opacity = color(start.opacity, end.opacity);\n return function(t) {\n start.h = h(t);\n start.c = c(t);\n start.l = l(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n}\n\nexport default hcl(hue);\nexport var hclLong = hcl(color);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/hcl.js\n// module id = 180\n// module chunks = 0","import {cubehelix as colorCubehelix} from \"d3-color\";\nimport color, {hue} from \"./color\";\n\nfunction cubehelix(hue) {\n return (function cubehelixGamma(y) {\n y = +y;\n\n function cubehelix(start, end) {\n var h = hue((start = colorCubehelix(start)).h, (end = colorCubehelix(end)).h),\n s = color(start.s, end.s),\n l = color(start.l, end.l),\n opacity = color(start.opacity, end.opacity);\n return function(t) {\n start.h = h(t);\n start.s = s(t);\n start.l = l(Math.pow(t, y));\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n\n cubehelix.gamma = cubehelixGamma;\n\n return cubehelix;\n })(1);\n}\n\nexport default cubehelix(hue);\nexport var cubehelixLong = cubehelix(color);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/cubehelix.js\n// module id = 181\n// module chunks = 0","export default function(interpolator, n) {\n var samples = new Array(n);\n for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));\n return samples;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-interpolate/src/quantize.js\n// module id = 182\n// module chunks = 0","import {tickStep} from \"d3-array\";\nimport {format, formatPrefix, formatSpecifier, precisionFixed, precisionPrefix, precisionRound} from \"d3-format\";\n\nexport default function(domain, count, specifier) {\n var start = domain[0],\n stop = domain[domain.length - 1],\n step = tickStep(start, stop, count == null ? 10 : count),\n precision;\n specifier = formatSpecifier(specifier == null ? \",f\" : specifier);\n switch (specifier.type) {\n case \"s\": {\n var value = Math.max(Math.abs(start), Math.abs(stop));\n if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;\n return formatPrefix(specifier, value);\n }\n case \"\":\n case \"e\":\n case \"g\":\n case \"p\":\n case \"r\": {\n if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === \"e\");\n break;\n }\n case \"f\":\n case \"%\": {\n if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === \"%\") * 2;\n break;\n }\n }\n return format(specifier);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/tickFormat.js\n// module id = 183\n// module chunks = 0","import {ticks} from \"d3-array\";\nimport {format} from \"d3-format\";\nimport constant from \"./constant\";\nimport nice from \"./nice\";\nimport {default as continuous, copy} from \"./continuous\";\n\nfunction deinterpolate(a, b) {\n return (b = Math.log(b / a))\n ? function(x) { return Math.log(x / a) / b; }\n : constant(b);\n}\n\nfunction reinterpolate(a, b) {\n return a < 0\n ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }\n : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };\n}\n\nfunction pow10(x) {\n return isFinite(x) ? +(\"1e\" + x) : x < 0 ? 0 : x;\n}\n\nfunction powp(base) {\n return base === 10 ? pow10\n : base === Math.E ? Math.exp\n : function(x) { return Math.pow(base, x); };\n}\n\nfunction logp(base) {\n return base === Math.E ? Math.log\n : base === 10 && Math.log10\n || base === 2 && Math.log2\n || (base = Math.log(base), function(x) { return Math.log(x) / base; });\n}\n\nfunction reflect(f) {\n return function(x) {\n return -f(-x);\n };\n}\n\nexport default function log() {\n var scale = continuous(deinterpolate, reinterpolate).domain([1, 10]),\n domain = scale.domain,\n base = 10,\n logs = logp(10),\n pows = powp(10);\n\n function rescale() {\n logs = logp(base), pows = powp(base);\n if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);\n return scale;\n }\n\n scale.base = function(_) {\n return arguments.length ? (base = +_, rescale()) : base;\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.ticks = function(count) {\n var d = domain(),\n u = d[0],\n v = d[d.length - 1],\n r;\n\n if (r = v < u) i = u, u = v, v = i;\n\n var i = logs(u),\n j = logs(v),\n p,\n k,\n t,\n n = count == null ? 10 : +count,\n z = [];\n\n if (!(base % 1) && j - i < n) {\n i = Math.round(i) - 1, j = Math.round(j) + 1;\n if (u > 0) for (; i < j; ++i) {\n for (k = 1, p = pows(i); k < base; ++k) {\n t = p * k;\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n } else for (; i < j; ++i) {\n for (k = base - 1, p = pows(i); k >= 1; --k) {\n t = p * k;\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n }\n } else {\n z = ticks(i, j, Math.min(j - i, n)).map(pows);\n }\n\n return r ? z.reverse() : z;\n };\n\n scale.tickFormat = function(count, specifier) {\n if (specifier == null) specifier = base === 10 ? \".0e\" : \",\";\n if (typeof specifier !== \"function\") specifier = format(specifier);\n if (count === Infinity) return specifier;\n if (count == null) count = 10;\n var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?\n return function(d) {\n var i = d / pows(Math.round(logs(d)));\n if (i * base < base - 0.5) i *= base;\n return i <= k ? specifier(d) : \"\";\n };\n };\n\n scale.nice = function() {\n return domain(nice(domain(), {\n floor: function(x) { return pows(Math.floor(logs(x))); },\n ceil: function(x) { return pows(Math.ceil(logs(x))); }\n }));\n };\n\n scale.copy = function() {\n return copy(scale, log().base(base));\n };\n\n return scale;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/log.js\n// module id = 184\n// module chunks = 0","import constant from \"./constant\";\nimport {linearish} from \"./linear\";\nimport {default as continuous, copy} from \"./continuous\";\n\nfunction raise(x, exponent) {\n return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);\n}\n\nexport default function pow() {\n var exponent = 1,\n scale = continuous(deinterpolate, reinterpolate),\n domain = scale.domain;\n\n function deinterpolate(a, b) {\n return (b = raise(b, exponent) - (a = raise(a, exponent)))\n ? function(x) { return (raise(x, exponent) - a) / b; }\n : constant(b);\n }\n\n function reinterpolate(a, b) {\n b = raise(b, exponent) - (a = raise(a, exponent));\n return function(t) { return raise(a + b * t, 1 / exponent); };\n }\n\n scale.exponent = function(_) {\n return arguments.length ? (exponent = +_, domain(domain())) : exponent;\n };\n\n scale.copy = function() {\n return copy(scale, pow().exponent(exponent));\n };\n\n return linearish(scale);\n}\n\nexport function sqrt() {\n return pow().exponent(0.5);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/pow.js\n// module id = 185\n// module chunks = 0","import {ascending, bisect, quantile as threshold} from \"d3-array\";\nimport {slice} from \"./array\";\n\nexport default function quantile() {\n var domain = [],\n range = [],\n thresholds = [];\n\n function rescale() {\n var i = 0, n = Math.max(1, range.length);\n thresholds = new Array(n - 1);\n while (++i < n) thresholds[i - 1] = threshold(domain, i / n);\n return scale;\n }\n\n function scale(x) {\n if (!isNaN(x = +x)) return range[bisect(thresholds, x)];\n }\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return i < 0 ? [NaN, NaN] : [\n i > 0 ? thresholds[i - 1] : domain[0],\n i < thresholds.length ? thresholds[i] : domain[domain.length - 1]\n ];\n };\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [];\n for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);\n domain.sort(ascending);\n return rescale();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice.call(_), rescale()) : range.slice();\n };\n\n scale.quantiles = function() {\n return thresholds.slice();\n };\n\n scale.copy = function() {\n return quantile()\n .domain(domain)\n .range(range);\n };\n\n return scale;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/quantile.js\n// module id = 186\n// module chunks = 0","import {bisect} from \"d3-array\";\nimport {slice} from \"./array\";\nimport {linearish} from \"./linear\";\n\nexport default function quantize() {\n var x0 = 0,\n x1 = 1,\n n = 1,\n domain = [0.5],\n range = [0, 1];\n\n function scale(x) {\n if (x <= x) return range[bisect(domain, x, 0, n)];\n }\n\n function rescale() {\n var i = -1;\n domain = new Array(n);\n while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);\n return scale;\n }\n\n scale.domain = function(_) {\n return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];\n };\n\n scale.range = function(_) {\n return arguments.length ? (n = (range = slice.call(_)).length - 1, rescale()) : range.slice();\n };\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return i < 0 ? [NaN, NaN]\n : i < 1 ? [x0, domain[0]]\n : i >= n ? [domain[n - 1], x1]\n : [domain[i - 1], domain[i]];\n };\n\n scale.copy = function() {\n return quantize()\n .domain([x0, x1])\n .range(range);\n };\n\n return linearish(scale);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/quantize.js\n// module id = 187\n// module chunks = 0","import {bisect} from \"d3-array\";\nimport {slice} from \"./array\";\n\nexport default function threshold() {\n var domain = [0.5],\n range = [0, 1],\n n = 1;\n\n function scale(x) {\n if (x <= x) return range[bisect(domain, x, 0, n)];\n }\n\n scale.domain = function(_) {\n return arguments.length ? (domain = slice.call(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice.call(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice();\n };\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return [domain[i - 1], domain[i]];\n };\n\n scale.copy = function() {\n return threshold()\n .domain(domain)\n .range(range);\n };\n\n return scale;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/threshold.js\n// module id = 188\n// module chunks = 0","import interval from \"./interval\";\n\nvar millisecond = interval(function() {\n // noop\n}, function(date, step) {\n date.setTime(+date + step);\n}, function(start, end) {\n return end - start;\n});\n\n// An optimized implementation for this simple case.\nmillisecond.every = function(k) {\n k = Math.floor(k);\n if (!isFinite(k) || !(k > 0)) return null;\n if (!(k > 1)) return millisecond;\n return interval(function(date) {\n date.setTime(Math.floor(date / k) * k);\n }, function(date, step) {\n date.setTime(+date + step * k);\n }, function(start, end) {\n return (end - start) / k;\n });\n};\n\nexport default millisecond;\nexport var milliseconds = millisecond.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/millisecond.js\n// module id = 189\n// module chunks = 0","import interval from \"./interval\";\nimport {durationSecond} from \"./duration\";\n\nvar second = interval(function(date) {\n date.setTime(Math.floor(date / durationSecond) * durationSecond);\n}, function(date, step) {\n date.setTime(+date + step * durationSecond);\n}, function(start, end) {\n return (end - start) / durationSecond;\n}, function(date) {\n return date.getUTCSeconds();\n});\n\nexport default second;\nexport var seconds = second.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/second.js\n// module id = 190\n// module chunks = 0","import interval from \"./interval\";\nimport {durationMinute} from \"./duration\";\n\nvar minute = interval(function(date) {\n date.setTime(Math.floor(date / durationMinute) * durationMinute);\n}, function(date, step) {\n date.setTime(+date + step * durationMinute);\n}, function(start, end) {\n return (end - start) / durationMinute;\n}, function(date) {\n return date.getMinutes();\n});\n\nexport default minute;\nexport var minutes = minute.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/minute.js\n// module id = 191\n// module chunks = 0","import interval from \"./interval\";\nimport {durationHour, durationMinute} from \"./duration\";\n\nvar hour = interval(function(date) {\n var offset = date.getTimezoneOffset() * durationMinute % durationHour;\n if (offset < 0) offset += durationHour;\n date.setTime(Math.floor((+date - offset) / durationHour) * durationHour + offset);\n}, function(date, step) {\n date.setTime(+date + step * durationHour);\n}, function(start, end) {\n return (end - start) / durationHour;\n}, function(date) {\n return date.getHours();\n});\n\nexport default hour;\nexport var hours = hour.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/hour.js\n// module id = 192\n// module chunks = 0","import interval from \"./interval\";\nimport {durationDay, durationMinute} from \"./duration\";\n\nvar day = interval(function(date) {\n date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setDate(date.getDate() + step);\n}, function(start, end) {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay;\n}, function(date) {\n return date.getDate() - 1;\n});\n\nexport default day;\nexport var days = day.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/day.js\n// module id = 193\n// module chunks = 0","import interval from \"./interval\";\nimport {durationMinute, durationWeek} from \"./duration\";\n\nfunction weekday(i) {\n return interval(function(date) {\n date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);\n date.setHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setDate(date.getDate() + step * 7);\n }, function(start, end) {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;\n });\n}\n\nexport var sunday = weekday(0);\nexport var monday = weekday(1);\nexport var tuesday = weekday(2);\nexport var wednesday = weekday(3);\nexport var thursday = weekday(4);\nexport var friday = weekday(5);\nexport var saturday = weekday(6);\n\nexport var sundays = sunday.range;\nexport var mondays = monday.range;\nexport var tuesdays = tuesday.range;\nexport var wednesdays = wednesday.range;\nexport var thursdays = thursday.range;\nexport var fridays = friday.range;\nexport var saturdays = saturday.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/week.js\n// module id = 194\n// module chunks = 0","import interval from \"./interval\";\n\nvar month = interval(function(date) {\n date.setDate(1);\n date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setMonth(date.getMonth() + step);\n}, function(start, end) {\n return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;\n}, function(date) {\n return date.getMonth();\n});\n\nexport default month;\nexport var months = month.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/month.js\n// module id = 195\n// module chunks = 0","import interval from \"./interval\";\n\nvar year = interval(function(date) {\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setFullYear(date.getFullYear() + step);\n}, function(start, end) {\n return end.getFullYear() - start.getFullYear();\n}, function(date) {\n return date.getFullYear();\n});\n\n// An optimized implementation for this simple case.\nyear.every = function(k) {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : interval(function(date) {\n date.setFullYear(Math.floor(date.getFullYear() / k) * k);\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setFullYear(date.getFullYear() + step * k);\n });\n};\n\nexport default year;\nexport var years = year.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/year.js\n// module id = 196\n// module chunks = 0","import interval from \"./interval\";\nimport {durationMinute} from \"./duration\";\n\nvar utcMinute = interval(function(date) {\n date.setUTCSeconds(0, 0);\n}, function(date, step) {\n date.setTime(+date + step * durationMinute);\n}, function(start, end) {\n return (end - start) / durationMinute;\n}, function(date) {\n return date.getUTCMinutes();\n});\n\nexport default utcMinute;\nexport var utcMinutes = utcMinute.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/utcMinute.js\n// module id = 197\n// module chunks = 0","import interval from \"./interval\";\nimport {durationHour} from \"./duration\";\n\nvar utcHour = interval(function(date) {\n date.setUTCMinutes(0, 0, 0);\n}, function(date, step) {\n date.setTime(+date + step * durationHour);\n}, function(start, end) {\n return (end - start) / durationHour;\n}, function(date) {\n return date.getUTCHours();\n});\n\nexport default utcHour;\nexport var utcHours = utcHour.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/utcHour.js\n// module id = 198\n// module chunks = 0","import interval from \"./interval\";\nimport {durationDay} from \"./duration\";\n\nvar utcDay = interval(function(date) {\n date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setUTCDate(date.getUTCDate() + step);\n}, function(start, end) {\n return (end - start) / durationDay;\n}, function(date) {\n return date.getUTCDate() - 1;\n});\n\nexport default utcDay;\nexport var utcDays = utcDay.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/utcDay.js\n// module id = 199\n// module chunks = 0","import interval from \"./interval\";\nimport {durationWeek} from \"./duration\";\n\nfunction utcWeekday(i) {\n return interval(function(date) {\n date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);\n date.setUTCHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setUTCDate(date.getUTCDate() + step * 7);\n }, function(start, end) {\n return (end - start) / durationWeek;\n });\n}\n\nexport var utcSunday = utcWeekday(0);\nexport var utcMonday = utcWeekday(1);\nexport var utcTuesday = utcWeekday(2);\nexport var utcWednesday = utcWeekday(3);\nexport var utcThursday = utcWeekday(4);\nexport var utcFriday = utcWeekday(5);\nexport var utcSaturday = utcWeekday(6);\n\nexport var utcSundays = utcSunday.range;\nexport var utcMondays = utcMonday.range;\nexport var utcTuesdays = utcTuesday.range;\nexport var utcWednesdays = utcWednesday.range;\nexport var utcThursdays = utcThursday.range;\nexport var utcFridays = utcFriday.range;\nexport var utcSaturdays = utcSaturday.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/utcWeek.js\n// module id = 200\n// module chunks = 0","import interval from \"./interval\";\n\nvar utcMonth = interval(function(date) {\n date.setUTCDate(1);\n date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setUTCMonth(date.getUTCMonth() + step);\n}, function(start, end) {\n return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;\n}, function(date) {\n return date.getUTCMonth();\n});\n\nexport default utcMonth;\nexport var utcMonths = utcMonth.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/utcMonth.js\n// module id = 201\n// module chunks = 0","import interval from \"./interval\";\n\nvar utcYear = interval(function(date) {\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setUTCFullYear(date.getUTCFullYear() + step);\n}, function(start, end) {\n return end.getUTCFullYear() - start.getUTCFullYear();\n}, function(date) {\n return date.getUTCFullYear();\n});\n\n// An optimized implementation for this simple case.\nutcYear.every = function(k) {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : interval(function(date) {\n date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setUTCFullYear(date.getUTCFullYear() + step * k);\n });\n};\n\nexport default utcYear;\nexport var utcYears = utcYear.range;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time/src/utcYear.js\n// module id = 202\n// module chunks = 0","import {isoSpecifier} from \"./isoFormat\";\nimport {utcParse} from \"./defaultLocale\";\n\nfunction parseIsoNative(string) {\n var date = new Date(string);\n return isNaN(date) ? null : date;\n}\n\nvar parseIso = +new Date(\"2000-01-01T00:00:00.000Z\")\n ? parseIsoNative\n : utcParse(isoSpecifier);\n\nexport default parseIso;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-time-format/src/isoParse.js\n// module id = 203\n// module chunks = 0","import {calendar} from \"./time\";\nimport {utcFormat} from \"d3-time-format\";\nimport {utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute, utcSecond, utcMillisecond} from \"d3-time\";\n\nexport default function() {\n return calendar(utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute, utcSecond, utcMillisecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/utcTime.js\n// module id = 204\n// module chunks = 0","import {linearish} from \"./linear\";\n\nexport default function sequential(interpolator) {\n var x0 = 0,\n x1 = 1,\n clamp = false;\n\n function scale(x) {\n var t = (x - x0) / (x1 - x0);\n return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);\n }\n\n scale.domain = function(_) {\n return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = !!_, scale) : clamp;\n };\n\n scale.interpolator = function(_) {\n return arguments.length ? (interpolator = _, scale) : interpolator;\n };\n\n scale.copy = function() {\n return sequential(interpolator).domain([x0, x1]).clamp(clamp);\n };\n\n return linearish(scale);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-scale/src/sequential.js\n// module id = 205\n// module chunks = 0","var nextId = 0;\n\nexport default function local() {\n return new Local;\n}\n\nfunction Local() {\n this._ = \"@\" + (++nextId).toString(36);\n}\n\nLocal.prototype = local.prototype = {\n constructor: Local,\n get: function(node) {\n var id = this._;\n while (!(id in node)) if (!(node = node.parentNode)) return;\n return node[id];\n },\n set: function(node, value) {\n return node[this._] = value;\n },\n remove: function(node) {\n return this._ in node && delete node[this._];\n },\n toString: function() {\n return this._;\n }\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/local.js\n// module id = 206\n// module chunks = 0","import sourceEvent from \"./sourceEvent\";\nimport point from \"./point\";\n\nexport default function(node) {\n var event = sourceEvent();\n if (event.changedTouches) event = event.changedTouches[0];\n return point(node, event);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/mouse.js\n// module id = 207\n// module chunks = 0","import {Selection, root} from \"./selection/index\";\n\nexport default function(selector) {\n return typeof selector === \"string\"\n ? new Selection([[document.querySelector(selector)]], [document.documentElement])\n : new Selection([[selector]], root);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/select.js\n// module id = 208\n// module chunks = 0","import {Selection} from \"./index\";\nimport selector from \"../selector\";\n\nexport default function(select) {\n if (typeof select !== \"function\") select = selector(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n if (\"__data__\" in node) subnode.__data__ = node.__data__;\n subgroup[i] = subnode;\n }\n }\n }\n\n return new Selection(subgroups, this._parents);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/select.js\n// module id = 209\n// module chunks = 0","import {Selection} from \"./index\";\nimport selectorAll from \"../selectorAll\";\n\nexport default function(select) {\n if (typeof select !== \"function\") select = selectorAll(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n subgroups.push(select.call(node, node.__data__, i, group));\n parents.push(node);\n }\n }\n }\n\n return new Selection(subgroups, parents);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/selectAll.js\n// module id = 210\n// module chunks = 0","import {Selection} from \"./index\";\nimport matcher from \"../matcher\";\n\nexport default function(match) {\n if (typeof match !== \"function\") match = matcher(match);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n subgroup.push(node);\n }\n }\n }\n\n return new Selection(subgroups, this._parents);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/filter.js\n// module id = 211\n// module chunks = 0","import {Selection} from \"./index\";\nimport {EnterNode} from \"./enter\";\nimport constant from \"../constant\";\n\nvar keyPrefix = \"$\"; // Protect against keys like “__proto__”.\n\nfunction bindIndex(parent, group, enter, update, exit, data) {\n var i = 0,\n node,\n groupLength = group.length,\n dataLength = data.length;\n\n // Put any non-null nodes that fit into update.\n // Put any null nodes into enter.\n // Put any remaining data into enter.\n for (; i < dataLength; ++i) {\n if (node = group[i]) {\n node.__data__ = data[i];\n update[i] = node;\n } else {\n enter[i] = new EnterNode(parent, data[i]);\n }\n }\n\n // Put any non-null nodes that don’t fit into exit.\n for (; i < groupLength; ++i) {\n if (node = group[i]) {\n exit[i] = node;\n }\n }\n}\n\nfunction bindKey(parent, group, enter, update, exit, data, key) {\n var i,\n node,\n nodeByKeyValue = {},\n groupLength = group.length,\n dataLength = data.length,\n keyValues = new Array(groupLength),\n keyValue;\n\n // Compute the key for each node.\n // If multiple nodes have the same key, the duplicates are added to exit.\n for (i = 0; i < groupLength; ++i) {\n if (node = group[i]) {\n keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);\n if (keyValue in nodeByKeyValue) {\n exit[i] = node;\n } else {\n nodeByKeyValue[keyValue] = node;\n }\n }\n }\n\n // Compute the key for each datum.\n // If there a node associated with this key, join and add it to update.\n // If there is not (or the key is a duplicate), add it to enter.\n for (i = 0; i < dataLength; ++i) {\n keyValue = keyPrefix + key.call(parent, data[i], i, data);\n if (node = nodeByKeyValue[keyValue]) {\n update[i] = node;\n node.__data__ = data[i];\n nodeByKeyValue[keyValue] = null;\n } else {\n enter[i] = new EnterNode(parent, data[i]);\n }\n }\n\n // Add any remaining nodes that were not bound to data to exit.\n for (i = 0; i < groupLength; ++i) {\n if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {\n exit[i] = node;\n }\n }\n}\n\nexport default function(value, key) {\n if (!value) {\n data = new Array(this.size()), j = -1;\n this.each(function(d) { data[++j] = d; });\n return data;\n }\n\n var bind = key ? bindKey : bindIndex,\n parents = this._parents,\n groups = this._groups;\n\n if (typeof value !== \"function\") value = constant(value);\n\n for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {\n var parent = parents[j],\n group = groups[j],\n groupLength = group.length,\n data = value.call(parent, parent && parent.__data__, j, parents),\n dataLength = data.length,\n enterGroup = enter[j] = new Array(dataLength),\n updateGroup = update[j] = new Array(dataLength),\n exitGroup = exit[j] = new Array(groupLength);\n\n bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);\n\n // Now connect the enter nodes to their following update node, such that\n // appendChild can insert the materialized enter node before this node,\n // rather than at the end of the parent node.\n for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {\n if (previous = enterGroup[i0]) {\n if (i0 >= i1) i1 = i0 + 1;\n while (!(next = updateGroup[i1]) && ++i1 < dataLength);\n previous._next = next || null;\n }\n }\n }\n\n update = new Selection(update, parents);\n update._enter = enter;\n update._exit = exit;\n return update;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/data.js\n// module id = 212\n// module chunks = 0","export default function(x) {\n return function() {\n return x;\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/constant.js\n// module id = 213\n// module chunks = 0","import sparse from \"./sparse\";\nimport {Selection} from \"./index\";\n\nexport default function() {\n return new Selection(this._exit || this._groups.map(sparse), this._parents);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/exit.js\n// module id = 214\n// module chunks = 0","import {Selection} from \"./index\";\n\nexport default function(selection) {\n\n 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) {\n for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group0[i] || group1[i]) {\n merge[i] = node;\n }\n }\n }\n\n for (; j < m0; ++j) {\n merges[j] = groups0[j];\n }\n\n return new Selection(merges, this._parents);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/merge.js\n// module id = 215\n// module chunks = 0","export default function() {\n\n for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {\n for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {\n if (node = group[i]) {\n if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);\n next = node;\n }\n }\n }\n\n return this;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/order.js\n// module id = 216\n// module chunks = 0","import {Selection} from \"./index\";\n\nexport default function(compare) {\n if (!compare) compare = ascending;\n\n function compareNode(a, b) {\n return a && b ? compare(a.__data__, b.__data__) : !a - !b;\n }\n\n for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n sortgroup[i] = node;\n }\n }\n sortgroup.sort(compareNode);\n }\n\n return new Selection(sortgroups, this._parents).order();\n}\n\nfunction ascending(a, b) {\n return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/sort.js\n// module id = 217\n// module chunks = 0","export default function() {\n var callback = arguments[0];\n arguments[0] = this;\n callback.apply(null, arguments);\n return this;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/call.js\n// module id = 218\n// module chunks = 0","export default function() {\n var nodes = new Array(this.size()), i = -1;\n this.each(function() { nodes[++i] = this; });\n return nodes;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/nodes.js\n// module id = 219\n// module chunks = 0","export default function() {\n\n for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {\n var node = group[i];\n if (node) return node;\n }\n }\n\n return null;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/node.js\n// module id = 220\n// module chunks = 0","export default function() {\n var size = 0;\n this.each(function() { ++size; });\n return size;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/size.js\n// module id = 221\n// module chunks = 0","export default function() {\n return !this.node();\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/empty.js\n// module id = 222\n// module chunks = 0","export default function(callback) {\n\n for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {\n if (node = group[i]) callback.call(node, node.__data__, i, group);\n }\n }\n\n return this;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/each.js\n// module id = 223\n// module chunks = 0","import namespace from \"../namespace\";\n\nfunction attrRemove(name) {\n return function() {\n this.removeAttribute(name);\n };\n}\n\nfunction attrRemoveNS(fullname) {\n return function() {\n this.removeAttributeNS(fullname.space, fullname.local);\n };\n}\n\nfunction attrConstant(name, value) {\n return function() {\n this.setAttribute(name, value);\n };\n}\n\nfunction attrConstantNS(fullname, value) {\n return function() {\n this.setAttributeNS(fullname.space, fullname.local, value);\n };\n}\n\nfunction attrFunction(name, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) this.removeAttribute(name);\n else this.setAttribute(name, v);\n };\n}\n\nfunction attrFunctionNS(fullname, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) this.removeAttributeNS(fullname.space, fullname.local);\n else this.setAttributeNS(fullname.space, fullname.local, v);\n };\n}\n\nexport default function(name, value) {\n var fullname = namespace(name);\n\n if (arguments.length < 2) {\n var node = this.node();\n return fullname.local\n ? node.getAttributeNS(fullname.space, fullname.local)\n : node.getAttribute(fullname);\n }\n\n return this.each((value == null\n ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === \"function\"\n ? (fullname.local ? attrFunctionNS : attrFunction)\n : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/attr.js\n// module id = 224\n// module chunks = 0","function propertyRemove(name) {\n return function() {\n delete this[name];\n };\n}\n\nfunction propertyConstant(name, value) {\n return function() {\n this[name] = value;\n };\n}\n\nfunction propertyFunction(name, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) delete this[name];\n else this[name] = v;\n };\n}\n\nexport default function(name, value) {\n return arguments.length > 1\n ? this.each((value == null\n ? propertyRemove : typeof value === \"function\"\n ? propertyFunction\n : propertyConstant)(name, value))\n : this.node()[name];\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/property.js\n// module id = 225\n// module chunks = 0","function classArray(string) {\n return string.trim().split(/^|\\s+/);\n}\n\nfunction classList(node) {\n return node.classList || new ClassList(node);\n}\n\nfunction ClassList(node) {\n this._node = node;\n this._names = classArray(node.getAttribute(\"class\") || \"\");\n}\n\nClassList.prototype = {\n add: function(name) {\n var i = this._names.indexOf(name);\n if (i < 0) {\n this._names.push(name);\n this._node.setAttribute(\"class\", this._names.join(\" \"));\n }\n },\n remove: function(name) {\n var i = this._names.indexOf(name);\n if (i >= 0) {\n this._names.splice(i, 1);\n this._node.setAttribute(\"class\", this._names.join(\" \"));\n }\n },\n contains: function(name) {\n return this._names.indexOf(name) >= 0;\n }\n};\n\nfunction classedAdd(node, names) {\n var list = classList(node), i = -1, n = names.length;\n while (++i < n) list.add(names[i]);\n}\n\nfunction classedRemove(node, names) {\n var list = classList(node), i = -1, n = names.length;\n while (++i < n) list.remove(names[i]);\n}\n\nfunction classedTrue(names) {\n return function() {\n classedAdd(this, names);\n };\n}\n\nfunction classedFalse(names) {\n return function() {\n classedRemove(this, names);\n };\n}\n\nfunction classedFunction(names, value) {\n return function() {\n (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);\n };\n}\n\nexport default function(name, value) {\n var names = classArray(name + \"\");\n\n if (arguments.length < 2) {\n var list = classList(this.node()), i = -1, n = names.length;\n while (++i < n) if (!list.contains(names[i])) return false;\n return true;\n }\n\n return this.each((typeof value === \"function\"\n ? classedFunction : value\n ? classedTrue\n : classedFalse)(names, value));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/classed.js\n// module id = 226\n// module chunks = 0","function textRemove() {\n this.textContent = \"\";\n}\n\nfunction textConstant(value) {\n return function() {\n this.textContent = value;\n };\n}\n\nfunction textFunction(value) {\n return function() {\n var v = value.apply(this, arguments);\n this.textContent = v == null ? \"\" : v;\n };\n}\n\nexport default function(value) {\n return arguments.length\n ? this.each(value == null\n ? textRemove : (typeof value === \"function\"\n ? textFunction\n : textConstant)(value))\n : this.node().textContent;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/text.js\n// module id = 227\n// module chunks = 0","function htmlRemove() {\n this.innerHTML = \"\";\n}\n\nfunction htmlConstant(value) {\n return function() {\n this.innerHTML = value;\n };\n}\n\nfunction htmlFunction(value) {\n return function() {\n var v = value.apply(this, arguments);\n this.innerHTML = v == null ? \"\" : v;\n };\n}\n\nexport default function(value) {\n return arguments.length\n ? this.each(value == null\n ? htmlRemove : (typeof value === \"function\"\n ? htmlFunction\n : htmlConstant)(value))\n : this.node().innerHTML;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/html.js\n// module id = 228\n// module chunks = 0","function raise() {\n if (this.nextSibling) this.parentNode.appendChild(this);\n}\n\nexport default function() {\n return this.each(raise);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/raise.js\n// module id = 229\n// module chunks = 0","function lower() {\n if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);\n}\n\nexport default function() {\n return this.each(lower);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/lower.js\n// module id = 230\n// module chunks = 0","import creator from \"../creator\";\n\nexport default function(name) {\n var create = typeof name === \"function\" ? name : creator(name);\n return this.select(function() {\n return this.appendChild(create.apply(this, arguments));\n });\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/append.js\n// module id = 231\n// module chunks = 0","import creator from \"../creator\";\nimport selector from \"../selector\";\n\nfunction constantNull() {\n return null;\n}\n\nexport default function(name, before) {\n var create = typeof name === \"function\" ? name : creator(name),\n select = before == null ? constantNull : typeof before === \"function\" ? before : selector(before);\n return this.select(function() {\n return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);\n });\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/insert.js\n// module id = 232\n// module chunks = 0","function remove() {\n var parent = this.parentNode;\n if (parent) parent.removeChild(this);\n}\n\nexport default function() {\n return this.each(remove);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/remove.js\n// module id = 233\n// module chunks = 0","export default function(value) {\n return arguments.length\n ? this.property(\"__data__\", value)\n : this.node().__data__;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/datum.js\n// module id = 234\n// module chunks = 0","import defaultView from \"../window\";\n\nfunction dispatchEvent(node, type, params) {\n var window = defaultView(node),\n event = window.CustomEvent;\n\n if (typeof event === \"function\") {\n event = new event(type, params);\n } else {\n event = window.document.createEvent(\"Event\");\n if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;\n else event.initEvent(type, false, false);\n }\n\n node.dispatchEvent(event);\n}\n\nfunction dispatchConstant(type, params) {\n return function() {\n return dispatchEvent(this, type, params);\n };\n}\n\nfunction dispatchFunction(type, params) {\n return function() {\n return dispatchEvent(this, type, params.apply(this, arguments));\n };\n}\n\nexport default function(type, params) {\n return this.each((typeof params === \"function\"\n ? dispatchFunction\n : dispatchConstant)(type, params));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selection/dispatch.js\n// module id = 235\n// module chunks = 0","import {Selection, root} from \"./selection/index\";\n\nexport default function(selector) {\n return typeof selector === \"string\"\n ? new Selection([document.querySelectorAll(selector)], [document.documentElement])\n : new Selection([selector == null ? [] : selector], root);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/selectAll.js\n// module id = 236\n// module chunks = 0","import sourceEvent from \"./sourceEvent\";\nimport point from \"./point\";\n\nexport default function(node, touches, identifier) {\n if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;\n\n for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {\n if ((touch = touches[i]).identifier === identifier) {\n return point(node, touch);\n }\n }\n\n return null;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/touch.js\n// module id = 237\n// module chunks = 0","import sourceEvent from \"./sourceEvent\";\nimport point from \"./point\";\n\nexport default function(node, touches) {\n if (touches == null) touches = sourceEvent().touches;\n\n for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {\n points[i] = point(node, touches[i]);\n }\n\n return points;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-selection/src/touches.js\n// module id = 238\n// module chunks = 0","import {selection} from \"d3-selection\";\nimport selection_interrupt from \"./interrupt\";\nimport selection_transition from \"./transition\";\n\nselection.prototype.interrupt = selection_interrupt;\nselection.prototype.transition = selection_transition;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/selection/index.js\n// module id = 239\n// module chunks = 0","import interrupt from \"../interrupt\";\n\nexport default function(name) {\n return this.each(function() {\n interrupt(this, name);\n });\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/selection/interrupt.js\n// module id = 240\n// module chunks = 0","import {Timer} from \"./timer\";\n\nexport default function(callback, delay, time) {\n var t = new Timer;\n delay = delay == null ? 0 : +delay;\n t.restart(function(elapsed) {\n t.stop();\n callback(elapsed + delay);\n }, delay, time);\n return t;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-timer/src/timeout.js\n// module id = 241\n// module chunks = 0","import {Timer, now} from \"./timer\";\n\nexport default function(callback, delay, time) {\n var t = new Timer, total = delay;\n if (delay == null) return t.restart(callback, delay, time), t;\n delay = +delay, time = time == null ? now() : +time;\n t.restart(function tick(elapsed) {\n elapsed += total;\n t.restart(tick, total += delay, time);\n callback(elapsed);\n }, delay, time);\n return t;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-timer/src/interval.js\n// module id = 242\n// module chunks = 0","import {Transition, newId} from \"../transition/index\";\nimport schedule from \"../transition/schedule\";\nimport {easeCubicInOut} from \"d3-ease\";\nimport {now} from \"d3-timer\";\n\nvar defaultTiming = {\n time: null, // Set on use.\n delay: 0,\n duration: 250,\n ease: easeCubicInOut\n};\n\nfunction inherit(node, id) {\n var timing;\n while (!(timing = node.__transition) || !(timing = timing[id])) {\n if (!(node = node.parentNode)) {\n return defaultTiming.time = now(), defaultTiming;\n }\n }\n return timing;\n}\n\nexport default function(name) {\n var id,\n timing;\n\n if (name instanceof Transition) {\n id = name._id, name = name._name;\n } else {\n id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + \"\";\n }\n\n for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n schedule(node, name, id, i, group, timing || inherit(node, id));\n }\n }\n }\n\n return new Transition(groups, this._parents, name, id);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/selection/transition.js\n// module id = 243\n// module chunks = 0","import {interpolateTransformSvg as interpolateTransform} from \"d3-interpolate\";\nimport {namespace} from \"d3-selection\";\nimport {tweenValue} from \"./tween\";\nimport interpolate from \"./interpolate\";\n\nfunction attrRemove(name) {\n return function() {\n this.removeAttribute(name);\n };\n}\n\nfunction attrRemoveNS(fullname) {\n return function() {\n this.removeAttributeNS(fullname.space, fullname.local);\n };\n}\n\nfunction attrConstant(name, interpolate, value1) {\n var value00,\n interpolate0;\n return function() {\n var value0 = this.getAttribute(name);\n return value0 === value1 ? null\n : value0 === value00 ? interpolate0\n : interpolate0 = interpolate(value00 = value0, value1);\n };\n}\n\nfunction attrConstantNS(fullname, interpolate, value1) {\n var value00,\n interpolate0;\n return function() {\n var value0 = this.getAttributeNS(fullname.space, fullname.local);\n return value0 === value1 ? null\n : value0 === value00 ? interpolate0\n : interpolate0 = interpolate(value00 = value0, value1);\n };\n}\n\nfunction attrFunction(name, interpolate, value) {\n var value00,\n value10,\n interpolate0;\n return function() {\n var value0, value1 = value(this);\n if (value1 == null) return void this.removeAttribute(name);\n value0 = this.getAttribute(name);\n return value0 === value1 ? null\n : value0 === value00 && value1 === value10 ? interpolate0\n : interpolate0 = interpolate(value00 = value0, value10 = value1);\n };\n}\n\nfunction attrFunctionNS(fullname, interpolate, value) {\n var value00,\n value10,\n interpolate0;\n return function() {\n var value0, value1 = value(this);\n if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);\n value0 = this.getAttributeNS(fullname.space, fullname.local);\n return value0 === value1 ? null\n : value0 === value00 && value1 === value10 ? interpolate0\n : interpolate0 = interpolate(value00 = value0, value10 = value1);\n };\n}\n\nexport default function(name, value) {\n var fullname = namespace(name), i = fullname === \"transform\" ? interpolateTransform : interpolate;\n return this.attrTween(name, typeof value === \"function\"\n ? (fullname.local ? attrFunctionNS : attrFunction)(fullname, i, tweenValue(this, \"attr.\" + name, value))\n : value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname)\n : (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value + \"\"));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/attr.js\n// module id = 244\n// module chunks = 0","import {namespace} from \"d3-selection\";\n\nfunction attrTweenNS(fullname, value) {\n function tween() {\n var node = this, i = value.apply(node, arguments);\n return i && function(t) {\n node.setAttributeNS(fullname.space, fullname.local, i(t));\n };\n }\n tween._value = value;\n return tween;\n}\n\nfunction attrTween(name, value) {\n function tween() {\n var node = this, i = value.apply(node, arguments);\n return i && function(t) {\n node.setAttribute(name, i(t));\n };\n }\n tween._value = value;\n return tween;\n}\n\nexport default function(name, value) {\n var key = \"attr.\" + name;\n if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n if (value == null) return this.tween(key, null);\n if (typeof value !== \"function\") throw new Error;\n var fullname = namespace(name);\n return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/attrTween.js\n// module id = 245\n// module chunks = 0","import {get, init} from \"./schedule\";\n\nfunction delayFunction(id, value) {\n return function() {\n init(this, id).delay = +value.apply(this, arguments);\n };\n}\n\nfunction delayConstant(id, value) {\n return value = +value, function() {\n init(this, id).delay = value;\n };\n}\n\nexport default function(value) {\n var id = this._id;\n\n return arguments.length\n ? this.each((typeof value === \"function\"\n ? delayFunction\n : delayConstant)(id, value))\n : get(this.node(), id).delay;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/delay.js\n// module id = 246\n// module chunks = 0","import {get, set} from \"./schedule\";\n\nfunction durationFunction(id, value) {\n return function() {\n set(this, id).duration = +value.apply(this, arguments);\n };\n}\n\nfunction durationConstant(id, value) {\n return value = +value, function() {\n set(this, id).duration = value;\n };\n}\n\nexport default function(value) {\n var id = this._id;\n\n return arguments.length\n ? this.each((typeof value === \"function\"\n ? durationFunction\n : durationConstant)(id, value))\n : get(this.node(), id).duration;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/duration.js\n// module id = 247\n// module chunks = 0","import {get, set} from \"./schedule\";\n\nfunction easeConstant(id, value) {\n if (typeof value !== \"function\") throw new Error;\n return function() {\n set(this, id).ease = value;\n };\n}\n\nexport default function(value) {\n var id = this._id;\n\n return arguments.length\n ? this.each(easeConstant(id, value))\n : get(this.node(), id).ease;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/ease.js\n// module id = 248\n// module chunks = 0","import {matcher} from \"d3-selection\";\nimport {Transition} from \"./index\";\n\nexport default function(match) {\n if (typeof match !== \"function\") match = matcher(match);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n subgroup.push(node);\n }\n }\n }\n\n return new Transition(subgroups, this._parents, this._name, this._id);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/filter.js\n// module id = 249\n// module chunks = 0","import {Transition} from \"./index\";\n\nexport default function(transition) {\n if (transition._id !== this._id) throw new Error;\n\n 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) {\n for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group0[i] || group1[i]) {\n merge[i] = node;\n }\n }\n }\n\n for (; j < m0; ++j) {\n merges[j] = groups0[j];\n }\n\n return new Transition(merges, this._parents, this._name, this._id);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/merge.js\n// module id = 250\n// module chunks = 0","import {get, set, init} from \"./schedule\";\n\nfunction start(name) {\n return (name + \"\").trim().split(/^|\\s+/).every(function(t) {\n var i = t.indexOf(\".\");\n if (i >= 0) t = t.slice(0, i);\n return !t || t === \"start\";\n });\n}\n\nfunction onFunction(id, name, listener) {\n var on0, on1, sit = start(name) ? init : set;\n return function() {\n var schedule = sit(this, id),\n on = schedule.on;\n\n // If this node shared a dispatch with the previous node,\n // just assign the updated shared dispatch and we’re done!\n // Otherwise, copy-on-write.\n if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);\n\n schedule.on = on1;\n };\n}\n\nexport default function(name, listener) {\n var id = this._id;\n\n return arguments.length < 2\n ? get(this.node(), id).on.on(name)\n : this.each(onFunction(id, name, listener));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/on.js\n// module id = 251\n// module chunks = 0","function removeFunction(id) {\n return function() {\n var parent = this.parentNode;\n for (var i in this.__transition) if (+i !== id) return;\n if (parent) parent.removeChild(this);\n };\n}\n\nexport default function() {\n return this.on(\"end.remove\", removeFunction(this._id));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/remove.js\n// module id = 252\n// module chunks = 0","import {selector} from \"d3-selection\";\nimport {Transition} from \"./index\";\nimport schedule, {get} from \"./schedule\";\n\nexport default function(select) {\n var name = this._name,\n id = this._id;\n\n if (typeof select !== \"function\") select = selector(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n if (\"__data__\" in node) subnode.__data__ = node.__data__;\n subgroup[i] = subnode;\n schedule(subgroup[i], name, id, i, subgroup, get(node, id));\n }\n }\n }\n\n return new Transition(subgroups, this._parents, name, id);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/select.js\n// module id = 253\n// module chunks = 0","import {selectorAll} from \"d3-selection\";\nimport {Transition} from \"./index\";\nimport schedule, {get} from \"./schedule\";\n\nexport default function(select) {\n var name = this._name,\n id = this._id;\n\n if (typeof select !== \"function\") select = selectorAll(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, id), k = 0, l = children.length; k < l; ++k) {\n if (child = children[k]) {\n schedule(child, name, id, k, children, inherit);\n }\n }\n subgroups.push(children);\n parents.push(node);\n }\n }\n }\n\n return new Transition(subgroups, parents, name, id);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/selectAll.js\n// module id = 254\n// module chunks = 0","import {selection} from \"d3-selection\";\n\nvar Selection = selection.prototype.constructor;\n\nexport default function() {\n return new Selection(this._groups, this._parents);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/selection.js\n// module id = 255\n// module chunks = 0","import {interpolateTransformCss as interpolateTransform} from \"d3-interpolate\";\nimport {style} from \"d3-selection\";\nimport {tweenValue} from \"./tween\";\nimport interpolate from \"./interpolate\";\n\nfunction styleRemove(name, interpolate) {\n var value00,\n value10,\n interpolate0;\n return function() {\n var value0 = style(this, name),\n value1 = (this.style.removeProperty(name), style(this, name));\n return value0 === value1 ? null\n : value0 === value00 && value1 === value10 ? interpolate0\n : interpolate0 = interpolate(value00 = value0, value10 = value1);\n };\n}\n\nfunction styleRemoveEnd(name) {\n return function() {\n this.style.removeProperty(name);\n };\n}\n\nfunction styleConstant(name, interpolate, value1) {\n var value00,\n interpolate0;\n return function() {\n var value0 = style(this, name);\n return value0 === value1 ? null\n : value0 === value00 ? interpolate0\n : interpolate0 = interpolate(value00 = value0, value1);\n };\n}\n\nfunction styleFunction(name, interpolate, value) {\n var value00,\n value10,\n interpolate0;\n return function() {\n var value0 = style(this, name),\n value1 = value(this);\n if (value1 == null) value1 = (this.style.removeProperty(name), style(this, name));\n return value0 === value1 ? null\n : value0 === value00 && value1 === value10 ? interpolate0\n : interpolate0 = interpolate(value00 = value0, value10 = value1);\n };\n}\n\nexport default function(name, value, priority) {\n var i = (name += \"\") === \"transform\" ? interpolateTransform : interpolate;\n return value == null ? this\n .styleTween(name, styleRemove(name, i))\n .on(\"end.style.\" + name, styleRemoveEnd(name))\n : this.styleTween(name, typeof value === \"function\"\n ? styleFunction(name, i, tweenValue(this, \"style.\" + name, value))\n : styleConstant(name, i, value + \"\"), priority);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/style.js\n// module id = 256\n// module chunks = 0","function styleTween(name, value, priority) {\n function tween() {\n var node = this, i = value.apply(node, arguments);\n return i && function(t) {\n node.style.setProperty(name, i(t), priority);\n };\n }\n tween._value = value;\n return tween;\n}\n\nexport default function(name, value, priority) {\n var key = \"style.\" + (name += \"\");\n if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n if (value == null) return this.tween(key, null);\n if (typeof value !== \"function\") throw new Error;\n return this.tween(key, styleTween(name, value, priority == null ? \"\" : priority));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/styleTween.js\n// module id = 257\n// module chunks = 0","import {tweenValue} from \"./tween\";\n\nfunction textConstant(value) {\n return function() {\n this.textContent = value;\n };\n}\n\nfunction textFunction(value) {\n return function() {\n var value1 = value(this);\n this.textContent = value1 == null ? \"\" : value1;\n };\n}\n\nexport default function(value) {\n return this.tween(\"text\", typeof value === \"function\"\n ? textFunction(tweenValue(this, \"text\", value))\n : textConstant(value == null ? \"\" : value + \"\"));\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/text.js\n// module id = 258\n// module chunks = 0","import {Transition, newId} from \"./index\";\nimport schedule, {get} from \"./schedule\";\n\nexport default function() {\n var name = this._name,\n id0 = this._id,\n id1 = newId();\n\n for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n var inherit = get(node, id0);\n schedule(node, name, id1, i, group, {\n time: inherit.time + inherit.delay + inherit.duration,\n delay: 0,\n duration: inherit.duration,\n ease: inherit.ease\n });\n }\n }\n }\n\n return new Transition(groups, this._parents, name, id1);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/transition/transition.js\n// module id = 259\n// module chunks = 0","import {Transition} from \"./transition/index\";\nimport {SCHEDULED} from \"./transition/schedule\";\n\nvar root = [null];\n\nexport default function(node, name) {\n var schedules = node.__transition,\n schedule,\n i;\n\n if (schedules) {\n name = name == null ? null : name + \"\";\n for (i in schedules) {\n if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) {\n return new Transition([[node]], root, name, +i);\n }\n }\n }\n\n return null;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-transition/src/active.js\n// module id = 260\n// module chunks = 0","import {path} from \"d3-path\";\nimport constant from \"./constant\";\nimport {abs, acos, asin, atan2, cos, epsilon, halfPi, max, min, pi, sin, sqrt, tau} from \"./math\";\n\nfunction arcInnerRadius(d) {\n return d.innerRadius;\n}\n\nfunction arcOuterRadius(d) {\n return d.outerRadius;\n}\n\nfunction arcStartAngle(d) {\n return d.startAngle;\n}\n\nfunction arcEndAngle(d) {\n return d.endAngle;\n}\n\nfunction arcPadAngle(d) {\n return d && d.padAngle; // Note: optional!\n}\n\nfunction intersect(x0, y0, x1, y1, x2, y2, x3, y3) {\n var x10 = x1 - x0, y10 = y1 - y0,\n x32 = x3 - x2, y32 = y3 - y2,\n t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);\n return [x0 + t * x10, y0 + t * y10];\n}\n\n// Compute perpendicular offset line of length rc.\n// http://mathworld.wolfram.com/Circle-LineIntersection.html\nfunction cornerTangents(x0, y0, x1, y1, r1, rc, cw) {\n var x01 = x0 - x1,\n y01 = y0 - y1,\n lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01),\n ox = lo * y01,\n oy = -lo * x01,\n x11 = x0 + ox,\n y11 = y0 + oy,\n x10 = x1 + ox,\n y10 = y1 + oy,\n x00 = (x11 + x10) / 2,\n y00 = (y11 + y10) / 2,\n dx = x10 - x11,\n dy = y10 - y11,\n d2 = dx * dx + dy * dy,\n r = r1 - rc,\n D = x11 * y10 - x10 * y11,\n d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)),\n cx0 = (D * dy - dx * d) / d2,\n cy0 = (-D * dx - dy * d) / d2,\n cx1 = (D * dy + dx * d) / d2,\n cy1 = (-D * dx + dy * d) / d2,\n dx0 = cx0 - x00,\n dy0 = cy0 - y00,\n dx1 = cx1 - x00,\n dy1 = cy1 - y00;\n\n // Pick the closer of the two intersection points.\n // TODO Is there a faster way to determine which intersection to use?\n if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;\n\n return {\n cx: cx0,\n cy: cy0,\n x01: -ox,\n y01: -oy,\n x11: cx0 * (r1 / r - 1),\n y11: cy0 * (r1 / r - 1)\n };\n}\n\nexport default function() {\n var innerRadius = arcInnerRadius,\n outerRadius = arcOuterRadius,\n cornerRadius = constant(0),\n padRadius = null,\n startAngle = arcStartAngle,\n endAngle = arcEndAngle,\n padAngle = arcPadAngle,\n context = null;\n\n function arc() {\n var buffer,\n r,\n r0 = +innerRadius.apply(this, arguments),\n r1 = +outerRadius.apply(this, arguments),\n a0 = startAngle.apply(this, arguments) - halfPi,\n a1 = endAngle.apply(this, arguments) - halfPi,\n da = abs(a1 - a0),\n cw = a1 > a0;\n\n if (!context) context = buffer = path();\n\n // Ensure that the outer radius is always larger than the inner radius.\n if (r1 < r0) r = r1, r1 = r0, r0 = r;\n\n // Is it a point?\n if (!(r1 > epsilon)) context.moveTo(0, 0);\n\n // Or is it a circle or annulus?\n else if (da > tau - epsilon) {\n context.moveTo(r1 * cos(a0), r1 * sin(a0));\n context.arc(0, 0, r1, a0, a1, !cw);\n if (r0 > epsilon) {\n context.moveTo(r0 * cos(a1), r0 * sin(a1));\n context.arc(0, 0, r0, a1, a0, cw);\n }\n }\n\n // Or is it a circular or annular sector?\n else {\n var a01 = a0,\n a11 = a1,\n a00 = a0,\n a10 = a1,\n da0 = da,\n da1 = da,\n ap = padAngle.apply(this, arguments) / 2,\n rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)),\n rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),\n rc0 = rc,\n rc1 = rc,\n t0,\n t1;\n\n // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.\n if (rp > epsilon) {\n var p0 = asin(rp / r0 * sin(ap)),\n p1 = asin(rp / r1 * sin(ap));\n if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;\n else da0 = 0, a00 = a10 = (a0 + a1) / 2;\n if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;\n else da1 = 0, a01 = a11 = (a0 + a1) / 2;\n }\n\n var x01 = r1 * cos(a01),\n y01 = r1 * sin(a01),\n x10 = r0 * cos(a10),\n y10 = r0 * sin(a10);\n\n // Apply rounded corners?\n if (rc > epsilon) {\n var x11 = r1 * cos(a11),\n y11 = r1 * sin(a11),\n x00 = r0 * cos(a00),\n y00 = r0 * sin(a00);\n\n // Restrict the corner radius according to the sector angle.\n if (da < pi) {\n var oc = da0 > epsilon ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],\n ax = x01 - oc[0],\n ay = y01 - oc[1],\n bx = x11 - oc[0],\n by = y11 - oc[1],\n kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2),\n lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]);\n rc0 = min(rc, (r0 - lc) / (kc - 1));\n rc1 = min(rc, (r1 - lc) / (kc + 1));\n }\n }\n\n // Is the sector collapsed to a line?\n if (!(da1 > epsilon)) context.moveTo(x01, y01);\n\n // Does the sector’s outer ring have rounded corners?\n else if (rc1 > epsilon) {\n t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);\n t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);\n\n context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);\n context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the outer ring just a circular arc?\n else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);\n\n // Is there no inner ring, and it’s a circular sector?\n // Or perhaps it’s an annular sector collapsed due to padding?\n if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10);\n\n // Does the sector’s inner ring (or point) have rounded corners?\n else if (rc0 > epsilon) {\n t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);\n t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);\n\n context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);\n context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the inner ring just a circular arc?\n else context.arc(0, 0, r0, a10, a00, cw);\n }\n\n context.closePath();\n\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n arc.centroid = function() {\n var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,\n a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;\n return [cos(a) * r, sin(a) * r];\n };\n\n arc.innerRadius = function(_) {\n return arguments.length ? (innerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : innerRadius;\n };\n\n arc.outerRadius = function(_) {\n return arguments.length ? (outerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : outerRadius;\n };\n\n arc.cornerRadius = function(_) {\n return arguments.length ? (cornerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : cornerRadius;\n };\n\n arc.padRadius = function(_) {\n return arguments.length ? (padRadius = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), arc) : padRadius;\n };\n\n arc.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : startAngle;\n };\n\n arc.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : endAngle;\n };\n\n arc.padAngle = function(_) {\n return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : padAngle;\n };\n\n arc.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), arc) : context;\n };\n\n return arc;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/arc.js\n// module id = 261\n// module chunks = 0","var pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction Path() {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n}\n\nfunction path() {\n return new Path;\n}\n\nPath.prototype = path.prototype = {\n constructor: Path,\n moveTo: function(x, y) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n },\n closePath: function() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._ += \"Z\";\n }\n },\n lineTo: function(x, y) {\n this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n quadraticCurveTo: function(x1, y1, x, y) {\n this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n arcTo: function(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n var x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon)) {}\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Otherwise, draw an arc!\n else {\n var x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n }\n\n this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n }\n },\n arc: function(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r;\n var dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._ += \"M\" + x0 + \",\" + y0;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._ += \"L\" + x0 + \",\" + y0;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n }\n },\n rect: function(x, y, w, h) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n },\n toString: function() {\n return this._;\n }\n};\n\nexport default path;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-path/src/path.js\n// module id = 262\n// module chunks = 0","import constant from \"./constant\";\nimport descending from \"./descending\";\nimport identity from \"./identity\";\nimport {tau} from \"./math\";\n\nexport default function() {\n var value = identity,\n sortValues = descending,\n sort = null,\n startAngle = constant(0),\n endAngle = constant(tau),\n padAngle = constant(0);\n\n function pie(data) {\n var i,\n n = data.length,\n j,\n k,\n sum = 0,\n index = new Array(n),\n arcs = new Array(n),\n a0 = +startAngle.apply(this, arguments),\n da = Math.min(tau, Math.max(-tau, endAngle.apply(this, arguments) - a0)),\n a1,\n p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),\n pa = p * (da < 0 ? -1 : 1),\n v;\n\n for (i = 0; i < n; ++i) {\n if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {\n sum += v;\n }\n }\n\n // Optionally sort the arcs by previously-computed values or by data.\n if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });\n else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });\n\n // Compute the arcs! They are stored in the original data's order.\n for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {\n j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {\n data: data[j],\n index: i,\n value: v,\n startAngle: a0,\n endAngle: a1,\n padAngle: p\n };\n }\n\n return arcs;\n }\n\n pie.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : constant(+_), pie) : value;\n };\n\n pie.sortValues = function(_) {\n return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;\n };\n\n pie.sort = function(_) {\n return arguments.length ? (sort = _, sortValues = null, pie) : sort;\n };\n\n pie.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant(+_), pie) : startAngle;\n };\n\n pie.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant(+_), pie) : endAngle;\n };\n\n pie.padAngle = function(_) {\n return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant(+_), pie) : padAngle;\n };\n\n return pie;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/pie.js\n// module id = 263\n// module chunks = 0","export default function(a, b) {\n return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/descending.js\n// module id = 264\n// module chunks = 0","export default function(d) {\n return d;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/identity.js\n// module id = 265\n// module chunks = 0","import curveRadial, {curveRadialLinear} from \"./curve/radial\";\nimport area from \"./area\";\nimport {lineRadial} from \"./lineRadial\"\n\nexport default function() {\n var a = area().curve(curveRadialLinear),\n c = a.curve,\n x0 = a.lineX0,\n x1 = a.lineX1,\n y0 = a.lineY0,\n y1 = a.lineY1;\n\n a.angle = a.x, delete a.x;\n a.startAngle = a.x0, delete a.x0;\n a.endAngle = a.x1, delete a.x1;\n a.radius = a.y, delete a.y;\n a.innerRadius = a.y0, delete a.y0;\n a.outerRadius = a.y1, delete a.y1;\n a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0;\n a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1;\n a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0;\n a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1;\n\n a.curve = function(_) {\n return arguments.length ? c(curveRadial(_)) : c()._curve;\n };\n\n return a;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/areaRadial.js\n// module id = 266\n// module chunks = 0","import {path} from \"d3-path\";\nimport {slice} from \"../array\";\nimport constant from \"../constant\";\nimport {x as pointX, y as pointY} from \"../point\";\nimport pointRadial from \"../pointRadial\";\n\nfunction linkSource(d) {\n return d.source;\n}\n\nfunction linkTarget(d) {\n return d.target;\n}\n\nfunction link(curve) {\n var source = linkSource,\n target = linkTarget,\n x = pointX,\n y = pointY,\n context = null;\n\n function link() {\n var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);\n if (!context) context = buffer = path();\n curve(context, +x.apply(this, (argv[0] = s, argv)), +y.apply(this, argv), +x.apply(this, (argv[0] = t, argv)), +y.apply(this, argv));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n link.source = function(_) {\n return arguments.length ? (source = _, link) : source;\n };\n\n link.target = function(_) {\n return arguments.length ? (target = _, link) : target;\n };\n\n link.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant(+_), link) : x;\n };\n\n link.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant(+_), link) : y;\n };\n\n link.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), link) : context;\n };\n\n return link;\n}\n\nfunction curveHorizontal(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);\n}\n\nfunction curveVertical(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);\n}\n\nfunction curveRadial(context, x0, y0, x1, y1) {\n var p0 = pointRadial(x0, y0),\n p1 = pointRadial(x0, y0 = (y0 + y1) / 2),\n p2 = pointRadial(x1, y0),\n p3 = pointRadial(x1, y1);\n context.moveTo(p0[0], p0[1]);\n context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);\n}\n\nexport function linkHorizontal() {\n return link(curveHorizontal);\n}\n\nexport function linkVertical() {\n return link(curveVertical);\n}\n\nexport function linkRadial() {\n var l = link(curveRadial);\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n return l;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/link/index.js\n// module id = 267\n// module chunks = 0","import {path} from \"d3-path\";\nimport circle from \"./symbol/circle\";\nimport cross from \"./symbol/cross\";\nimport diamond from \"./symbol/diamond\";\nimport star from \"./symbol/star\";\nimport square from \"./symbol/square\";\nimport triangle from \"./symbol/triangle\";\nimport wye from \"./symbol/wye\";\nimport constant from \"./constant\";\n\nexport var symbols = [\n circle,\n cross,\n diamond,\n square,\n star,\n triangle,\n wye\n];\n\nexport default function() {\n var type = constant(circle),\n size = constant(64),\n context = null;\n\n function symbol() {\n var buffer;\n if (!context) context = buffer = path();\n type.apply(this, arguments).draw(context, +size.apply(this, arguments));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n symbol.type = function(_) {\n return arguments.length ? (type = typeof _ === \"function\" ? _ : constant(_), symbol) : type;\n };\n\n symbol.size = function(_) {\n return arguments.length ? (size = typeof _ === \"function\" ? _ : constant(+_), symbol) : size;\n };\n\n symbol.context = function(_) {\n return arguments.length ? (context = _ == null ? null : _, symbol) : context;\n };\n\n return symbol;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/symbol.js\n// module id = 268\n// module chunks = 0","import noop from \"../noop\";\nimport {point} from \"./basis\";\n\nfunction BasisClosed(context) {\n this._context = context;\n}\n\nBasisClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x2, this._y2);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);\n this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x2, this._y2);\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x2 = x, this._y2 = y; break;\n case 1: this._point = 2; this._x3 = x, this._y3 = y; break;\n case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new BasisClosed(context);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/curve/basisClosed.js\n// module id = 269\n// module chunks = 0","import {point} from \"./basis\";\n\nfunction BasisOpen(context) {\n this._context = context;\n}\n\nBasisOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;\n case 3: this._point = 4; // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new BasisOpen(context);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/curve/basisOpen.js\n// module id = 270\n// module chunks = 0","import {Basis} from \"./basis\";\n\nfunction Bundle(context, beta) {\n this._basis = new Basis(context);\n this._beta = beta;\n}\n\nBundle.prototype = {\n lineStart: function() {\n this._x = [];\n this._y = [];\n this._basis.lineStart();\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n j = x.length - 1;\n\n if (j > 0) {\n var x0 = x[0],\n y0 = y[0],\n dx = x[j] - x0,\n dy = y[j] - y0,\n i = -1,\n t;\n\n while (++i <= j) {\n t = i / j;\n this._basis.point(\n this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),\n this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)\n );\n }\n }\n\n this._x = this._y = null;\n this._basis.lineEnd();\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\nexport default (function custom(beta) {\n\n function bundle(context) {\n return beta === 1 ? new Basis(context) : new Bundle(context, beta);\n }\n\n bundle.beta = function(beta) {\n return custom(+beta);\n };\n\n return bundle;\n})(0.85);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/curve/bundle.js\n// module id = 271\n// module chunks = 0","import {CardinalClosed} from \"./cardinalClosed\";\nimport noop from \"../noop\";\nimport {point} from \"./catmullRom\";\n\nfunction CatmullRomClosed(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/curve/catmullRomClosed.js\n// module id = 272\n// module chunks = 0","import {CardinalOpen} from \"./cardinalOpen\";\nimport {point} from \"./catmullRom\";\n\nfunction CatmullRomOpen(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // proceed\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/curve/catmullRomOpen.js\n// module id = 273\n// module chunks = 0","import noop from \"../noop\";\n\nfunction LinearClosed(context) {\n this._context = context;\n}\n\nLinearClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._point) this._context.closePath();\n },\n point: function(x, y) {\n x = +x, y = +y;\n if (this._point) this._context.lineTo(x, y);\n else this._point = 1, this._context.moveTo(x, y);\n }\n};\n\nexport default function(context) {\n return new LinearClosed(context);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/curve/linearClosed.js\n// module id = 274\n// module chunks = 0","function sign(x) {\n return x < 0 ? -1 : 1;\n}\n\n// Calculate the slopes of the tangents (Hermite-type interpolation) based on\n// the following paper: Steffen, M. 1990. A Simple Method for Monotonic\n// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.\n// NOV(II), P. 443, 1990.\nfunction slope3(that, x2, y2) {\n var h0 = that._x1 - that._x0,\n h1 = x2 - that._x1,\n s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),\n s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),\n p = (s0 * h1 + s1 * h0) / (h0 + h1);\n return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;\n}\n\n// Calculate a one-sided slope.\nfunction slope2(that, t) {\n var h = that._x1 - that._x0;\n return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;\n}\n\n// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations\n// \"you can express cubic Hermite interpolation in terms of cubic Bézier curves\n// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1\".\nfunction point(that, t0, t1) {\n var x0 = that._x0,\n y0 = that._y0,\n x1 = that._x1,\n y1 = that._y1,\n dx = (x1 - x0) / 3;\n that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);\n}\n\nfunction MonotoneX(context) {\n this._context = context;\n}\n\nMonotoneX.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 =\n this._t0 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x1, this._y1); break;\n case 3: point(this, this._t0, slope2(this, this._t0)); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n var t1 = NaN;\n\n x = +x, y = +y;\n if (x === this._x1 && y === this._y1) return; // Ignore coincident points.\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break;\n default: point(this, this._t0, t1 = slope3(this, x, y)); break;\n }\n\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n this._t0 = t1;\n }\n}\n\nfunction MonotoneY(context) {\n this._context = new ReflectContext(context);\n}\n\n(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {\n MonotoneX.prototype.point.call(this, y, x);\n};\n\nfunction ReflectContext(context) {\n this._context = context;\n}\n\nReflectContext.prototype = {\n moveTo: function(x, y) { this._context.moveTo(y, x); },\n closePath: function() { this._context.closePath(); },\n lineTo: function(x, y) { this._context.lineTo(y, x); },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }\n};\n\nexport function monotoneX(context) {\n return new MonotoneX(context);\n}\n\nexport function monotoneY(context) {\n return new MonotoneY(context);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/curve/monotone.js\n// module id = 275\n// module chunks = 0","function Natural(context) {\n this._context = context;\n}\n\nNatural.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = [];\n this._y = [];\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n n = x.length;\n\n if (n) {\n this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);\n if (n === 2) {\n this._context.lineTo(x[1], y[1]);\n } else {\n var px = controlPoints(x),\n py = controlPoints(y);\n for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {\n this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);\n }\n }\n }\n\n if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();\n this._line = 1 - this._line;\n this._x = this._y = null;\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\n// See https://www.particleincell.com/2012/bezier-splines/ for derivation.\nfunction controlPoints(x) {\n var i,\n n = x.length - 1,\n m,\n a = new Array(n),\n b = new Array(n),\n r = new Array(n);\n a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];\n for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];\n a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];\n for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];\n a[n - 1] = r[n - 1] / b[n - 1];\n for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];\n b[n - 1] = (x[n] + a[n - 1]) / 2;\n for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];\n return [a, b];\n}\n\nexport default function(context) {\n return new Natural(context);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/curve/natural.js\n// module id = 276\n// module chunks = 0","function Step(context, t) {\n this._context = context;\n this._t = t;\n}\n\nStep.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = this._y = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // proceed\n default: {\n if (this._t <= 0) {\n this._context.lineTo(this._x, y);\n this._context.lineTo(x, y);\n } else {\n var x1 = this._x * (1 - this._t) + x * this._t;\n this._context.lineTo(x1, this._y);\n this._context.lineTo(x1, y);\n }\n break;\n }\n }\n this._x = x, this._y = y;\n }\n};\n\nexport default function(context) {\n return new Step(context, 0.5);\n}\n\nexport function stepBefore(context) {\n return new Step(context, 0);\n}\n\nexport function stepAfter(context) {\n return new Step(context, 1);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/curve/step.js\n// module id = 277\n// module chunks = 0","import {slice} from \"./array\";\nimport constant from \"./constant\";\nimport offsetNone from \"./offset/none\";\nimport orderNone from \"./order/none\";\n\nfunction stackValue(d, key) {\n return d[key];\n}\n\nexport default function() {\n var keys = constant([]),\n order = orderNone,\n offset = offsetNone,\n value = stackValue;\n\n function stack(data) {\n var kz = keys.apply(this, arguments),\n i,\n m = data.length,\n n = kz.length,\n sz = new Array(n),\n oz;\n\n for (i = 0; i < n; ++i) {\n for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {\n si[j] = sij = [0, +value(data[j], ki, j, data)];\n sij.data = data[j];\n }\n si.key = ki;\n }\n\n for (i = 0, oz = order(sz); i < n; ++i) {\n sz[oz[i]].index = i;\n }\n\n offset(sz, oz);\n return sz;\n }\n\n stack.keys = function(_) {\n return arguments.length ? (keys = typeof _ === \"function\" ? _ : constant(slice.call(_)), stack) : keys;\n };\n\n stack.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : constant(+_), stack) : value;\n };\n\n stack.order = function(_) {\n return arguments.length ? (order = _ == null ? orderNone : typeof _ === \"function\" ? _ : constant(slice.call(_)), stack) : order;\n };\n\n stack.offset = function(_) {\n return arguments.length ? (offset = _ == null ? offsetNone : _, stack) : offset;\n };\n\n return stack;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/stack.js\n// module id = 278\n// module chunks = 0","import none from \"./none\";\n\nexport default function(series, order) {\n if (!((n = series.length) > 0)) return;\n for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {\n for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;\n if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;\n }\n none(series, order);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/offset/expand.js\n// module id = 279\n// module chunks = 0","export default function(series, order) {\n if (!((n = series.length) > 1)) return;\n for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) {\n for (yp = yn = 0, i = 0; i < n; ++i) {\n if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) {\n d[0] = yp, d[1] = yp += dy;\n } else if (dy < 0) {\n d[1] = yn, d[0] = yn += dy;\n } else {\n d[0] = yp;\n }\n }\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/offset/diverging.js\n// module id = 280\n// module chunks = 0","import none from \"./none\";\n\nexport default function(series, order) {\n if (!((n = series.length) > 0)) return;\n for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {\n for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;\n s0[j][1] += s0[j][0] = -y / 2;\n }\n none(series, order);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/offset/silhouette.js\n// module id = 281\n// module chunks = 0","import none from \"./none\";\n\nexport default function(series, order) {\n if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;\n for (var y = 0, j = 1, s0, m, n; j < m; ++j) {\n for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {\n var si = series[order[i]],\n sij0 = si[j][1] || 0,\n sij1 = si[j - 1][1] || 0,\n s3 = (sij0 - sij1) / 2;\n for (var k = 0; k < i; ++k) {\n var sk = series[order[k]],\n skj0 = sk[j][1] || 0,\n skj1 = sk[j - 1][1] || 0;\n s3 += skj0 - skj1;\n }\n s1 += sij0, s2 += s3 * sij0;\n }\n s0[j - 1][1] += s0[j - 1][0] = y;\n if (s1) y -= s2 / s1;\n }\n s0[j - 1][1] += s0[j - 1][0] = y;\n none(series, order);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/offset/wiggle.js\n// module id = 282\n// module chunks = 0","import ascending from \"./ascending\";\n\nexport default function(series) {\n return ascending(series).reverse();\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/order/descending.js\n// module id = 283\n// module chunks = 0","import none from \"./none\";\nimport {sum} from \"./ascending\";\n\nexport default function(series) {\n var n = series.length,\n i,\n j,\n sums = series.map(sum),\n order = none(series).sort(function(a, b) { return sums[b] - sums[a]; }),\n top = 0,\n bottom = 0,\n tops = [],\n bottoms = [];\n\n for (i = 0; i < n; ++i) {\n j = order[i];\n if (top < bottom) {\n top += sums[j];\n tops.push(j);\n } else {\n bottom += sums[j];\n bottoms.push(j);\n }\n }\n\n return bottoms.reverse().concat(tops);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/order/insideOut.js\n// module id = 284\n// module chunks = 0","import none from \"./none\";\n\nexport default function(series) {\n return none(series).reverse();\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-shape/src/order/reverse.js\n// module id = 285\n// module chunks = 0","module.exports = (function() {\n\n 'use strict';\n\n // Styles inherited from style sheets will not be rendered for elements with these tag names\n const noStyleTags = {\n 'BASE': true,\n 'HEAD': true,\n 'HTML': true,\n 'META': true,\n 'NOFRAME': true,\n 'NOSCRIPT': true,\n 'PARAM': true,\n 'SCRIPT': true,\n 'STYLE': true,\n 'TITLE': true\n };\n\n // This list determines which css default values lookup tables are precomputed at load time\n // Lookup tables for other tag names will be automatically built at runtime if needed\n const tagNames = ['A', 'ABBR', 'ADDRESS', 'AREA', 'ARTICLE', 'ASIDE', 'AUDIO', 'B', 'BASE', 'BDI', 'BDO', 'BLOCKQUOTE', 'BODY', 'BR', 'BUTTON', 'CANVAS', 'CAPTION', 'CENTER', 'CITE', 'CODE', 'COL', 'COLGROUP', 'COMMAND', 'DATALIST', 'DD', 'DEL', 'DETAILS', 'DFN', 'DIV', 'DL', 'DT', 'EM', 'EMBED', 'FIELDSET', 'FIGCAPTION', 'FIGURE', 'FONT', 'FOOTER', 'FORM', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEAD', 'HEADER', 'HGROUP', 'HR', 'HTML', 'I', 'IFRAME', 'IMG', 'INPUT', 'INS', 'KBD', 'LABEL', 'LEGEND', 'LI', 'LINK', 'MAP', 'MARK', 'MATH', 'MENU', 'META', 'METER', 'NAV', 'NOBR', 'NOSCRIPT', 'OBJECT', 'OL', 'OPTION', 'OPTGROUP', 'OUTPUT', 'P', 'PARAM', 'PRE', 'PROGRESS', 'Q', 'RP', 'RT', 'RUBY', 'S', 'SAMP', 'SCRIPT', 'SECTION', 'SELECT', 'SMALL', 'SOURCE', 'SPAN', 'STRONG', 'STYLE', 'SUB', 'SUMMARY', 'SUP', 'SVG', 'TABLE', 'TBODY', 'TD', 'TEXTAREA', 'TFOOT', 'TH', 'THEAD', 'TIME', 'TITLE', 'TR', 'TRACK', 'U', 'UL', 'VAR', 'VIDEO', 'WBR'];\n\n /**\n * Extracts the styles of elements of the given tag name\n * @param {String} tagName Tag name that we will check for styles\n * @return {Object} Values of the styles applied to the given element\n */\n const computeDefaultStyleByTagName = (tagName) => {\n let defaultStyle = {},\n element = document.body.appendChild(document.createElement(tagName)),\n computedStyle = window.getComputedStyle(element);\n\n [].forEach.call(computedStyle, (style) => {\n defaultStyle[style] = computedStyle[style];\n });\n document.body.removeChild(element);\n\n return defaultStyle;\n };\n\n return {\n\n /**\n * returns serializer function, only run it when you know you want to serialize your chart\n * @return {func} serializer to add styles in line to dom string\n */\n initializeSerializer() {\n\n // Mapping between tag names and css default values lookup tables. This allows to exclude default values in the result.\n var defaultStylesByTagName = {};\n\n // Precompute the lookup tables.\n [].forEach.call(tagNames, (name) => {\n if (!noStyleTags[name]) {\n defaultStylesByTagName[name] = computeDefaultStyleByTagName(name);\n }\n });\n\n function getDefaultStyleByTagName(tagName) {\n tagName = tagName.toUpperCase();\n\n if (!defaultStylesByTagName[tagName]) {\n defaultStylesByTagName[tagName] = computeDefaultStyleByTagName(tagName);\n }\n\n return defaultStylesByTagName[tagName];\n }\n\n function serializeWithStyles(elem) {\n let cssTexts = [],\n elements,\n computedStyle,\n defaultStyle,\n result;\n\n if (!elem || elem.nodeType !== Node.ELEMENT_NODE) {\n // 'Error: Object passed in to serializeWithSyles not of nodeType Node.ELEMENT_NODE'\n\n return;\n }\n\n cssTexts = [];\n elements = elem.querySelectorAll('*');\n\n [].forEach.call(elements, (el, i) => {\n if (!noStyleTags[el.tagName]) {\n computedStyle = window.getComputedStyle(el);\n defaultStyle = getDefaultStyleByTagName(el.tagName);\n cssTexts[i] = el.style.cssText;\n [].forEach.call(computedStyle, (cssPropName) => {\n if (computedStyle[cssPropName] !== defaultStyle[cssPropName]) {\n el.style[cssPropName] = computedStyle[cssPropName];\n }\n });\n }\n });\n\n result = elem.outerHTML;\n elements = [].map.call(elements, (el, i) => {\n el.style.cssText = cssTexts[i];\n\n return el;\n });\n\n return result;\n };\n\n return serializeWithStyles;\n }\n }\n})();\n\n\n// WEBPACK FOOTER //\n// ./src/charts/helpers/style.js","/*! http://mths.be/base64 v0.1.0 by @mathias | MIT license */\n;(function(root) {\n\n\t// Detect free variables `exports`.\n\tvar freeExports = typeof exports == 'object' && exports;\n\n\t// Detect free variable `module`.\n\tvar freeModule = typeof module == 'object' && module &&\n\t\tmodule.exports == freeExports && module;\n\n\t// Detect free variable `global`, from Node.js or Browserified code, and use\n\t// it as `root`.\n\tvar freeGlobal = typeof global == 'object' && global;\n\tif (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {\n\t\troot = freeGlobal;\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\tvar InvalidCharacterError = function(message) {\n\t\tthis.message = message;\n\t};\n\tInvalidCharacterError.prototype = new Error;\n\tInvalidCharacterError.prototype.name = 'InvalidCharacterError';\n\n\tvar error = function(message) {\n\t\t// Note: the error messages used throughout this file match those used by\n\t\t// the native `atob`/`btoa` implementation in Chromium.\n\t\tthrow new InvalidCharacterError(message);\n\t};\n\n\tvar TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\t// http://whatwg.org/html/common-microsyntaxes.html#space-character\n\tvar REGEX_SPACE_CHARACTERS = /[\\t\\n\\f\\r ]/g;\n\n\t// `decode` is designed to be fully compatible with `atob` as described in the\n\t// HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob\n\t// The optimized base64-decoding algorithm used is based on @atk’s excellent\n\t// implementation. https://gist.github.com/atk/1020396\n\tvar decode = function(input) {\n\t\tinput = String(input)\n\t\t\t.replace(REGEX_SPACE_CHARACTERS, '');\n\t\tvar length = input.length;\n\t\tif (length % 4 == 0) {\n\t\t\tinput = input.replace(/==?$/, '');\n\t\t\tlength = input.length;\n\t\t}\n\t\tif (\n\t\t\tlength % 4 == 1 ||\n\t\t\t// http://whatwg.org/C#alphanumeric-ascii-characters\n\t\t\t/[^+a-zA-Z0-9/]/.test(input)\n\t\t) {\n\t\t\terror(\n\t\t\t\t'Invalid character: the string to be decoded is not correctly encoded.'\n\t\t\t);\n\t\t}\n\t\tvar bitCounter = 0;\n\t\tvar bitStorage;\n\t\tvar buffer;\n\t\tvar output = '';\n\t\tvar position = -1;\n\t\twhile (++position < length) {\n\t\t\tbuffer = TABLE.indexOf(input.charAt(position));\n\t\t\tbitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;\n\t\t\t// Unless this is the first of a group of 4 characters…\n\t\t\tif (bitCounter++ % 4) {\n\t\t\t\t// …convert the first 8 bits to a single ASCII character.\n\t\t\t\toutput += String.fromCharCode(\n\t\t\t\t\t0xFF & bitStorage >> (-2 * bitCounter & 6)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t};\n\n\t// `encode` is designed to be fully compatible with `btoa` as described in the\n\t// HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa\n\tvar encode = function(input) {\n\t\tinput = String(input);\n\t\tif (/[^\\0-\\xFF]/.test(input)) {\n\t\t\t// Note: no need to special-case astral symbols here, as surrogates are\n\t\t\t// matched, and the input is supposed to only contain ASCII anyway.\n\t\t\terror(\n\t\t\t\t'The string to be encoded contains characters outside of the ' +\n\t\t\t\t'Latin1 range.'\n\t\t\t);\n\t\t}\n\t\tvar padding = input.length % 3;\n\t\tvar output = '';\n\t\tvar position = -1;\n\t\tvar a;\n\t\tvar b;\n\t\tvar c;\n\t\tvar d;\n\t\tvar buffer;\n\t\t// Make sure any padding is handled outside of the loop.\n\t\tvar length = input.length - padding;\n\n\t\twhile (++position < length) {\n\t\t\t// Read three bytes, i.e. 24 bits.\n\t\t\ta = input.charCodeAt(position) << 16;\n\t\t\tb = input.charCodeAt(++position) << 8;\n\t\t\tc = input.charCodeAt(++position);\n\t\t\tbuffer = a + b + c;\n\t\t\t// Turn the 24 bits into four chunks of 6 bits each, and append the\n\t\t\t// matching character for each of them to the output.\n\t\t\toutput += (\n\t\t\t\tTABLE.charAt(buffer >> 18 & 0x3F) +\n\t\t\t\tTABLE.charAt(buffer >> 12 & 0x3F) +\n\t\t\t\tTABLE.charAt(buffer >> 6 & 0x3F) +\n\t\t\t\tTABLE.charAt(buffer & 0x3F)\n\t\t\t);\n\t\t}\n\n\t\tif (padding == 2) {\n\t\t\ta = input.charCodeAt(position) << 8;\n\t\t\tb = input.charCodeAt(++position);\n\t\t\tbuffer = a + b;\n\t\t\toutput += (\n\t\t\t\tTABLE.charAt(buffer >> 10) +\n\t\t\t\tTABLE.charAt((buffer >> 4) & 0x3F) +\n\t\t\t\tTABLE.charAt((buffer << 2) & 0x3F) +\n\t\t\t\t'='\n\t\t\t);\n\t\t} else if (padding == 1) {\n\t\t\tbuffer = input.charCodeAt(position);\n\t\t\toutput += (\n\t\t\t\tTABLE.charAt(buffer >> 2) +\n\t\t\t\tTABLE.charAt((buffer << 4) & 0x3F) +\n\t\t\t\t'=='\n\t\t\t);\n\t\t}\n\n\t\treturn output;\n\t};\n\n\tvar base64 = {\n\t\t'encode': encode,\n\t\t'decode': decode,\n\t\t'version': '0.1.0'\n\t};\n\n\t// Some AMD build optimizers, like r.js, check for specific condition patterns\n\t// like the following:\n\tif (\n\t\ttypeof define == 'function' &&\n\t\ttypeof define.amd == 'object' &&\n\t\tdefine.amd\n\t) {\n\t\tdefine(function() {\n\t\t\treturn base64;\n\t\t});\n\t}\telse if (freeExports && !freeExports.nodeType) {\n\t\tif (freeModule) { // in Node.js or RingoJS v0.8.0+\n\t\t\tfreeModule.exports = base64;\n\t\t} else { // in Narwhal or RingoJS v0.7.0-\n\t\t\tfor (var key in base64) {\n\t\t\t\tbase64.hasOwnProperty(key) && (freeExports[key] = base64[key]);\n\t\t\t}\n\t\t}\n\t} else { // in Rhino or a web browser\n\t\troot.base64 = base64;\n\t}\n\n}(this));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/base-64/base64.js\n// module id = 287\n// module chunks = 0","module.exports = function(module) {\r\n\tif(!module.webpackPolyfill) {\r\n\t\tmodule.deprecate = function() {};\r\n\t\tmodule.paths = [];\r\n\t\t// module.parent = undefined by default\r\n\t\tif(!module.children) module.children = [];\r\n\t\tObject.defineProperty(module, \"loaded\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tget: function() {\r\n\t\t\t\treturn module.l;\r\n\t\t\t}\r\n\t\t});\r\n\t\tObject.defineProperty(module, \"id\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tget: function() {\r\n\t\t\t\treturn module.i;\r\n\t\t\t}\r\n\t\t});\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/module.js\n// module id = 288\n// module chunks = 0","var g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/global.js\n// module id = 289\n// module chunks = 0","define(function(require) {\n 'use strict';\n\n const d3Dispatch = require('d3-dispatch');\n const d3Ease = require('d3-ease');\n const d3Format = require('d3-format');\n const d3Interpolate = require('d3-interpolate');\n const d3Scale = require('d3-scale');\n const d3Shape = require('d3-shape');\n const d3Selection = require('d3-selection');\n const d3Transition = require('d3-transition');\n\n const {exportChart} = require('./helpers/export');\n const textHelper = require('./helpers/text');\n const colorHelper = require('./helpers/color');\n const {calculatePercent} = require('./helpers/number');\n const {emptyDonutData} =require('./helpers/constants');\n const {donut} = require('./helpers/load');\n\n\n /**\n * @typedef DonutChartData\n * @type {Object[]}\n * @property {Number} quantity Quantity of the group (required)\n * @property {Number} percentage Percentage of the total (optional)\n * @property {String} name Name of the group (required)\n * @property {Number} id Identifier for the group required for legend feature (optional)\n *\n * @example\n * [\n * {\n * quantity: 1,\n * percentage: 50,\n * name: 'glittering',\n * id: 1\n * },\n * {\n * quantity: 1,\n * percentage: 50,\n * name: 'luminous',\n * id: 2\n * }\n * ]\n */\n\n /**\n * Reusable Donut Chart API class that renders a\n * simple and configurable donut chart.\n *\n * @module Donut\n * @tutorial donut\n * @requires d3-dispatch, d3-ease, d3-interpolate, d3-scale, d3-shape, d3-selection\n *\n * @example\n * var donutChart = donut();\n *\n * donutChart\n * .externalRadius(500)\n * .internalRadius(200);\n *\n * d3Selection.select('.css-selector')\n * .datum(dataset)\n * .call(donutChart);\n *\n */\n return function module() {\n let margin = {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n },\n width = 300,\n height = 300,\n loadingState = donut,\n ease = d3Ease.easeCubicInOut,\n arcTransitionDuration = 750,\n pieDrawingTransitionDuration = 1200,\n pieHoverTransitionDuration = 150,\n radiusHoverOffset = 12,\n paddingAngle = 0,\n data,\n chartWidth, chartHeight,\n externalRadius = 140,\n internalRadius = 45.5,\n legendWidth = externalRadius + internalRadius,\n layout,\n shape,\n slices,\n svg,\n\n isAnimated = false,\n isEmpty = false,\n\n highlightedSliceId,\n highlightedSlice,\n hasFixedHighlightedSlice = false,\n\n emptyDataConfig = {\n emptySliceColor: '#EFF2F5',\n showEmptySlice: false\n },\n\n quantityLabel = 'quantity',\n nameLabel = 'name',\n percentageLabel = 'percentage',\n\n percentageFormat = '.1f',\n numberFormat,\n\n // colors\n colorScale,\n colorSchema = colorHelper.colorSchemas.britecharts,\n\n centeredTextFunction = (d) => `${d.percentage}% ${d.name}`,\n\n // utils\n storeAngle = function(d) {\n this._current = d;\n },\n reduceOuterRadius = d => {\n d.outerRadius = externalRadius - radiusHoverOffset;\n },\n\n orderingFunction = (a, b) => b.quantity - a.quantity,\n\n sumValues = (data) => data.reduce((total, d) => d.quantity + total, 0),\n\n // extractors\n getQuantity = ({quantity}) => quantity,\n getSliceFill = ({data}) => colorScale(data.name),\n\n // events\n dispatcher = d3Dispatch.dispatch('customMouseOver', 'customMouseOut', 'customMouseMove', 'customClick');\n\n /**\n * This function creates the graph using the selection as container\n *\n * @param {D3Selection} _selection A d3 selection that represents\n * the container(s) where the chart(s) will be rendered\n * @param {DonutChartData} _data The data to attach and generate the chart\n */\n function exports(_selection) {\n _selection.each(function(_data) {\n chartWidth = width - margin.left - margin.right;\n chartHeight = height - margin.top - margin.bottom;\n data = cleanData(_data);\n\n buildLayout();\n buildColorScale();\n buildShape();\n buildSVG(this);\n drawSlices();\n initTooltip();\n\n if (highlightedSliceId) {\n initHighlightSlice();\n }\n if (isEmpty && emptyDataConfig.showEmptySlice) {\n drawEmptySlice();\n }\n });\n }\n\n /**\n * Builds color scale for chart, if any colorSchema was defined\n * @private\n */\n function buildColorScale() {\n if (colorSchema) {\n colorScale = d3Scale.scaleOrdinal().range(colorSchema);\n }\n }\n\n /**\n * Builds containers for the chart, the legend and a wrapper for all of them\n * @private\n */\n function buildContainerGroups() {\n let container = svg\n .append('g')\n .classed('container-group', true);\n\n container\n .append('g')\n .classed('chart-group', true);\n container\n .append('g')\n .classed('legend-group', true);\n }\n\n /**\n * Builds the pie layout that will produce data ready to draw\n * @private\n */\n function buildLayout() {\n layout = d3Shape.pie()\n .padAngle(paddingAngle)\n .value(getQuantity)\n .sort(orderingFunction);\n }\n\n /**\n * Builds the shape function\n * @private\n */\n function buildShape() {\n shape = d3Shape.arc()\n .innerRadius(internalRadius)\n .padRadius(externalRadius);\n }\n\n /**\n * Builds the SVG element that will contain the chart\n *\n * @param {HTMLElement} container DOM element that will work as the container of the graph\n * @private\n */\n function buildSVG(container) {\n if (!svg) {\n svg = d3Selection.select(container)\n .append('svg')\n .classed('britechart donut-chart', true);\n\n buildContainerGroups();\n }\n\n // Updates Container Group position\n svg\n .select('.container-group')\n .attr('transform', `translate(${width / 2}, ${height / 2})`);\n\n // Updates SVG size\n svg\n .attr('width', width)\n .attr('height', height);\n }\n\n /**\n * Cleaning data casting the quantities, names and percentages to the proper type while keeping\n * the rest of properties on the data. It also calculates the percentages if not present.\n * @param {DonutChartData} data Data as passed to the container\n * @return {DonutChartData} Clean data with percentages\n * @private\n */\n function cleanData(data) {\n let dataWithPercentages;\n let cleanData = data.reduce((acc, d) => {\n // Skip data without quantity\n if (d[quantityLabel] === undefined || d[quantityLabel] === null) {\n return acc;\n }\n\n d.quantity = +d[quantityLabel];\n d.name = String(d[nameLabel]);\n d.percentage = d[percentageLabel] || null;\n\n return [...acc, d];\n }, []);\n\n let totalQuantity = sumValues(cleanData);\n\n if (totalQuantity === 0 && emptyDataConfig.showEmptySlice) {\n isEmpty = true;\n }\n\n dataWithPercentages = cleanData.map((d) => {\n d.percentage = String(d.percentage || calculatePercent(d[quantityLabel], totalQuantity, percentageFormat));\n\n return d;\n });\n\n\n return dataWithPercentages;\n }\n\n /**\n * Cleans any value that could be on the legend text element\n * @private\n */\n function cleanLegend() {\n svg.select('.donut-text').text('');\n }\n\n /**\n * Draw an empty slice\n * @private\n */\n function drawEmptySlice() {\n\n if (slices) {\n svg.selectAll('g.arc').remove();\n }\n slices = svg.select('.chart-group')\n .selectAll('g.arc')\n .data(layout(emptyDonutData));\n\n let newSlices = slices.enter()\n .append('g')\n .each(storeAngle)\n .each(reduceOuterRadius)\n .classed('arc', true)\n .append('path');\n\n newSlices.merge(slices)\n .attr('fill', emptyDataConfig.emptySliceColor)\n .attr('d', shape)\n .transition()\n .ease(ease)\n .duration(pieDrawingTransitionDuration)\n .attrTween('d', tweenLoading);\n\n slices.exit().remove();\n }\n\n /**\n * Draws the values on the donut slice inside the text element\n *\n * @param {Object} obj Data object\n * @private\n */\n function drawLegend(obj) {\n if (obj.data) {\n\n svg.select('.donut-text')\n .text(() => centeredTextFunction(obj.data))\n .attr('dy', '.2em')\n .attr('text-anchor', 'middle');\n\n svg.select('.donut-text').call(wrapText, legendWidth);\n }\n }\n\n /**\n * Draws the slices of the donut\n * @private\n */\n function drawSlices() {\n // Not ideal, we need to figure out how to call exit for nested elements\n if (slices) {\n svg.selectAll('g.arc').remove();\n }\n\n slices = svg.select('.chart-group')\n .selectAll('g.arc')\n .data(layout(data));\n\n let newSlices = slices.enter()\n .append('g')\n .each(storeAngle)\n .each(reduceOuterRadius)\n .classed('arc', true)\n .append('path');\n\n if (isAnimated) {\n newSlices.merge(slices)\n .attr('fill', getSliceFill)\n .on('mouseover', function(d) {\n handleMouseOver(this, d, chartWidth, chartHeight);\n })\n .on('mousemove', function(d) {\n handleMouseMove(this, d, chartWidth, chartHeight);\n })\n .on('mouseout', function(d) {\n handleMouseOut(this, d, chartWidth, chartHeight);\n })\n .on('click', function(d) {\n handleClick(this, d, chartWidth, chartHeight);\n })\n .transition()\n .ease(ease)\n .duration(pieDrawingTransitionDuration)\n .attrTween('d', tweenLoading);\n } else {\n newSlices.merge(slices)\n .attr('fill', getSliceFill)\n .attr('d', shape)\n .on('mouseover', function(d) {\n handleMouseOver(this, d, chartWidth, chartHeight);\n })\n .on('mousemove', function(d) {\n handleMouseMove(this, d, chartWidth, chartHeight);\n })\n .on('mouseout', function(d) {\n handleMouseOut(this, d, chartWidth, chartHeight);\n })\n .on('click', function(d) {\n handleClick(this, d, chartWidth, chartHeight);\n });\n }\n\n slices.exit().remove();\n }\n\n /**\n * Checks if the given element id is the same as the highlightedSliceId and returns the\n * element if that's the case\n * @param {DOMElement} options.data Dom element to check\n * @return {DOMElement} Dom element if it has the same id\n */\n function filterHighlightedSlice({data}) {\n if (data.id === highlightedSliceId) {\n return this;\n }\n }\n\n /**\n * Handles a path mouse over\n * @return {void}\n * @private\n */\n function handleMouseOver(el, d, chartWidth, chartHeight) {\n drawLegend(d);\n dispatcher.call('customMouseOver', el, d, d3Selection.mouse(el), [chartWidth, chartHeight]);\n\n if (highlightedSlice && el !== highlightedSlice) {\n tweenGrowth(highlightedSlice, externalRadius - radiusHoverOffset);\n }\n tweenGrowth(el, externalRadius);\n }\n\n /**\n * Handles a path mouse move\n * @return {void}\n * @private\n */\n function handleMouseMove(el, d, chartWidth, chartHeight) {\n dispatcher.call('customMouseMove', el, d, d3Selection.mouse(el), [chartWidth, chartHeight]);\n }\n\n /**\n * Handles a path mouse out\n * @return {void}\n * @private\n */\n function handleMouseOut(el, d, chartWidth, chartHeight) {\n cleanLegend();\n\n // When there is a fixed highlighted slice,\n // we will always highlight it and render legend\n if (highlightedSlice && hasFixedHighlightedSlice) {\n drawLegend(highlightedSlice.__data__);\n tweenGrowth(highlightedSlice, externalRadius);\n }\n\n // When the current slice is not the highlighted, or there isn't a fixed highlighted slice and it is the highlighted\n // we will shrink the slice\n if (el !== highlightedSlice || (!hasFixedHighlightedSlice && el === highlightedSlice) ) {\n tweenGrowth(el, externalRadius - radiusHoverOffset, pieHoverTransitionDuration);\n }\n\n dispatcher.call('customMouseOut', el, d, d3Selection.mouse(el), [chartWidth, chartHeight]);\n }\n\n /**\n * Handles a path click\n * @return {void}\n * @private\n */\n function handleClick(el, d, chartWidth, chartHeight) {\n dispatcher.call('customClick', el, d, d3Selection.mouse(el), [chartWidth, chartHeight]);\n }\n\n /**\n * Find the slice by id and growth it if needed\n * @private\n */\n function initHighlightSlice() {\n highlightedSlice = svg.selectAll('.chart-group .arc path')\n .select(filterHighlightedSlice).node();\n\n if (highlightedSlice) {\n drawLegend(highlightedSlice.__data__);\n tweenGrowth(highlightedSlice, externalRadius, pieDrawingTransitionDuration);\n }\n }\n\n /**\n * Creates the text element that will hold the legend of the chart\n */\n function initTooltip() {\n svg.select('.legend-group')\n .append('text')\n .attr('class', 'donut-text');\n }\n\n /**\n * Stores current angles and interpolates with new angles\n * Check out {@link http://bl.ocks.org/mbostock/1346410| this example}\n *\n * @param {Object} a New data for slice\n * @return {Function} Tweening function for the donut shape\n * @private\n */\n function tweenArc(a) {\n let i = d3Interpolate.interpolate(this._current, a);\n\n this._current = i(0);\n\n return function(t) {\n return shape(i(t));\n };\n }\n\n /**\n * Animate slice with tweens depending on the attributes given\n *\n * @param {DOMElement} slice Slice to growth\n * @param {Number} outerRadius Final outer radius value\n * @param {Number} delay Delay of animation\n * @private\n */\n function tweenGrowth(slice, outerRadius, delay = 0) {\n d3Selection.select(slice)\n .transition()\n .delay(delay)\n .attrTween('d', function(d) {\n let i = d3Interpolate.interpolate(d.outerRadius, outerRadius);\n\n return (t) => {\n d.outerRadius = i(t);\n\n return shape(d);\n };\n });\n }\n\n /**\n * Animation for chart loading\n * Check out {@link http://bl.ocks.org/mbostock/4341574| this example}\n *\n * @param {Object} b Data point\n * @return {Function} Tween function\n * @private\n */\n function tweenLoading(b) {\n let i;\n\n b.innerRadius = 0;\n i = d3Interpolate.interpolate({ startAngle: 0, endAngle: 0}, b);\n\n return function(t) { return shape(i(t)); };\n }\n\n /**\n * Utility function that wraps a text into the given width\n *\n * @param {D3Selection} text Text to write\n * @param {Number} legendWidth Width of the container\n * @private\n */\n function wrapText(text, legendWidth) {\n let fontSize = externalRadius / 5;\n\n textHelper.wrapText.call(null, 0, fontSize, legendWidth, text.node());\n }\n\n\n // API\n\n /**\n * Gets or Sets the centeredTextFunction of the chart. If function is provided\n * the format will be changed by the custom function's value format.\n * The default format function value is \"${d.percentage}% ${d.name}\".\n * The callback will provide the data object with id, name, percentage, and quantity.\n * Also provides the component added by the user in each data entry.\n * @param {Function} _x Custom function that returns a formatted string\n * @return {Function | module} Current centeredTextFunction or Chart module to chain calls\n * @public\n * @example donutChart.centeredTextFunction(d => `${d.id} ${d.quantity}`)\n */\n exports.centeredTextFunction = function(_x) {\n if (!arguments.length) {\n return centeredTextFunction;\n }\n centeredTextFunction = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets the colorSchema of the chart\n * @param {String[]} _x Desired colorSchema for the graph\n * @return { String | module} Current colorSchema or Chart module to chain calls\n * @public\n */\n exports.colorSchema = function(_x) {\n if (!arguments.length) {\n return colorSchema;\n }\n colorSchema = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the emptyDataConfig of the chart. If set and data is empty (quantity\n * adds up to zero or there are no entries), the chart will render an empty slice\n * with a given color (light gray by default)\n * @param {Object} _x emptyDataConfig object to get/set\n * @return { Object | module} Current config for when chart data is an empty array\n * @public\n * @example donutChart.emptyDataConfig({showEmptySlice: true, emptySliceColor: '#000000'})\n */\n exports.emptyDataConfig = function(_x) {\n if (!arguments.length) {\n return emptyDataConfig;\n }\n emptyDataConfig = _x;\n\n return this;\n };\n\n /**\n * Chart exported to png and a download action is fired\n * @param {String} filename File title for the resulting picture\n * @param {String} title Title to add at the top of the exported picture\n * @public\n */\n exports.exportChart = function(filename, title) {\n exportChart.call(exports, svg, filename, title);\n };\n\n /**\n * Gets or Sets the externalRadius of the chart\n * @param {Number} _x ExternalRadius number to get/set\n * @return { (Number | Module) } Current externalRadius or Donut Chart module to chain calls\n * @public\n */\n exports.externalRadius = function(_x) {\n if (!arguments.length) {\n return externalRadius;\n }\n externalRadius = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the hasFixedHighlightedSlice property of the chart, making it to\n * highlight the selected slice id set with `highlightSliceById` all the time.\n *\n * @param {Boolean} _x If we want to make the highlighted slice permanently highlighted\n * @return { Boolean | module} Current hasFixedHighlightedSlice flag or Chart module\n * @public\n */\n exports.hasFixedHighlightedSlice = function(_x) {\n if (!arguments.length) {\n return hasFixedHighlightedSlice;\n }\n hasFixedHighlightedSlice = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the height of the chart\n * @param {Number} _x Desired width for the graph\n * @return { (Number | Module) } Current height or Donut Chart module to chain calls\n * @public\n */\n exports.height = function(_x) {\n if (!arguments.length) {\n return height;\n }\n height = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the id of the slice to highlight\n * @param {Number} _x Slice id\n * @return { (Number | Module) } Current highlighted slice id or Donut Chart module to chain calls\n * @public\n */\n exports.highlightSliceById = function(_x) {\n if (!arguments.length) {\n return highlightedSliceId;\n }\n highlightedSliceId = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the internalRadius of the chart\n * @param {Number} _x InternalRadius number to get/set\n * @return { (Number | Module) } Current internalRadius or Donut Chart module to chain calls\n * @public\n */\n exports.internalRadius = function(_x) {\n if (!arguments.length) {\n return internalRadius;\n }\n internalRadius = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the isAnimated property of the chart, making it to animate when render.\n * By default this is 'false'\n *\n * @param {Boolean} _x Desired animation flag\n * @return { Boolean | module} Current isAnimated flag or Chart module\n * @public\n */\n exports.isAnimated = function(_x) {\n if (!arguments.length) {\n return isAnimated;\n }\n isAnimated = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the loading state of the chart\n * @param {string} markup Desired markup to show when null data\n * @return { loadingState | module} Current loading state markup or Chart module to chain calls\n * @public\n */\n exports.loadingState = function(_markup) {\n if (!arguments.length) {\n return loadingState;\n }\n loadingState = _markup;\n\n return this;\n };\n\n /**\n * Gets or Sets the margin of the chart\n * @param {Object} _x Margin object to get/set\n * @return { (Object | Module) } Current margin or Donut Chart module to chain calls\n * @public\n */\n exports.margin = function(_x) {\n if (!arguments.length) {\n return margin;\n }\n margin = {\n ...margin,\n ..._x\n };\n\n return this;\n };\n\n /**\n * Gets or Sets the number format of the donut chart\n * @param {string} _x Desired number format for the donut chart\n * @return {numberFormat | module} Current numberFormat or Chart module to chain calls\n * @public\n */\n exports.numberFormat = function(_x) {\n if (!arguments.length) {\n return numberFormat;\n }\n numberFormat = _x;\n\n return this;\n }\n\n /**\n * Exposes an 'on' method that acts as a bridge with the event dispatcher\n * We are going to expose this events:\n * customMouseOver, customMouseMove, customMouseOut and customClick\n *\n * @return {module} Bar Chart\n * @public\n */\n exports.on = function() {\n let value = dispatcher.on.apply(dispatcher, arguments);\n\n return value === dispatcher ? exports : value;\n };\n\n /**\n * Changes the order of items given custom function\n * @param {Function} _x A custom function that sets logic for ordering\n * @return { (Function | Module) } Void function with no return\n * @public\n */\n exports.orderingFunction = function(_x) {\n if (!arguments.length) {\n return orderingFunction;\n }\n orderingFunction = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the percentage format for the percentage label\n * @param {String} _x Format for the percentage label (e.g. '.1f')\n * @return { (Number | Module) } Current format or Donut Chart module to chain calls\n * @public\n */\n exports.percentageFormat = function(_x) {\n if (!arguments.length) {\n return percentageFormat;\n }\n percentageFormat = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the radiusHoverOffset of the chart\n * @param {Number} _x Desired offset for the hovered slice\n * @return { (Number | Module) } Current offset or Donut Chart module to chain calls\n * @public\n */\n exports.radiusHoverOffset = function(_x) {\n if (!arguments.length) {\n return radiusHoverOffset;\n }\n radiusHoverOffset = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the width of the chart\n * @param {Number} _x Desired width for the graph\n * @return { (Number | Module) } Current width or Donut Chart module to chain calls\n * @public\n */\n exports.width = function(_x) {\n if (!arguments.length) {\n return width;\n }\n width = _x;\n\n return this;\n };\n\n return exports;\n };\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/donut.js","define(function(require){\n 'use strict';\n\n const d3Format = require('d3-format');\n const d3Scale = require('d3-scale');\n const d3Selection = require('d3-selection');\n const d3Transition = require('d3-transition');\n\n const textHelper = require('./helpers/text');\n const colorHelper = require('./helpers/color');\n\n /**\n * @typedef LegendChartData\n * @type {Object[]}\n * @property {Number} id Id of the group (required)\n * @property {Number} quantity Quantity of the group (required)\n * @property {String} name Name of the group (required)\n *\n * @example\n * [\n * {\n * id: 1,\n * quantity: 2,\n * name: 'glittering'\n * },\n * {\n * id: 2,\n * quantity: 3,\n * name: 'luminous'\n * }\n * ]\n */\n\n\n /**\n * @fileOverview Legend Component reusable API class that renders a\n * simple and configurable legend element.\n *\n * @example\n * var donutChart = donut(),\n * legendBox = legend();\n *\n * donutChart\n * .externalRadius(500)\n * .internalRadius(200)\n * .on('customMouseOver', function(data) {\n * legendBox.highlight(data.data.id);\n * })\n * .on('customMouseOut', function() {\n * legendBox.clearHighlight();\n * });\n *\n * d3Selection.select('.css-selector')\n * .datum(dataset)\n * .call(donutChart);\n *\n * d3Selection.select('.other-css-selector')\n * .datum(dataset)\n * .call(legendBox);\n *\n * @module Legend\n * @tutorial legend\n * @exports charts/legend\n * @requires d3\n */\n return function module() {\n\n let margin = {\n top: 5,\n right: 5,\n bottom: 5,\n left: 5\n },\n width = 320,\n height = 180,\n\n textSize = 12,\n textLetterSpacing = 0.5,\n\n markerSize = 16,\n markerYOffset = - (textSize - 2) / 2,\n marginRatio = 1.5,\n\n valueReservedSpace = 40,\n numberLetterSpacing = 0.8,\n numberFormat = 's',\n unit = '',\n\n isFadedClassName = 'is-faded',\n isHorizontal = false,\n highlightedEntryId = null,\n\n // colors\n colorScale,\n colorSchema = colorHelper.colorSchemas.britecharts,\n\n getId = ({id}) => id,\n getName = ({name}) => name,\n getFormattedQuantity = ({quantity}) => d3Format.format(numberFormat)(quantity) + unit,\n getCircleFill = ({name}) => colorScale(name),\n\n entries,\n chartWidth, chartHeight,\n data,\n svg;\n\n\n /**\n * This function creates the graph using the selection as container\n * @param {D3Selection} _selection A d3 selection that represents\n * the container(s) where the chart(s) will be rendered\n * @param {object} _data The data to attach and generate the chart\n * @private\n */\n function exports(_selection) {\n _selection.each(function(_data){\n chartWidth = width - margin.left - margin.right;\n chartHeight = height - margin.top - margin.bottom;\n data = _data;\n\n buildColorScale();\n buildSVG(this);\n\n if (isHorizontal) {\n drawHorizontalLegend();\n } else {\n drawVerticalLegend();\n }\n\n if (highlightedEntryId) {\n cleanFadedLines();\n fadeLinesBut(highlightedEntryId);\n }\n });\n }\n\n /**\n * Depending on the size of the horizontal legend, we are going to add a new\n * line with the last entry of the legend\n * @return {void}\n * @private\n */\n function adjustLines() {\n let lineWidth = svg.select('.legend-line').node().getBoundingClientRect().width + markerSize;\n let lineWidthSpace = chartWidth - lineWidth;\n\n if (lineWidthSpace <= 0) {\n splitInLines();\n }\n\n centerLegendOnSVG();\n }\n\n /**\n * Builds containers for the legend\n * Also applies the Margin convention\n * @private\n */\n function buildContainerGroups() {\n let container = svg\n .append('g')\n .classed('legend-container-group', true)\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n container\n .append('g')\n .classed('legend-group', true);\n }\n\n /**\n * Builds color scale for chart, if any colorSchema was defined\n * @private\n */\n function buildColorScale() {\n if (colorSchema) {\n colorScale = d3Scale.scaleOrdinal().range(colorSchema);\n }\n }\n\n /**\n * Builds the SVG element that will contain the chart\n * @param {HTMLElement} container DOM element that will work as the container of the graph\n * @private\n */\n function buildSVG(container) {\n if (!svg) {\n svg = d3Selection.select(container)\n .append('svg')\n .classed('britechart britechart-legend', true);\n\n buildContainerGroups();\n }\n\n svg\n .attr('width', width)\n .attr('height', height);\n }\n\n /**\n * Centers the legend on the chart given that is a single line of labels\n * @return {void}\n * @private\n */\n function centerLegendOnSVG() {\n let legendGroupSize = svg.select('g.legend-container-group').node().getBoundingClientRect().width + getLineElementMargin();\n let emptySpace = width - legendGroupSize;\n\n if (emptySpace > 0) {\n svg.select('g.legend-container-group')\n .attr('transform', `translate(${emptySpace/2},0)`)\n }\n }\n\n /**\n * Removes the faded class from all the entry lines\n * @private\n */\n function cleanFadedLines() {\n svg.select('.legend-group')\n .selectAll('g.legend-entry')\n .classed(isFadedClassName, false);\n }\n\n /**\n * Draws the entries of the legend within a single line\n * @private\n */\n function drawHorizontalLegend() {\n let xOffset = markerSize;\n\n svg.select('.legend-group')\n .selectAll('g')\n .remove();\n\n // We want a single line\n svg.select('.legend-group')\n .append('g')\n .classed('legend-line', true);\n\n // And one entry per data item\n entries = svg.select('.legend-line')\n .selectAll('g.legend-entry')\n .data(data);\n\n // Enter\n entries.enter()\n .append('g')\n .classed('legend-entry', true)\n .attr('data-item', getId)\n .attr('transform', function({name}) {\n let horizontalOffset = xOffset,\n lineHeight = chartHeight / 2,\n verticalOffset = lineHeight,\n labelWidth = textHelper.getTextWidth(name, textSize);\n\n xOffset += markerSize + 2 * getLineElementMargin() + labelWidth;\n\n return `translate(${horizontalOffset},${verticalOffset})`;\n })\n .merge(entries)\n .append('circle')\n .classed('legend-circle', true)\n .attr('cx', markerSize/2)\n .attr('cy', markerYOffset)\n .attr('r', markerSize / 2)\n .style('fill', getCircleFill)\n .style('stroke-width', 1);\n\n svg.select('.legend-group')\n .selectAll('g.legend-entry')\n .append('text')\n .classed('legend-entry-name', true)\n .text(getName)\n .attr('x', getLineElementMargin())\n .style('font-size', `${textSize}px`)\n .style('letter-spacing', `${textLetterSpacing}px`);\n\n // Exit\n svg.select('.legend-group')\n .selectAll('g.legend-entry')\n .exit()\n .transition()\n .style('opacity', 0)\n .remove();\n\n adjustLines();\n }\n\n /**\n * Draws the entries of the legend\n * @private\n */\n function drawVerticalLegend() {\n svg.select('.legend-group')\n .selectAll('g')\n .remove();\n\n entries = svg.select('.legend-group')\n .selectAll('g.legend-line')\n .data(data);\n\n // Enter\n entries.enter()\n .append('g')\n .classed('legend-line', true)\n .append('g')\n .classed('legend-entry', true)\n .attr('data-item', getId)\n .attr('transform', function(d, i) {\n let horizontalOffset = markerSize + getLineElementMargin(),\n lineHeight = chartHeight/ (data.length + 1),\n verticalOffset = (i + 1) * lineHeight;\n\n return `translate(${horizontalOffset},${verticalOffset})`;\n })\n .merge(entries)\n .append('circle')\n .classed('legend-circle', true)\n .attr('cx', markerSize/2)\n .attr('cy', markerYOffset)\n .attr('r', markerSize/2 )\n .style('fill', getCircleFill)\n .style('stroke-width', 1);\n\n svg.select('.legend-group')\n .selectAll('g.legend-line')\n .selectAll('g.legend-entry')\n .append('text')\n .classed('legend-entry-name', true)\n .text(getName)\n .attr('x', getLineElementMargin())\n .style('font-size', `${textSize}px`)\n .style('letter-spacing', `${textLetterSpacing}px`);\n\n svg.select('.legend-group')\n .selectAll('g.legend-line')\n .selectAll('g.legend-entry')\n .append('text')\n .classed('legend-entry-value', true)\n .text(getFormattedQuantity)\n .attr('x', chartWidth - valueReservedSpace)\n .style('font-size', `${textSize}px`)\n .style('letter-spacing', `${numberLetterSpacing}px`)\n .style('text-anchor', 'end')\n .style('startOffset', '100%');\n\n // Exit\n svg.select('.legend-group')\n .selectAll('g.legend-line')\n .exit()\n .transition()\n .style('opacity', 0)\n .remove();\n }\n\n /**\n * Applies the faded class to all lines but the one that has the given id\n * @param {number} exceptionItemId Id of the line that needs to stay the same\n * @private\n */\n function fadeLinesBut(exceptionItemId) {\n let classToFade = 'g.legend-entry';\n let entryLine = svg.select(`[data-item=\"${exceptionItemId}\"]`);\n\n if (entryLine.nodes().length){\n svg.select('.legend-group')\n .selectAll(classToFade)\n .classed(isFadedClassName, true);\n\n entryLine.classed(isFadedClassName, false);\n }\n }\n\n /**\n * Calculates the margin between elements of the legend\n * @return {Number} Margin to apply between elements\n * @private\n */\n function getLineElementMargin() {\n return marginRatio * markerSize;\n }\n\n /**\n * Simple method to move the last item of an overflowing legend into the next line\n * @return {void}\n * @private\n */\n function splitInLines() {\n let legendEntries = svg.selectAll('.legend-entry');\n let numberOfEntries = legendEntries.size();\n let lineHeight = (chartHeight / 2) * 1.7;\n let newLine = svg.select('.legend-group')\n .append('g')\n .classed('legend-line', true)\n .attr('transform', `translate(0, ${lineHeight})`);\n let lastEntry = legendEntries.filter(`:nth-child(${numberOfEntries})`);\n\n lastEntry.attr('transform', `translate(${markerSize},0)`);\n newLine.append(() => lastEntry.node());\n }\n\n // API\n\n /**\n * Clears all highlighted entries\n * @public\n */\n exports.clearHighlight = function() {\n cleanFadedLines();\n };\n\n /**\n * Gets or Sets the colorSchema of the chart\n * @param {array} _x Color scheme array to get/set\n * @return {number | module} Current colorSchema or Donut Chart module to chain calls\n * @public\n */\n exports.colorSchema = function(_x) {\n if (!arguments.length) {\n return colorSchema;\n }\n colorSchema = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the height of the legend chart\n * @param {number} _x Desired width for the chart\n * @return {height | module} Current height or Legend module to chain calls\n * @public\n */\n exports.height = function(_x) {\n if (!arguments.length) {\n return height;\n }\n height = _x;\n\n return this;\n };\n\n /**\n * Highlights a line entry by fading the rest of lines\n * @param {number} entryId ID of the entry line\n * @public\n */\n exports.highlight = function(entryId) {\n cleanFadedLines();\n fadeLinesBut(entryId);\n };\n\n /**\n * Gets or Sets the id of the entry to highlight\n * @param {Number} _x Entry id\n * @return { (Number | Module) } Current highlighted slice id or Donut Chart module to chain calls\n * @public\n */\n exports.highlightEntryById = function (_x) {\n if (!arguments.length) {\n return highlightedEntryId;\n }\n highlightedEntryId = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the horizontal mode on the legend\n * @param {Boolean} _x Desired horizontal mode for the graph\n * @return {Boolean | module} If it is horizontal or Legend module to chain calls\n * @public\n */\n exports.isHorizontal = function(_x) {\n if (!arguments.length) {\n return isHorizontal;\n }\n isHorizontal = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the margin of the legend chart\n * @param {object} _x Margin object to get/set\n * @return {object | module} Current margin or Legend module to chain calls\n * @public\n */\n exports.margin = function(_x) {\n if (!arguments.length) {\n return margin;\n }\n margin = {\n ...margin,\n ..._x\n };\n\n return this;\n };\n\n /**\n * Gets or Sets the margin ratio of the legend chart.\n * Used to determine spacing between legend elements.\n * @param {number} _x Margin Ratio to get/set\n * @return {number | module} Current marginRatio or Legend module to chain calls\n * @public\n */\n exports.marginRatio = function(_x) {\n if (!arguments.length) {\n return marginRatio;\n }\n marginRatio = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the markerSize of the legend chart.\n * This markerSize will determine the horizontal and vertical size of the colored marks\n * added as color identifiers for the chart's categories.\n *\n * @param {object} _x Margin object to get/set\n * @return {object | module} Current markerSize or Legend module to chain calls\n * @public\n */\n exports.markerSize = function(_x) {\n if (!arguments.length) {\n return markerSize;\n }\n markerSize = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the number format of the legend chart\n * @param {string} _x Desired number format for the legend chart\n * @return {string | module} Current number format or Legend module to chain calls\n * @public\n */\n exports.numberFormat = function (_x) {\n if (!arguments.length) {\n return numberFormat;\n }\n numberFormat = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the unit of the value\n * @param {String} _x Desired unit\n * @return {String | module} Current unit or Legend module to chain calls\n * @public\n */\n exports.unit = function(_x) {\n if (!arguments.length) {\n return unit;\n }\n unit = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the width of the legend chart\n * @param {number} _x Desired width for the graph\n * @return {number | module} Current width or Legend module to chain calls\n * @public\n */\n exports.width = function(_x) {\n if (!arguments.length) {\n return width;\n }\n width = _x;\n\n return this;\n };\n\n return exports;\n };\n\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/legend.js","define(function(require){\n 'use strict';\n\n const d3Array = require('d3-array');\n const d3Axis = require('d3-axis');\n const d3Collection = require('d3-collection');\n const d3Dispatch = require('d3-dispatch');\n const d3Ease = require('d3-ease');\n const d3Format = require('d3-format');\n const d3Scale = require('d3-scale');\n const d3Shape = require('d3-shape');\n const d3Selection = require('d3-selection');\n const d3Transition = require('d3-transition');\n const d3TimeFormat = require('d3-time-format');\n\n const {exportChart} = require('./helpers/export');\n const colorHelper = require('./helpers/color');\n const {line} = require('./helpers/load');\n\n const { getTimeSeriesAxis } = require('./helpers/axis');\n const {\n axisTimeCombinations,\n curveMap\n } = require('./helpers/constants');\n const {\n createFilterContainer,\n createGlowWithMatrix\n } = require('./helpers/filter');\n const {\n formatIntegerValue,\n formatDecimalValue,\n isInteger,\n uniqueId\n } = require('./helpers/number');\n\n /**\n * @typedef D3Selection\n * @type {Array[]}\n * @property {Number} length Size of the selection\n * @property {DOMElement} parentNode Parent of the selection\n */\n\n /**\n * @typedef lineChartDataByTopic\n * @type {Object}\n * @property {String} topicName Topic name (required)\n * @property {Number} topic Topic identifier (required)\n * @property {Object[]} dates All date entries with values for that topic (required)\n *\n * @example\n * {\n * topicName: 'San Francisco',\n * topic: 123,\n * dates: [\n * {\n * date: '2017-01-16T16:00:00-08:00',\n * value: 1\n * },\n * {\n * date: '2017-01-16T17:00:00-08:00',\n * value: 2\n * }\n * ]\n * }\n */\n\n /**\n * @typedef LineChartData\n * @type {Object[]}\n * @property {lineChartDataByTopic[]} dataByTopic Data values to chart (required)\n *\n * @example\n * {\n * dataByTopic: [\n * {\n * topicName: 'San Francisco',\n * topic: 123,\n * dates: [\n * {\n * date: '2017-01-16T16:00:00-08:00',\n * value: 1\n * },\n * {\n * date: '2017-01-16T17:00:00-08:00',\n * value: 2\n * }\n * ]\n * },\n * {\n * topicName: 'Other',\n * topic: 345,\n * dates: [\n * {...},\n * {...}\n * ]\n * }\n * ]\n * }\n */\n\n /**\n * Line Chart reusable API module that allows us\n * rendering a multi line and configurable chart.\n *\n * @module Line\n * @tutorial line\n * @requires d3-array, d3-axis, d3-brush, d3-ease, d3-format, d3-scale, d3-shape, d3-selection, d3-time, d3-time-format\n *\n * @example\n * let lineChart = line();\n *\n * lineChart\n * .aspectRatio(0.5)\n * .width(500);\n *\n * d3Selection.select('.css-selector')\n * .datum(dataset)\n * .call(lineChart);\n *\n */\n return function module() {\n\n let margin = {\n top: 60,\n right: 30,\n bottom: 40,\n left: 70,\n },\n width = 960,\n height = 500,\n loadingState = line,\n aspectRatio = null,\n tooltipThreshold = 480,\n svg,\n paths,\n chartWidth, chartHeight,\n xScale, yScale, colorScale,\n xAxis, xMonthAxis, yAxis,\n xAxisPadding = {\n top: 0,\n left: 15,\n bottom: 0,\n right: 0\n },\n monthAxisPadding = 28,\n tickPadding = 5,\n colorSchema = colorHelper.colorSchemas.britecharts,\n singleLineGradientColors = colorHelper.colorGradients.greenBlue,\n topicColorMap,\n linearGradient,\n lineGradientId = uniqueId('one-line-gradient'),\n\n highlightFilter = null,\n highlightFilterId = null,\n highlightCircleSize = 12,\n highlightCircleRadius = 5,\n highlightCircleStroke = 2,\n highlightCircleActiveRadius = highlightCircleRadius + 2,\n highlightCircleActiveStrokeWidth = 5,\n highlightCircleActiveStrokeOpacity = 0.6,\n\n xAxisFormat = null,\n xTicks = null,\n xAxisCustomFormat = null,\n locale,\n\n shouldShowAllDataPoints = false,\n isAnimated = false,\n ease = d3Ease.easeQuadInOut,\n animationDuration = 1500,\n maskingRectangle,\n\n lineCurve = 'linear',\n\n dataByTopic,\n dataByDate,\n\n dateLabel = 'date',\n valueLabel = 'value',\n topicLabel = 'topic',\n topicNameLabel = 'topicName',\n\n xAxisLabel = null,\n xAxisLabelEl = null,\n xAxisLabelPadding = 36,\n yAxisLabel = null,\n yAxisLabelEl = null,\n yAxisLabelPadding = 36,\n\n yTicks = 5,\n\n overlay,\n overlayColor = 'rgba(0, 0, 0, 0)',\n verticalMarkerContainer,\n verticalMarkerLine,\n numberFormat,\n\n verticalGridLines,\n horizontalGridLines,\n grid = null,\n\n baseLine,\n\n pathYCache = {},\n\n // extractors\n getDate = ({date}) => date,\n getValue = ({value}) => value,\n getTopic = ({topic}) => topic,\n getLineColor = ({topic}) => colorScale(topic),\n\n // events\n dispatcher = d3Dispatch.dispatch(\n 'customMouseOver',\n 'customMouseOut',\n 'customMouseMove',\n 'customDataEntryClick',\n 'customTouchMove'\n );\n\n /**\n * This function creates the graph using the selection and data provided\n *\n * @param {D3Selection} _selection A d3 selection that represents\n * the container(s) where the chart(s) will be rendered\n * @param {LineChartData} _data The data to attach and generate the chart\n */\n function exports(_selection) {\n _selection.each(function(_data) {\n ({\n dataByTopic,\n dataByDate\n } = cleanData(_data));\n\n chartWidth = width - margin.left - margin.right;\n chartHeight = height - margin.top - margin.bottom;\n\n buildScales();\n buildSVG(this);\n buildAxis();\n drawAxis();\n buildGradient();\n drawLines();\n createMaskingClip();\n\n if (shouldShowTooltip()) {\n drawHoverOverlay();\n drawVerticalMarker();\n addMouseEvents();\n }\n\n if (shouldShowAllDataPoints) {\n drawAllDataPoints();\n }\n\n addTouchEvents();\n });\n }\n\n /**\n * Adds a filter to the element\n * @param {DOMElement} el\n * @private\n */\n function addGlowFilter(el) {\n if (!highlightFilter) {\n highlightFilter = createFilterContainer(svg.select('.metadata-group'));\n highlightFilterId = createGlowWithMatrix(highlightFilter);\n }\n\n d3Selection.select(el)\n .style('stroke-width', highlightCircleActiveStrokeWidth)\n .style('r', highlightCircleActiveRadius)\n .style('stroke-opacity', highlightCircleActiveStrokeOpacity)\n .attr('filter', `url(#${highlightFilterId})`);\n }\n\n /**\n * Adds events to the container group if the environment is not mobile\n * Adding: mouseover, mouseout and mousemove\n */\n function addMouseEvents() {\n svg\n .on('mouseover', function(d) {\n handleMouseOver(this, d);\n })\n .on('mouseout', function(d) {\n handleMouseOut(this, d);\n })\n .on('mousemove', function(d) {\n handleMouseMove(this, d);\n });\n }\n\n /**\n * Adds events to the container group for the mobile environment\n * Adding: touchmove\n * @private\n */\n function addTouchEvents() {\n svg\n .on('touchmove', function(d) {\n handleTouchMove(this, d);\n });\n }\n\n /**\n * Adjusts the position of the y axis' ticks\n * @param {D3Selection} selection Y axis group\n * @return void\n */\n function adjustYTickLabels(selection) {\n selection.selectAll('.tick text')\n .attr('transform', 'translate(0, -7)');\n }\n\n /**\n * Formats the value depending on its characteristics\n * @param {Number} value Value to format\n * @return {Number} Formatted value\n */\n function getFormattedValue(value) {\n let format;\n\n if (isInteger(value)) {\n format = formatIntegerValue;\n } else {\n format = formatDecimalValue;\n }\n\n if (numberFormat) {\n format = d3Format.format(numberFormat)\n }\n\n return format(value);\n }\n\n /**\n * Creates the d3 x and y axis, setting orientations\n * @private\n */\n function buildAxis() {\n let minor, major;\n\n if (xAxisFormat === 'custom' && typeof xAxisCustomFormat === 'string') {\n minor = {\n tick: xTicks,\n format: d3TimeFormat.timeFormat(xAxisCustomFormat)\n };\n major = null;\n } else {\n ({minor, major} = getTimeSeriesAxis(dataByDate, width, xAxisFormat, locale));\n\n xMonthAxis = d3Axis.axisBottom(xScale)\n .ticks(major.tick)\n .tickSize(0, 0)\n .tickFormat(major.format);\n }\n\n xAxis = d3Axis.axisBottom(xScale)\n .ticks(minor.tick)\n .tickSize(10, 0)\n .tickPadding(tickPadding)\n .tickFormat(minor.format);\n\n yAxis = d3Axis.axisLeft(yScale)\n .ticks(yTicks)\n .tickSize([0])\n .tickPadding(tickPadding)\n .tickFormat(getFormattedValue);\n\n drawGridLines(minor.tick, yTicks);\n }\n\n /**\n * Builds containers for the chart, the axis and a wrapper for all of them\n * NOTE: The order of drawing of this group elements is really important,\n * as everything else will be drawn on top of them\n * @private\n */\n function buildContainerGroups(){\n let container = svg\n .append('g')\n .classed('container-group', true)\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n container\n .append('g').classed('x-axis-group', true)\n .append('g').classed('axis x', true);\n container.selectAll('.x-axis-group')\n .append('g').classed('month-axis', true);\n container\n .append('g').classed('y-axis-group', true)\n .append('g').classed('axis y', true);\n container\n .append('g').classed('grid-lines-group', true);\n container\n .append('g').classed('chart-group', true);\n container\n .append('g').classed('metadata-group', true);\n }\n\n /**\n * Builds the gradient element to be used later\n * @return {void}\n */\n function buildGradient() {\n if (!linearGradient) {\n linearGradient = svg.select('.metadata-group')\n .append('linearGradient')\n .attr('id', lineGradientId)\n .attr('x1', '0%')\n .attr('y1', '0%')\n .attr('x2', '100%')\n .attr('y2', '0%')\n .attr('gradientUnits', 'userSpaceOnUse')\n .selectAll('stop')\n .data([\n {offset:'0%', color: singleLineGradientColors[0]},\n {offset:'100%', color: singleLineGradientColors[1]}\n ])\n .enter()\n .append('stop')\n .attr('offset', ({offset}) => offset)\n .attr('stop-color', ({color}) => color)\n }\n }\n\n /**\n * Creates the x and y scales of the graph\n * @private\n */\n function buildScales(){\n let minX = d3Array.min(dataByTopic, ({dates}) => d3Array.min(dates, getDate)),\n maxX = d3Array.max(dataByTopic, ({dates}) => d3Array.max(dates, getDate)),\n maxY = d3Array.max(dataByTopic, ({dates}) => d3Array.max(dates, getValue)),\n minY = d3Array.min(dataByTopic, ({dates}) => d3Array.min(dates, getValue));\n let yScaleBottomValue = Math.abs(minY) < 0 ? Math.abs(minY) : 0;\n\n xScale = d3Scale.scaleTime()\n .domain([minX, maxX])\n .rangeRound([0, chartWidth]);\n\n yScale = d3Scale.scaleLinear()\n .domain([yScaleBottomValue, Math.abs(maxY)])\n .rangeRound([chartHeight, 0])\n .nice();\n\n colorScale = d3Scale.scaleOrdinal()\n .range(colorSchema)\n .domain(dataByTopic.map(getTopic));\n\n let range = colorScale.range();\n\n topicColorMap = colorScale.domain().reduce((memo, item, i) => {\n memo[item] = range[i];\n\n return memo;\n }, {});\n }\n\n /**\n * Builds the SVG element that will contain the chart\n *\n * @param {HTMLElement} container DOM element that will work as the container of the graph\n * @private\n */\n function buildSVG(container){\n if (!svg) {\n svg = d3Selection.select(container)\n .append('svg')\n .classed('britechart line-chart', true);\n\n buildContainerGroups();\n }\n\n svg\n .attr('width', width)\n .attr('height', height);\n }\n\n /**\n * Parses dates and values into JS Date objects and numbers\n * @param {obj} dataByTopic Raw data grouped by topic\n * @return {obj} Parsed data with dataByTopic and dataByDate\n */\n function cleanData({dataByTopic, dataByDate}) {\n if (!dataByTopic) {\n throw new Error('Data needs to have a dataByTopic property');\n }\n\n const flatData = dataByTopic.reduce((accum, topic) => {\n topic.dates.forEach((date) => {\n accum.push({\n topicName: topic[topicNameLabel],\n name: topic[topicLabel],\n date: date[dateLabel],\n value: date[valueLabel]\n });\n });\n\n return accum;\n }, []);\n\n // Nest data by date and format\n dataByDate = d3Collection.nest()\n .key(getDate)\n .entries(flatData)\n .map((d) => {\n return {\n date: new Date(d.key),\n topics: d.values\n }\n });\n\n // Normalize dates in keys\n dataByDate = dataByDate.map((d) => {\n d.date = new Date(d.date);\n\n return d;\n });\n\n const normalizedDataByTopic = dataByTopic.reduce((accum, topic) => {\n let {dates, ...restProps} = topic;\n\n let newDates = dates.map(d => ({\n date: new Date(d[dateLabel]),\n value: +d[valueLabel]\n }));\n\n accum.push({ dates: newDates, ...restProps });\n\n return accum;\n }, []);\n\n return {\n dataByTopic: normalizedDataByTopic,\n dataByDate\n };\n }\n\n /**\n * Removes all the datapoints highlighter circles added to the marker container\n * @return void\n */\n function cleanDataPointHighlights(){\n verticalMarkerContainer.selectAll('.circle-container').remove();\n }\n\n /**\n * Creates a masking clip that would help us fake an animation if the\n * proper flag is true\n *\n * @return {void}\n */\n function createMaskingClip() {\n if (isAnimated) {\n // We use a white rectangle to simulate the line drawing animation\n maskingRectangle = svg.append('rect')\n .attr('class', 'masking-rectangle')\n .attr('width', width)\n .attr('height', height)\n .attr('x', 0)\n .attr('y', 0);\n\n maskingRectangle.transition()\n .duration(animationDuration)\n .ease(ease)\n .attr('x', width)\n .on('end', () => maskingRectangle.remove());\n }\n }\n\n /**\n * Draws the x and y axis on the svg object within their\n * respective groups along with the axis labels if given\n * @private\n */\n function drawAxis(){\n svg.select('.x-axis-group .axis.x')\n .attr('transform', `translate(0, ${chartHeight})`)\n .call(xAxis);\n\n if (xAxisFormat !== 'custom') {\n svg.select('.x-axis-group .month-axis')\n .attr('transform', `translate(0, ${(chartHeight + monthAxisPadding)})`)\n .call(xMonthAxis);\n }\n\n if (xAxisLabel) {\n if (xAxisLabelEl) {\n svg.selectAll('.x-axis-label').remove();\n }\n let xLabelXPosition = chartWidth/2;\n let xLabelYPosition = chartHeight + monthAxisPadding + xAxisLabelPadding;\n\n xAxisLabelEl = svg.select('.x-axis-group')\n .append('text')\n .attr('x', xLabelXPosition)\n .attr('y', xLabelYPosition)\n .attr('text-anchor', 'middle')\n .attr('class', 'x-axis-label')\n .text(xAxisLabel);\n }\n\n svg.select('.y-axis-group .axis.y')\n .attr('transform', `translate(${-xAxisPadding.left}, 0)`)\n .call(yAxis)\n .call(adjustYTickLabels);\n\n if (yAxisLabel) {\n if (yAxisLabelEl) {\n svg.selectAll('.y-axis-label').remove();\n }\n // Note this coordinates are rotated, so they are not what they look\n let yLabelYPosition = -yAxisLabelPadding - xAxisPadding.left;\n let yLabelXPosition = -chartHeight/2;\n\n yAxisLabelEl = svg.select('.y-axis-group')\n .append('text')\n .attr('x', yLabelXPosition)\n .attr('y', yLabelYPosition)\n .attr('text-anchor', 'middle')\n .attr('transform', 'rotate(270)')\n .attr('class', 'y-axis-label')\n .text(yAxisLabel);\n }\n }\n\n /**\n * Draws the line elements within the chart group\n * @private\n */\n function drawLines(){\n let lines,\n topicLine;\n\n topicLine = d3Shape.line()\n .curve(curveMap[lineCurve])\n .x(({date}) => xScale(date))\n .y(({value}) => yScale(value));\n\n lines = svg.select('.chart-group').selectAll('.line')\n .data(dataByTopic, getTopic);\n\n paths = lines.merge(lines.enter()\n .append('g')\n .attr('class', 'topic')\n .append('path')\n .attr('class', 'line')\n .attr('id', ({topic}) => topic)\n .attr('d', ({dates}) => topicLine(dates))\n .style('stroke', (d) => (\n dataByTopic.length === 1 ? `url(#${lineGradientId})` : getLineColor(d)\n ))\n );\n\n lines\n .exit()\n .remove();\n }\n\n /**\n * Draws grid lines on the background of the chart\n * @return void\n */\n function drawGridLines(xTicks, yTicks){\n svg.select('.grid-lines-group')\n .selectAll('line')\n .remove();\n\n if (grid === 'horizontal' || grid === 'full') {\n horizontalGridLines = svg.select('.grid-lines-group')\n .selectAll('line.horizontal-grid-line')\n .data(yScale.ticks(yTicks))\n .enter()\n .append('line')\n .attr('class', 'horizontal-grid-line')\n .attr('x1', (-xAxisPadding.left - 30))\n .attr('x2', chartWidth)\n .attr('y1', (d) => yScale(d))\n .attr('y2', (d) => yScale(d));\n }\n\n if (grid === 'vertical' || grid === 'full') {\n verticalGridLines = svg.select('.grid-lines-group')\n .selectAll('line.vertical-grid-line')\n .data(xScale.ticks(xTicks))\n .enter()\n .append('line')\n .attr('class', 'vertical-grid-line')\n .attr('y1', 0)\n .attr('y2', chartHeight)\n .attr('x1', (d) => xScale(d))\n .attr('x2', (d) => xScale(d));\n }\n\n //draw a horizontal line to extend x-axis till the edges\n baseLine = svg.select('.grid-lines-group')\n .selectAll('line.extended-x-line')\n .data([0])\n .enter()\n .append('line')\n .attr('class', 'extended-x-line')\n .attr('x1', (-xAxisPadding.left - 30))\n .attr('x2', chartWidth)\n .attr('y1', height - margin.bottom - margin.top)\n .attr('y2', height - margin.bottom - margin.top);\n }\n\n /**\n * Draws an overlay element over the graph\n * @inner\n * @return void\n */\n function drawHoverOverlay(){\n if (!overlay) {\n overlay = svg.select('.metadata-group')\n .append('rect')\n .attr('class','overlay')\n .attr('y1', 0)\n .attr('y2', height)\n .attr('height', chartHeight)\n .attr('width', chartWidth)\n .attr('fill', overlayColor)\n .style('display', 'none');\n }\n }\n\n /**\n * Draws all data points of the chart\n * if shouldShowAllDataPoints is set to true\n * @private\n * @return void\n */\n function drawAllDataPoints() {\n svg.select('.chart-group')\n .selectAll('.data-points-container')\n .remove();\n\n const nodesById = paths.nodes().reduce((acc, node) => {\n acc[node.id] = node\n\n return acc;\n }, {});\n\n\n const allTopics = dataByDate.reduce((accum, dataPoint) => {\n const dataPointTopics = dataPoint.topics.map(topic => ({\n topic,\n node: nodesById[topic.name]\n }));\n\n accum = [...accum, ...dataPointTopics];\n\n return accum;\n }, []);\n\n let allDataPoints = svg.select('.chart-group')\n .append('g')\n .classed('data-points-container', true)\n .selectAll('circle')\n .data(allTopics)\n .enter()\n .append('circle')\n .classed('data-point-mark', true)\n .attr('r', highlightCircleRadius)\n .style('stroke-width', highlightCircleStroke)\n .style('stroke', (d) => topicColorMap[d.topic.name])\n .style('cursor', 'pointer')\n .attr('cx', d => xScale(new Date(d.topic.date)))\n .attr('cy', d => getPathYFromX(xScale(new Date(d.topic.date)), d.node, d.topic.name));\n }\n\n /**\n * Creates the vertical marker\n * @return void\n */\n function drawVerticalMarker(){\n if (!verticalMarkerContainer) {\n verticalMarkerContainer = svg.select('.metadata-group')\n .append('g')\n .attr('class', 'hover-marker vertical-marker-container')\n .attr('transform', 'translate(9999, 0)');\n\n verticalMarkerLine = verticalMarkerContainer.selectAll('path')\n .data([{\n x1: 0,\n y1: 0,\n x2: 0,\n y2: 0\n }])\n .enter()\n .append('line')\n .classed('vertical-marker', true)\n .attr('x1', 0)\n .attr('y1', chartHeight)\n .attr('x2', 0)\n .attr('y2', 0);\n }\n }\n\n /**\n * Finds out which datapoint is closer to the given x position\n * @param {Number} x0 Date value for data point\n * @param {Object} d0 Previous datapoint\n * @param {Object} d1 Next datapoint\n * @return {Object} d0 or d1, the datapoint with closest date to x0\n */\n function findOutNearestDate(x0, d0, d1){\n return (new Date(x0).getTime() - new Date(d0.date).getTime()) > (new Date(d1.date).getTime() - new Date(x0).getTime()) ? d0 : d1;\n }\n\n /**\n * Finds out the data entry that is closer to the given position on pixels\n * @param {Number} mouseX X position of the mouse\n * @return {Object} Data entry that is closer to that x axis position\n */\n function getNearestDataPoint(mouseX) {\n let dateFromInvertedX = xScale.invert(mouseX);\n let bisectDate = d3Array.bisector(getDate).left;\n let dataEntryIndex = bisectDate(dataByDate, dateFromInvertedX, 1);\n let dataEntryForXPosition = dataByDate[dataEntryIndex];\n let previousDataEntryForXPosition = dataByDate[dataEntryIndex - 1];\n let nearestDataPoint;\n\n if (previousDataEntryForXPosition && dataEntryForXPosition) {\n nearestDataPoint = findOutNearestDate(dateFromInvertedX, dataEntryForXPosition, previousDataEntryForXPosition);\n } else {\n nearestDataPoint = dataEntryForXPosition;\n }\n\n return nearestDataPoint;\n }\n\n /**\n * MouseMove handler, calculates the nearest dataPoint to the cursor\n * and updates metadata related to it\n * @private\n */\n function handleMouseMove(e){\n let [xPosition, yPosition] = d3Selection.mouse(e),\n xPositionOffset = -margin.left, //Arbitrary number, will love to know how to assess it\n dataPoint = getNearestDataPoint(xPosition + xPositionOffset),\n dataPointXPosition;\n\n if (dataPoint) {\n dataPointXPosition = xScale(new Date(dataPoint.date));\n // More verticalMarker to that datapoint\n moveVerticalMarker(dataPointXPosition);\n // Add data points highlighting\n highlightDataPoints(dataPoint);\n // Emit event with xPosition for tooltip or similar feature\n dispatcher.call('customMouseMove', e, dataPoint, topicColorMap, dataPointXPosition, yPosition);\n }\n }\n\n /**\n * MouseOut handler, hides overlay and removes active class on verticalMarkerLine\n * It also resets the container of the vertical marker\n * @private\n */\n function handleMouseOut(e, d){\n overlay.style('display', 'none');\n verticalMarkerLine.classed('bc-is-active', false);\n verticalMarkerContainer.attr('transform', 'translate(9999, 0)');\n\n dispatcher.call('customMouseOut', e, d, d3Selection.mouse(e));\n }\n\n /**\n * Mouseover handler, shows overlay and adds active class to verticalMarkerLine\n * @private\n */\n function handleMouseOver(e, d){\n overlay.style('display', 'block');\n verticalMarkerLine.classed('bc-is-active', true);\n\n dispatcher.call('customMouseOver', e, d, d3Selection.mouse(e));\n }\n\n /**\n * Mouseclick handler over one of the highlight points\n * It will only pass the information with the event\n * @private\n */\n function handleHighlightClick(e, d) {\n dispatcher.call('customDataEntryClick', e, d, d3Selection.mouse(e));\n }\n\n /**\n * Touchmove highlighted points\n * It will only pass the information with the event\n * @private\n */\n function handleTouchMove(e, d) {\n dispatcher.call('customTouchMove', e, d, d3Selection.touch(e));\n }\n\n /**\n * Creates coloured circles marking where the exact data y value is for a given data point\n * @param {Object} dataPoint Data point to extract info from\n * @private\n */\n function highlightDataPoints(dataPoint) {\n cleanDataPointHighlights();\n\n const nodes = paths.nodes()\n const nodesById = nodes.reduce((acc, node) => {\n acc[node.id] = node\n\n return acc;\n }, {});\n\n // Group corresponding path node with its topic, and\n // sorting the topics based on the order of the colors,\n // so that the order always stays constant\n const topicsWithNode = dataPoint.topics\n .map(topic => ({\n topic,\n node: nodesById[topic.name]\n }))\n .filter(({topic}) => !!topic)\n .sort((a, b) => topicColorMap[a.topic.name] < topicColorMap[b.topic.name])\n\n dataPoint.topics = topicsWithNode.map(({topic}) => topic);\n\n dataPoint.topics.forEach((d, index) => {\n let marker = verticalMarkerContainer\n .append('g')\n .classed('circle-container', true)\n .append('circle')\n .classed('data-point-highlighter', true)\n .attr('cx', highlightCircleSize)\n .attr('cy', 0)\n .attr('r', highlightCircleRadius)\n .style('stroke-width', highlightCircleStroke)\n .style('stroke', topicColorMap[d.name])\n .style('cursor', 'pointer')\n .on('click', function () {\n addGlowFilter(this);\n handleHighlightClick(this, d);\n })\n .on('mouseout', function () {\n removeFilter(this);\n });\n\n\n const path = topicsWithNode[index].node;\n const x = xScale(new Date(dataPoint.topics[index].date));\n const y = getPathYFromX(x, path, d.name);\n\n marker.attr('transform', `translate( ${(-highlightCircleSize)}, ${y} )` );\n });\n }\n\n /**\n * Finds the y coordinate of a path given an x coordinate and the line's path node.\n * @param {number} x The x coordinate\n * @param {node} path The path node element\n * @param {*} name - The name identifier of the topic\n * @param {number} error The margin of error from the actual x coordinate. Default 0.01\n * @private\n */\n function getPathYFromX(x, path, name, error) {\n const key = `${name}-${x}`;\n\n if (key in pathYCache) {\n return pathYCache[key];\n }\n\n error = error || 0.01;\n\n const maxIterations = 100;\n\n let lengthStart = 0;\n let lengthEnd = path.getTotalLength();\n let point = path.getPointAtLength((lengthEnd + lengthStart) / 2);\n let iterations = 0;\n\n while (x < point.x - error || x > point.x + error) {\n const midpoint = (lengthStart + lengthEnd) / 2;\n\n point = path.getPointAtLength(midpoint);\n\n if (x < point.x) {\n lengthEnd = midpoint;\n } else {\n lengthStart = midpoint;\n }\n\n iterations += 1;\n if (maxIterations < iterations) {\n break;\n }\n }\n\n pathYCache[key] = point.y\n\n return pathYCache[key]\n }\n\n /**\n * Helper method to update the x position of the vertical marker\n * @param {Object} dataPoint Data entry to extract info\n * @return void\n */\n function moveVerticalMarker(verticalMarkerXPosition){\n verticalMarkerContainer.attr('transform', `translate(${verticalMarkerXPosition},0)`);\n }\n\n /**\n * Resets a point filter\n * @param {DOMElement} point Point to reset\n */\n function removeFilter(point) {\n d3Selection.select(point)\n .attr('filter', 'none');\n }\n\n /**\n * Determines if we should add the tooltip related logic depending on the\n * size of the chart and the tooltipThreshold variable value\n * @return {Boolean} Should we build the tooltip?\n */\n function shouldShowTooltip() {\n return width > tooltipThreshold;\n }\n\n // API\n\n /**\n * Gets or Sets the aspect ratio of the chart\n * @param {Number} _x Desired aspect ratio for the graph\n * @return { (Number | Module) } Current aspect ratio or Line Chart module to chain calls\n * @public\n */\n exports.aspectRatio = function(_x) {\n if (!arguments.length) {\n return aspectRatio;\n }\n aspectRatio = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the label of the X axis of the chart\n * @param {String} _x Desired label for the X axis\n * @return { (String | Module) } Current label of the X axis or Line Chart module to chain calls\n * @public\n */\n exports.xAxisLabel = function(_x) {\n if (!arguments.length) {\n return xAxisLabel;\n }\n xAxisLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the label of the Y axis of the chart\n * @param {String} _x Desired label for the Y axis\n * @return { (String | Module) } Current label of the Y axis or Line Chart module to chain calls\n * @public\n */\n exports.yAxisLabel = function(_x) {\n if (!arguments.length) {\n return yAxisLabel;\n }\n yAxisLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the colorSchema of the chart\n * @param {String[]} _x Desired colorSchema for the graph\n * @return { colorSchema | module} Current colorSchema or Chart module to chain calls\n * @public\n */\n exports.colorSchema = function(_x) {\n if (!arguments.length) {\n return colorSchema;\n }\n colorSchema = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the dateLabel of the chart\n * @param {Number} _x Desired dateLabel for the graph\n * @return { dateLabel | module} Current dateLabel or Chart module to chain calls\n * @public\n */\n exports.dateLabel = function(_x) {\n if (!arguments.length) {\n return dateLabel;\n }\n dateLabel = _x;\n\n return this;\n };\n\n /**\n * Exposes the ability to force the chart to show a certain x axis grouping\n * @param {String} _x Desired format\n * @return { (String|Module) } Current format or module to chain calls\n * @public\n * @example\n * line.xAxisFormat(line.axisTimeCombinations.HOUR_DAY)\n */\n exports.xAxisFormat = function(_x) {\n if (!arguments.length) {\n return xAxisFormat;\n }\n xAxisFormat = _x;\n\n return this;\n };\n\n /**\n * Exposes the ability to force the chart to show a certain x format\n * It requires a `xAxisFormat` of 'custom' in order to work.\n * NOTE: localization not supported\n * @param {String} _x Desired format for x axis\n * @return { (String|Module) } Current format or module to chain calls\n * @public\n */\n exports.xAxisCustomFormat = function(_x) {\n if (!arguments.length) {\n return xAxisCustomFormat;\n }\n xAxisCustomFormat = _x;\n\n return this;\n };\n\n /**\n * Exposes the ability to force the chart to show a certain x ticks. It requires a `xAxisFormat` of 'custom' in order to work.\n * NOTE: This value needs to be a multiple of 2, 5 or 10. They won't always work as expected, as D3 decides at the end\n * how many and where the ticks will appear.\n *\n * @param {Number} _x Desired number of x axis ticks (multiple of 2, 5 or 10)\n * @return { (Number|Module) } Current number or ticks or module to chain calls\n * @public\n */\n exports.xTicks = function(_x) {\n if (!arguments.length) {\n return xTicks;\n }\n xTicks = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the grid mode.\n *\n * @param {String} _x Desired mode for the grid ('vertical'|'horizontal'|'full')\n * @return { String | module} Current mode of the grid or Line Chart module to chain calls\n * @public\n */\n exports.grid = function(_x) {\n if (!arguments.length) {\n return grid;\n }\n grid = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the height of the chart\n * @param {Number} _x Desired width for the graph\n * @return { (Number | Module) } Current height or Line Chart module to chain calls\n * @public\n */\n exports.height = function(_x) {\n if (!arguments.length) {\n return height;\n }\n if (aspectRatio) {\n width = Math.ceil(_x / aspectRatio);\n }\n height = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the isAnimated property of the chart, making it to animate when render.\n * By default this is 'false'\n *\n * @param {Boolean} _x Desired animation flag\n * @return { isAnimated | module} Current isAnimated flag or Chart module\n * @public\n */\n exports.isAnimated = function(_x) {\n if (!arguments.length) {\n return isAnimated;\n }\n isAnimated = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the loading state of the chart\n * @param {string} markup Desired markup to show when null data\n * @return { loadingState | module} Current loading state markup or Chart module to chain calls\n * @public\n */\n exports.loadingState = function(_markup) {\n if (!arguments.length) {\n return loadingState;\n }\n loadingState = _markup;\n\n return this;\n };\n\n /**\n * Gets or Sets the margin of the chart\n * @param {Object} _x Margin object to get/set\n * @return { (Object | Module) } Current margin or Line Chart module to chain calls\n * @public\n */\n exports.margin = function(_x) {\n if (!arguments.length) {\n return margin;\n }\n margin = {\n ...margin,\n ..._x\n };\n\n return this;\n };\n\n /**\n * Gets or Sets the number format of the line chart\n * @param {string} _x Desired number format for the line chart\n * @return {numberFormat | module} Current numberFormat or Chart module to chain calls\n * @public\n */\n exports.numberFormat = function(_x) {\n if (!arguments.length) {\n return numberFormat;\n }\n numberFormat = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets the curve of the line chart\n * @param {curve} _x Desired curve for the lines, default 'linear'. Other options are:\n * basis, natural, monotoneX, monotoneY, step, stepAfter, stepBefore, cardinal, and\n * catmullRom. Visit https://github.com/d3/d3-shape#curves for more information.\n * @return { (curve | Module) } Current line curve or Line Chart module to chain calls\n * @public\n */\n exports.lineCurve = function(_x) {\n if (!arguments.length) {\n return lineCurve;\n }\n lineCurve = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the gradient colors of the line chart when there is only one line\n * @param {String[]} _x Desired color gradient for the line (array of two hexadecimal numbers)\n * @return { (Number | Module) } Current color gradient or Line Chart module to chain calls\n * @public\n */\n exports.lineGradient = function(_x) {\n if (!arguments.length) {\n return singleLineGradientColors;\n }\n singleLineGradientColors = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the topicLabel of the chart\n * @param {Boolean} _x=false Whether all data points should be drawn\n * @return {shouldShowAllDataPoints | module} Current shouldShowAllDataPoints or Chart module to chain calls\n * @public\n */\n exports.shouldShowAllDataPoints = function(_x) {\n if (!arguments.length) {\n return shouldShowAllDataPoints;\n }\n shouldShowAllDataPoints = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets the minimum width of the graph in order to show the tooltip\n * NOTE: This could also depend on the aspect ratio\n * @param {Number} _x Desired tooltip threshold for the graph\n * @return { (Number | Module) } Current tooltip threshold or Line Chart module to chain calls\n * @public\n */\n exports.tooltipThreshold = function(_x) {\n if (!arguments.length) {\n return tooltipThreshold;\n }\n tooltipThreshold = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the topicLabel of the chart\n * @param {Number} _x Desired topicLabel for the graph\n * @return {topicLabel | module} Current topicLabel or Chart module to chain calls\n * @public\n */\n exports.topicLabel = function(_x) {\n if (!arguments.length) {\n return topicLabel;\n }\n topicLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the valueLabel of the chart\n * @param {Number} _x Desired valueLabel for the graph\n * @return {valueLabel | module} Current valueLabel or Chart module to chain calls\n * @public\n */\n exports.valueLabel = function(_x) {\n if (!arguments.length) {\n return valueLabel;\n }\n valueLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the yAxisLabelPadding of the chart.\n * The default value is -36\n * @param {Number} _x Desired yAxisLabelPadding for the graph\n * @return {yAxisLabelPadding | module} Current yAxisLabelPadding or Chart module to chain calls\n * @public\n */\n exports.yAxisLabelPadding = function(_x) {\n if (!arguments.length) {\n return yAxisLabelPadding;\n }\n yAxisLabelPadding = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets the number of ticks of the y axis on the chart\n * (Default is 5)\n * @param {Number} _x Desired yTicks\n * @return {Number | module} Current yTicks or Chart module to chain calls\n * @public\n */\n exports.yTicks = function(_x) {\n if (!arguments.length) {\n return yTicks;\n }\n yTicks = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the width of the chart\n * @param {Number} _x Desired width for the graph\n * @return {Number | Module} Current width or Line Chart module to chain calls\n * @public\n */\n exports.width = function(_x) {\n if (!arguments.length) {\n return width;\n }\n if (aspectRatio) {\n height = Math.ceil(_x * aspectRatio);\n }\n width = _x;\n\n return this;\n };\n\n /**\n * Pass language tag for the tooltip to localize the date.\n * Feature uses Intl.DateTimeFormat, for compatability and support, refer to\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat\n * @param {String} _x must be a language tag (BCP 47) like 'en-US' or 'fr-FR'\n * @return { (String|Module) } Current locale or module to chain calls\n * @public\n */\n exports.locale = function(_x) {\n if (!arguments.length) {\n return locale;\n }\n locale = _x;\n\n return this;\n };\n\n /**\n * Chart exported to png and a download action is fired\n * @param {String} filename File title for the resulting picture\n * @param {String} title Title to add at the top of the exported picture\n * @public\n */\n exports.exportChart = function(filename, title) {\n exportChart.call(exports, svg, filename, title);\n };\n\n /**\n * Exposes an 'on' method that acts as a bridge with the event dispatcher\n * We are going to expose this events:\n * customMouseHover, customMouseMove, customMouseOut,\n * customDataEntryClick, and customTouchMove\n *\n * @return {module} Bar Chart\n * @public\n */\n exports.on = function() {\n let value = dispatcher.on.apply(dispatcher, arguments);\n\n return value === dispatcher ? exports : value;\n };\n\n /**\n * Exposes the constants to be used to force the x axis to respect a certain granularity\n * current options: MINUTE_HOUR, HOUR_DAY, DAY_MONTH, MONTH_YEAR\n * @example\n * line.xAxisCustomFormat(line.axisTimeCombinations.HOUR_DAY)\n */\n exports.axisTimeCombinations = axisTimeCombinations;\n\n return exports;\n };\n\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/line.js","define(function(require){\n 'use strict';\n\n const d3Ease = require('d3-ease');\n const d3Format = require('d3-format');\n const d3Selection = require('d3-selection');\n const d3Transition = require('d3-transition');\n const d3TimeFormat = require('d3-time-format');\n\n const {axisTimeCombinations} = require('./helpers/constants');\n const {\n formatIntegerValue,\n formatDecimalValue,\n isInteger\n } = require('./helpers/number');\n\n /**\n * Tooltip Component reusable API class that renders a\n * simple and configurable tooltip element for Britechart's\n * line chart or stacked area chart.\n *\n * @module Tooltip\n * @tutorial tooltip\n * @requires d3-array, d3-axis, d3-dispatch, d3-format, d3-scale, d3-selection, d3-transition\n *\n * @example\n * var lineChart = line(),\n * tooltip = tooltip();\n *\n * tooltip\n * .title('Tooltip title');\n *\n * lineChart\n * .width(500)\n * .on('customMouseOver', function() {\n * tooltip.show();\n * })\n * .on('customMouseMove', function(dataPoint, topicColorMap, dataPointXPosition) {\n * tooltip.update(dataPoint, topicColorMap, dataPointXPosition);\n * })\n * .on('customMouseOut', function() {\n * tooltip.hide();\n * });\n *\n * d3Selection.select('.css-selector')\n * .datum(dataset)\n * .call(lineChart);\n *\n * d3Selection.select('.metadata-group .hover-marker')\n * .datum([])\n * .call(tooltip);\n *\n */\n return function module() {\n\n let margin = {\n top: 2,\n right: 2,\n bottom: 2,\n left: 2\n },\n width = 250,\n height = 45,\n\n title = 'Tooltip title',\n shouldShowDateInTitle = true,\n valueFormat = null,\n\n // tooltip\n tooltip,\n tooltipOffset = {\n y: -55,\n x: 0\n },\n tooltipMaxTopicLength = 170,\n tooltipTextContainer,\n tooltipDivider,\n tooltipBody,\n tooltipTitle,\n tooltipWidth = 250,\n tooltipHeight = 48,\n tooltipBorderRadius = 3,\n ttTextX = 0,\n ttTextY = 37,\n textSize,\n entryLineLimit = 3,\n initialTooltipTextXPosition = -25,\n tooltipTextLinePadding = 5,\n\n // Animations\n mouseChaseDuration = 100,\n ease = d3Ease.easeQuadInOut,\n\n circleYOffset = 8,\n\n colorMap,\n bodyFillColor = '#FFFFFF',\n borderStrokeColor = '#D2D6DF',\n titleFillColor = '#6D717A',\n textFillColor = '#282C35',\n tooltipTextColor = '#000000',\n\n dateLabel = 'date',\n valueLabel = 'value',\n nameLabel = 'name',\n topicLabel = 'topics',\n\n defaultAxisSettings = axisTimeCombinations.DAY_MONTH,\n dateFormat = null,\n dateCustomFormat = null,\n topicsOrder = [],\n\n // formats\n numberFormat = null,\n monthDayYearFormat = d3TimeFormat.timeFormat('%b %d, %Y'),\n monthDayHourFormat = d3TimeFormat.timeFormat('%b %d, %I %p'),\n locale,\n\n chartWidth, chartHeight,\n data,\n svg;\n\n\n /**\n * This function creates the graph using the selection as container\n * @param {D3Selection} _selection A d3 selection that represents\n * the container(s) where the chart(s) will be rendered\n * @param {Object} _data The data to attach and generate the chart\n */\n function exports(_selection) {\n _selection.each(function(_data){\n chartWidth = width - margin.left - margin.right;\n chartHeight = height - margin.top - margin.bottom;\n data = _data;\n\n buildSVG(this);\n });\n }\n\n /**\n * Builds containers for the tooltip\n * Also applies the Margin convention\n * @private\n */\n function buildContainerGroups() {\n var container = svg.append('g')\n .classed('tooltip-container-group', true)\n .attr('transform', `translate( ${margin.left}, ${margin.top})`);\n\n container.append('g').classed('tooltip-group', true);\n }\n\n /**\n * Builds the SVG element that will contain the chart\n * @param {HTMLElement} container DOM element that will work as the container of the graph\n * @private\n */\n function buildSVG(container) {\n if (!svg) {\n svg = d3Selection.select(container)\n .append('g')\n .classed('britechart britechart-tooltip', true)\n .style('display', 'none');\n\n buildContainerGroups();\n drawTooltip();\n }\n svg\n .transition()\n .attr('width', width)\n .attr('height', height);\n\n // Hidden by default\n exports.hide();\n }\n\n /**\n * Resets the tooltipBody content\n * @return void\n * @private\n */\n function cleanContent(){\n tooltipBody.selectAll('text').remove();\n tooltipBody.selectAll('circle').remove();\n }\n\n /**\n * Draws the different elements of the Tooltip box\n * @return void\n * @private\n */\n function drawTooltip(){\n tooltipTextContainer = svg.selectAll('.tooltip-group')\n .append('g')\n .classed('tooltip-text', true);\n\n tooltip = tooltipTextContainer\n .append('rect')\n .classed('tooltip-text-container', true)\n .attr('x', -tooltipWidth / 4 + 8)\n .attr('y', 0)\n .attr('width', tooltipWidth)\n .attr('height', tooltipHeight)\n .attr('rx', tooltipBorderRadius)\n .attr('ry', tooltipBorderRadius)\n .style('fill', bodyFillColor)\n .style('stroke', borderStrokeColor)\n .style('stroke-width', 1);\n\n tooltipTitle = tooltipTextContainer\n .append('text')\n .classed('tooltip-title', true)\n .attr('x', -tooltipWidth / 4 + 16)\n .attr('dy', '.35em')\n .attr('y', 16)\n .style('fill', titleFillColor);\n\n tooltipDivider = tooltipTextContainer\n .append('line')\n .classed('tooltip-divider', true)\n .attr('x1', -tooltipWidth / 4 + 16)\n .attr('x2', 265)\n .attr('y1', 31)\n .attr('y2', 31)\n .style('stroke', borderStrokeColor);\n\n tooltipBody = tooltipTextContainer\n .append('g')\n .classed('tooltip-body', true)\n .style('transform', 'translateY(8px)')\n .style('fill', textFillColor);\n }\n\n /**\n * Formats the value depending on its characteristics\n * @param {Number} value Value to format\n * @return {Number} Formatted value\n * @private\n */\n function getFormattedValue(value) {\n let valueFormatter = formatDecimalValue;\n\n if (!value) {\n return 0;\n }\n if (numberFormat !== null) {\n valueFormatter = d3Format.format(numberFormat);\n } else if (isInteger(value)) {\n valueFormatter = formatIntegerValue;\n }\n\n return valueFormatter(value);\n }\n\n /**\n * Calculates the desired position for the tooltip\n * @param {Number} mouseX Current horizontal mouse position\n * @param {Number} mouseY Current vertical mouse position\n * @return {Number[]} X and Y position\n * @private\n */\n function getTooltipPosition([mouseX, mouseY]) {\n let tooltipX, tooltipY;\n\n // show tooltip to the right\n if ((mouseX - tooltipWidth) < 0) {\n // Tooltip on the right\n tooltipX = tooltipWidth - 185;\n } else {\n // Tooltip on the left\n tooltipX = -205\n }\n\n if (mouseY) {\n tooltipY = tooltipOffset.y;\n // tooltipY = mouseY + tooltipOffset.y;\n } else {\n tooltipY = tooltipOffset.y;\n }\n\n return [tooltipX, tooltipY];\n }\n\n /**\n * Extracts the value from the data object\n * @param {Object} data Data value containing the info\n * @return {String} Value to show\n */\n function getValueText(data) {\n let value = data[valueLabel];\n let valueText;\n\n if (data.missingValue) {\n valueText = '-';\n } else {\n valueText = getFormattedValue(value).toString();\n }\n\n return valueText;\n }\n\n /**\n * Resets the height of the tooltip and the pointer for the text\n * position\n */\n function resetSizeAndPositionPointers() {\n tooltipHeight = 48;\n ttTextY = 37;\n ttTextX = 0;\n }\n\n /**\n * Draws the data entries inside the tooltip for a given topic\n * @param {Object} topic Topic to extract data from\n * @return void\n * @private\n */\n function updateTopicContent(topic){\n let name = topic[nameLabel],\n textHeight,\n tooltipRight,\n tooltipLeftText,\n tooltipRightText,\n elementText;\n\n tooltipLeftText = topic.topicName || name;\n tooltipRightText = getValueText(topic);\n\n elementText = tooltipBody\n .append('text')\n .classed('tooltip-left-text', true)\n .attr('dy', '1em')\n .attr('x', ttTextX)\n .attr('y', ttTextY)\n .style('fill', tooltipTextColor)\n .text(tooltipLeftText)\n .call(textWrap, tooltipMaxTopicLength, initialTooltipTextXPosition);\n\n tooltipRight = tooltipBody\n .append('text')\n .classed('tooltip-right-text', true)\n .attr('dy', '1em')\n .attr('x', ttTextX)\n .attr('y', ttTextY)\n .style('fill', tooltipTextColor)\n .text(tooltipRightText);\n\n textSize = elementText.node().getBBox();\n\n // IE11 give us sometimes a height of 0 when hovering on top of the vertical marker\n // This hack fixes it for some cases, but it doesn't work in multiline (they won't wrap)\n // Let's remove this once we stop supporting IE11\n textHeight = textSize.height ? textSize.height : 18.4;\n\n tooltipHeight += textHeight + tooltipTextLinePadding;\n\n // Not sure if necessary\n tooltipRight.attr('x', tooltipWidth - tooltipRight.node().getBBox().width - 10 - tooltipWidth / 4)\n\n tooltipBody\n .append('circle')\n .classed('tooltip-circle', true)\n .attr('cx', 23 - tooltipWidth / 4)\n .attr('cy', (ttTextY + circleYOffset))\n .attr('r', 5)\n .style('fill', colorMap[name])\n .style('stroke-width', 1);\n\n ttTextY += textHeight + 7;\n }\n\n /**\n * Updates size and position of tooltip depending on the side of the chart we are in\n * TODO: This needs a refactor, following the mini-tooltip code.\n *\n * @param {Object} dataPoint DataPoint of the tooltip\n * @param {Number} xPosition DataPoint's x position in the chart\n * @param {Number} xPosition DataPoint's y position in the chart\n * @return void\n * @private\n */\n function updatePositionAndSize(dataPoint, xPosition, yPosition){\n let [tooltipX, tooltipY] = getTooltipPosition([xPosition, yPosition])\n\n tooltip\n .attr('width', tooltipWidth)\n .attr('height', tooltipHeight + 10);\n\n tooltipTextContainer.transition()\n .duration(mouseChaseDuration)\n .ease(ease)\n .attr('transform', `translate(${tooltipX}, ${tooltipY})`);\n\n tooltipDivider\n .attr('x2', tooltipWidth - 60);\n }\n\n /**\n * Updates value of tooltipTitle with the data meaning and the date\n * @param {Object} dataPoint Point of data to use as source\n * @return void\n * @private\n */\n function updateTitle(dataPoint) {\n let tTitle = title;\n let formattedDate = formatDate(new Date(dataPoint[dateLabel]));\n\n if (tTitle.length) {\n if (shouldShowDateInTitle) {\n tTitle = `${tTitle} - ${formattedDate}`;\n }\n } else {\n tTitle = formattedDate;\n }\n\n tooltipTitle.text(tTitle);\n }\n\n /**\n * Figures out which date format to use when showing the date of the current data entry\n * @param {Date} date Date object to format\n * @return {Function} The proper date formatting function\n * @private\n */\n function formatDate(date) {\n let settings = dateFormat || defaultAxisSettings;\n let format = null;\n let localeOptions = {month:'short', day:'numeric'};\n\n if (settings === axisTimeCombinations.DAY_MONTH || settings === axisTimeCombinations.MONTH_YEAR) {\n format = monthDayYearFormat;\n localeOptions.year = 'numeric';\n } else if (settings === axisTimeCombinations.HOUR_DAY || settings === axisTimeCombinations.MINUTE_HOUR) {\n format = monthDayHourFormat;\n localeOptions.hour = 'numeric';\n } else if (settings === axisTimeCombinations.CUSTOM && typeof dateCustomFormat === 'string') {\n format = d3TimeFormat.timeFormat(dateCustomFormat);\n }\n\n if (locale && ((typeof Intl !== 'undefined') && (typeof Intl === 'object' && Intl.DateTimeFormat))) {\n let f = Intl.DateTimeFormat(locale, localeOptions);\n\n return f.format(date);\n }\n\n return format(date);\n }\n\n /**\n * Helper method to sort the passed topics array by the names passed int he order arary\n * @param {Object[]} topics Topics data, retrieved from datapoint passed by line chart\n * @param {Object[]} order Array of names in the order to sort topics by\n * @return {Object[]} sorted topics object\n * @private\n */\n function _sortByTopicsOrder(topics, order=topicsOrder) {\n return order.map((orderName) => topics.filter(({name}) => name === orderName)[0]);\n }\n\n /**\n * Sorts topic by alphabetical order for arrays of objects with a name proeprty\n * @param {Array} topics List of topic objects\n * @return {Array} List of topic name strings\n * @private\n */\n function _sortByAlpha(topics) {\n return topics\n .map(d => d)\n .sort((a, b) => {\n if (a.name > b.name) return 1;\n if (a.name === b.name) return 0;\n\n return -1;\n });\n\n let otherIndex = topics.map(({ name }) => name).indexOf('Other');\n\n if (otherIndex >= 0) {\n let other = topics.splice(otherIndex, 1);\n\n topics = topics.concat(other);\n }\n }\n\n /**\n * Wraps a text given the text, width, x position and textFormatter function\n * @param {D3Selection} text Selection with the text to wrap inside\n * @param {Number} width Desired max width for that line\n * @param {Number} xpos Initial x position of the text\n * REF: http://bl.ocks.org/mbostock/7555321\n * More discussions on https://github.com/mbostock/d3/issues/1642\n * @private\n *\n */\n function textWrap(text, width, xpos = 0) {\n text.each(function() {\n var words,\n word,\n line,\n lineNumber,\n lineHeight,\n y,\n dy,\n tspan;\n\n text = d3Selection.select(this);\n\n words = text.text().split(/\\s+/).reverse();\n line = [];\n lineNumber = 0;\n lineHeight = 1.2;\n y = text.attr('y');\n dy = parseFloat(text.attr('dy'));\n tspan = text\n .text(null)\n .append('tspan')\n .attr('x', xpos)\n .attr('y', y)\n .attr('dy', dy + 'em');\n\n while ((word = words.pop())) {\n line.push(word);\n tspan.text(line.join(' '));\n\n if (tspan.node().getComputedTextLength() > width) {\n line.pop();\n tspan.text(line.join(' '));\n\n if (lineNumber < entryLineLimit - 1) {\n line = [word];\n tspan = text.append('tspan')\n .attr('x', xpos)\n .attr('y', y)\n .attr('dy', ++lineNumber * lineHeight + dy + 'em')\n .text(word);\n }\n }\n }\n });\n }\n\n /**\n * Draws the data entries inside the tooltip\n * @param {Object} dataPoint Data entry from to take the info\n * @return void\n * @private\n */\n function updateContent(dataPoint){\n var topics = dataPoint[topicLabel];\n\n // sort order by topicsOrder array if passed\n if (topicsOrder.length) {\n topics = _sortByTopicsOrder(topics);\n } else if (topics.length && topics[0].name) {\n topics = _sortByAlpha(topics);\n }\n\n cleanContent();\n updateTitle(dataPoint);\n resetSizeAndPositionPointers();\n topics.forEach(updateTopicContent);\n }\n\n /**\n * Updates tooltip title, content, size and position\n * sorts by alphatical name order if not forced order given\n *\n * @param {lineChartPointByDate} dataPoint Current datapoint to show info about\n * @param {Number} xPosition Position of the mouse on the X axis\n * @return void\n * @private\n */\n function updateTooltip(dataPoint, xPosition, yPosition) {\n updateContent(dataPoint);\n updatePositionAndSize(dataPoint, xPosition, yPosition);\n }\n\n\n // API\n\n /**\n * constants to be used to force the x axis to respect a certain granularity\n * current options: HOUR_DAY, DAY_MONTH, MONTH_YEAR\n * @example tooltip.dateFormat(tooltip.axisTimeCombinations.HOUR_DAY)\n */\n exports.axisTimeCombinations = axisTimeCombinations;\n\n /**\n * Exposes the ability to force the tooltip to use a certain date format\n * @param {String} _x Desired format\n * @return {String | module} Current format or module to chain calls\n * @public\n */\n exports.dateFormat = function(_x) {\n if (!arguments.length) {\n return dateFormat || defaultAxisSettings;\n }\n dateFormat = _x;\n\n return this;\n };\n\n /**\n * Exposes the ability to use a custom date format\n * @param {String} _x Desired custom format\n * @return {String | module} Current format or module to chain calls\n * @public\n * @example tooltip.dateFormat(tooltip.axisTimeCombinations.CUSTOM);\n * tooltip.dateCustomFormat('%H:%M %p')\n */\n exports.dateCustomFormat = function(_x) {\n if (!arguments.length) {\n return dateCustomFormat;\n }\n dateCustomFormat = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the dateLabel of the data\n * @param {String} _x Desired dateLabel\n * @return {String | module} Current dateLabel or Chart module to chain calls\n * @public\n */\n exports.dateLabel = function(_x) {\n if (!arguments.length) {\n return dateLabel;\n }\n dateLabel = _x;\n\n return this;\n };\n\n /**\n * Hides the tooltip\n * @return {module} Tooltip module to chain calls\n * @public\n */\n exports.hide = function() {\n svg.style('display', 'none');\n\n return this;\n };\n\n /**\n * Pass locale for the tooltip to render the date in\n * @param {String} _x Must be a locale tag like 'en-US' or 'fr-FR'\n * @return {String | module} Current locale or module to chain calls\n * @public\n */\n exports.locale = function(_x) {\n if (!arguments.length) {\n return locale;\n }\n locale = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the nameLabel of the data\n * @param {String} _x Desired nameLabel\n * @return {String | module} Current nameLabel or Chart module to chain calls\n * @public\n */\n exports.nameLabel = function(_x) {\n if (!arguments.length) {\n return nameLabel;\n }\n nameLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the number format for the value displayed on the tooltip\n * @param {string} Desired number format\n * @return {string | module} Current numberFormat or Chart module to chain calls\n * @public\n */\n exports.numberFormat = function(_x) {\n if (!arguments.length) {\n return numberFormat;\n }\n numberFormat = _x;\n return this;\n }\n\n /**\n * Gets or Sets shouldShowDateInTitle\n * @param {Boolean} _x Desired value\n * @return {Boolean | module} Current shouldShowDateInTitle or Chart module to chain calls\n * @public\n */\n exports.shouldShowDateInTitle = function(_x) {\n if (!arguments.length) {\n return shouldShowDateInTitle;\n }\n shouldShowDateInTitle = _x;\n\n return this;\n };\n\n /**\n * Shows the tooltip\n * @return {module} Tooltip module to chain calls\n * @public\n */\n exports.show = function() {\n svg.style('display', 'block');\n\n return this;\n };\n\n /**\n * Gets or Sets the title of the tooltip (to only show the date, set a blank title)\n * @param {String} _x Desired title\n * @return {String | module} Current title or module to chain calls\n * @public\n */\n exports.title = function(_x) {\n if (!arguments.length) {\n return title;\n }\n title = _x;\n\n return this;\n };\n\n /**\n * Pass an override for the offset of your tooltip\n * @param {Object} tooltipOffset Object representing the X and Y offsets\n * @return {Object | module} Current tooltipOffset\n * @public\n */\n exports.tooltipOffset = function(_x) {\n if (!arguments.length) {\n return tooltipOffset;\n }\n tooltipOffset = _x;\n\n return this;\n };\n\n /**\n * Pass an override for the ordering of your tooltip\n * @param {String[]} _x Array of the names of your tooltip items\n * @return {String[] | module} Current overrideOrder or Chart module to chain calls\n * @public\n */\n exports.topicsOrder = function(_x) {\n if (!arguments.length) {\n return topicsOrder;\n }\n topicsOrder = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the topicLabel of the data\n * @param {String} _x Desired topicLabel\n * @return {String | module} Current topicLabel or Chart module to chain calls\n * @public\n */\n exports.topicLabel = function(_x) {\n if (!arguments.length) {\n return topicLabel;\n }\n topicLabel = _x;\n\n return this;\n };\n\n /**\n * Updates the position and content of the tooltip\n * @param {Object} dataPoint Datapoint to represent\n * @param {Object} colorMapping Color scheme of the topics\n * @param {Number} position X-scale position in pixels\n * @return {Module} Tooltip module to chain calls\n * @public\n */\n exports.update = function(dataPoint, colorMapping, xPosition, yPosition = null) {\n colorMap = colorMapping;\n updateTooltip(dataPoint, xPosition, yPosition);\n\n return this;\n };\n\n /**\n * Gets or Sets the valueLabel of the data\n * @param {String} _x Desired valueLabel\n * @return {String | module} Current valueLabel or Chart module to chain calls\n * @public\n */\n exports.valueLabel = function(_x) {\n if (!arguments.length) {\n return valueLabel;\n }\n valueLabel = _x;\n\n return this;\n };\n\n return exports;\n };\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/tooltip.js","define(function(require){\n 'use strict';\n\n const d3Array = require('d3-array');\n const d3Ease = require('d3-ease');\n const d3Format = require('d3-format');\n const d3Selection = require('d3-selection');\n const d3Transition = require('d3-transition');\n\n const NUMBER_FORMAT = '.2f';\n\n /**\n * Mini Tooltip Component reusable API class that renders a\n * simple and configurable tooltip element for Britechart's\n * bar and step chart.\n *\n * @module Mini-tooltip\n * @tutorial bar\n * @requires d3\n *\n * @example\n * var barChart = line(),\n * miniTooltip = miniTooltip();\n *\n * barChart\n * .width(500)\n * .height(300)\n * .on('customMouseHover', miniTooltip.show)\n * .on('customMouseMove', miniTooltip.update)\n * .on('customMouseOut', miniTooltip.hide);\n *\n * d3Selection.select('.css-selector')\n * .datum(dataset)\n * .call(barChart);\n *\n * d3Selection.select('.metadata-group .mini-tooltip-container')\n * .datum([])\n * .call(miniTooltip);\n *\n */\n return function module() {\n\n let margin = {\n top: 12,\n right: 12,\n bottom: 12,\n left: 12\n },\n width = 100,\n height = 100,\n\n // Optional Title\n title = '',\n\n // Data Format\n valueLabel = 'value',\n nameLabel = 'name',\n\n // Animations\n mouseChaseDuration = 100,\n ease = d3Ease.easeQuadInOut,\n\n // tooltip\n tooltipBackground,\n backgroundBorderRadius = 1,\n tooltipTextContainer,\n tooltipOffset = {\n y: 0,\n x: 20\n },\n\n // Fonts\n textSize = 14,\n textLineHeight = 1.5,\n valueTextSize = 27,\n valueTextLineHeight = 1.18,\n\n // Colors\n bodyFillColor = '#FFFFFF',\n borderStrokeColor = '#D2D6DF',\n titleFillColor = '#666a73',\n nameTextFillColor = '#666a73',\n valueTextFillColor = '#45494E',\n valueTextWeight = 200,\n\n // formats\n numberFormat = NUMBER_FORMAT,\n valueFormatter = (value) => d3Format.format(numberFormat)(value),\n\n chartWidth,\n chartHeight,\n svg;\n\n\n /**\n * This function creates the graph using the selection as container\n * @param {D3Selection} _selection A d3 selection that represents\n * the container(s) where the chart(s) will be rendered\n */\n function exports(_selection) {\n _selection.each(function(){\n chartWidth = width - margin.left - margin.right;\n chartHeight = height - margin.top - margin.bottom;\n\n buildSVG(this);\n drawTooltip();\n });\n }\n\n /**\n * Builds containers for the tooltip\n * Also applies the Margin convention\n * @private\n */\n function buildContainerGroups() {\n let container = svg\n .append('g')\n .classed('tooltip-container-group', true)\n .attr('transform', `translate( ${margin.left}, ${margin.top})`);\n\n container.append('g').classed('tooltip-group', true);\n }\n\n /**\n * Builds the SVG element that will contain the chart\n * @param {HTMLElement} container DOM element that will work as the container of the graph\n * @private\n */\n function buildSVG(container) {\n if (!svg) {\n svg = d3Selection.select(container)\n .append('g')\n .classed('britechart britechart-mini-tooltip', true);\n\n buildContainerGroups();\n }\n svg\n .transition()\n .attr('width', width)\n .attr('height', height);\n\n // Hidden by default\n exports.hide();\n }\n\n /**\n * Draws the different elements of the Tooltip box\n * @return void\n */\n function drawTooltip(){\n tooltipTextContainer = svg.selectAll('.tooltip-group')\n .append('g')\n .classed('tooltip-text', true);\n\n tooltipBackground = tooltipTextContainer\n .append('rect')\n .classed('tooltip-background', true)\n .attr('width', width)\n .attr('height', height)\n .attr('rx', backgroundBorderRadius)\n .attr('ry', backgroundBorderRadius)\n .attr('y', - margin.top)\n .attr('x', - margin.left)\n .style('fill', bodyFillColor)\n .style('stroke', borderStrokeColor)\n .style('stroke-width', 1)\n .style('pointer-events', 'none')\n .style('opacity', 0.9);\n }\n\n /**\n * Figures out the max length of the tooltip lines\n * @param {D3Selection[]} texts List of svg elements of each line\n * @return {Number} Max size of the lines\n */\n function getMaxLengthLine(...texts) {\n let textSizes = texts.filter(x => !!x)\n .map(x => x.node().getBBox().width);\n\n return d3Array.max(textSizes);\n }\n\n /**\n * Calculates the desired position for the tooltip\n * @param {Number} mouseX Current horizontal mouse position\n * @param {Number} mouseY Current vertical mouse position\n * @param {Number} parentChartWidth Parent's chart width\n * @param {Number} parentChartHeight Parent's chart height\n * @return {Number[]} X and Y position\n * @private\n */\n function getTooltipPosition([mouseX, mouseY], [parentChartWidth, parentChartHeight]) {\n let tooltipX, tooltipY;\n\n if (hasEnoughHorizontalRoom(parentChartWidth, mouseX)) {\n tooltipX = mouseX + tooltipOffset.x;\n } else {\n tooltipX = mouseX - chartWidth - tooltipOffset.x - margin.right;\n }\n\n if (hasEnoughVerticalRoom(parentChartHeight, mouseY)) {\n tooltipY = mouseY + tooltipOffset.y;\n } else {\n tooltipY = mouseY - chartHeight - tooltipOffset.y - margin.bottom;\n }\n\n return [tooltipX, tooltipY];\n }\n\n /**\n * Checks if the mouse is over the bounds of the parent chart\n * @param {Number} chartWidth Parent's chart\n * @param {Number} positionX Mouse position\n * @return {Boolean} If the mouse position allows space for the tooltip\n */\n function hasEnoughHorizontalRoom(parentChartWidth, positionX) {\n return (parentChartWidth - margin.left - margin.right - chartWidth) - positionX > 0;\n }\n\n /**\n * Checks if the mouse is over the bounds of the parent chart\n * @param {Number} chartWidth Parent's chart\n * @param {Number} positionX Mouse position\n * @return {Boolean} If the mouse position allows space for the tooltip\n */\n function hasEnoughVerticalRoom(parentChartHeight, positionY) {\n return (parentChartHeight - margin.top - margin.bottom - chartHeight) - positionY > 0;\n }\n\n /**\n * Hides the tooltip\n * @return {void}\n */\n function hideTooltip() {\n svg.style('display', 'none');\n }\n\n /**\n * Shows the tooltip updating it's content\n * @param {Object} dataPoint Data point from the chart\n * @return {void}\n */\n function showTooltip(dataPoint) {\n updateContent(dataPoint);\n svg.style('display', 'block');\n }\n\n /**\n * Draws the data entries inside the tooltip for a given topic\n * @param {Object} topic Topic to extract data from\n * @return void\n */\n function updateContent(dataPoint = {}){\n let value = dataPoint[valueLabel] || '',\n name = dataPoint[nameLabel] || '',\n lineHeight = textSize * textLineHeight,\n valueLineHeight = valueTextSize * valueTextLineHeight,\n defaultDy = '1em',\n temporalHeight = 0,\n tooltipValue,\n tooltipName,\n tooltipTitle;\n\n tooltipTextContainer.selectAll('text')\n .remove();\n\n if (title) {\n tooltipTitle = tooltipTextContainer\n .append('text')\n .classed('mini-tooltip-title', true)\n .attr('dy', defaultDy)\n .attr('y', 0)\n .style('fill', titleFillColor)\n .style('font-size', textSize)\n .text(title);\n\n temporalHeight = lineHeight + temporalHeight;\n }\n\n if (name) {\n tooltipName = tooltipTextContainer\n .append('text')\n .classed('mini-tooltip-name', true)\n .attr('dy', defaultDy)\n .attr('y', temporalHeight || 0)\n .style('fill', nameTextFillColor)\n .style('font-size', textSize)\n .text(name);\n\n temporalHeight = lineHeight + temporalHeight;\n }\n\n if (value) {\n tooltipValue = tooltipTextContainer\n .append('text')\n .classed('mini-tooltip-value', true)\n .attr('dy', defaultDy)\n .attr('y', temporalHeight || 0)\n .style('fill', valueTextFillColor)\n .style('font-size', valueTextSize)\n .style('font-weight', valueTextWeight)\n .text(valueFormatter(value));\n\n temporalHeight = valueLineHeight + temporalHeight;\n }\n\n chartWidth = getMaxLengthLine(tooltipName, tooltipTitle, tooltipValue);\n chartHeight = temporalHeight;\n }\n\n /**\n * Updates size and position of tooltip depending on the side of the chart we are in\n * @param {Object} dataPoint DataPoint of the tooltip\n * @return void\n */\n function updatePositionAndSize(mousePosition, parentChartSize) {\n let [tooltipX, tooltipY] = getTooltipPosition(mousePosition, parentChartSize);\n\n svg.transition()\n .duration(mouseChaseDuration)\n .ease(ease)\n .attr('height', chartHeight + margin.top + margin.bottom)\n .attr('width', chartWidth + margin.left + margin.right)\n .attr('transform', `translate(${tooltipX},${tooltipY})`);\n\n tooltipBackground\n .attr('height', chartHeight + margin.top + margin.bottom)\n .attr('width', chartWidth + margin.left + margin.right);\n }\n\n /**\n * Updates tooltip content, size and position\n *\n * @param {Object} dataPoint Current datapoint to show info about\n * @return void\n */\n function updateTooltip(dataPoint, position, chartSize) {\n updateContent(dataPoint);\n updatePositionAndSize(position, chartSize);\n }\n\n /**\n * Hides the tooltip\n * @return {Module} Tooltip module to chain calls\n * @public\n */\n exports.hide = function() {\n hideTooltip();\n\n return this;\n };\n\n /**\n * Gets or Sets data's nameLabel\n * @param {text} _x Desired nameLabel\n * @return { text | module} nameLabel or Step Chart module to chain calls\n * @public\n */\n exports.nameLabel = function(_x) {\n if (!arguments.length) {\n return nameLabel;\n }\n nameLabel = _x;\n return this;\n };\n\n /**\n * Gets or Sets the number format for the value displayed on the tooltip\n * @param {string} [_x=\".2f\"] Desired number format\n * @return {string | module} Current numberFormat or Chart module to chain calls\n * @public\n */\n exports.numberFormat = function(_x) {\n if (!arguments.length) {\n return numberFormat;\n }\n numberFormat = _x;\n return this;\n }\n\n /**\n * Shows the tooltip\n * @return {Module} Tooltip module to chain calls\n * @public\n */\n exports.show = function() {\n showTooltip();\n\n return this;\n };\n\n /**\n * Gets or Sets the title of the tooltip\n * @param {string} _x Desired title\n * @return { string | module} Current title or module to chain calls\n * @public\n */\n exports.title = function(_x) {\n if (!arguments.length) {\n return title;\n }\n title = _x;\n return this;\n };\n\n /**\n * Updates the position and content of the tooltip\n * @param {Object} dataPoint Datapoint of the hovered element\n * @param {Array} mousePosition Mouse position relative to the parent chart [x, y]\n * @param {Array} chartSize Parent chart size [x, y]\n * @return {module} Current component\n */\n exports.update = function(dataPoint, mousePosition, chartSize) {\n updateTooltip(dataPoint, mousePosition, chartSize);\n\n return this;\n };\n\n /**\n * Gets or Sets data's valueLabel\n * @param {text} _x Desired valueLabel\n * @return {text | module} valueLabel or Step Chart module to chain calls\n * @public\n */\n exports.valueLabel = function(_x) {\n if (!arguments.length) {\n return valueLabel;\n }\n valueLabel = _x;\n return this;\n }\n\n return exports;\n };\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/mini-tooltip.js","define(function(require){\n 'use strict';\n\n const d3Array = require('d3-array');\n const d3Ease = require('d3-ease');\n const d3Scale = require('d3-scale');\n const d3Shape = require('d3-shape');\n const d3Selection = require('d3-selection');\n const d3Transition = require('d3-transition');\n\n const {exportChart} = require('./helpers/export');\n const colorHelper = require('./helpers/color');\n const {line} = require('./helpers/load');\n const {uniqueId} = require('./helpers/number');\n\n const DEFAULT_TITLE_TEXT_STYLE = {\n 'font-size': '22px',\n 'font-family': 'sans-serif',\n 'font-style': 'normal',\n 'font-weight': 0\n }\n\n /**\n * @typedef SparklineChartData\n * @type {Object[]}\n * @property {Number} value Value of the group (required)\n * @property {String} name Name of the group (required)\n *\n * @example\n * [\n * {\n * value: 1,\n * date: '2011-01-06T00:00:00Z'\n * },\n * {\n * value: 2,\n * date: '2011-01-07T00:00:00Z'\n * }\n * ]\n */\n\n /**\n * Sparkline Chart reusable API module that allows us\n * rendering a sparkline configurable chart.\n *\n * @module Sparkline\n * @tutorial sparkline\n * @requires d3\n *\n * @example\n * var sparkLineChart = sparkline();\n *\n * sparkLineChart\n * .width(200)\n * .height(100);\n *\n * d3Selection.select('.css-selector')\n * .datum(dataset)\n * .call(sparkLineChart);\n *\n */\n return function module(){\n\n let margin = {\n left: 5,\n right: 5,\n top: 5,\n bottom: 5\n },\n width = 100,\n height = 30,\n loadingState = line,\n\n xScale,\n yScale,\n\n areaGradient = ['#F5FDFF', '#F6FEFC'],\n areaGradientEl,\n areaGradientId = uniqueId('sparkline-area-gradient'),\n\n lineGradient = colorHelper.colorGradients.greenBlue,\n lineGradientEl,\n lineGradientId = uniqueId('sparkline-line-gradient'),\n\n maskingClip,\n maskingClipId = uniqueId('maskingClip'),\n\n svg,\n chartWidth, chartHeight,\n data,\n\n hasArea = true,\n isAnimated = false,\n clipDuration = 3000,\n ease = d3Ease.easeQuadInOut,\n\n line,\n area,\n circle,\n\n titleEl,\n titleText,\n titleTextStyle = DEFAULT_TITLE_TEXT_STYLE,\n\n markerSize = 1.5,\n\n valueLabel = 'value',\n dateLabel = 'date',\n\n // getters\n getDate = ({date}) => date,\n getValue = ({value}) => value;\n\n /**\n * This function creates the graph using the selection and data provided\n *\n * @param {D3Selection} _selection A d3 selection that represents\n * the container(s) where the chart(s) will be rendered\n * @param {SparklineChartData} _data The data to attach and generate the chart\n */\n function exports(_selection) {\n _selection.each(function(_data){\n chartWidth = width - margin.left - margin.right;\n chartHeight = height - margin.top - margin.bottom;\n data = cleanData(_data);\n\n buildScales();\n buildSVG(this);\n createGradients();\n createMaskingClip();\n drawLine();\n drawArea();\n drawEndMarker();\n\n if (titleText) {\n drawSparklineTitle();\n }\n });\n }\n\n /**\n * Builds containers for the chart, the axis and a wrapper for all of them\n * NOTE: The order of drawing of this group elements is really important,\n * as everything else will be drawn on top of them\n * @private\n */\n function buildContainerGroups(){\n let container = svg\n .append('g')\n .classed('container-group', true)\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n container\n .append('g').classed('text-group', true);\n container\n .append('g').classed('chart-group', true);\n container\n .append('g').classed('metadata-group', true);\n }\n\n /**\n * Creates the x, y and color scales of the chart\n * @private\n */\n function buildScales(){\n xScale = d3Scale.scaleLinear()\n .domain(d3Array.extent(data, getDate))\n .range([0, chartWidth]);\n\n yScale = d3Scale.scaleLinear()\n .domain(d3Array.extent(data, getValue))\n .range([chartHeight, 0]);\n }\n\n /**\n * Builds the SVG element that will contain the chart\n * @param {HTMLElement} container DOM element that will work as the container of the graph\n * @private\n */\n function buildSVG(container){\n if (!svg) {\n svg = d3Selection.select(container)\n .append('svg')\n .classed('britechart sparkline', true);\n\n buildContainerGroups();\n }\n\n svg\n .attr('width', width)\n .attr('height', height);\n }\n\n /**\n * Cleaning data casting the values and dates to the proper type while keeping\n * the rest of properties on the data\n * @param {SparklineChartData} originalData Raw data from the container\n * @return {SparklineChartData} Clean data\n * @private\n */\n function cleanData(originalData) {\n return originalData.reduce((acc, d) => {\n d.date = new Date(d[dateLabel]);\n d.value = +d[valueLabel];\n\n return [...acc, d];\n }, []);\n }\n\n /**\n * Creates the gradient on the area below the line\n * @return {void}\n */\n function createGradients() {\n let metadataGroup = svg.select('.metadata-group');\n\n if (areaGradientEl || lineGradientEl) {\n svg.selectAll(`#${areaGradientId}`).remove();\n svg.selectAll(`#${lineGradientId}`).remove();\n }\n\n areaGradientEl = metadataGroup.append('linearGradient')\n .attr('id', areaGradientId)\n .attr('class', 'area-gradient')\n .attr('gradientUnits', 'userSpaceOnUse')\n .attr('x1', 0)\n .attr('x2', xScale(data[data.length - 1].date))\n .attr('y1', 0)\n .attr('y2', 0)\n .selectAll('stop')\n .data([\n {offset: '0%', color: areaGradient[0]},\n {offset: '100%', color: areaGradient[1]}\n ])\n .enter().append('stop')\n .attr('offset', ({offset}) => offset)\n .attr('stop-color', ({color}) => color);\n\n lineGradientEl = metadataGroup.append('linearGradient')\n .attr('id', lineGradientId)\n .attr('class', 'line-gradient')\n .attr('gradientUnits', 'userSpaceOnUse')\n .attr('x1', 0)\n .attr('x2', xScale(data[data.length - 1].date))\n .attr('y1', 0)\n .attr('y2', 0)\n .selectAll('stop')\n .data([\n {offset: '0%', color: lineGradient[0]},\n {offset: '100%', color: lineGradient[1]}\n ])\n .enter().append('stop')\n .attr('offset', ({offset}) => offset)\n .attr('stop-color', ({color}) => color);\n }\n\n /**\n * Creates a masking clip that would help us fake an animation if the\n * proper flag is true\n *\n * @return {void}\n */\n function createMaskingClip() {\n if (maskingClip) {\n svg.selectAll(`#${maskingClipId}`).remove();\n }\n\n if (isAnimated) {\n maskingClip = svg.select('.metadata-group')\n .append('clipPath')\n .attr('id', maskingClipId)\n .attr('class', 'clip-path')\n .append('rect')\n .attr('width', 0)\n .attr('height', height);\n\n d3Selection.select(`#${maskingClipId} rect`)\n .transition()\n .ease(ease)\n .duration(clipDuration)\n .attr('width', width);\n }\n }\n\n /**\n * Draws the area that will be placed below the line\n * @private\n */\n function drawArea(){\n if (area) {\n svg.selectAll('.sparkline-area').remove();\n }\n\n area = d3Shape.area()\n .x(({date}) => xScale(date))\n .y0(() => yScale(0))\n .y1(({value}) => yScale(value))\n .curve(d3Shape.curveBasis);\n\n svg.select('.chart-group')\n .append('path')\n .datum(data)\n .attr('class', 'sparkline-area')\n .attr('fill', `url(#${areaGradientId})`)\n .attr('d', area)\n .attr('clip-path', `url(#${maskingClipId})`);\n }\n\n /**\n * Draws the line element within the chart group\n * @private\n */\n function drawLine(){\n if (line) {\n svg.selectAll('.line').remove();\n }\n\n line = d3Shape.line()\n .curve(d3Shape.curveBasis)\n .x(({date}) => xScale(date))\n .y(({value}) => yScale(value));\n\n svg.select('.chart-group')\n .append('path')\n .datum(data)\n .attr('class', 'line')\n .attr('stroke', `url(#${lineGradientId})`)\n .attr('d', line)\n .attr('clip-path', `url(#${maskingClipId})`);\n }\n\n /**\n * Draws the text element within the text group\n * Is displayed at the top of sparked area\n * @private\n */\n function drawSparklineTitle() {\n if (titleEl) {\n svg.selectAll('.sparkline-text').remove();\n }\n\n titleEl = svg.selectAll('.text-group')\n .append('text')\n .attr('x', chartWidth / 2)\n .attr('y', chartHeight / 6)\n .attr('text-anchor', 'middle')\n .attr('class', 'sparkline-text')\n .style('font-size', titleTextStyle['font-size'] || DEFAULT_TITLE_TEXT_STYLE['font-size']) \n .style('fill', titleTextStyle['fill'] || lineGradient[0])\n .style('font-family', titleTextStyle['font-family'] || DEFAULT_TITLE_TEXT_STYLE['font-family'])\n .style('font-weight', titleTextStyle['font-weight'] || DEFAULT_TITLE_TEXT_STYLE['font-weight'])\n .style('font-style', titleTextStyle['font-style'] || DEFAULT_TITLE_TEXT_STYLE['font-style'])\n .text(titleText)\n }\n\n /**\n * Draws a marker at the end of the sparkline\n */\n function drawEndMarker(){\n if (circle) {\n svg.selectAll('.sparkline-circle').remove();\n }\n\n circle = svg.selectAll('.chart-group')\n .append('circle')\n .attr('class', 'sparkline-circle')\n .attr('cx', xScale(data[data.length - 1].date))\n .attr('cy', yScale(data[data.length - 1].value))\n .attr('r', markerSize);\n }\n\n // API\n\n /**\n * Gets or Sets the areaGradient of the chart\n * @param {String[]} _x Desired areaGradient for the graph\n * @return {areaGradient | module} Current areaGradient or Chart module to chain calls\n * @public\n */\n exports.areaGradient = function(_x) {\n if (!arguments.length) {\n return areaGradient;\n }\n areaGradient = _x;\n return this;\n };\n\n /**\n * Gets or Sets the dateLabel of the chart\n * @param {Number} _x Desired dateLabel for the graph\n * @return {dateLabel | module} Current dateLabel or Chart module to chain calls\n * @public\n */\n exports.dateLabel = function(_x) {\n if (!arguments.length) {\n return dateLabel;\n }\n dateLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the duration of the animation\n * @param {Number} _x Desired animation duration for the graph\n * @return {dateLabel | module} Current animation duration or Chart module to chain calls\n * @public\n */\n exports.duration = function(_x) {\n if (!arguments.length) {\n return clipDuration;\n }\n clipDuration = _x;\n\n return this;\n };\n\n /**\n * Chart exported to png and a download action is fired\n * @param {String} filename File title for the resulting picture\n * @param {String} title Title to add at the top of the exported picture\n * @public\n */\n exports.exportChart = function(filename, title) {\n exportChart.call(exports, svg, filename, title);\n };\n\n /**\n * Gets or Sets the height of the chart\n * @param {Number} _x Desired width for the graph\n * @return { height | module} Current height or Chart module to chain calls\n * @public\n */\n exports.height = function(_x) {\n if (!arguments.length) {\n return height;\n }\n height = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the isAnimated property of the chart, making it to animate when render.\n * By default this is 'false'\n *\n * @param {Boolean} _x Desired animation flag\n * @return {isAnimated | module} Current isAnimated flag or Chart module\n * @public\n */\n exports.isAnimated = function(_x) {\n if (!arguments.length) {\n return isAnimated;\n }\n isAnimated = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the lineGradient of the chart\n * @param {String[]} _x Desired lineGradient for the graph\n * @return {lineGradient | module} Current lineGradient or Chart module to chain calls\n * @public\n */\n exports.lineGradient = function(_x) {\n if (!arguments.length) {\n return lineGradient;\n }\n lineGradient = _x;\n return this;\n };\n\n /**\n * Gets or Sets the loading state of the chart\n * @param {string} markup Desired markup to show when null data\n * @return {loadingState | module} Current loading state markup or Chart module to chain calls\n * @public\n */\n exports.loadingState = function(_markup) {\n if (!arguments.length) {\n return loadingState;\n }\n loadingState = _markup;\n\n return this;\n };\n\n /**\n * Gets or Sets the margin of the chart\n * @param {Object} _x Margin object to get/set\n * @return {margin | module} Current margin or Chart module to chain calls\n * @public\n */\n exports.margin = function(_x) {\n if (!arguments.length) {\n return margin;\n }\n margin = {\n ...margin,\n ..._x\n };\n\n return this;\n };\n\n /**\n * Gets or Sets the text of the title at the top of sparkline.\n * To style the title, use the titleTextStyle method below.\n * @param {String} _x String to set\n * @return {String | module} Current titleText or Chart module to chain calls\n * @public\n */\n exports.titleText = function(_x) {\n if (!arguments.length) {\n return titleText;\n }\n titleText = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the text style object of the title at the top of sparkline.\n * Using this method, you can set font-family, font-size, font-weight, font-style,\n * and color (fill). The default text font settings:\n * \n * \n * \n * {\n * 'font-family': 'sans-serif',\n * 'font-size': '22px',\n * 'font-weight': 0,\n * 'font-style': 'normal',\n * 'fill': linearGradient[0]\n * }\n *
\n *
\n * \n * You can set attributes individually. Setting just 'font-family'\n * within the object will set custom 'font-family` while the rest\n * of the attributes will have the default values provided above.\n * @param {Object} _x Object with text font configurations\n * @return {Object | module} Current titleTextStyle or Chart module to chain calls\n * @public\n * @example \n * sparkline.titleTextStyle({\n * 'font-family': 'Roboto',\n * 'font-size': '1.5em',\n * 'font-weight': 600,\n * 'font-style': 'italic',\n * 'fill': 'lightblue'\n * })\n */\n exports.titleTextStyle = function(_x) {\n if (!arguments.length) {\n return titleTextStyle;\n }\n titleTextStyle = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets the valueLabel of the chart\n * @param {Number} _x Desired valueLabel for the graph\n * @return {valueLabel | module} Current valueLabel or Chart module to chain calls\n * @public\n */\n exports.valueLabel = function(_x) {\n if (!arguments.length) {\n return valueLabel;\n }\n valueLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the width of the chart\n * @param {Number} _x Desired width for the graph\n * @return {width | module} Current width or Chart module to chain calls\n * @public\n */\n exports.width = function(_x) {\n if (!arguments.length) {\n return width;\n }\n width = _x;\n\n return this;\n };\n\n return exports;\n };\n\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/sparkline.js","define(function(require){\n 'use strict';\n\n const d3Array = require('d3-array');\n const d3Axis = require('d3-axis');\n const d3Collection = require('d3-collection');\n const d3Dispatch = require('d3-dispatch');\n const d3Ease = require('d3-ease');\n const d3Scale = require('d3-scale');\n const d3Shape = require('d3-shape');\n const d3Selection = require('d3-selection');\n const d3Transition = require('d3-transition');\n const d3TimeFormat = require('d3-time-format');\n const assign = require('lodash.assign');\n\n const {exportChart} = require('./helpers/export');\n const colorHelper = require('./helpers/color');\n const {getTimeSeriesAxis} = require('./helpers/axis');\n const {axisTimeCombinations, curveMap} = require('./helpers/constants');\n const {\n formatIntegerValue,\n formatDecimalValue,\n isInteger\n } = require('./helpers/number');\n const {\n createFilterContainer,\n createGlowWithMatrix,\n } = require('./helpers/filter');\n const {\n addDays,\n diffDays\n } = require('./helpers/date');\n const { stackedArea} = require('./helpers/load');\n\n\n const uniq = (arrArg) => arrArg.filter((elem, pos, arr) => arr.indexOf(elem) === pos);\n\n\n /**\n * @typdef D3Layout\n * @type function\n */\n\n /**\n * @typedef areaChartData\n * @type {Object[]}\n * @property {String} date Date of the entry\n * @property {String} name Name of the entry\n * @property {Number} value Value of the entry\n *\n * @example\n * [\n * {\n * \"date\": \"2011-01-05T00:00:00Z\",\n * \"name\": \"Direct\",\n * \"value\": 0\n * }\n * ]\n */\n\n /**\n * Stacked Area Chart reusable API module that allows us\n * rendering a multi area and configurable chart.\n *\n * @module Stacked-area\n * @tutorial stacked-area\n * @requires d3-array, d3-axis, d3-collection, d3-ease, d3-scale, d3-shape, d3-selection, d3-time, d3-time-format\n *\n * @example\n * let stackedArea = stackedArea();\n *\n * stackedArea\n * .width(containerWidth);\n *\n * d3Selection.select('.css-selector')\n * .datum(dataset.data)\n * .call(stackedArea);\n *\n */\n\n return function module() {\n\n let margin = {\n top: 70,\n right: 30,\n bottom: 60,\n left: 70\n },\n width = 960,\n height = 500,\n loadingState = stackedArea,\n\n xScale, xAxis, xMonthAxis,\n yScale, yAxis,\n\n aspectRatio = null,\n\n monthAxisPadding = 30,\n yTicks = 5,\n yTickTextYOffset = -8,\n yAxisLabel,\n yAxisLabelEl,\n yAxisLabelOffset = -60,\n yTickTextXOffset = -20,\n tickPadding = 5,\n\n colorSchema = colorHelper.colorSchemas.britecharts,\n lineGradient = colorHelper.colorGradients.greenBlue,\n\n highlightFilter = null,\n highlightFilterId = null,\n highlightCircleSize = 12,\n highlightCircleRadius = 5,\n highlightCircleStroke = 1.2,\n highlightCircleActiveRadius = highlightCircleRadius + 2,\n highlightCircleActiveStrokeWidth = 5,\n highlightCircleActiveStrokeOpacity = 0.6,\n\n areaOpacity = 0.24,\n categoryColorMap,\n order,\n topicsOrder,\n\n xAxisFormat = null,\n xTicks = null,\n xAxisCustomFormat = null,\n locale,\n\n baseLine,\n areaCurve = 'monotoneX',\n\n layers,\n series,\n layersInitial,\n area,\n areaOutline,\n\n // Area Animation\n maxAreaNumber = 8,\n areaAnimationDelayStep = 20,\n areaAnimationDelays = d3Array.range(areaAnimationDelayStep, maxAreaNumber* areaAnimationDelayStep, areaAnimationDelayStep),\n\n overlay,\n overlayColor = 'rgba(0, 0, 0, 0)',\n verticalMarkerContainer,\n verticalMarkerLine,\n epsilon,\n\n dataPoints = {},\n pointsSize = 1.5,\n pointsColor = '#c0c6cc',\n pointsBorderColor = '#ffffff',\n\n isAnimated = false,\n ease = d3Ease.easeQuadInOut,\n areaAnimationDuration = 1000,\n\n svg,\n chartWidth, chartHeight,\n data,\n dataByDate,\n dataByDateFormatted,\n dataByDateZeroed,\n\n verticalGridLines,\n horizontalGridLines,\n grid = null,\n\n tooltipThreshold = 480,\n\n xAxisPadding = {\n top: 0,\n left: 15,\n bottom: 0,\n right: 0\n },\n\n dateLabel = 'date',\n valueLabel = 'value',\n keyLabel = 'name',\n\n emptyDataConfig = {\n minDate: new Date(new Date().setDate(new Date().getDate()-30)),\n maxDate: new Date(),\n maxY: 500\n },\n\n isUsingFakeData = false,\n\n // getters\n getName = ({name}) => name,\n getDate = ({date}) => date,\n\n // events\n dispatcher = d3Dispatch.dispatch(\n 'customMouseOver',\n 'customMouseOut',\n 'customMouseMove',\n 'customDataEntryClick',\n 'customTouchMove'\n );\n\n /**\n * This function creates the graph using the selection and data provided\n * @param {D3Selection} _selection A d3 selection that represents\n * the container(s) where the chart(s) will be rendered\n * @param {areaChartData} _data The data to attach and generate the chart\n */\n function exports(_selection) {\n _selection.each(function(_data) {\n chartWidth = width - margin.left - margin.right;\n chartHeight = height - margin.top - margin.bottom;\n data = cleanData(_data);\n dataByDate = getDataByDate(data);\n\n buildLayers();\n buildScales();\n buildSVG(this);\n buildAxis();\n drawAxis();\n drawStackedAreas();\n\n addTouchEvents();\n\n if (shouldShowTooltip()) {\n drawHoverOverlay();\n drawVerticalMarker();\n addMouseEvents();\n }\n });\n }\n\n /**\n * Adds a filter to the element\n * @param {DOMElement} el\n * @private\n */\n function addGlowFilter(el) {\n if (!highlightFilter) {\n highlightFilter = createFilterContainer(svg.select('.metadata-group'));\n highlightFilterId = createGlowWithMatrix(highlightFilter);\n }\n\n d3Selection.select(el)\n .style('stroke-width', highlightCircleActiveStrokeWidth)\n .style('r', highlightCircleActiveRadius)\n .style('stroke-opacity', highlightCircleActiveStrokeOpacity)\n .attr('filter', `url(#${highlightFilterId})`);\n }\n\n /**\n * Adds events to the container group if the environment is not mobile\n * Adding: mouseover, mouseout and mousemove\n * @private\n */\n function addMouseEvents() {\n svg\n .on('mouseover', function(d) {\n handleMouseOver(this, d);\n })\n .on('mouseout', function(d) {\n handleMouseOut(this, d);\n })\n .on('mousemove', function(d) {\n handleMouseMove(this, d);\n });\n }\n\n /**\n * Adds events to the container group for the mobile environment\n * Adding: touchmove\n * @private\n */\n function addTouchEvents() {\n svg\n .on('touchmove', function(d) {\n handleTouchMove(this, d);\n });\n }\n\n /**\n * Formats the value depending on its characteristics\n * @param {Number} value Value to format\n * @return {Number} Formatted value\n */\n function getFormattedValue(value) {\n let format;\n\n if (isInteger(value)) {\n format = formatIntegerValue;\n } else {\n format = formatDecimalValue;\n }\n\n return format(value);\n }\n\n /**\n * Creates the d3 x and y axis, setting orientations\n * @private\n */\n function buildAxis() {\n let minor, major;\n\n if (xAxisFormat === 'custom' && typeof xAxisCustomFormat === 'string') {\n minor = {\n tick: xTicks,\n format: d3TimeFormat.timeFormat(xAxisCustomFormat)\n };\n major = null;\n } else {\n ({minor, major} = getTimeSeriesAxis(dataByDate, width, xAxisFormat, locale));\n\n xMonthAxis = d3Axis.axisBottom(xScale)\n .ticks(major.tick)\n .tickSize(0, 0)\n .tickFormat(major.format);\n }\n\n xAxis = d3Axis.axisBottom(xScale)\n .ticks(minor.tick)\n .tickSize(10, 0)\n .tickPadding(tickPadding)\n .tickFormat(minor.format);\n\n\n yAxis = d3Axis.axisRight(yScale)\n .ticks(yTicks)\n .tickSize([0])\n .tickPadding(tickPadding)\n .tickFormat(getFormattedValue);\n\n drawGridLines(minor.tick, yTicks);\n }\n\n /**\n * Builds containers for the chart, the axis and a wrapper for all of them\n * NOTE: The order of drawing of this group elements is really important,\n * as everything else will be drawn on top of them\n * @private\n */\n function buildContainerGroups() {\n let container = svg\n .append('g')\n .classed('container-group', true)\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n container\n .append('g').classed('x-axis-group', true)\n .append('g').classed('x axis', true);\n container.selectAll('.x-axis-group')\n .append('g').classed('month-axis', true);\n container\n .append('g').classed('y-axis-group axis', true);\n container\n .append('g').classed('grid-lines-group', true);\n container\n .append('g').classed('y-axis-label', true);\n container\n .append('g').classed('chart-group', true);\n container\n .append('g').classed('metadata-group', true);\n }\n\n /**\n * Builds the stacked layers layout\n * @return {D3Layout} Layout for drawing the chart\n * @private\n */\n function buildLayers() {\n dataByDateFormatted = dataByDate\n .map(d => assign({}, d, d.values))\n .map(d => {\n Object.keys(d).forEach(k => {\n const entry = d[k];\n\n if (entry && entry.name) {\n d[entry.name] = entry.value;\n }\n });\n\n return assign({}, d, {\n date: new Date(d['key'])\n });\n });\n\n dataByDateZeroed = dataByDate\n .map(d => assign({}, d, d.values))\n .map(d => {\n Object.keys(d).forEach(k => {\n const entry = d[k];\n\n if (entry && entry.name) {\n d[entry.name] = 0;\n }\n });\n\n return assign({}, d, {\n date: new Date(d['key'])\n });\n });\n\n let initialTotalsObject = uniq(data.map(getName))\n .reduce((memo, key) => (\n assign({}, memo, {[key]: 0})\n ), {});\n\n let totals = data\n .reduce((memo, item) => (\n assign({}, memo, {[item.name]: memo[item.name] += item.value})\n ), initialTotalsObject);\n\n order = topicsOrder || formatOrder(totals);\n\n let stack3 = d3Shape.stack()\n .keys(order)\n .order(d3Shape.stackOrderNone)\n .offset(d3Shape.stackOffsetNone);\n\n layersInitial = stack3(dataByDateZeroed);\n layers = stack3(dataByDateFormatted);\n }\n\n /**\n * Takes an object with all topics as keys and their aggregate totals as values,\n * sorts them into a list by descending total value and\n * moves \"Other\" to the end\n * @param {Object} totals Keys of all the topics and their corresponding totals\n * @return {Array} List of topic names in aggregate order\n */\n function formatOrder(totals) {\n let order = Object.keys(totals)\n .sort((a, b) => {\n if (totals[a] > totals[b]) return -1;\n if (totals[a] === totals[b]) return 0;\n\n return 1;\n });\n\n let otherIndex = order.indexOf('Other');\n\n if (otherIndex >= 0) {\n let other = order.splice(otherIndex, 1);\n\n order = order.concat(other);\n }\n\n return order;\n }\n\n /**\n * Creates the x, y and color scales of the chart\n * @private\n */\n function buildScales() {\n const maxValueByDate = isUsingFakeData ? emptyDataConfig.maxY : getMaxValueByDate();\n\n xScale = d3Scale.scaleTime()\n .domain(d3Array.extent(dataByDate, ({date}) => date))\n .rangeRound([0, chartWidth]);\n\n yScale = d3Scale.scaleLinear()\n .domain([0, maxValueByDate])\n .rangeRound([chartHeight, 0])\n .nice();\n\n categoryColorMap = order.reduce((memo, topic, index) => (\n assign({}, memo, {[topic]: colorSchema[index]})\n ), {});\n }\n\n /**\n * @param {HTMLElement} container DOM element that will work as the container of the graph\n * @private\n */\n function buildSVG(container) {\n if (!svg) {\n svg = d3Selection.select(container)\n .append('svg')\n .classed('britechart stacked-area', true);\n\n buildContainerGroups();\n }\n\n svg\n .attr('width', width)\n .attr('height', height);\n }\n\n /**\n * Creates fake data for when data is an empty array\n * @return {array} Fake data built from emptyDataConfig settings\n */\n function createFakeData() {\n const numDays = diffDays(emptyDataConfig.minDate, emptyDataConfig.maxDate)\n const emptyArray = Array.apply(null, Array(numDays));\n\n isUsingFakeData = true;\n\n return [\n ...emptyArray.map((el, i) => ({\n [dateLabel]: addDays(emptyDataConfig.minDate, i),\n [valueLabel]: 0,\n [keyLabel]: '1',\n })),\n ...emptyArray.map((el, i) => ({\n [dateLabel]: addDays(emptyDataConfig.minDate, i),\n [valueLabel]: 0,\n [keyLabel]: '2',\n }))\n ];\n\n }\n\n /**\n * Cleaning data casting the values and dates to the proper type while keeping\n * the rest of properties on the data. It creates fake data is the data is empty.\n * @param {areaChartData} originalData Raw data from the container\n * @return {areaChartData} Parsed data with values and dates\n * @private\n */\n function cleanData(originalData) {\n originalData = originalData.length === 0 ? createFakeData() : originalData;\n\n return originalData.reduce((acc, d) => {\n d.date = new Date(d[dateLabel]),\n d.value = +d[valueLabel]\n\n return [...acc, d];\n }, []);\n }\n\n /**\n * Draws the x and y axis on the svg object within their\n * respective groups\n * @private\n */\n function drawAxis() {\n svg.select('.x-axis-group .axis.x')\n .attr('transform', `translate( 0, ${chartHeight} )`)\n .call(xAxis);\n\n if (xAxisFormat !== 'custom') {\n svg.select('.x-axis-group .month-axis')\n .attr('transform', `translate(0, ${(chartHeight + monthAxisPadding)})`)\n .call(xMonthAxis);\n }\n\n svg.select('.y-axis-group.axis')\n .attr('transform', `translate( ${-xAxisPadding.left}, 0)`)\n .call(yAxis)\n .call(adjustYTickLabels);\n\n if (yAxisLabel) {\n if (yAxisLabelEl) {\n svg.selectAll('.y-axis-label-text').remove();\n }\n\n yAxisLabelEl = svg.select('.y-axis-label')\n .append('text')\n .classed('y-axis-label-text', true)\n .attr('x', -chartHeight / 2)\n .attr('y', yAxisLabelOffset)\n .attr('text-anchor', 'middle')\n .attr('transform', 'rotate(270 0 0)')\n .text(yAxisLabel)\n }\n\n // Moving the YAxis tick labels to the right side\n // d3Selection.selectAll('.y-axis-group .tick text')\n // .attr('transform', `translate( ${-chartWidth - yTickTextXOffset}, ${yTickTextYOffset})` );\n }\n\n /**\n * Adjusts the position of the y axis' ticks\n * @param {D3Selection} selection Y axis group\n * @return void\n */\n function adjustYTickLabels(selection) {\n selection.selectAll('.tick text')\n .attr('transform', `translate(${yTickTextXOffset}, ${yTickTextYOffset})`);\n }\n\n /**\n * Creates SVG dot elements for each data entry and draws them\n * TODO: Plug\n */\n function drawDataReferencePoints() {\n // Creates Dots on Data points\n var points = svg.select('.chart-group').selectAll('.dots')\n .data(layers)\n .enter()\n .append('g')\n .attr('class', 'dots')\n .attr('d', ({values}) => area(values))\n .attr('clip-path', 'url(#clip)');\n\n // Processes the points\n // TODO: Optimize this code\n points.selectAll('.dot')\n .data(({values}, index) => values.map((point) => ({index, point})))\n .enter()\n .append('circle')\n .attr('class','dot')\n .attr('r', () => pointsSize)\n .attr('fill', () => pointsColor)\n .attr('stroke-width', '0')\n .attr('stroke', pointsBorderColor)\n .attr('transform', function(d) {\n let {point} = d;\n let key = xScale(point.date);\n\n dataPoints[key] = dataPoints[key] || [];\n dataPoints[key].push(d);\n\n let {date, y, y0} = point;\n\n return `translate( ${xScale(date)}, ${yScale(y + y0)} )`;\n });\n }\n\n /**\n * Draws grid lines on the background of the chart\n * @return void\n */\n function drawGridLines(xTicks, yTicks) {\n svg.select('.grid-lines-group')\n .selectAll('line')\n .remove();\n\n if (grid === 'horizontal' || grid === 'full') {\n horizontalGridLines = svg.select('.grid-lines-group')\n .selectAll('line.horizontal-grid-line')\n .data(yScale.ticks(yTicks))\n .enter()\n .append('line')\n .attr('class', 'horizontal-grid-line')\n .attr('x1', (-xAxisPadding.left - 30))\n .attr('x2', chartWidth)\n .attr('y1', (d) => yScale(d))\n .attr('y2', (d) => yScale(d));\n }\n\n if (grid === 'vertical' || grid === 'full') {\n verticalGridLines = svg.select('.grid-lines-group')\n .selectAll('line.vertical-grid-line')\n .data(xScale.ticks(xTicks))\n .enter()\n .append('line')\n .attr('class', 'vertical-grid-line')\n .attr('y1', 0)\n .attr('y2', chartHeight)\n .attr('x1', (d) => xScale(d))\n .attr('x2', (d) => xScale(d));\n }\n\n //draw a horizontal line to extend x-axis till the edges\n baseLine = svg.select('.grid-lines-group')\n .selectAll('line.extended-x-line')\n .data([0])\n .enter()\n .append('line')\n .attr('class', 'extended-x-line')\n .attr('x1', (-xAxisPadding.left - 30))\n .attr('x2', chartWidth)\n .attr('y1', height - margin.bottom - margin.top)\n .attr('y2', height - margin.bottom - margin.top);\n }\n\n /**\n * Draws an overlay element over the graph\n * @private\n */\n function drawHoverOverlay() {\n // Not ideal, we need to figure out how to call exit for nested elements\n if (overlay) {\n svg.selectAll('.overlay').remove();\n }\n\n overlay = svg.select('.metadata-group')\n .append('rect')\n .attr('class', 'overlay')\n .attr('y1', 0)\n .attr('y2', chartHeight)\n .attr('height', chartHeight)\n .attr('width', chartWidth)\n .attr('fill', overlayColor)\n .style('display', 'none');\n }\n\n /**\n * Draws an empty line when the data is all zero\n * @private\n */\n function drawEmptyDataLine() {\n let emptyDataLine = d3Shape.line()\n .x( (d) => xScale(d.date) )\n .y( () => yScale(0) - 1 );\n\n let chartGroup = svg.select('.chart-group');\n\n chartGroup\n .append('path')\n .attr('class', 'empty-data-line')\n .attr('d', emptyDataLine(dataByDateFormatted))\n .style('stroke', 'url(#empty-data-line-gradient)');\n\n chartGroup\n .append('linearGradient')\n .attr('id', 'empty-data-line-gradient')\n .attr('gradientUnits', 'userSpaceOnUse')\n .attr('x1', 0)\n .attr('x2', xScale(data[data.length - 1].date))\n .attr('y1', 0)\n .attr('y2', 0)\n .selectAll('stop')\n .data([\n {offset: '0%', color: lineGradient[0]},\n {offset: '100%', color: lineGradient[1]}\n ])\n .enter()\n .append('stop')\n .attr('offset', ({offset}) => offset)\n .attr('stop-color', ({color}) => color);\n }\n\n /**\n * Draws the different areas into the chart-group element\n * @private\n */\n function drawStackedAreas() {\n // Not ideal, we need to figure out how to call exit for nested elements\n if (series) {\n svg.selectAll('.layer-container').remove();\n svg.selectAll('.layer').remove();\n svg.selectAll('.area-outline').remove();\n }\n\n if (isUsingFakeData) {\n drawEmptyDataLine();\n\n return;\n }\n\n area = d3Shape.area()\n .curve(curveMap[areaCurve])\n .x(({data})=> xScale(data.date))\n .y0((d) => yScale(d[0]))\n .y1((d) => yScale(d[1]));\n\n areaOutline = d3Shape.line()\n .curve(area.curve())\n .x(({data}) => xScale(data.date))\n .y((d) => yScale(d[1]));\n\n if (isAnimated) {\n series = svg.select('.chart-group').selectAll('.layer')\n .data(layersInitial, getName)\n .enter()\n .append('g')\n .classed('layer-container', true);\n\n series\n .append('path')\n .attr('class', 'layer')\n .attr('d', area)\n .style('opacity', areaOpacity)\n .style('fill', ({key}) => categoryColorMap[key]);\n\n series\n .append('path')\n .attr('class', 'area-outline')\n .attr('d', areaOutline)\n .style('stroke', ({key}) => categoryColorMap[key]);\n\n // Update\n svg.select('.chart-group').selectAll('.layer')\n .data(layers)\n .transition()\n .delay((_, i) => areaAnimationDelays[i])\n .duration(areaAnimationDuration)\n .ease(ease)\n .attr('d', area)\n .style('opacity', areaOpacity)\n .style('fill', ({key}) => categoryColorMap[key]);\n\n svg.select('.chart-group').selectAll('.area-outline')\n .data(layers)\n .transition()\n .delay( (_, i) => areaAnimationDelays[i])\n .duration(areaAnimationDuration)\n .ease(ease)\n .attr('d', areaOutline);\n\n } else {\n series = svg.select('.chart-group').selectAll('.layer')\n .data(layers)\n .enter()\n .append('g')\n .classed('layer-container', true);\n\n series\n .append('path')\n .attr('class', 'layer')\n .attr('d', area)\n .style('opacity', areaOpacity)\n .style('fill', ({key}) => categoryColorMap[key]);\n\n series\n .append('path')\n .attr('class', 'area-outline')\n .attr('d', areaOutline)\n .style('stroke', ({key}) => categoryColorMap[key]);\n\n\n // Update\n svg.select('.chart-group').selectAll('.layer')\n .attr('d', area)\n .style('opacity', areaOpacity)\n .style('fill', ({key}) => categoryColorMap[key]);\n\n svg.select('.chart-group').selectAll('.area-outline')\n .attr('class', 'area-outline')\n .attr('d', areaOutline)\n .style('stroke', ({key}) => categoryColorMap[key]);\n }\n\n // Exit\n series.exit()\n .transition()\n .style('opacity', 0)\n .remove();\n }\n\n /**\n * Creates the vertical marker\n * @return void\n */\n function drawVerticalMarker() {\n // Not ideal, we need to figure out how to call exit for nested elements\n if (verticalMarkerContainer) {\n svg.selectAll('.vertical-marker-container').remove();\n }\n\n verticalMarkerContainer = svg.select('.metadata-group')\n .append('g')\n .attr('class', 'vertical-marker-container')\n .attr('transform', 'translate(9999, 0)');\n\n verticalMarkerLine = verticalMarkerContainer.selectAll('path')\n .data([{\n x1: 0,\n y1: 0,\n x2: 0,\n y2: 0\n }])\n .enter()\n .append('line')\n .classed('vertical-marker', true)\n .attr('x1', 0)\n .attr('y1', chartHeight)\n .attr('x2', 0)\n .attr('y2', 0);\n }\n\n /**\n * Removes all the datapoints highlighter circles added to the marker container\n * @return void\n * @private\n */\n function cleanDataPointHighlights() {\n verticalMarkerContainer.selectAll('.circle-container').remove();\n }\n\n /**\n * Orders the data by date for consumption on the chart tooltip\n * @param {areaChartData} data Chart data\n * @return {Object[]} Chart data ordered by date\n * @private\n */\n function getDataByDate(data) {\n return d3Collection.nest()\n .key(getDate)\n .entries(\n data.sort((a, b) => a.date - b.date)\n )\n .map(d => {\n return assign({}, d, {\n date: new Date(d.key)\n });\n });\n\n // let b = d3Collection.nest()\n // .key(getDate).sortKeys(d3Array.ascending)\n // .entries(data);\n }\n\n /**\n * Computes the maximum sum of values for any date\n *\n * @return {Number} Max value\n */\n function getMaxValueByDate() {\n let keys = uniq(data.map(o => o.name));\n let maxValueByDate = d3Array.max(dataByDateFormatted, function(d){\n let vals = keys.map((key) => d[key]);\n\n return d3Array.sum(vals);\n });\n\n return maxValueByDate;\n }\n\n /**\n * Finds out the data entry that is closer to the given position on pixels\n * @param {Number} mouseX X position of the mouse\n * @return {obj} Data entry that is closer to that x axis position\n */\n function getNearestDataPoint(mouseX) {\n let points = dataByDate.filter(({date}) => Math.abs(xScale(date) - mouseX) <= epsilon);\n\n if (points.length) {\n return points[0];\n }\n }\n\n /**\n * Epsilon is the value given to the number representing half of the distance in\n * pixels between two date data points\n * @return {Number} half distance between any two points\n */\n function setEpsilon() {\n let dates = dataByDate.map(({date}) => date);\n\n epsilon = (xScale(dates[1]) - xScale(dates[0])) / 2;\n }\n\n /**\n * MouseMove handler, calculates the nearest dataPoint to the cursor\n * and updates metadata related to it\n * @private\n */\n function handleMouseMove(e) {\n epsilon || setEpsilon();\n\n let [xPosition, yPosition] = d3Selection.mouse(e),\n dataPoint = getNearestDataPoint(xPosition - margin.left),\n dataPointXPosition;\n\n if (dataPoint) {\n dataPointXPosition = xScale(new Date( dataPoint.key ));\n // Move verticalMarker to that datapoint\n moveVerticalMarker(dataPointXPosition);\n // Add data points highlighting\n highlightDataPoints(dataPoint);\n // Emit event with xPosition for tooltip or similar feature\n dispatcher.call('customMouseMove', e, dataPoint, categoryColorMap, dataPointXPosition, yPosition);\n }\n }\n\n /**\n * MouseOut handler, hides overlay and removes active class on verticalMarkerLine\n * It also resets the container of the vertical marker\n * @private\n */\n function handleMouseOut(e, d) {\n overlay.style('display', 'none');\n verticalMarkerLine.classed('bc-is-active', false);\n verticalMarkerContainer.attr('transform', 'translate(9999, 0)');\n\n dispatcher.call('customMouseOut', e, d, d3Selection.mouse(e));\n }\n\n /**\n * Mouseover handler, shows overlay and adds active class to verticalMarkerLine\n * @private\n */\n function handleMouseOver(e, d) {\n overlay.style('display', 'block');\n verticalMarkerLine.classed('bc-is-active', true);\n\n dispatcher.call('customMouseOver', e, d, d3Selection.mouse(e));\n }\n\n /**\n * Touchmove highlighted points\n * It will only pass the information with the event\n * @private\n */\n function handleTouchMove(e, d) {\n dispatcher.call('customTouchMove', e, d, d3Selection.touch(e));\n }\n\n /**\n * Mouseclick handler over one of the highlight points\n * It will only pass the information with the event\n * @private\n */\n function handleHighlightClick(e, d) {\n dispatcher.call('customDataEntryClick', e, d, d3Selection.mouse(e));\n }\n\n /**\n * Creates coloured circles marking where the exact data y value is for a given data point\n * @param {obj} dataPoint Data point to extract info from\n * @private\n */\n function highlightDataPoints({values}) {\n let accumulator = 0;\n\n cleanDataPointHighlights();\n\n // ensure order stays constant\n values = values\n .filter(v => !!v)\n .sort((a,b) => order.indexOf(a.name) > order.indexOf(b.name));\n\n values.forEach((d, index) => {\n let marker = verticalMarkerContainer\n .append('g')\n .classed('circle-container', true)\n .append('circle')\n .classed('data-point-highlighter', true)\n .attr('cx', highlightCircleSize)\n .attr('cy', 0)\n .attr('r', highlightCircleRadius)\n .style('stroke-width', highlightCircleStroke)\n .style('stroke', categoryColorMap[d.name])\n .style('cursor', 'pointer')\n .on('click', function() {\n addGlowFilter(this);\n handleHighlightClick(this, d);\n })\n .on('mouseout', function() {\n removeFilter(this);\n });\n\n accumulator = accumulator + values[index][valueLabel];\n\n marker.attr('transform', `translate( ${(- highlightCircleSize)}, ${(yScale(accumulator))} )` );\n });\n }\n\n /**\n * Helper method to update the x position of the vertical marker\n * @param {obj} dataPoint Data entry to extract info\n * @return void\n */\n function moveVerticalMarker(verticalMarkerXPosition) {\n verticalMarkerContainer.attr('transform', `translate(${verticalMarkerXPosition},0)`);\n }\n\n /**\n * Resets a point filter\n * @param {DOMElement} point Point to reset\n */\n function removeFilter(point) {\n d3Selection.select(point)\n .attr('filter', 'none');\n }\n\n /**\n * Determines if we should add the tooltip related logic depending on the\n * size of the chart and the tooltipThreshold variable value\n * @return {boolean} Should we build the tooltip?\n * @private\n */\n function shouldShowTooltip() {\n return width > tooltipThreshold && !isUsingFakeData;\n }\n\n\n // API\n\n /**\n * Gets or Sets the area curve of the stacked area.\n * @param {String} [_x='monotoneX'] Desired curve for the stacked area, default 'monotoneX'. Other options are:\n * basis, natural, linear, monotoneY, step, stepAfter, stepBefore, cardinal, and\n * catmullRom. Visit https://github.com/d3/d3-shape#curves for more information.\n * @return {String | module} Current area curve setting or Chart module to chain calls\n * @public\n * @example stackedArea.areaCurve('step')\n */\n exports.areaCurve = function(_x) {\n if (!arguments.length) {\n return areaCurve;\n }\n areaCurve = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets the opacity of the stacked areas in the chart (all of them will have the same opacity)\n * @param {Number} _x Opacity to get/set\n * @return {Number | module} Current opacity or Area Chart module to chain calls\n * @public\n */\n exports.areaOpacity = function(_x) {\n if (!arguments.length) {\n return areaOpacity;\n }\n areaOpacity = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the aspect ratio of the chart\n * @param {Number} _x Desired aspect ratio for the graph\n * @return {Number | Module} Current aspect ratio or Area Chart module to chain calls\n * @public\n */\n exports.aspectRatio = function(_x) {\n if (!arguments.length) {\n return aspectRatio;\n }\n aspectRatio = _x;\n\n return this;\n };\n\n /**\n * Exposes the constants to be used to force the x axis to respect a certain granularity\n * current options: MINUTE_HOUR, HOUR_DAY, DAY_MONTH, MONTH_YEAR\n * @example\n * area.xAxisFormat(area.axisTimeCombinations.HOUR_DAY)\n */\n exports.axisTimeCombinations = axisTimeCombinations;\n\n /**\n * Gets or Sets the colorSchema of the chart\n * @param {String[]} _x Desired colorSchema for the graph\n * @return {String[] | module} Current colorSchema or Chart module to chain calls\n * @public\n */\n exports.colorSchema = function(_x) {\n if (!arguments.length) {\n return colorSchema;\n }\n colorSchema = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the dateLabel of the chart\n * @param {String} _x Desired dateLabel for the graph\n * @return {String | module} Current dateLabel or Chart module to chain calls\n * @public\n */\n exports.dateLabel = function(_x) {\n if (!arguments.length) {\n return dateLabel;\n }\n dateLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the emptyDataConfig of the chart\n * @param {Object} _x emptyDataConfig object to get/set\n * @return {Object | module} Current config for when chart data is an empty array\n * @public\n */\n exports.emptyDataConfig = function(_x) {\n if (!arguments.length) {\n return emptyDataConfig;\n }\n emptyDataConfig = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the grid mode.\n *\n * @param {String} _x Desired mode for the grid ('vertical'|'horizontal'|'full')\n * @return {String | module} Current mode of the grid or Area Chart module to chain calls\n * @public\n */\n exports.grid = function(_x) {\n if (!arguments.length) {\n return grid;\n }\n grid = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the height of the chart\n * @param {Number} _x Desired width for the graph\n * @return {Number | module} Current height or Area Chart module to chain calls\n * @public\n */\n exports.height = function(_x) {\n if (!arguments.length) {\n return height;\n }\n if (aspectRatio) {\n width = Math.ceil(_x / aspectRatio);\n }\n height = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the isAnimated property of the chart, making it to animate when render.\n * By default this is 'false'\n *\n * @param {Boolean} _x Desired animation flag\n * @return {Boolean | module} Current isAnimated flag or Chart module\n * @public\n */\n exports.isAnimated = function(_x) {\n if (!arguments.length) {\n return isAnimated;\n }\n isAnimated = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the keyLabel of the chart\n * @param {Number} _x Desired keyLabel for the graph\n * @return {Number | module} Current keyLabel or Chart module to chain calls\n * @public\n */\n exports.keyLabel = function(_x) {\n if (!arguments.length) {\n return keyLabel;\n }\n keyLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the margin of the chart\n * @param {Object} _x Margin object to get/set\n * @return {Object | module} Current margin or Area Chart module to chain calls\n * @public\n */\n exports.margin = function(_x) {\n if (!arguments.length) {\n return margin;\n }\n margin = {\n ...margin,\n ..._x\n };\n\n return this;\n };\n\n /**\n * Gets or Sets the minimum width of the graph in order to show the tooltip\n * NOTE: This could also depend on the aspect ratio\n *\n * @param {Number} _x Minimum width of the graph\n * @return {Number | module} Current tooltipThreshold or Area Chart module to chain calls\n * @public\n */\n exports.tooltipThreshold = function(_x) {\n if (!arguments.length) {\n return tooltipThreshold;\n }\n tooltipThreshold = _x;\n\n return this;\n };\n\n /**\n * Pass an override for the ordering of the topics\n * @param {String[]} _x Array of the names of your tooltip items\n * @return {String[] | module} Current override order or Chart module to chain calls\n * @public\n */\n exports.topicsOrder = function(_x) {\n if (!arguments.length) {\n return topicsOrder;\n }\n topicsOrder = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the loading state of the chart\n * @param {String} markup Desired markup to show when null data\n * @return {String | module} Current loading state markup or Chart module to chain calls\n * @public\n */\n exports.loadingState = function(_markup) {\n if (!arguments.length) {\n return loadingState;\n }\n loadingState = _markup;\n\n return this;\n };\n\n /**\n * Pass language tag for the tooltip to localize the date.\n * Feature uses Intl.DateTimeFormat, for compatability and support, refer to\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat\n * @param {String} _x must be a language tag (BCP 47) like 'en-US' or 'fr-FR'\n * @return {String | Module} Current locale or module to chain calls\n * @public\n */\n exports.locale = function(_x) {\n if (!arguments.length) {\n return locale;\n }\n locale = _x;\n\n return this;\n };\n\n /**\n * Chart exported to png and a download action is fired\n * @param {String} filename File title for the resulting picture\n * @param {String} title Title to add at the top of the exported picture\n * @public\n */\n exports.exportChart = function(filename, title) {\n exportChart.call(exports, svg, filename, title);\n };\n\n /**\n * Exposes an 'on' method that acts as a bridge with the event dispatcher\n * We are going to expose this events:\n * customMouseOver, customMouseMove, customMouseOut,\n * customDataEntryClick and customTouchMove\n * @return {module} Stacked Area\n * @public\n */\n exports.on = function() {\n let value = dispatcher.on.apply(dispatcher, arguments);\n\n return value === dispatcher ? exports : value;\n };\n\n /**\n * Gets or Sets the valueLabel of the chart\n * @param {Number} _x Desired valueLabel for the graph\n * @return {Number | module} Current valueLabel or Chart module to chain calls\n * @public\n */\n exports.valueLabel = function(_x) {\n if (!arguments.length) {\n return valueLabel;\n }\n valueLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the width of the chart\n * @param {Number} _x Desired width for the graph\n * @return {Number | module} Current width or Area Chart module to chain calls\n * @public\n */\n exports.width = function(_x) {\n if (!arguments.length) {\n return width;\n }\n if (aspectRatio) {\n height = Math.ceil(_x * aspectRatio);\n }\n width = _x;\n\n return this;\n };\n\n /**\n * Exposes the ability to force the chart to show a certain x format\n * It requires a `xAxisFormat` of 'custom' in order to work.\n * NOTE: localization not supported\n * @param {String} _x Desired format for x axis\n * @return {String | Module} Current format or module to chain calls\n * @public\n */\n exports.xAxisCustomFormat = function(_x) {\n if (!arguments.length) {\n return xAxisCustomFormat;\n }\n xAxisCustomFormat = _x;\n\n return this;\n };\n\n /**\n * Exposes the ability to force the chart to show a certain x axis grouping\n * @param {String} _x Desired format\n * @return {String | Module} Current format or module to chain calls\n * @public\n * @example\n * area.xAxisFormat(area.axisTimeCombinations.HOUR_DAY)\n */\n exports.xAxisFormat = function(_x) {\n if (!arguments.length) {\n return xAxisFormat;\n }\n xAxisFormat = _x;\n\n return this;\n };\n\n /**\n * Exposes the ability to force the chart to show a certain x ticks. It requires a `xAxisFormat` of 'custom' in order to work.\n * NOTE: This value needs to be a multiple of 2, 5 or 10. They won't always work as expected, as D3 decides at the end\n * how many and where the ticks will appear.\n *\n * @param {Number} _x Desired number of x axis ticks (multiple of 2, 5 or 10)\n * @return {Number | Module} Current number or ticks or module to chain calls\n * @public\n */\n exports.xTicks = function(_x) {\n if (!arguments.length) {\n return xTicks;\n }\n xTicks = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the y-axis label of the chart\n * @param {String} _x Desired label string\n * @return {String | module} Current yAxisLabel or Chart module to chain calls\n * @public\n * @example stackedArea.yAxisLabel('Ticket Sales')\n */\n exports.yAxisLabel = function (_x) {\n if (!arguments.length) {\n return yAxisLabel;\n }\n yAxisLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the offset of the yAxisLabel of the chart.\n * The method accepts both positive and negative values.\n * The default value is -60\n * @param {Number} [_x=-60] Desired offset for the label\n * @return {Number | module} Current yAxisLabelOffset or Chart module to chain calls\n * @public\n * @example stackedArea.yAxisLabelOffset(-55)\n */\n exports.yAxisLabelOffset = function (_x) {\n if (!arguments.length) {\n return yAxisLabelOffset;\n }\n yAxisLabelOffset = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the number of ticks of the y axis on the chart\n * (Default is 5)\n * @param {Number} [_x=5] Desired vertical ticks\n * @return {Number | module} Current vertical ticks or Chart module to chain calls\n * @public\n */\n exports.yTicks = function (_x) {\n if (!arguments.length) {\n return yTicks;\n }\n yTicks = _x;\n\n return this;\n };\n\n return exports;\n };\n\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/stacked-area.js","define(function (require) {\n 'use strict';\n\n const d3Array = require('d3-array');\n const d3Axis = require('d3-axis');\n const d3Color = require('d3-color');\n const d3Collection = require('d3-collection');\n const d3Dispatch = require('d3-dispatch');\n const d3Ease = require('d3-ease');\n const d3Interpolate = require('d3-interpolate');\n const d3Scale = require('d3-scale');\n const d3Selection = require('d3-selection');\n const assign = require('lodash.assign');\n const d3Transition = require('d3-transition');\n\n const { exportChart } = require('./helpers/export');\n const colorHelper = require('./helpers/color');\n const {bar} = require('./helpers/load');\n\n const NUMBER_FORMAT = ',f';\n const uniq = (arrArg) => arrArg.filter((elem, pos, arr) => arr.indexOf(elem) == pos);\n\n\n /**\n * @typdef D3Layout\n * @type function\n */\n\n /**\n * @typedef GroupedBarChartData\n * @type {Object[]}\n * @property {String} name Name of the entry\n * @property {String} group group of the entry\n * @property {Number} value Value of the entry\n *\n * @example\n * [\n * {\n * \"name\": \"2011-01\",\n * \"group\": \"Direct\",\n * \"value\": 0\n * }\n * ]\n */\n\n /**\n * Grouped Bar Chart reusable API module that allows us\n * rendering a multi grouped bar and configurable chart.\n *\n * @module Grouped-bar\n * @tutorial grouped-bar\n * @requires d3-array, d3-axis, d3-color, d3-collection, d3-dispatch, d3-ease,\n * d3-interpolate, d3-scale, d3-selection, lodash assign\n *\n * @example\n * let groupedBar = GroupedBar();\n *\n * groupedBar\n * .width(containerWidth);\n *\n * d3Selection.select('.css-selector')\n * .datum(dataset.data)\n * .call(groupedBar);\n *\n */\n return function module() {\n\n let margin = {\n top: 40,\n right: 30,\n bottom: 60,\n left: 70\n },\n width = 960,\n height = 500,\n loadingState = bar,\n\n xScale,\n xScale2,\n xAxis,\n yScale,\n yScale2,\n yAxis,\n\n aspectRatio = null,\n\n yTickTextOffset = {\n y: -8,\n x: -20\n },\n\n yTicks = 5,\n xTicks = 5,\n baseLine,\n\n colorSchema = colorHelper.colorSchemas.britecharts,\n\n colorScale,\n categoryColorMap,\n\n layers,\n\n ease = d3Ease.easeQuadInOut,\n isHorizontal = false,\n\n svg,\n chartWidth, chartHeight,\n data,\n groups,\n layerElements,\n\n transformedData,\n\n tooltipThreshold = 480,\n\n xAxisPadding = {\n top: 0,\n left: 0,\n bottom: 0,\n right: 0\n },\n yAxisLabel,\n yAxisLabelEl,\n yAxisLabelOffset = -60,\n\n maxBarNumber = 8,\n barOpacity = 0.24,\n\n animationDelayStep = 20,\n animationDelays = d3Array.range(animationDelayStep, maxBarNumber * animationDelayStep, animationDelayStep),\n animationDuration = 1000,\n\n grid = null,\n\n nameLabel = 'name',\n valueLabel = 'value',\n groupLabel = 'group',\n valueLabelFormat = NUMBER_FORMAT,\n\n // getters\n getName = ({name}) => name,\n getValue = ({value}) => value,\n getGroup = ({group}) => group,\n isAnimated = false,\n\n // events\n dispatcher = d3Dispatch.dispatch(\n 'customMouseOver',\n 'customMouseOut',\n 'customMouseMove',\n 'customClick'\n );\n\n /**\n * This function creates the graph using the selection and data provided\n * @param {D3Selection} _selection A d3 selection that represents\n * the container(s) where the chart(s) will be rendered\n * @param {GroupedBarChartData} _data The data to attach and generate the chart\n */\n function exports(_selection) {\n _selection.each(function (_data) {\n chartWidth = width - margin.left - margin.right;\n chartHeight = height - margin.top - margin.bottom;\n data = cleanData(_data);\n\n prepareData(data);\n buildScales();\n buildLayers();\n buildSVG(this);\n drawGridLines();\n buildAxis();\n drawAxis();\n drawGroupedBar();\n addMouseEvents();\n });\n }\n\n /**\n * Adds events to the container group if the environment is not mobile\n * Adding: mouseover, mouseout and mousemove\n */\n function addMouseEvents() {\n if (shouldShowTooltip()) {\n svg\n .on('mouseover', function(d) {\n handleMouseOver(this, d);\n })\n .on('mouseout', function(d) {\n handleMouseOut(this, d);\n })\n .on('mousemove', function(d) {\n handleMouseMove(this, d);\n })\n .on('click', function(d) {\n handleCustomClick(this, d);\n });;\n }\n\n svg.selectAll('.bar')\n .on('mouseover', function(d) {\n handleBarsMouseOver(this, d);\n })\n .on('mouseout', function(d) {\n handleBarsMouseOut(this, d);\n });\n }\n\n /**\n * Adjusts the position of the y axis' ticks\n * @param {D3Selection} selection Y axis group\n * @return void\n */\n function adjustYTickLabels(selection) {\n selection.selectAll('.tick text')\n .attr('transform', `translate(${yTickTextOffset['x']}, ${yTickTextOffset['y']})`);\n }\n\n /**\n * Creates the d3 x and y axis, setting orientations\n * @private\n */\n function buildAxis() {\n if (isHorizontal) {\n xAxis = d3Axis.axisBottom(xScale)\n .ticks(xTicks, valueLabelFormat);\n yAxis = d3Axis.axisLeft(yScale)\n } else {\n xAxis = d3Axis.axisBottom(xScale)\n yAxis = d3Axis.axisLeft(yScale)\n .ticks(yTicks, valueLabelFormat)\n }\n }\n\n /**\n * Builds containers for the chart, the axis and a wrapper for all of them\n * NOTE: The order of drawing of this group elements is really important,\n * as everything else will be drawn on top of them\n * @private\n */\n function buildContainerGroups() {\n let container = svg\n .append('g')\n .classed('container-group', true)\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n container\n .append('g').classed('x-axis-group', true)\n .append('g').classed('x axis', true);\n container.selectAll('.x-axis-group')\n .append('g').classed('month-axis', true);\n container\n .append('g').classed('y-axis-group axis', true);\n container\n .append('g').classed('y-axis-label', true);\n container\n .append('g').classed('grid-lines-group', true);\n container\n .append('g').classed('chart-group', true);\n container\n .append('g').classed('metadata-group', true);\n }\n\n /**\n * Builds the grouped layers layout\n * @return {D3Layout} Layout for drawing the chart\n * @private\n */\n function buildLayers() {\n layers = transformedData.map((item) => {\n let ret = {};\n\n groups.forEach((key) => {\n ret[key] = item[key];\n });\n\n return assign({}, item, ret);\n });\n }\n\n /**\n * Creates the x, y and color scales of the chart\n * @private\n */\n function buildScales() {\n let yMax = d3Array.max(data.map(getValue));\n\n if (isHorizontal) {\n xScale = d3Scale.scaleLinear()\n .domain([0, yMax])\n .rangeRound([0, chartWidth - 1]);\n // 1 pix for edge tick\n\n yScale = d3Scale.scaleBand()\n .domain(data.map(getName))\n .rangeRound([chartHeight, 0])\n .padding(0.1);\n\n yScale2 = d3Scale.scaleBand()\n .domain(data.map(getGroup))\n .rangeRound([yScale.bandwidth(), 0])\n .padding(0.1);\n } else {\n xScale = d3Scale.scaleBand()\n .domain(data.map(getName))\n .rangeRound([0, chartWidth])\n .padding(0.1);\n xScale2 = d3Scale.scaleBand()\n .domain(data.map(getGroup))\n .rangeRound([0, xScale.bandwidth()])\n .padding(0.1);\n\n yScale = d3Scale.scaleLinear()\n .domain([0, yMax])\n .rangeRound([chartHeight, 0])\n .nice();\n }\n\n colorScale = d3Scale.scaleOrdinal()\n .range(colorSchema)\n .domain(data.map(getGroup));\n\n categoryColorMap = colorScale\n .domain(data.map(getName)).domain()\n .reduce((memo, item) => {\n data.forEach(function (v) {\n if (getName(v) == item) {\n memo[v.name] = colorScale(v.group)\n memo[v.group] = colorScale(v.group)\n memo[v.group + item] = colorScale(v.group)\n }\n })\n return memo;\n }, {});\n }\n\n /**\n * @param {HTMLElement} container DOM element that will work as the container of the graph\n * @private\n */\n function buildSVG(container) {\n if (!svg) {\n svg = d3Selection.select(container)\n .append('svg')\n .classed('britechart grouped-bar', true);\n\n buildContainerGroups();\n }\n\n svg\n .attr('width', width)\n .attr('height', height);\n }\n\n /**\n * Cleaning data casting the values, groups, topic names and names to the proper type while keeping\n * the rest of properties on the data\n * @param {GroupedBarChartData} originalData Raw data from the container\n * @return {GroupedBarChartData} Parsed data with values and dates\n * @private\n */\n function cleanData(originalData) {\n return originalData.reduce((acc, d) => {\n d.value = +d[valueLabel];\n d.group = d[groupLabel];\n // for tooltip\n d.topicName = getGroup(d);\n d.name = d[nameLabel];\n\n return [...acc, d];\n }, []);\n }\n\n /**\n * Draws the x and y axis on the svg object within their\n * respective groups\n * @private\n */\n function drawAxis() {\n if (isHorizontal) {\n svg.select('.x-axis-group .axis.x')\n .attr('transform', `translate( 0, ${chartHeight} )`)\n .call(xAxis);\n\n svg.select('.y-axis-group.axis')\n .attr('transform', `translate( ${-xAxisPadding.left}, 0)`)\n .call(yAxis);\n } else {\n svg.select('.x-axis-group .axis.x')\n .attr('transform', `translate( 0, ${chartHeight} )`)\n .call(xAxis);\n\n svg.select('.y-axis-group.axis')\n .attr('transform', `translate( ${-xAxisPadding.left}, 0)`)\n .call(yAxis)\n .call(adjustYTickLabels);\n }\n\n if (yAxisLabel) {\n if (yAxisLabelEl) {\n svg.selectAll('.y-axis-label-text').remove();\n }\n\n yAxisLabelEl = svg.select('.y-axis-label')\n .append('text')\n .classed('y-axis-label-text', true)\n .attr('x', -chartHeight / 2)\n .attr('y', yAxisLabelOffset)\n .attr('text-anchor', 'middle')\n .attr('transform', 'rotate(270 0 0)')\n .text(yAxisLabel)\n }\n }\n\n /**\n * Draws a vertical line to extend x-axis till the edges\n * @return {void}\n */\n function drawHorizontalExtendedLine() {\n baseLine = svg.select('.grid-lines-group')\n .selectAll('line.extended-x-line')\n .data([0])\n .enter()\n .append('line')\n .attr('class', 'extended-x-line')\n .attr('x1', (xAxisPadding.left))\n .attr('x2', chartWidth)\n .attr('y1', chartHeight)\n .attr('y2', chartHeight);\n }\n\n /**\n * Draws a vertical line to extend y-axis till the edges\n * @return {void}\n */\n function drawVerticalExtendedLine() {\n baseLine = svg.select('.grid-lines-group')\n .selectAll('line.extended-y-line')\n .data([0])\n .enter()\n .append('line')\n .attr('class', 'extended-y-line')\n .attr('y1', (xAxisPadding.bottom))\n .attr('y2', chartHeight)\n .attr('x1', 0)\n .attr('x2', 0);\n }\n\n /**\n * Draws grid lines on the background of the chart\n * @return void\n */\n function drawGridLines() {\n let scale = isHorizontal ? xScale : yScale;\n\n svg.select('.grid-lines-group')\n .selectAll('line')\n .remove();\n\n if (grid === 'horizontal' || grid === 'full') {\n svg.select('.grid-lines-group')\n .selectAll('line.horizontal-grid-line')\n .data(scale.ticks(yTicks).slice(1))\n .enter()\n .append('line')\n .attr('class', 'horizontal-grid-line')\n .attr('x1', (-xAxisPadding.left + 1))\n .attr('x2', chartWidth)\n .attr('y1', (d) => yScale(d))\n .attr('y2', (d) => yScale(d));\n }\n\n if (grid === 'vertical' || grid === 'full') {\n svg.select('.grid-lines-group')\n .selectAll('line.vertical-grid-line')\n .data(scale.ticks(xTicks).slice(1))\n .enter()\n .append('line')\n .attr('class', 'vertical-grid-line')\n .attr('y1', 0)\n .attr('y2', chartHeight)\n .attr('x1', (d) => xScale(d))\n .attr('x2', (d) => xScale(d));\n }\n\n if (isHorizontal) {\n drawVerticalExtendedLine();\n } else {\n drawHorizontalExtendedLine();\n }\n }\n\n /**\n * Draws the bars along the x axis\n * @param {D3Selection} layersSelection Selection of layers\n * @return {void}\n */\n function drawHorizontalBars(layersSelection) {\n let layerJoin = layersSelection\n .data(layers);\n\n layerElements = layerJoin\n .enter()\n .append('g')\n .attr('transform', ({key}) => `translate(0,${yScale(key)})`)\n .classed('layer', true);\n\n let barJoin = layerElements\n .selectAll('.bar')\n .data(({values}) => values);\n\n // Enter + Update\n let bars = barJoin\n .enter()\n .append('rect')\n .classed('bar', true)\n .attr('x', 1)\n .attr('y', (d) => yScale2(getGroup(d)))\n .attr('height', yScale2.bandwidth())\n .attr('fill', (({group}) => categoryColorMap[group]));\n\n if (isAnimated) {\n bars.style('opacity', barOpacity)\n .transition()\n .delay((_, i) => animationDelays[i])\n .duration(animationDuration)\n .ease(ease)\n .tween('attr.width', horizontalBarsTween);\n } else {\n bars.attr('width', (d) => xScale(getValue(d)));\n }\n }\n\n /**\n * Draws the bars along the y axis\n * @param {D3Selection} layersSelection Selection of layers\n * @return {void}\n */\n function drawVerticalBars(layersSelection) {\n let layerJoin = layersSelection\n .data(layers);\n\n layerElements = layerJoin\n .enter()\n .append('g')\n .attr('transform', ({key}) => `translate(${xScale(key)},0)`)\n .classed('layer', true);\n\n let barJoin = layerElements\n .selectAll('.bar')\n .data(({values}) => values);\n\n let bars = barJoin\n .enter()\n .append('rect')\n .classed('bar', true)\n .attr('x', (d) => xScale2(getGroup(d)))\n .attr('y', ({value}) => yScale(value))\n .attr('width', xScale2.bandwidth)\n .attr('fill', (({group}) => categoryColorMap[group]));\n\n if (isAnimated) {\n bars.style('opacity', barOpacity)\n .transition()\n .delay((_, i) => animationDelays[i])\n .duration(animationDuration)\n .ease(ease)\n .tween('attr.height', verticalBarsTween);\n } else {\n bars.attr('height', (d) => chartHeight - yScale(getValue(d)));\n }\n }\n\n /**\n * Draws the different areas into the chart-group element\n * @private\n */\n function drawGroupedBar() {\n // Not ideal, we need to figure out how to call exit for nested elements\n if (layerElements) {\n svg.selectAll('.layer').remove();\n }\n\n let series = svg.select('.chart-group').selectAll('.layer');\n\n if (isHorizontal) {\n drawHorizontalBars(series);\n } else {\n drawVerticalBars(series);\n }\n\n // Exit\n series.exit()\n .transition()\n .style('opacity', 0)\n .remove();\n }\n\n /**\n * Extract X position on the chart from a given mouse event\n * @param {obj} event D3 mouse event\n * @return {Number} Position on the x axis of the mouse\n * @private\n */\n function getMousePosition(event) {\n return d3Selection.mouse(event);\n }\n\n /**\n * Finds out the data entry that is closer to the given position on pixels\n * @param {Number} mouseX X position of the mouse\n * @return {obj} Data entry that is closer to that x axis position\n */\n function getNearestDataPoint(mouseX) {\n let adjustedMouseX = mouseX - margin.left,\n epsilon = xScale2.bandwidth(),\n nearest = [];\n\n layers.forEach(function (data) {\n let found = data.values.find((d2) => Math.abs(adjustedMouseX >= xScale(d2[nameLabel]) + xScale2(d2[groupLabel])) && Math.abs(adjustedMouseX - xScale2(d2[groupLabel]) - xScale(d2[nameLabel]) <= epsilon));\n\n if (found) {\n found.values = data.values;\n found.key = found.name;\n nearest.push(found);\n }\n\n });\n\n return nearest.length ? nearest[0] : undefined;\n }\n\n /**\n * Finds out the data entry that is closer to the given position on pixels\n * @param {Number} mouseX X position of the mouse\n * @return {obj} Data entry that is closer to that x axis position\n */\n function getNearestDataPoint2(mouseY) {\n let adjustedMouseY = mouseY - margin.bottom,\n epsilon = yScale.bandwidth(),\n nearest = [];\n\n layers.map(function (data) {\n let found = data.values.find((d2) => Math.abs(adjustedMouseY >= yScale(d2[nameLabel])) && Math.abs(adjustedMouseY - yScale(d2[nameLabel]) <= epsilon * 2));\n\n if (found) {\n found.values = data.values;\n found.key = found.name;\n nearest.push(found)\n }\n });\n\n return nearest.length ? nearest[0] : undefined;\n }\n\n /**\n * Handles a mouseover event on top of a bar\n * @param {obj} e the fired event\n * @param {obj} d data of bar\n * @return {void}\n */\n function handleBarsMouseOver(e, d) {\n d3Selection.select(e)\n .attr('fill', () => d3Color.color(categoryColorMap[d.group]).darker());\n }\n\n /**\n * Handles a mouseout event out of a bar\n * @param {obj} e the fired event\n * @param {obj} d data of bar\n * @return {void}\n */\n function handleBarsMouseOut(e, d) {\n d3Selection.select(e)\n .attr('fill', () => categoryColorMap[d.group])\n }\n\n /**\n * MouseMove handler, calculates the nearest dataPoint to the cursor\n * and updates metadata related to it\n * @param {obj} e the fired event\n * @private\n */\n function handleMouseMove(e) {\n let [mouseX, mouseY] = getMousePosition(e),\n dataPoint = isHorizontal ? getNearestDataPoint2(mouseY) : getNearestDataPoint(mouseX),\n x,\n y;\n\n if (dataPoint) {\n // Move verticalMarker to that datapoint\n if (isHorizontal) {\n x = mouseX - margin.left;\n y = yScale(dataPoint.key) + yScale.bandwidth() / 2;\n } else {\n x = xScale(dataPoint.key) + xScale2(dataPoint[groupLabel]);\n y = mouseY - margin.bottom;\n }\n moveTooltipOriginXY(x, y);\n\n // Emit event with xPosition for tooltip or similar feature\n dispatcher.call('customMouseMove', e, dataPoint, categoryColorMap, x, y);\n }\n }\n\n /**\n * Click handler, shows data that was clicked and passes to the user\n * @private\n */\n function handleCustomClick (e, d) {\n let [mouseX, mouseY] = getMousePosition(e);\n let dataPoint = isHorizontal ? getNearestDataPoint2(mouseY) : getNearestDataPoint(mouseX);\n\n dispatcher.call('customClick', e, dataPoint, d3Selection.mouse(e));\n }\n\n /**\n * MouseOut handler, hides overlay and removes active class on verticalMarkerLine\n * It also resets the container of the vertical marker\n * @private\n */\n function handleMouseOut(e, d) {\n svg.select('.metadata-group').attr('transform', 'translate(9999, 0)');\n dispatcher.call('customMouseOut', e, d, d3Selection.mouse(e));\n }\n\n /**\n * Mouseover handler, shows overlay and adds active class to verticalMarkerLine\n * @private\n */\n function handleMouseOver(e, d) {\n dispatcher.call('customMouseOver', e, d, d3Selection.mouse(e));\n }\n\n /**\n * Animation tween of horizontal bars\n * @param {obj} d data of bar\n * @return {void}\n */\n function horizontalBarsTween(d) {\n let node = d3Selection.select(this),\n i = d3Interpolate.interpolateRound(0, xScale(getValue(d))),\n j = d3Interpolate.interpolateNumber(0, 1);\n\n return function (t) {\n node.attr('width', i(t))\n .style('opacity', j(t));\n }\n }\n\n /**\n * Helper method to update the x position of the vertical marker\n * @param {obj} dataPoint Data entry to extract info\n * @return void\n */\n function moveTooltipOriginXY(originXPosition, originYPosition) {\n svg.select('.metadata-group')\n .attr('transform', `translate(${originXPosition},${originYPosition})`);\n }\n\n /**\n * Prepare data for create chart.\n * @private\n */\n function prepareData(data) {\n groups = uniq(data.map((d) => getGroup(d)));\n transformedData = d3Collection.nest()\n .key(getName)\n .rollup(function (values) {\n let ret = {};\n\n values.forEach((entry) => {\n if (entry && entry[groupLabel]) {\n ret[entry[groupLabel]] = getValue(entry);\n }\n });\n //for tooltip\n ret.values = values;\n return ret;\n })\n .entries(data)\n .map(function (data) {\n return assign({}, {\n total: d3Array.sum(d3Array.permute(data.value, groups)),\n key: data.key\n }, data.value);\n });\n }\n\n /**\n * Determines if we should add the tooltip related logic depending on the\n * size of the chart and the tooltipThreshold variable value\n * @return {boolean} Should we build the tooltip?\n * @private\n */\n function shouldShowTooltip() {\n return width > tooltipThreshold;\n }\n\n /**\n * Animation tween of vertical bars\n * @param {obj} d data of bar\n * @return {void}\n */\n function verticalBarsTween(d) {\n let node = d3Selection.select(this),\n i = d3Interpolate.interpolateRound(0, chartHeight - yScale(getValue(d))),\n y = d3Interpolate.interpolateRound(chartHeight, yScale(getValue(d))),\n j = d3Interpolate.interpolateNumber(0, 1);\n\n return function (t) {\n node.attr('y', y(t))\n .attr('height', i(t)).style('opacity', j(t));\n }\n }\n\n // API\n\n /**\n * Gets or Sets the aspect ratio of the chart\n * @param {Number} _x Desired aspect ratio for the graph\n * @return { (Number | Module) } Current aspect ratio or Area Chart module to chain calls\n * @public\n */\n exports.aspectRatio = function (_x) {\n if (!arguments.length) {\n return aspectRatio;\n }\n aspectRatio = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the colorSchema of the chart\n * @param {String[]} _x Desired colorSchema for the graph\n * @return { colorSchema | module} Current colorSchema or Chart module to chain calls\n * @public\n */\n exports.colorSchema = function (_x) {\n if (!arguments.length) {\n return colorSchema;\n }\n colorSchema = _x;\n\n return this;\n };\n\n /**\n * Chart exported to png and a download action is fired\n * @param {String} filename File title for the resulting picture\n * @param {String} title Title to add at the top of the exported picture\n * @public\n */\n exports.exportChart = function (filename, title) {\n exportChart.call(exports, svg, filename, title);\n };\n\n /**\n * Gets or Sets the groupLabel of the chart\n * @param {String} _x Desired groupLabel for the graph\n * @return { groupLabel | module} Current groupLabel or Chart module to chain calls\n * @public\n */\n exports.groupLabel = function (_x) {\n if (!arguments.length) {\n return groupLabel;\n }\n groupLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the grid mode.\n *\n * @param {String} _x Desired mode for the grid ('vertical'|'horizontal'|'full')\n * @return { String | module} Current mode of the grid or Area Chart module to chain calls\n * @public\n */\n exports.grid = function (_x) {\n if (!arguments.length) {\n return grid;\n }\n grid = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the height of the chart\n * @param {Number} _x Desired width for the graph\n * @return { height | module} Current height or Area Chart module to chain calls\n * @public\n */\n exports.height = function (_x) {\n if (!arguments.length) {\n return height;\n }\n if (aspectRatio) {\n width = Math.ceil(_x / aspectRatio);\n }\n height = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the horizontal direction of the chart\n * @param {number} _x Desired horizontal direction for the graph\n * @return { isHorizontal | module} If it is horizontal or Bar Chart module to chain calls\n * @public\n */\n exports.isHorizontal = function (_x) {\n if (!arguments.length) {\n return isHorizontal;\n }\n isHorizontal = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the isAnimated property of the chart, making it to animate when render.\n * By default this is 'false'\n *\n * @param {Boolean} _x Desired animation flag\n * @return { isAnimated | module} Current isAnimated flag or Chart module\n * @public\n */\n exports.isAnimated = function (_x) {\n if (!arguments.length) {\n return isAnimated;\n }\n isAnimated = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the loading state of the chart\n * @param {string} markup Desired markup to show when null data\n * @return { loadingState | module} Current loading state markup or Chart module to chain calls\n * @public\n */\n exports.loadingState = function(_markup) {\n if (!arguments.length) {\n return loadingState;\n }\n loadingState = _markup;\n\n return this;\n };\n\n /**\n * Gets or Sets the margin of the chart\n * @param {Object} _x Margin object to get/set\n * @return { margin | module} Current margin or Area Chart module to chain calls\n * @public\n */\n exports.margin = function (_x) {\n if (!arguments.length) {\n return margin;\n }\n margin = {\n ...margin,\n ..._x\n };\n\n return this;\n };\n\n /**\n * Gets or Sets the nameLabel of the chart\n * @param {Number} _x Desired dateLabel for the graph\n * @return { nameLabel | module} Current nameLabel or Chart module to chain calls\n * @public\n */\n exports.nameLabel = function (_x) {\n if (!arguments.length) {\n return nameLabel;\n }\n nameLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the number of ticks of the y axis on the chart\n * @param {Number} _x Desired vertical ticks\n * @return {Number | module} Current yTicks or Chart module to chain calls\n * @public\n */\n exports.yTicks = function (_x) {\n if (!arguments.length) {\n return yTicks;\n }\n yTicks = _x;\n\n return this;\n };\n\n /**\n * Exposes an 'on' method that acts as a bridge with the event dispatcher\n * We are going to expose this events:\n * customMouseOver, customMouseMove, customMouseOut, and customClick\n *\n * @return {module} Bar Chart\n * @public\n */\n exports.on = function () {\n let value = dispatcher.on.apply(dispatcher, arguments);\n\n return value === dispatcher ? exports : value;\n };\n\n /**\n * Gets or Sets the minimum width of the graph in order to show the tooltip\n * NOTE: This could also depend on the aspect ratio\n *\n * @param {Number} [_x=480] Minimum width of chart to show the tooltip\n * @return {Number | module} Current tooltipThreshold or Area Chart module to chain calls\n * @public\n */\n exports.tooltipThreshold = function (_x) {\n if (!arguments.length) {\n return tooltipThreshold;\n }\n tooltipThreshold = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the valueLabel of the chart\n * @param {Number} _x Desired valueLabel for the graph\n * @return {Number | module} Current valueLabel or Chart module to chain calls\n * @public\n */\n exports.valueLabel = function (_x) {\n if (!arguments.length) {\n return valueLabel;\n }\n valueLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the valueLabelFormat of the chart\n * @param {String[]} _x Desired valueLabelFormat for the graph\n * @return {String[] | module} Current valueLabelFormat or Chart module to chain calls\n * @public\n */\n exports.valueLabelFormat = function (_x) {\n if (!arguments.length) {\n return valueLabelFormat;\n }\n valueLabelFormat = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the width of the chart\n * @param {Number} _x Desired width for the graph\n * @return {Number | module} Current width or Area Chart module to chain calls\n * @public\n */\n exports.width = function (_x) {\n if (!arguments.length) {\n return width;\n }\n if (aspectRatio) {\n height = Math.ceil(_x * aspectRatio);\n }\n width = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the number of ticks of the x axis on the chart\n * @param {Number} _x Desired xTicks\n * @return {Number | module} Current xTicks or Chart module to chain calls\n * @public\n */\n exports.xTicks = function (_x) {\n if (!arguments.length) {\n return xTicks;\n }\n xTicks = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the y-axis label of the chart\n * @param {String} _x Desired label string\n * @return {String | module} Current yAxisLabel or Chart module to chain calls\n * @public\n * @example groupedBar.yAxisLabel('Ticket Sales')\n */\n exports.yAxisLabel = function (_x) {\n if (!arguments.length) {\n return yAxisLabel;\n }\n yAxisLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the offset of the yAxisLabel of the chart.\n * The method accepts both positive and negative values.\n * The default value is -60\n * @param {Number} _x Desired offset for the label\n * @return {Number | module} Current yAxisLabelOffset or Chart module to chain calls\n * @public\n * @example groupedBar.yAxisLabelOffset(-55)\n */\n exports.yAxisLabelOffset = function (_x) {\n if (!arguments.length) {\n return yAxisLabelOffset;\n }\n yAxisLabelOffset = _x;\n\n return this;\n }\n\n /**\n * Gets or Sets the x and y offset of ticks of the y axis on the chart\n * @param {Object} _x Desired offset\n * @return {Object | module} Current offset or Chart module to chain calls\n * @public\n */\n exports.yTickTextOffset = function (_x) {\n if (!arguments.length) {\n return yTickTextOffset;\n }\n yTickTextOffset = _x;\n\n return this;\n };\n\n return exports;\n };\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/grouped-bar.js","define(function(require){\n 'use strict';\n\n const d3Array = require('d3-array');\n const d3Axis = require('d3-axis');\n const d3Color = require('d3-color');\n const d3Collection = require('d3-collection');\n const d3Dispatch = require('d3-dispatch');\n const d3Ease = require('d3-ease');\n const d3Interpolate = require('d3-interpolate');\n const d3Scale = require('d3-scale');\n const d3Shape = require('d3-shape');\n const d3Selection = require('d3-selection');\n const assign = require('lodash.assign');\n const d3Transition = require('d3-transition');\n\n const {exportChart} = require('./helpers/export');\n const colorHelper = require('./helpers/color');\n const {bar} = require('./helpers/load');\n\n const PERCENTAGE_FORMAT = '%';\n const NUMBER_FORMAT = ',f';\n const uniq = (arrArg) => arrArg.filter((elem, pos, arr) => arr.indexOf(elem) == pos);\n\n\n /**\n * @typdef D3Layout\n * @type function\n */\n\n /**\n * @typedef stackedBarData\n * @type {Object[]}\n * @property {String} name Name of the entry\n * @property {String} stack Stack of the entry\n * @property {Number} value Value of the entry\n *\n * @example\n * [\n * {\n * \"name\": \"2011-01\",\n * \"stack\": \"Direct\",\n * \"value\": 0\n * }\n * ]\n */\n\n /**\n * Stacked Area Chart reusable API module that allows us\n * rendering a multi area and configurable chart.\n *\n * @module Stacked-bar\n * @tutorial stacked-bar\n * @requires d3-array, d3-axis, d3-color, d3-collection, d3-dispatch, d3-ease,\n * d3-interpolate, d3-scale, d3-shape, d3-selection, lodash assign\n *\n * @example\n * let stackedBar = stackedBar();\n *\n * stackedBar\n * .width(containerWidth);\n *\n * d3Selection.select('.css-selector')\n * .datum(dataset.data)\n * .call(stackedBar);\n *\n */\n return function module() {\n\n let margin = {\n top: 40,\n right: 30,\n bottom: 60,\n left: 70\n },\n width = 960,\n height = 500,\n loadingState = bar,\n\n\n xScale,\n xAxis,\n yScale,\n yAxis,\n\n aspectRatio = null,\n betweenBarsPadding = 0.1,\n\n yTickTextYOffset = -8,\n yTickTextXOffset = -20,\n\n locale,\n\n yTicks = 5,\n xTicks = 5,\n percentageAxisToMaxRatio = 1,\n\n colorSchema = colorHelper.colorSchemas.britecharts,\n\n colorScale,\n categoryColorMap,\n\n layers,\n\n ease = d3Ease.easeQuadInOut,\n isHorizontal = false,\n\n svg,\n chartWidth, chartHeight,\n data,\n transformedData,\n stacks,\n layerElements,\n hasReversedStacks = false,\n\n tooltipThreshold = 480,\n\n yAxisLabel,\n yAxisLabelEl,\n yAxisLabelOffset = -60,\n\n baseLine,\n xAxisPadding = {\n top: 0,\n left: 0,\n bottom: 0,\n right: 0\n },\n maxBarNumber = 8,\n barOpacity = 0.24,\n\n animationDelayStep = 20,\n animationDelays = d3Array.range(animationDelayStep, maxBarNumber* animationDelayStep, animationDelayStep),\n animationDuration = 1000,\n\n grid = null,\n\n nameLabel = 'name',\n valueLabel = 'value',\n stackLabel = 'stack',\n nameLabelFormat,\n valueLabelFormat = NUMBER_FORMAT,\n\n // getters\n getName = (data) => data[nameLabel],\n getValue = (data) => data[valueLabel],\n getStack = (data) => data[stackLabel],\n isAnimated = false,\n\n // events\n dispatcher = d3Dispatch.dispatch(\n 'customMouseOver',\n 'customMouseOut',\n 'customMouseMove',\n 'customClick'\n );\n\n /**\n * This function creates the graph using the selection and data provided\n * @param {D3Selection} _selection A d3 selection that represents\n * the container(s) where the chart(s) will be rendered\n * @param {stackedBarData} _data The data to attach and generate the chart\n */\n function exports(_selection) {\n _selection.each(function(_data){\n chartWidth = width - margin.left - margin.right;\n chartHeight = height - margin.top - margin.bottom;\n data = cleanData(_data);\n\n prepareData(data);\n buildScales();\n buildLayers();\n buildSVG(this);\n drawGridLines();\n buildAxis();\n drawAxis();\n drawStackedBar();\n addMouseEvents();\n });\n }\n\n /**\n * Adds events to the container group if the environment is not mobile\n * Adding: mouseover, mouseout and mousemove\n */\n function addMouseEvents() {\n if (shouldShowTooltip()){\n svg\n .on('mouseover', function(d) {\n handleMouseOver(this, d);\n })\n .on('mouseout', function(d) {\n handleMouseOut(this, d);\n })\n .on('mousemove', function(d) {\n handleMouseMove(this, d);\n })\n .on('click', function(d) {\n handleClick(this, d);\n });\n }\n\n svg.selectAll('.bar')\n .on('mouseover', handleBarsMouseOver)\n .on('mouseout', handleBarsMouseOut);\n }\n\n /**\n * Adjusts the position of the y axis' ticks\n * @param {D3Selection} selection Y axis group\n * @return void\n */\n function adjustYTickLabels(selection) {\n selection.selectAll('.tick text')\n .attr('transform', `translate(${yTickTextXOffset}, ${yTickTextYOffset})`);\n }\n\n /**\n * Creates the d3 x and y axis, setting orientations\n * @private\n */\n function buildAxis() {\n if (isHorizontal) {\n xAxis = d3Axis.axisBottom(xScale)\n .ticks(xTicks, valueLabelFormat);\n yAxis = d3Axis.axisLeft(yScale)\n } else {\n xAxis = d3Axis.axisBottom(xScale)\n yAxis = d3Axis.axisLeft(yScale)\n .ticks(yTicks, valueLabelFormat)\n }\n }\n\n /**\n * Builds containers for the chart, the axis and a wrapper for all of them\n * NOTE: The order of drawing of this group elements is really important,\n * as everything else will be drawn on top of them\n * @private\n */\n function buildContainerGroups(){\n let container = svg\n .append('g')\n .classed('container-group', true)\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n container\n .append('g').classed('x-axis-group', true)\n .append('g').classed('x axis', true);\n container.selectAll('.x-axis-group')\n .append('g').classed('month-axis', true);\n container\n .append('g').classed('y-axis-group axis', true);\n container\n .append('g').classed('grid-lines-group', true);\n container\n .append('g').classed('chart-group', true);\n container\n .append('g').classed('y-axis-label', true);\n container\n .append('g').classed('metadata-group', true);\n }\n\n /**\n * Builds the stacked layers layout\n * @return {D3Layout} Layout for drawing the chart\n * @private\n */\n function buildLayers(){\n let stack3 = d3Shape.stack().keys(stacks),\n dataInitial = transformedData.map((item) => {\n let ret = {};\n\n stacks.forEach((key) => {\n ret[key] = item[key];\n });\n\n return assign({}, item, ret);\n });\n\n layers = stack3(dataInitial);\n }\n\n /**\n * Creates the x, y and color scales of the chart\n * @private\n */\n function buildScales() {\n let yMax = d3Array.max(transformedData.map(function(d){\n return d.total;\n }));\n\n if (isHorizontal) {\n xScale = d3Scale.scaleLinear()\n .domain([0, yMax])\n .rangeRound([0, chartWidth - 1]);\n // 1 pix for edge tick\n\n yScale = d3Scale.scaleBand()\n .domain(data.map(getName))\n .rangeRound([chartHeight, 0])\n .padding(betweenBarsPadding);\n } else {\n xScale = d3Scale.scaleBand()\n .domain(data.map(getName))\n .rangeRound([0, chartWidth ])\n .padding(betweenBarsPadding);\n\n yScale = d3Scale.scaleLinear()\n .domain([0,yMax])\n .rangeRound([chartHeight, 0])\n .nice();\n }\n\n colorScale = d3Scale.scaleOrdinal()\n .range(colorSchema)\n .domain(data.map(getStack));\n\n categoryColorMap = colorScale\n .domain(data.map(getStack))\n .domain()\n .reduce((memo, item) => {\n memo[item] = colorScale(item)\n return memo;\n }, {});\n }\n\n /**\n * @param {HTMLElement} container DOM element that will work as the container of the graph\n * @private\n */\n function buildSVG(container) {\n if (!svg) {\n svg = d3Selection.select(container)\n .append('svg')\n .classed('britechart stacked-bar', true);\n\n buildContainerGroups();\n }\n\n svg\n .attr('width', width)\n .attr('height', height);\n }\n\n /**\n * Cleaning data casting the values, stacks, names and topic names to the proper type while keeping\n * the rest of properties on the data\n * @param {stackedBarData} originalData Raw data from the container\n * @return {stackedBarData} Parsed data with values and dates\n * @private\n */\n function cleanData(originalData) {\n return originalData.reduce((acc, d) => {\n d.value = +d[valueLabel];\n d.stack = d[stackLabel];\n d.topicName = getStack(d); // for tooltip\n d.name = d[nameLabel];\n\n return [...acc, d];\n }, []);\n }\n\n /**\n * Draws the x and y axis on the svg object within their\n * respective groups\n * @private\n */\n function drawAxis(){\n if (isHorizontal) {\n svg.select('.x-axis-group .axis.x')\n .attr('transform', `translate( 0, ${chartHeight} )`)\n .call(xAxis);\n\n svg.select('.y-axis-group.axis')\n .attr('transform', `translate( ${-xAxisPadding.left}, 0)`)\n .call(yAxis);\n } else {\n svg.select('.x-axis-group .axis.x')\n .attr('transform', `translate( 0, ${chartHeight} )`)\n .call(xAxis);\n\n svg.select('.y-axis-group.axis')\n .attr('transform', `translate( ${-xAxisPadding.left}, 0)`)\n .call(yAxis)\n .call(adjustYTickLabels);\n }\n\n if (yAxisLabel) {\n if (yAxisLabelEl) {\n svg.selectAll('.y-axis-label-text').remove();\n }\n\n yAxisLabelEl = svg.select('.y-axis-label')\n .append('text')\n .classed('y-axis-label-text', true)\n .attr('x', -chartHeight / 2)\n .attr('y', yAxisLabelOffset)\n .attr('text-anchor', 'middle')\n .attr('transform', 'rotate(270 0 0)')\n .text(yAxisLabel)\n }\n }\n\n /**\n * Draws grid lines on the background of the chart\n * @return void\n */\n function drawGridLines() {\n let scale = isHorizontal ? xScale : yScale;\n\n svg.select('.grid-lines-group')\n .selectAll('line')\n .remove();\n\n if (grid === 'horizontal' || grid === 'full') {\n svg.select('.grid-lines-group')\n .selectAll('line.horizontal-grid-line')\n .data(scale.ticks(yTicks).slice(1))\n .enter()\n .append('line')\n .attr('class', 'horizontal-grid-line')\n .attr('x1', (-xAxisPadding.left + 1 ))\n .attr('x2', chartWidth)\n .attr('y1', (d) => yScale(d))\n .attr('y2', (d) => yScale(d));\n }\n\n if (grid === 'vertical' || grid === 'full') {\n svg.select('.grid-lines-group')\n .selectAll('line.vertical-grid-line')\n .data(scale.ticks(xTicks).slice(1))\n .enter()\n .append('line')\n .attr('class', 'vertical-grid-line')\n .attr('y1', 0)\n .attr('y2', chartHeight)\n .attr('x1', (d) => xScale(d))\n .attr('x2', (d) => xScale(d));\n }\n\n if (isHorizontal) {\n drawVerticalExtendedLine();\n } else {\n drawHorizontalExtendedLine();\n }\n }\n\n /**\n * Draws the bars along the x axis\n * @param {D3Selection} layersSelection Selection of bars\n * @return {void}\n */\n function drawHorizontalBars(layersSelection) {\n let layerJoin = layersSelection\n .data(layers);\n\n layerElements = layerJoin\n .enter()\n .append('g')\n .attr('fill', (({key}) => categoryColorMap[key]))\n .classed('layer', true);\n\n let barJoin = layerElements\n .selectAll('.bar')\n .data((d) => d);\n\n // Enter + Update\n let bars = barJoin\n .enter()\n .append('rect')\n .classed('bar', true)\n .attr('x', (d) => xScale(d[0]) )\n .attr('y', (d) => yScale(d.data.key) )\n .attr('height', yScale.bandwidth());\n\n if (isAnimated) {\n bars.style('opacity', barOpacity)\n .transition()\n .delay((_, i) => animationDelays[i])\n .duration(animationDuration)\n .ease(ease)\n .tween('attr.width', horizontalBarsTween);\n } else {\n bars.attr('width', (d) => xScale(d[1] - d[0]));\n }\n }\n\n /**\n * Draws a vertical line to extend x-axis till the edges\n * @return {void}\n */\n function drawHorizontalExtendedLine() {\n baseLine = svg.select('.grid-lines-group')\n .selectAll('line.extended-x-line')\n .data([0])\n .enter()\n .append('line')\n .attr('class', 'extended-x-line')\n .attr('x1', (xAxisPadding.left))\n .attr('x2', chartWidth)\n .attr('y1', chartHeight)\n .attr('y2', chartHeight);\n }\n\n /**\n * Draws the bars along the y axis\n * @param {D3Selection} layersSelection Selection of bars\n * @return {void}\n */\n function drawVerticalBars(layersSelection) {\n let layerJoin = layersSelection\n .data(layers);\n\n layerElements = layerJoin\n .enter()\n .append('g')\n .attr('fill', (({key}) => categoryColorMap[key]))\n .classed('layer', true);\n\n let barJoin = layerElements\n .selectAll('.bar')\n .data((d) => d);\n\n // Enter + Update\n let bars = barJoin\n .enter()\n .append('rect')\n .classed('bar', true)\n .attr('x', (d) => xScale(d.data.key))\n .attr('y', (d) => yScale(d[1]))\n .attr('width', xScale.bandwidth );\n\n if (isAnimated) {\n bars.style('opacity', barOpacity)\n .transition()\n .delay((_, i) => animationDelays[i])\n .duration(animationDuration)\n .ease(ease)\n .tween('attr.height', verticalBarsTween);\n } else {\n bars.attr('height', (d) => yScale(d[0]) - yScale(d[1]));\n }\n }\n\n /**\n * Draws a vertical line to extend y-axis till the edges\n * @return {void}\n */\n function drawVerticalExtendedLine() {\n baseLine = svg.select('.grid-lines-group')\n .selectAll('line.extended-y-line')\n .data([0])\n .enter()\n .append('line')\n .attr('class', 'extended-y-line')\n .attr('y1', (xAxisPadding.bottom))\n .attr('y2', chartHeight)\n .attr('x1', 0)\n .attr('x2', 0);\n }\n\n /**\n * Draws the different areas into the chart-group element\n * @private\n */\n function drawStackedBar(){\n // Not ideal, we need to figure out how to call exit for nested elements\n if (layerElements) {\n svg.selectAll('.layer').remove();\n }\n\n let series = svg.select('.chart-group').selectAll('.layer')\n\n if (isHorizontal) {\n drawHorizontalBars(series)\n } else {\n drawVerticalBars(series)\n }\n // Exit\n series.exit()\n .transition()\n .style('opacity', 0)\n .remove();\n }\n\n /**\n * Extract X position on the chart from a given mouse event\n * @param {obj} event D3 mouse event\n * @return {Number} Position on the x axis of the mouse\n * @private\n */\n function getMousePosition(event) {\n return d3Selection.mouse(event);\n }\n\n /**\n * Finds out the data entry that is closer to the given position on pixels\n * @param {Number} mouseX X position of the mouse\n * @return {obj} Data entry that is closer to that x axis position\n */\n function getNearestDataPoint(mouseX) {\n const adjustedMouseX = mouseX - margin.left;\n\n const nearest = transformedData.find(({key}) => {\n const barStart = xScale(key);\n const barEnd = barStart + xScale.bandwidth();\n\n // If mouseX is between barStart & barEnd\n return (adjustedMouseX >= barStart) && (adjustedMouseX < barEnd);\n });\n\n return nearest;\n }\n\n /**\n * Finds out the data entry that is closer to the given position on pixels (horizontal)\n * @param {Number} mouseY Y position of the mouse\n * @return {obj} Data entry that is closer to that y axis position\n */\n function getNearestDataPoint2(mouseY) {\n const adjustedMouseY = mouseY - margin.top;\n\n const nearest = transformedData.find(({key}) => {\n const barStart = yScale(key);\n const barEnd = barStart + yScale.bandwidth();\n\n // If mouseY is between barStart & barEnd\n return (adjustedMouseY >= barStart) && (adjustedMouseY < barEnd);\n });\n\n return nearest;\n }\n\n /**\n * Handles a mouseover event on top of a bar\n * @return {void}\n */\n function handleBarsMouseOver() {\n d3Selection.select(this)\n .attr('fill', () => d3Color.color(d3Selection.select(this.parentNode).attr('fill')).darker())\n }\n\n /**\n * Handles a mouseout event out of a bar\n * @return {void}\n */\n function handleBarsMouseOut() {\n d3Selection\n .select(this).attr('fill', () => d3Selection.select(this.parentNode).attr('fill'))\n }\n\n /**\n * MouseMove handler, calculates the nearest dataPoint to the cursor\n * and updates metadata related to it\n * @private\n */\n function handleMouseMove(e){\n let [mouseX, mouseY] = getMousePosition(e),\n dataPoint = isHorizontal ? getNearestDataPoint2(mouseY) : getNearestDataPoint(mouseX),\n x,\n y;\n\n if (dataPoint) {\n // Move verticalMarker to that datapoint\n if (isHorizontal) {\n x = mouseX - margin.left;\n y = yScale(dataPoint.key) + yScale.bandwidth()/2;\n } else {\n x = xScale(dataPoint.key) + margin.left;\n y = mouseY - margin.bottom;\n }\n moveTooltipOriginXY(x,y);\n\n // Emit event with xPosition for tooltip or similar feature\n dispatcher.call('customMouseMove', e, dataPoint, categoryColorMap, x, y);\n }\n }\n\n /**\n * Click handler, passes the data point of the clicked bar\n * (or it's nearest point)\n * @private\n */\n\n function handleClick(e) {\n let [mouseX, mouseY] = getMousePosition(e);\n let dataPoint = isHorizontal ? getNearestDataPoint2(mouseY) : getNearestDataPoint(mouseX);\n\n dispatcher.call('customClick', e, dataPoint, d3Selection.mouse(e));\n }\n\n /**\n * MouseOut handler, hides overlay and removes active class on verticalMarkerLine\n * It also resets the container of the vertical marker\n * @private\n */\n function handleMouseOut(e, d) {\n svg.select('.metadata-group').attr('transform', 'translate(9999, 0)');\n dispatcher.call('customMouseOut', e, d, d3Selection.mouse(e));\n }\n\n /**\n * Mouseover handler, shows overlay and adds active class to verticalMarkerLine\n * @private\n */\n function handleMouseOver(e, d) {\n dispatcher.call('customMouseOver', e, d, d3Selection.mouse(e));\n }\n\n /**\n * Animation tween of horizontal bars\n * @param {obj} d data of bar\n * @return {void}\n */\n function horizontalBarsTween(d) {\n let node = d3Selection.select(this),\n i = d3Interpolate.interpolateRound(0, xScale(d[1] - d[0])),\n j = d3Interpolate.interpolateNumber(0, 1);\n\n return function (t) {\n node.attr('width', i(t))\n .style('opacity', j(t));\n }\n }\n\n /**\n * Helper method to update the x position of the vertical marker\n * @param {obj} dataPoint Data entry to extract info\n * @return void\n */\n function moveTooltipOriginXY(originXPosition, originYPosition){\n svg.select('.metadata-group')\n .attr('transform', `translate(${originXPosition},${originYPosition})`);\n }\n\n /**\n * Prepare data for create chart.\n * @private\n */\n function prepareData(data) {\n stacks = uniq(data.map(({stack}) => stack));\n\n if (hasReversedStacks) {\n stacks = stacks.reverse();\n }\n\n transformedData = d3Collection.nest()\n .key(getName)\n .rollup(function(values) {\n let ret = {};\n\n values.forEach((entry) => {\n if (entry && entry[stackLabel]) {\n ret[entry[stackLabel]] = getValue(entry);\n }\n });\n ret.values = values; //for tooltip\n\n return ret;\n })\n .entries(data)\n .map(function(data){\n return assign({}, {\n total:d3Array.sum( d3Array.permute(data.value, stacks) ),\n key:data.key\n }, data.value);\n });\n }\n\n /**\n * Determines if we should add the tooltip related logic depending on the\n * size of the chart and the tooltipThreshold variable value\n * @return {boolean} Should we build the tooltip?\n * @private\n */\n function shouldShowTooltip() {\n return width > tooltipThreshold;\n }\n\n /**\n * Animation tween of vertical bars\n * @param {obj} d data of bar\n * @return {void}\n */\n function verticalBarsTween(d) {\n let node = d3Selection.select(this),\n i = d3Interpolate.interpolateRound(0, yScale(d[0]) - yScale(d[1])),\n j = d3Interpolate.interpolateNumber(0,1);\n\n return function (t) {\n node\n .attr('height', i(t))\n .style('opacity', j(t));\n }\n }\n\n // API\n /**\n * Gets or Sets the aspect ratio of the chart\n * @param {Number} _x Desired aspect ratio for the graph\n * @return {Number | module} Current aspect ratio or Area Chart module to chain calls\n * @public\n */\n exports.aspectRatio = function(_x) {\n if (!arguments.length) {\n return aspectRatio;\n }\n aspectRatio = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the padding of the stacked bar chart\n * The default value is\n * @param {Number} _x Padding value to get/set\n * @return {Number | module} Current padding or Chart module to chain calls\n * @public\n */\n exports.betweenBarsPadding = function (_x) {\n if (!arguments.length) {\n return betweenBarsPadding;\n }\n betweenBarsPadding = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the colorSchema of the chart\n * @param {String[]} _x Desired colorSchema for the graph\n * @return {String[] | module} Current colorSchema or Chart module to chain calls\n * @public\n */\n exports.colorSchema = function(_x) {\n if (!arguments.length) {\n return colorSchema;\n }\n colorSchema = _x;\n\n return this;\n };\n\n /**\n * Chart exported to png and a download action is fired\n * @param {String} filename File title for the resulting picture\n * @param {String} title Title to add at the top of the exported picture\n * @public\n */\n exports.exportChart = function(filename, title) {\n exportChart.call(exports, svg, filename, title);\n };\n\n /**\n * Gets or Sets the grid mode.\n *\n * @param {String} _x Desired mode for the grid ('vertical'|'horizontal'|'full')\n * @return {String | module} Current mode of the grid or Area Chart module to chain calls\n * @public\n */\n exports.grid = function(_x) {\n if (!arguments.length) {\n return grid;\n }\n grid = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the hasPercentage status\n * @param {Boolean} _x Should use percentage as value format\n * @return {Boolean | module} Is percentage used or Chart module to chain calls\n * @public\n */\n exports.hasPercentage = function(_x) {\n if (!arguments.length) {\n return valueLabelFormat === PERCENTAGE_FORMAT;\n }\n if (_x) {\n valueLabelFormat = PERCENTAGE_FORMAT;\n } else {\n valueLabelFormat = NUMBER_FORMAT;\n }\n\n return this;\n };\n\n /**\n * Gets or Sets the height of the chart\n * @param {Number} _x Desired width for the graph\n * @return {Number | module} Current height or Area Chart module to chain calls\n * @public\n */\n exports.height = function(_x) {\n if (!arguments.length) {\n return height;\n }\n if (aspectRatio) {\n width = Math.ceil(_x / aspectRatio);\n }\n height = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the horizontal direction of the chart\n * @param {Boolean} _x Desired horizontal direction for the graph\n * @return {Boolean | module} If it is horizontal or Bar Chart module to chain calls\n * @public\n */\n exports.isHorizontal = function(_x) {\n if (!arguments.length) {\n return isHorizontal;\n }\n isHorizontal = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the hasReversedStacks property of the chart, reversing the order of stacks.\n * @param {Boolean} _x Desired hasReversedStacks flag\n * @return {Boolean | module} Current hasReversedStacks or Chart module to chain calls\n * @public\n */\n exports.hasReversedStacks = function(_x) {\n if (!arguments.length) {\n return hasReversedStacks;\n }\n hasReversedStacks = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the isAnimated property of the chart, making it to animate when render.\n * By default this is 'false'\n *\n * @param {Boolean} _x Desired animation flag\n * @return {Boolean | module} Current isAnimated flag or Chart module\n * @public\n */\n exports.isAnimated = function(_x) {\n if (!arguments.length) {\n return isAnimated;\n }\n isAnimated = _x;\n\n return this;\n };\n\n /**\n * Pass language tag for the tooltip to localize the date.\n * Feature uses Intl.DateTimeFormat, for compatability and support, refer to\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat\n * @param {String} _x must be a language tag (BCP 47) like 'en-US' or 'fr-FR'\n * @return {String | module} Current locale or module to chain calls\n */\n exports.locale = function(_x) {\n if (!arguments.length) {\n return locale;\n }\n locale = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the margin of the chart\n * @param {Object} _x Margin object to get/set\n * @return {Object | module} Current margin or Area Chart module to chain calls\n * @public\n */\n exports.margin = function(_x) {\n if (!arguments.length) {\n return margin;\n }\n margin = {\n ...margin,\n ..._x\n };\n\n return this;\n };\n\n /**\n * Gets or Sets the nameLabel of the chart\n * @param {Number} _x Desired dateLabel for the graph\n * @return {Number | module} Current nameLabel or Chart module to chain calls\n * @public\n */\n exports.nameLabel = function(_x) {\n if (!arguments.length) {\n return nameLabel;\n }\n nameLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the valueLabelFormat of the chart\n * @param {String[]} _x Desired valueLabelFormat for the graph\n * @return {String[] | module} Current valueLabelFormat or Chart module to chain calls\n * @public\n */\n exports.nameLabelFormat = function(_x) {\n if (!arguments.length) {\n return nameLabelFormat;\n }\n nameLabelFormat = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the number of ticks of the x axis on the chart\n * (Default is 5)\n * @param {Number} _x Desired horizontal ticks\n * @return {Number | module} Current xTicks or Chart module to chain calls\n * @public\n */\n exports.xTicks = function (_x) {\n if (!arguments.length) {\n return xTicks;\n }\n xTicks = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the number of vertical ticks of the axis on the chart\n * @param {Number} _x Desired vertical ticks\n * @return {Number | module} Current yTicks or Chart module to chain calls\n * @public\n */\n exports.yTicks = function (_x) {\n if (!arguments.length) {\n return yTicks;\n }\n yTicks = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the loading state of the chart\n * @param {String} markup Desired markup to show when null data\n * @return {String | module} Current loading state markup or Chart module to chain calls\n * @public\n */\n exports.loadingState = function(_markup) {\n if (!arguments.length) {\n return loadingState;\n }\n loadingState = _markup;\n\n return this;\n };\n\n /**\n * Exposes an 'on' method that acts as a bridge with the event dispatcher\n * We are going to expose this events:\n * customMouseOver, customMouseMove, customMouseOut, and customClick\n *\n * @return {module} Bar Chart\n * @public\n */\n exports.on = function() {\n let value = dispatcher.on.apply(dispatcher, arguments);\n\n return value === dispatcher ? exports : value;\n };\n\n /**\n * Configurable extension of the x axis\n * if your max point was 50% you might want to show x axis to 60%, pass 1.2\n * @param {Number} _x ratio to max data point to add to the x axis\n * @return {Number | module} Current ratio or Bar Chart module to chain calls\n * @public\n */\n exports.percentageAxisToMaxRatio = function(_x) {\n if (!arguments.length) {\n return percentageAxisToMaxRatio;\n }\n percentageAxisToMaxRatio = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the stackLabel of the chart\n * @param {String} _x Desired stackLabel for the graph\n * @return {String | module} Current stackLabel or Chart module to chain calls\n * @public\n */\n exports.stackLabel = function(_x) {\n if (!arguments.length) {\n return stackLabel;\n }\n stackLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the minimum width of the graph in order to show the tooltip\n * NOTE: This could also depend on the aspect ratio\n *\n * @param {Number} [_x=480] Minimum width of the graph\n * @return {Number | module} Current tooltipThreshold or Area Chart module to chain calls\n * @public\n */\n exports.tooltipThreshold = function(_x) {\n if (!arguments.length) {\n return tooltipThreshold;\n }\n tooltipThreshold = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the valueLabel of the chart\n * @param {Number} _x Desired valueLabel for the graph\n * @return {Number | module} Current valueLabel or Chart module to chain calls\n * @public\n */\n exports.valueLabel = function(_x) {\n if (!arguments.length) {\n return valueLabel;\n }\n valueLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the valueLabelFormat of the chart\n * @param {String[]} _x Desired valueLabelFormat for the graph\n * @return {String[] | module} Current valueLabelFormat or Chart module to chain calls\n * @public\n */\n exports.valueLabelFormat = function(_x) {\n if (!arguments.length) {\n return valueLabelFormat;\n }\n valueLabelFormat = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the width of the chart\n * @param {Number} _x Desired width for the graph\n * @return {Number | module} Current width or Area Chart module to chain calls\n * @public\n */\n exports.width = function(_x) {\n if (!arguments.length) {\n return width;\n }\n if (aspectRatio) {\n height = Math.ceil(_x * aspectRatio);\n }\n width = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the y-axis label of the chart\n * @param {String} _x Desired label string\n * @return {String | module} Current yAxisLabel or Chart module to chain calls\n * @public\n * @example stackedBar.yAxisLabel('Ticket Sales')\n */\n exports.yAxisLabel = function (_x) {\n if (!arguments.length) {\n return yAxisLabel;\n }\n yAxisLabel = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the offset of the yAxisLabel of the chart.\n * The method accepts both positive and negative values.\n * The default value is -60\n * @param {Number} _x Desired offset for the label\n * @return {Number | module} Current yAxisLabelOffset or Chart module to chain calls\n * @public\n * @example stackedBar.yAxisLabelOffset(-55)\n */\n exports.yAxisLabelOffset = function (_x) {\n if (!arguments.length) {\n return yAxisLabelOffset;\n }\n yAxisLabelOffset = _x;\n\n return this;\n }\n\n return exports;\n };\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/stacked-bar.js","define(function(require) {\n 'use strict';\n\n const d3Array = require('d3-array');\n const d3Axis = require('d3-axis');\n const d3Dispatch = require('d3-dispatch');\n const d3Ease = require('d3-ease');\n const d3Format = require('d3-format');\n const d3Scale = require('d3-scale');\n const d3Selection = require('d3-selection');\n const d3Transition = require('d3-transition');\n\n const {exportChart} = require('./helpers/export');\n const {line} = require('./helpers/load');\n\n\n /**\n * @typedef StepChartData\n * @type Object[]\n *\n * @property {String} key Key we measure (required)\n * @property {Number} value value of the key (required)\n *\n * @example\n * [\n * {\n * value: 1,\n * key: 'glittering'\n * },\n * {\n * value: 1,\n * key: 'luminous'\n * }\n * ]\n */\n\n /**\n * Step Chart reusable API class that renders a\n * simple and configurable step chart.\n *\n * @module Step\n * @tutorial step\n * @requires d3-array, d3-axis, d3-dispatch, d3-format, d3-scale, d3-selection, d3-transition\n *\n * @example\n * var stepChart= step();\n *\n * stepChart\n * .height(500)\n * .width(800);\n *\n * d3Selection.select('.css-selector')\n * .datum(dataset)\n * .call(stepChart);\n *\n */\n\n return function module() {\n\n let margin = {\n top: 20,\n right: 20,\n bottom: 30,\n left: 40\n },\n width = 960,\n height = 500,\n loadingState = line,\n ease = d3Ease.easeQuadInOut,\n data,\n chartWidth, chartHeight,\n xScale, yScale,\n yTicks = 6,\n xAxis,\n xAxisLabel,\n xAxisLabelEl,\n yAxis,\n yAxisLabel,\n yAxisLabelEl,\n xAxisLabelOffset = 80,\n yAxisLabelOffset = -20,\n xAxisPadding = {\n top: 0,\n left: 0,\n bottom: 0,\n right: 0\n },\n yTickPadding = 8,\n svg,\n\n valueLabel = 'value',\n nameLabel = 'key',\n\n maskGridLines,\n baseLine,\n\n // Dispatcher object to broadcast the mouse events\n // Ref: https://github.com/mbostock/d3/wiki/Internals#d3_dispatch\n dispatcher = d3Dispatch.dispatch('customMouseOver', 'customMouseOut', 'customMouseMove'),\n\n // Formats\n yAxisTickFormat = d3Format.format('.3'),\n\n // extractors\n getKey = ({key}) => key,\n getValue = ({value}) => value;\n\n\n /**\n * This function creates the graph using the selection as container\n * @param {D3Selection} _selection A d3 selection that represents\n * the container(s) where the chart(s) will be rendered\n * @param {StepChartData} _data The data to attach and generate the chart\n */\n function exports(_selection){\n _selection.each(function(_data){\n // Make space on the left of the graph for the y axis label\n chartWidth = width - margin.left - margin.right;\n chartHeight = height - margin.top - margin.bottom;\n data = cleanData(_data);\n\n buildScales();\n buildAxis();\n buildSVG(this);\n drawGridLines();\n drawSteps();\n drawAxis();\n });\n }\n\n /**\n * Creates the d3 x and y axis, setting orientations\n * @private\n */\n function buildAxis(){\n xAxis = d3Axis.axisBottom(xScale);\n\n yAxis = d3Axis.axisLeft(yScale)\n .ticks(yTicks)\n .tickPadding(yTickPadding)\n .tickFormat(yAxisTickFormat);\n }\n\n /**\n * Builds containers for the chart, the axis and a wrapper for all of them\n * Also applies the Margin convention\n * @private\n */\n function buildContainerGroups(){\n let container = svg\n .append('g')\n .classed('container-group', true)\n .attr('transform', `translate(${margin.left}, ${margin.top})`);\n\n container\n .append('g')\n .classed('grid-lines-group', true);\n container\n .append('g')\n .classed('chart-group', true);\n container\n .append('g')\n .classed('x-axis-group axis', true)\n .append('g')\n .classed('x-axis-label', true);\n container\n .append('g')\n .classed('y-axis-group axis', true)\n .append('g')\n .classed('y-axis-label', true);\n container\n .append('g').classed('metadata-group', true);\n }\n\n /**\n * Creates the x and y scales of the graph\n * @private\n */\n function buildScales(){\n xScale = d3Scale.scaleBand()\n .domain(data.map(getKey))\n .rangeRound([0, chartWidth])\n .paddingInner(0);\n\n yScale = d3Scale.scaleLinear()\n .domain([0, d3Array.max(data, getValue)])\n .rangeRound([chartHeight, 0]);\n }\n\n /**\n * Builds the SVG element that will contain the chart\n * @param {HTMLElement} container DOM element that will work as the container of the graph\n * @private\n */\n function buildSVG(container){\n if (!svg) {\n svg = d3Selection.select(container)\n .append('svg')\n .classed('britechart step-chart', true);\n\n buildContainerGroups();\n }\n\n svg\n .attr('width', width)\n .attr('height', height);\n }\n\n /**\n * Cleaning data casting the values and keys to the proper type while keeping\n * the rest of properties on the data\n * @param {StepChartData} originalData Data as provided on the container\n * @private\n */\n function cleanData(originalData) {\n return originalData.reduce((acc, d) => {\n d.value = +d[valueLabel];\n d.key = String(d[nameLabel]);\n\n return [...acc, d];\n }, []);\n }\n\n /**\n * Draws the x and y axis on the svg object within their\n * respective groups\n * @private\n */\n function drawAxis(){\n svg.select('.x-axis-group.axis')\n .attr('transform', `translate(0, ${chartHeight})`)\n .call(xAxis);\n\n svg.selectAll('.x-axis-group .tick text')\n .style('text-anchor', 'start')\n .attr('transform', 'rotate(45 -1 10)');\n\n if (xAxisLabel) {\n if (xAxisLabelEl) {\n svg.selectAll('.x-axis-label-text').remove();\n }\n xAxisLabelEl = svg.select('.x-axis-label')\n .append('text')\n .attr('y', xAxisLabelOffset)\n .attr('text-anchor', 'middle')\n .classed('x-axis-label-text', true)\n .attr('x', chartWidth / 2)\n .text(xAxisLabel);\n }\n\n svg.select('.y-axis-group.axis')\n .call(yAxis);\n\n if (yAxisLabel) {\n if (yAxisLabelEl) {\n svg.selectAll('.y-axis-label-text').remove();\n }\n yAxisLabelEl = svg.select('.y-axis-label')\n .append('text')\n .classed('y-axis-label-text', true)\n .attr('x', -chartHeight / 2)\n .attr('y', yAxisLabelOffset)\n .attr('text-anchor', 'middle')\n .attr('transform', 'rotate(270 0 0)')\n .text(yAxisLabel);\n }\n }\n\n /**\n * Draws the step elements within the chart group\n * @private\n */\n function drawSteps(){\n let steps = svg.select('.chart-group').selectAll('.step').data(data);\n\n // Enter\n steps.enter()\n .append('rect')\n .classed('step', true)\n .attr('x', chartWidth) // Initially drawing the steps at the end of Y axis\n .attr('y', ({value}) => yScale(value))\n .attr('width', xScale.bandwidth())\n .attr('height', (d) => (chartHeight - yScale(d.value)))\n .on('mouseover', function(d) {\n handleMouseOver(this, d, chartWidth, chartHeight);\n })\n .on('mousemove', function(d) {\n handleMouseMove(this, d, chartWidth, chartHeight);\n })\n .on('mouseout', function(d) {\n handleMouseOut(this, d, chartWidth, chartHeight);\n })\n .merge(steps)\n .transition()\n .ease(ease)\n .attr('x', ({key}) => xScale(key))\n .attr('y', function(d) {\n return yScale(d.value);\n })\n .attr('width', xScale.bandwidth())\n .attr('height', function(d) {\n return chartHeight - yScale(d.value);\n });\n\n // Exit\n steps.exit()\n .transition()\n .style('opacity', 0)\n .remove();\n }\n\n /**\n * Draws grid lines on the background of the chart\n * @return void\n */\n function drawGridLines(){\n if (maskGridLines) {\n svg.selectAll('.horizontal-grid-line').remove();\n }\n if (baseLine) {\n svg.selectAll('.extended-x-line').remove();\n }\n\n maskGridLines = svg.select('.grid-lines-group')\n .selectAll('line.horizontal-grid-line')\n .data(yScale.ticks(yTicks))\n .enter()\n .append('line')\n .attr('class', 'horizontal-grid-line')\n .attr('x1', (xAxisPadding.left))\n .attr('x2', chartWidth)\n .attr('y1', (d) => yScale(d))\n .attr('y2', (d) => yScale(d));\n\n if (baseLine) {\n svg.selectAll('.extended-x-line').remove();\n }\n\n //draw a horizontal line to extend x-axis till the edges\n baseLine = svg.select('.grid-lines-group')\n .selectAll('line.extended-x-line')\n .data([0])\n .enter()\n .append('line')\n .attr('class', 'extended-x-line')\n .attr('x1', (xAxisPadding.left))\n .attr('x2', chartWidth)\n .attr('y1', chartHeight)\n .attr('y2', chartHeight);\n }\n\n // API\n\n /**\n * Custom OnMouseOver event handler\n * @return {void}\n * @private\n */\n function handleMouseOver(e, d, chartWidth, chartHeight) {\n dispatcher.call('customMouseOver', e, d, d3Selection.mouse(e), [chartWidth, chartHeight]);\n }\n\n /**\n * Custom OnMouseMove event handler\n * @return {void}\n * @private\n */\n function handleMouseMove(e, d, chartWidth, chartHeight) {\n dispatcher.call('customMouseMove', e, d, d3Selection.mouse(e), [chartWidth, chartHeight]);\n }\n\n /**\n * Custom OnMouseOver event handler\n * @return {void}\n * @private\n */\n function handleMouseOut(e, d, chartWidth, chartHeight) {\n dispatcher.call('customMouseOut', e, d, d3Selection.mouse(e), [chartWidth, chartHeight]);\n }\n\n /**\n * Chart exported to png and a download action is fired\n * @param {String} filename File title for the resulting picture\n * @param {String} title Title to add at the top of the exported picture\n * @public\n */\n exports.exportChart = function(filename) {\n exportChart.call(exports, svg, filename);\n };\n\n /**\n * Gets or Sets the margin of the chart\n * @param {object} _x Margin object to get/set\n * @return { margin | module} Current margin or Chart module to chain calls\n * @public\n */\n exports.margin = function(_x) {\n if (!arguments.length) {\n return margin;\n }\n margin = {\n ...margin,\n ..._x\n };\n return this;\n };\n\n /**\n * Gets or Sets the number of vertical ticks on the chart\n * (Default is 6)\n * @param {Number} _x Desired number of vertical ticks for the graph\n * @return {Number | module} Current yTicks or Chart module to chain calls\n * @public\n */\n exports.yTicks = function(_x) {\n if (!arguments.length) {\n return yTicks;\n }\n yTicks = _x;\n return this;\n };\n\n /**\n * Gets or Sets the height of the chart\n * @param {number} _x Desired width for the graph\n * @return { height | module} Current height or Chart module to chain calls\n * @public\n */\n exports.height = function(_x) {\n if (!arguments.length) {\n return height;\n }\n height = _x;\n return this;\n };\n\n /**\n * Gets or Sets the loading state of the chart\n * @param {string} markup Desired markup to show when null data\n * @return { loadingState | module} Current loading state markup or Chart module to chain calls\n * @public\n */\n exports.loadingState = function(_markup) {\n if (!arguments.length) {\n return loadingState;\n }\n loadingState = _markup;\n\n return this;\n };\n\n /**\n * Exposes an 'on' method that acts as a bridge with the event dispatcher\n * We are going to expose this events:\n * customMouseOver, customMouseMove and customMouseOut\n *\n * @return {module} Bar Chart\n * @public\n */\n exports.on = function(...args) {\n let value = dispatcher.on(...args);\n\n return value === dispatcher ? exports : value;\n };\n\n /**\n * Gets or Sets the width of the chart\n * @param {number} _x Desired width for the graph\n * @return { width | module} Current width or Chart module to chain calls\n * @public\n */\n exports.width = function(_x) {\n if (!arguments.length) {\n return width;\n }\n width = _x;\n return this;\n };\n\n /**\n * Gets or Sets the text of the xAxisLabel on the chart\n * @param {String} _x Desired text for the label\n * @return {String | module} label or Chart module to chain calls\n * @public\n */\n exports.xAxisLabel = function(_x) {\n if (!arguments.length) {\n return xAxisLabel;\n }\n xAxisLabel = _x;\n return this;\n };\n\n /**\n * Gets or Sets the offset of the xAxisLabel on the chart\n * @param {Number} _x Desired offset for the label\n * @return {Number | module} label or Chart module to chain calls\n * @public\n */\n exports.xAxisLabelOffset = function(_x) {\n if (!arguments.length) {\n return xAxisLabelOffset;\n }\n xAxisLabelOffset = _x;\n return this;\n };\n\n /**\n * Gets or Sets the text of the yAxisLabel on the chart\n * @param {String} _x Desired text for the label\n * @return {String | module} label or Chart module to chain calls\n * @public\n */\n exports.yAxisLabel = function(_x) {\n if (!arguments.length) {\n return yAxisLabel;\n }\n yAxisLabel = _x;\n return this;\n };\n\n /**\n * Gets or Sets the offset of the yAxisLabel on the chart\n * @param {Number} _x Desired offset for the label\n * @return {Number | module} label or Chart module to chain calls\n * @public\n */\n exports.yAxisLabelOffset = function(_x) {\n if (!arguments.length) {\n return yAxisLabelOffset;\n }\n yAxisLabelOffset = _x;\n return this;\n };\n\n return exports;\n };\n\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/step.js","define(function(require) {\n 'use strict';\n\n const d3Array = require('d3-array');\n const d3Axis = require('d3-axis');\n const d3Brush = require('d3-brush');\n const d3Ease = require('d3-ease');\n const d3Scale = require('d3-scale');\n const d3Shape = require('d3-shape');\n const d3Dispatch = require('d3-dispatch');\n const d3Selection = require('d3-selection');\n const d3Time = require('d3-time');\n const d3Transition = require('d3-transition');\n const d3TimeFormat = require('d3-time-format');\n\n const colorHelper = require('./helpers/color');\n const timeAxisHelper = require('./helpers/axis');\n\n const {axisTimeCombinations} = require('./helpers/constants');\n\n const {uniqueId} = require('./helpers/number');\n const {line} = require('./helpers/load');\n\n\n /**\n * @typedef BrushChartData\n * @type {Object[]}\n * @property {Number} value Value to chart (required)\n * @property {Date} date Date of the value (required)\n *\n * @example\n * [\n * {\n * value: 1,\n * date: '2011-01-06T00:00:00Z'\n * },\n * {\n * value: 2,\n * date: '2011-01-07T00:00:00Z'\n * }\n * ]\n */\n\n /**\n * Brush Chart reusable API class that renders a\n * simple and configurable brush chart.\n *\n * @module Brush\n * @tutorial brush\n * @requires d3-array\n * @requires d3-axis\n * @requires d3-brush\n * @requires d3-ease\n * @requires d3-scale\n * @requires d3-shape\n * @requires d3-dispatch\n * @requires d3-selection\n * @requires d3-time\n * @requires d3-transition\n * @requires d3-time-format\n *\n * @example\n * let brushChart = brush();\n *\n * brushChart\n * .height(500)\n * .width(800);\n *\n * d3Selection.select('.css-selector')\n * .datum(dataset)\n * .call(brushChart);\n */\n\n return function module() {\n\n let margin = {\n top: 20,\n right: 20,\n bottom: 30,\n left: 20\n },\n width = 960,\n height = 500,\n loadingState = line,\n data,\n svg,\n\n ease = d3Ease.easeQuadOut,\n\n dateLabel = 'date',\n valueLabel = 'value',\n\n dateRange = [null, null],\n\n chartWidth, chartHeight,\n xScale, yScale,\n xAxis,\n\n xAxisFormat = null,\n xTicks = null,\n xAxisCustomFormat = null,\n locale,\n\n brush,\n chartBrush,\n handle,\n\n tickPadding = 5,\n\n gradient = colorHelper.colorGradients.greenBlue,\n gradientId = uniqueId('brush-area-gradient'),\n\n // Dispatcher object to broadcast the mouse events\n // @see {@link https://github.com/d3/d3/blob/master/API.md#dispatches-d3-dispatch}\n dispatcher = d3Dispatch.dispatch('customBrushStart', 'customBrushEnd'),\n\n // extractors\n getValue = ({value}) => value,\n getDate = ({date}) => date;\n\n\n /**\n * This function creates the graph using the selection as container\n * @param {D3Selection} _selection A d3 selection that represents\n * the container(s) where the chart(s) will be rendered\n * @param {BrushChartData} _data The data to attach and generate the chart\n */\n function exports(_selection){\n _selection.each(function(_data){\n chartWidth = width - margin.left - margin.right;\n chartHeight = height - margin.top - margin.bottom;\n data = cleanData(cloneData(_data));\n\n buildScales();\n buildAxis();\n buildSVG(this);\n buildGradient();\n buildBrush();\n drawArea();\n drawAxis();\n drawBrush();\n drawHandles();\n });\n }\n\n /**\n * Creates the d3 x axis, setting orientation\n * @private\n */\n function buildAxis(){\n let minor, major;\n\n if (xAxisFormat === 'custom' && typeof xAxisCustomFormat === 'string') {\n minor = {\n tick: xTicks,\n format: d3TimeFormat.timeFormat(xAxisCustomFormat)\n };\n } else {\n ({minor, major} = timeAxisHelper.getTimeSeriesAxis(data, width, xAxisFormat));\n }\n\n xAxis = d3Axis.axisBottom(xScale)\n .ticks(minor.tick)\n .tickSize(10, 0)\n .tickPadding([tickPadding])\n .tickFormat(minor.format);\n }\n\n /**\n * Creates the brush element and attaches a listener\n * @return {void}\n */\n function buildBrush() {\n brush = d3Brush.brushX()\n .extent([[0, 0], [chartWidth, chartHeight]])\n .on('brush', handleBrushStart)\n .on('end', handleBrushEnd);\n }\n\n /**\n * Builds containers for the chart, the axis and a wrapper for all of them\n * Also applies the Margin convention\n * @private\n */\n function buildContainerGroups(){\n let container = svg\n .append('g')\n .classed('container-group', true)\n .attr('transform', `translate(${margin.left}, ${margin.top})`);\n\n container\n .append('g')\n .classed('chart-group', true);\n container\n .append('g')\n .classed('metadata-group', true);\n container\n .append('g')\n .classed('x-axis-group', true);\n container\n .append('g')\n .classed('brush-group', true);\n }\n\n /**\n * Creates the gradient on the area\n * @return {void}\n */\n function buildGradient() {\n let metadataGroup = svg.select('.metadata-group');\n\n metadataGroup.append('linearGradient')\n .attr('id', gradientId)\n .attr('gradientUnits', 'userSpaceOnUse')\n .attr('x1', 0)\n .attr('x2', xScale(data[data.length - 1].date))\n .attr('y1', 0)\n .attr('y2', 0)\n .selectAll('stop')\n .data([\n {offset: '0%', color: gradient[0]},\n {offset: '100%', color: gradient[1]}\n ])\n .enter().append('stop')\n .attr('offset', ({offset}) => offset)\n .attr('stop-color', ({color}) => color);\n }\n\n /**\n * Creates the x and y scales of the graph\n * @private\n */\n function buildScales(){\n xScale = d3Scale.scaleTime()\n .domain(d3Array.extent(data, getDate ))\n .range([0, chartWidth]);\n\n yScale = d3Scale.scaleLinear()\n .domain([0, d3Array.max(data, getValue)])\n .range([chartHeight, 0]);\n }\n\n /**\n * Builds the SVG element that will contain the chart\n * @param {HTMLElement} container DOM element that will work as the container of the graph\n * @private\n */\n function buildSVG(container){\n if (!svg) {\n svg = d3Selection.select(container)\n .append('svg')\n .classed('britechart brush-chart', true);\n\n buildContainerGroups();\n }\n\n svg\n .attr('width', width)\n .attr('height', height);\n }\n\n /**\n * Cleaning data casting the values and dates to the proper type while keeping\n * the rest of properties on the data\n * @param {BrushChartData} originalData Raw data from the container\n * @return {BrushChartData} Clean data\n * @private\n */\n function cleanData(originalData) {\n return originalData.reduce((acc, d) => {\n d.date = new Date(d[dateLabel]);\n d.value = +d[valueLabel];\n\n return [...acc, d];\n }, []);\n }\n\n /**\n * Clones the passed array of data\n * @param {Object[]} dataToClone Data to clone\n * @return {Object[]} Cloned data\n */\n function cloneData(dataToClone) {\n return JSON.parse(JSON.stringify(dataToClone));\n }\n\n /**\n * Draws the x axis on the svg object within its group\n *\n * @private\n */\n function drawAxis(){\n svg.select('.x-axis-group')\n .append('g')\n .attr('class', 'x axis')\n .attr('transform', `translate(0, ${chartHeight})`)\n .call(xAxis);\n }\n\n /**\n * Draws the area that is going to represent the data\n *\n * @return {void}\n */\n function drawArea() {\n // Create and configure the area generator\n let area = d3Shape.area()\n .x(({date}) => xScale(date))\n .y0(chartHeight)\n .y1(({value}) => yScale(value))\n .curve(d3Shape.curveBasis);\n\n // Create the area path\n svg.select('.chart-group')\n .append('path')\n .datum(data)\n .attr('class', 'brush-area')\n .attr('d', area);\n }\n\n /**\n * Draws the Brush components on its group\n * @return {void}\n */\n function drawBrush() {\n chartBrush = svg.select('.brush-group')\n .call(brush);\n\n // Update the height of the brushing rectangle\n chartBrush.selectAll('rect')\n .classed('brush-rect', true)\n .attr('height', chartHeight);\n\n chartBrush.selectAll('.selection')\n .attr('fill', `url(#${gradientId})`);\n }\n\n /**\n * Draws a handle for the Brush section\n * @return {void}\n */\n function drawHandles() {\n let handleFillColor = colorHelper.colorSchemasHuman.grey[1];\n\n // Styling\n handle = chartBrush\n .selectAll('.handle.brush-rect')\n .style('fill', handleFillColor);\n }\n\n /**\n * When a brush event starts, we can extract info from the extension\n * of the brush.\n *\n * @return {void}\n */\n function handleBrushStart() {\n let s = d3Selection.event.selection,\n dateExtent = s.map(xScale.invert);\n\n dispatcher.call('customBrushStart', this, dateExtent);\n // updateHandlers(dateExtent);\n }\n\n /**\n * Processes the end brush event, snapping the boundaries to days\n * as showed on the example on https://bl.ocks.org/mbostock/6232537\n * @return {void}\n * @private\n */\n function handleBrushEnd() {\n if (!d3Selection.event.sourceEvent) return; // Only transition after input.\n if (!d3Selection.event.selection) return; // Ignore empty selections.\n\n let s = d3Selection.event.selection,\n dateExtent = s.map(xScale.invert),\n dateExtentRounded = dateExtent.map(d3Time.timeDay.round);\n\n // If empty when rounded, use floor & ceil instead.\n if (dateExtentRounded[0] >= dateExtentRounded[1]) {\n dateExtentRounded[0] = d3Time.timeDay.floor(dateExtent[0]);\n dateExtentRounded[1] = d3Time.timeDay.offset(dateExtentRounded[0]);\n }\n\n d3Selection.select(this)\n .transition()\n .call(d3Selection.event.target.move, dateExtentRounded.map(xScale));\n\n dispatcher.call('customBrushEnd', this, dateExtentRounded);\n }\n\n /**\n * Sets a new brush extent within the passed percentage positions\n * @param {Number} a Percentage of data that the brush start with\n * @param {Number} b Percentage of data that the brush ends with\n * @example\n * setBrushByPercentages(0.25, 0.5)\n */\n function setBrushByPercentages(a, b) {\n let x0 = a * chartWidth,\n x1 = b * chartWidth;\n\n brush\n .move(chartBrush, [x0, x1]);\n }\n\n /**\n * Sets a new brush extent within the passed dates\n * @param {String | Date} dateA Initial Date\n * @param {String | Date} dateB End Date\n */\n function setBrushByDates(dateA, dateB) {\n let x0 = xScale(new Date(dateA)),\n x1 = xScale(new Date(dateB));\n\n brush\n .move(chartBrush, [x0, x1]);\n }\n\n /**\n * Updates visibility and position of the brush handlers\n * @param {Number[]} dateExtent Date range\n * @return {void}\n */\n function updateHandlers(dateExtent) {\n if (dateExtent === null) {\n handle.attr('display', 'none');\n } else {\n handle\n .attr('display', null)\n .attr('transform', function(d, i) {\n return `translate(${dateExtent[i]},${chartHeight / 2})`;\n });\n }\n }\n\n // API\n\n /**\n * Exposes the constants to be used to force the x axis to respect a certain granularity\n * current options: MINUTE_HOUR, HOUR_DAY, DAY_MONTH, MONTH_YEAR\n * @example\n * brush.xAxisCustomFormat(brush.axisTimeCombinations.HOUR_DAY)\n */\n exports.axisTimeCombinations = axisTimeCombinations;\n\n /**\n * Gets or Sets the dateRange for the selected part of the brush\n * @param {String[]} _x Desired dateRange for the graph\n * @return { dateRange | module} Current dateRange or Chart module to chain calls\n * @public\n */\n exports.dateRange = function(_x) {\n if (!arguments.length) {\n return dateRange;\n }\n dateRange = _x;\n\n if (Array.isArray(dateRange)) {\n setBrushByDates(...dateRange);\n }\n\n return this;\n };\n\n /**\n * Gets or Sets the gradient of the chart\n * @param {String[]} _x Desired gradient for the graph\n * @return {String | Module} Current gradient or Chart module to chain calls\n * @public\n */\n exports.gradient = function(_x) {\n if (!arguments.length) {\n return gradient;\n }\n gradient = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the height of the chart\n * @param {Number} _x Desired width for the graph\n * @return {Number | Module} Current height or Chart module to chain calls\n * @public\n */\n exports.height = function(_x) {\n if (!arguments.length) {\n return height;\n }\n height = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the loading state of the chart\n * @param {string} markup Desired markup to show when null data\n * @return { loadingState | module} Current loading state markup or Chart module to chain calls\n * @public\n */\n exports.loadingState = function(_markup) {\n if (!arguments.length) {\n return loadingState;\n }\n loadingState = _markup;\n\n return this;\n };\n\n /**\n * Pass language tag for the tooltip to localize the date.\n * Feature uses Intl.DateTimeFormat, for compatability and support, refer to\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat\n * @param {String} _x must be a language tag (BCP 47) like 'en-US' or 'fr-FR'\n * @return { (String|Module) } Current locale or module to chain calls\n */\n exports.locale = function(_x) {\n if (!arguments.length) {\n return locale;\n }\n locale = _x;\n\n return this;\n };\n\n /**\n * Gets or Sets the margin of the chart\n * @param {Object} _x Margin object to get/set\n * @return {Object | Module} Current margin or Chart module to chain calls\n * @public\n */\n exports.margin = function(_x) {\n if (!arguments.length) {\n return margin;\n }\n margin = {\n ...margin,\n ..._x\n };\n\n return this;\n };\n\n /**\n * Date range\n * @typedef DateExtent\n * @type {Date[]}\n * @property {Date} 0 Lower bound date selection\n * @property {Date} 1 Upper bound date selection\n * @see {@link https://github.com/d3/d3-brush#brushSelection|d3-brush:brushSelection}\n */\n\n /**\n * Event indicating when the brush moves\n * @event customBrushStart\n * @type {module:Brush~DateExtent}\n * @see {@link https://github.com/d3/d3-brush#brush_on|d3-brush:on(brush)}\n */\n \n /**\n * Event indicating the end of a brush gesture\n * @event customBrushEnd\n * @type {module:Brush~DateExtent}\n * @see {@link https://github.com/d3/d3-brush#brush_on|d3-brush:on(end)}\n */\n \n /**\n * @callback eventCallback\n * @param {module:Brush~DateExtent} dateExtent Date range\n */\n\n /**\n * Adds, removes, or gets the callback for the specified typenames.\n * @param {String} typenames One or more event type names, delimited by a space\n * @param {module:Brush~eventCallback} [callback] Callback to register\n * @return {module:Brush}\n * @listens customBrushStart\n * @listens customBrushEnd\n * @see {@link https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_on|d3-dispatch:on}\n * @public\n */\n exports.on = function() {\n let value = dispatcher.on.apply(dispatcher, arguments);\n\n return value === dispatcher ? exports : value;\n };\n\n /**\n * Gets or Sets the width of the chart\n * @param {Number} _x Desired width for the graph\n * @return {Number | Module} Current width or Chart module to chain calls\n * @public\n */\n exports.width = function(_x) {\n if (!arguments.length) {\n return width;\n }\n width = _x;\n\n return this;\n };\n\n /**\n * Exposes the ability to force the chart to show a certain x format\n * It requires a `xAxisFormat` of 'custom' in order to work.\n * @param {String} _x Desired format for x axis\n * @return {String | Module} Current format or module to chain calls\n */\n exports.xAxisCustomFormat = function(_x) {\n if (!arguments.length) {\n return xAxisCustomFormat;\n }\n xAxisCustomFormat = _x;\n\n return this;\n };\n\n /**\n * Exposes the ability to force the chart to show a certain x axis grouping\n * @param {String} _x Desired format\n * @return {String | Module} Current format or module to chain calls\n * @example\n * brush.xAxisFormat(brush.axisTimeCombinations.HOUR_DAY)\n */\n exports.xAxisFormat = function(_x) {\n if (!arguments.length) {\n return xAxisFormat;\n }\n xAxisFormat = _x;\n\n return this;\n };\n\n /**\n * Exposes the ability to force the chart to show a certain x ticks. It requires a `xAxisCustomFormat` of 'custom' in order to work.\n * NOTE: This value needs to be a multiple of 2, 5 or 10. They won't always work as expected, as D3 decides at the end\n * how many and where the ticks will appear.\n *\n * @param {Number} _x Desired number of x axis ticks (multiple of 2, 5 or 10)\n * @return {Number | Module} Current number or ticks or module to chain calls\n */\n exports.xTicks = function(_x) {\n if (!arguments.length) {\n return xTicks;\n }\n xTicks = _x;\n\n return this;\n };\n\n return exports;\n };\n\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/charts/brush.js","export {\n default as brush,\n brushX,\n brushY,\n brushSelection\n} from \"./src/brush\";\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-brush/index.js\n// module id = 301\n// module chunks = 0","import {dispatch} from \"d3-dispatch\";\nimport {dragDisable, dragEnable} from \"d3-drag\";\nimport {interpolate} from \"d3-interpolate\";\nimport {customEvent, event, mouse, select} from \"d3-selection\";\nimport {interrupt} from \"d3-transition\";\nimport constant from \"./constant\";\nimport BrushEvent from \"./event\";\nimport noevent, {nopropagation} from \"./noevent\";\n\nvar MODE_DRAG = {name: \"drag\"},\n MODE_SPACE = {name: \"space\"},\n MODE_HANDLE = {name: \"handle\"},\n MODE_CENTER = {name: \"center\"};\n\nvar X = {\n name: \"x\",\n handles: [\"e\", \"w\"].map(type),\n input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },\n output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }\n};\n\nvar Y = {\n name: \"y\",\n handles: [\"n\", \"s\"].map(type),\n input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },\n output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }\n};\n\nvar XY = {\n name: \"xy\",\n handles: [\"n\", \"e\", \"s\", \"w\", \"nw\", \"ne\", \"se\", \"sw\"].map(type),\n input: function(xy) { return xy; },\n output: function(xy) { return xy; }\n};\n\nvar cursors = {\n overlay: \"crosshair\",\n selection: \"move\",\n n: \"ns-resize\",\n e: \"ew-resize\",\n s: \"ns-resize\",\n w: \"ew-resize\",\n nw: \"nwse-resize\",\n ne: \"nesw-resize\",\n se: \"nwse-resize\",\n sw: \"nesw-resize\"\n};\n\nvar flipX = {\n e: \"w\",\n w: \"e\",\n nw: \"ne\",\n ne: \"nw\",\n se: \"sw\",\n sw: \"se\"\n};\n\nvar flipY = {\n n: \"s\",\n s: \"n\",\n nw: \"sw\",\n ne: \"se\",\n se: \"ne\",\n sw: \"nw\"\n};\n\nvar signsX = {\n overlay: +1,\n selection: +1,\n n: null,\n e: +1,\n s: null,\n w: -1,\n nw: -1,\n ne: +1,\n se: +1,\n sw: -1\n};\n\nvar signsY = {\n overlay: +1,\n selection: +1,\n n: -1,\n e: null,\n s: +1,\n w: null,\n nw: -1,\n ne: -1,\n se: +1,\n sw: +1\n};\n\nfunction type(t) {\n return {type: t};\n}\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter() {\n return !event.button;\n}\n\nfunction defaultExtent() {\n var svg = this.ownerSVGElement || this;\n return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];\n}\n\n// Like d3.local, but with the name “__brush” rather than auto-generated.\nfunction local(node) {\n while (!node.__brush) if (!(node = node.parentNode)) return;\n return node.__brush;\n}\n\nfunction empty(extent) {\n return extent[0][0] === extent[1][0]\n || extent[0][1] === extent[1][1];\n}\n\nexport function brushSelection(node) {\n var state = node.__brush;\n return state ? state.dim.output(state.selection) : null;\n}\n\nexport function brushX() {\n return brush(X);\n}\n\nexport function brushY() {\n return brush(Y);\n}\n\nexport default function() {\n return brush(XY);\n}\n\nfunction brush(dim) {\n var extent = defaultExtent,\n filter = defaultFilter,\n listeners = dispatch(brush, \"start\", \"brush\", \"end\"),\n handleSize = 6,\n touchending;\n\n function brush(group) {\n var overlay = group\n .property(\"__brush\", initialize)\n .selectAll(\".overlay\")\n .data([type(\"overlay\")]);\n\n overlay.enter().append(\"rect\")\n .attr(\"class\", \"overlay\")\n .attr(\"pointer-events\", \"all\")\n .attr(\"cursor\", cursors.overlay)\n .merge(overlay)\n .each(function() {\n var extent = local(this).extent;\n select(this)\n .attr(\"x\", extent[0][0])\n .attr(\"y\", extent[0][1])\n .attr(\"width\", extent[1][0] - extent[0][0])\n .attr(\"height\", extent[1][1] - extent[0][1]);\n });\n\n group.selectAll(\".selection\")\n .data([type(\"selection\")])\n .enter().append(\"rect\")\n .attr(\"class\", \"selection\")\n .attr(\"cursor\", cursors.selection)\n .attr(\"fill\", \"#777\")\n .attr(\"fill-opacity\", 0.3)\n .attr(\"stroke\", \"#fff\")\n .attr(\"shape-rendering\", \"crispEdges\");\n\n var handle = group.selectAll(\".handle\")\n .data(dim.handles, function(d) { return d.type; });\n\n handle.exit().remove();\n\n handle.enter().append(\"rect\")\n .attr(\"class\", function(d) { return \"handle handle--\" + d.type; })\n .attr(\"cursor\", function(d) { return cursors[d.type]; });\n\n group\n .each(redraw)\n .attr(\"fill\", \"none\")\n .attr(\"pointer-events\", \"all\")\n .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\")\n .on(\"mousedown.brush touchstart.brush\", started);\n }\n\n brush.move = function(group, selection) {\n if (group.selection) {\n group\n .on(\"start.brush\", function() { emitter(this, arguments).beforestart().start(); })\n .on(\"interrupt.brush end.brush\", function() { emitter(this, arguments).end(); })\n .tween(\"brush\", function() {\n var that = this,\n state = that.__brush,\n emit = emitter(that, arguments),\n selection0 = state.selection,\n selection1 = dim.input(typeof selection === \"function\" ? selection.apply(this, arguments) : selection, state.extent),\n i = interpolate(selection0, selection1);\n\n function tween(t) {\n state.selection = t === 1 && empty(selection1) ? null : i(t);\n redraw.call(that);\n emit.brush();\n }\n\n return selection0 && selection1 ? tween : tween(1);\n });\n } else {\n group\n .each(function() {\n var that = this,\n args = arguments,\n state = that.__brush,\n selection1 = dim.input(typeof selection === \"function\" ? selection.apply(that, args) : selection, state.extent),\n emit = emitter(that, args).beforestart();\n\n interrupt(that);\n state.selection = selection1 == null || empty(selection1) ? null : selection1;\n redraw.call(that);\n emit.start().brush().end();\n });\n }\n };\n\n function redraw() {\n var group = select(this),\n selection = local(this).selection;\n\n if (selection) {\n group.selectAll(\".selection\")\n .style(\"display\", null)\n .attr(\"x\", selection[0][0])\n .attr(\"y\", selection[0][1])\n .attr(\"width\", selection[1][0] - selection[0][0])\n .attr(\"height\", selection[1][1] - selection[0][1]);\n\n group.selectAll(\".handle\")\n .style(\"display\", null)\n .attr(\"x\", function(d) { return d.type[d.type.length - 1] === \"e\" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; })\n .attr(\"y\", function(d) { return d.type[0] === \"s\" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; })\n .attr(\"width\", function(d) { return d.type === \"n\" || d.type === \"s\" ? selection[1][0] - selection[0][0] + handleSize : handleSize; })\n .attr(\"height\", function(d) { return d.type === \"e\" || d.type === \"w\" ? selection[1][1] - selection[0][1] + handleSize : handleSize; });\n }\n\n else {\n group.selectAll(\".selection,.handle\")\n .style(\"display\", \"none\")\n .attr(\"x\", null)\n .attr(\"y\", null)\n .attr(\"width\", null)\n .attr(\"height\", null);\n }\n }\n\n function emitter(that, args) {\n return that.__brush.emitter || new Emitter(that, args);\n }\n\n function Emitter(that, args) {\n this.that = that;\n this.args = args;\n this.state = that.__brush;\n this.active = 0;\n }\n\n Emitter.prototype = {\n beforestart: function() {\n if (++this.active === 1) this.state.emitter = this, this.starting = true;\n return this;\n },\n start: function() {\n if (this.starting) this.starting = false, this.emit(\"start\");\n return this;\n },\n brush: function() {\n this.emit(\"brush\");\n return this;\n },\n end: function() {\n if (--this.active === 0) delete this.state.emitter, this.emit(\"end\");\n return this;\n },\n emit: function(type) {\n customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);\n }\n };\n\n function started() {\n if (event.touches) { if (event.changedTouches.length < event.touches.length) return noevent(); }\n else if (touchending) return;\n if (!filter.apply(this, arguments)) return;\n\n var that = this,\n type = event.target.__data__.type,\n mode = (event.metaKey ? type = \"overlay\" : type) === \"selection\" ? MODE_DRAG : (event.altKey ? MODE_CENTER : MODE_HANDLE),\n signX = dim === Y ? null : signsX[type],\n signY = dim === X ? null : signsY[type],\n state = local(that),\n extent = state.extent,\n selection = state.selection,\n W = extent[0][0], w0, w1,\n N = extent[0][1], n0, n1,\n E = extent[1][0], e0, e1,\n S = extent[1][1], s0, s1,\n dx,\n dy,\n moving,\n shifting = signX && signY && event.shiftKey,\n lockX,\n lockY,\n point0 = mouse(that),\n point = point0,\n emit = emitter(that, arguments).beforestart();\n\n if (type === \"overlay\") {\n state.selection = selection = [\n [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],\n [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]\n ];\n } else {\n w0 = selection[0][0];\n n0 = selection[0][1];\n e0 = selection[1][0];\n s0 = selection[1][1];\n }\n\n w1 = w0;\n n1 = n0;\n e1 = e0;\n s1 = s0;\n\n var group = select(that)\n .attr(\"pointer-events\", \"none\");\n\n var overlay = group.selectAll(\".overlay\")\n .attr(\"cursor\", cursors[type]);\n\n if (event.touches) {\n group\n .on(\"touchmove.brush\", moved, true)\n .on(\"touchend.brush touchcancel.brush\", ended, true);\n } else {\n var view = select(event.view)\n .on(\"keydown.brush\", keydowned, true)\n .on(\"keyup.brush\", keyupped, true)\n .on(\"mousemove.brush\", moved, true)\n .on(\"mouseup.brush\", ended, true);\n\n dragDisable(event.view);\n }\n\n nopropagation();\n interrupt(that);\n redraw.call(that);\n emit.start();\n\n function moved() {\n var point1 = mouse(that);\n if (shifting && !lockX && !lockY) {\n if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;\n else lockX = true;\n }\n point = point1;\n moving = true;\n noevent();\n move();\n }\n\n function move() {\n var t;\n\n dx = point[0] - point0[0];\n dy = point[1] - point0[1];\n\n switch (mode) {\n case MODE_SPACE:\n case MODE_DRAG: {\n if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;\n if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;\n break;\n }\n case MODE_HANDLE: {\n if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;\n else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;\n if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;\n else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;\n break;\n }\n case MODE_CENTER: {\n if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));\n if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));\n break;\n }\n }\n\n if (e1 < w1) {\n signX *= -1;\n t = w0, w0 = e0, e0 = t;\n t = w1, w1 = e1, e1 = t;\n if (type in flipX) overlay.attr(\"cursor\", cursors[type = flipX[type]]);\n }\n\n if (s1 < n1) {\n signY *= -1;\n t = n0, n0 = s0, s0 = t;\n t = n1, n1 = s1, s1 = t;\n if (type in flipY) overlay.attr(\"cursor\", cursors[type = flipY[type]]);\n }\n\n if (state.selection) selection = state.selection; // May be set by brush.move!\n if (lockX) w1 = selection[0][0], e1 = selection[1][0];\n if (lockY) n1 = selection[0][1], s1 = selection[1][1];\n\n if (selection[0][0] !== w1\n || selection[0][1] !== n1\n || selection[1][0] !== e1\n || selection[1][1] !== s1) {\n state.selection = [[w1, n1], [e1, s1]];\n redraw.call(that);\n emit.brush();\n }\n }\n\n function ended() {\n nopropagation();\n if (event.touches) {\n if (event.touches.length) return;\n if (touchending) clearTimeout(touchending);\n touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!\n group.on(\"touchmove.brush touchend.brush touchcancel.brush\", null);\n } else {\n dragEnable(event.view, moving);\n view.on(\"keydown.brush keyup.brush mousemove.brush mouseup.brush\", null);\n }\n group.attr(\"pointer-events\", \"all\");\n overlay.attr(\"cursor\", cursors.overlay);\n if (state.selection) selection = state.selection; // May be set by brush.move (on start)!\n if (empty(selection)) state.selection = null, redraw.call(that);\n emit.end();\n }\n\n function keydowned() {\n switch (event.keyCode) {\n case 16: { // SHIFT\n shifting = signX && signY;\n break;\n }\n case 18: { // ALT\n if (mode === MODE_HANDLE) {\n if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n mode = MODE_CENTER;\n move();\n }\n break;\n }\n case 32: { // SPACE; takes priority over ALT\n if (mode === MODE_HANDLE || mode === MODE_CENTER) {\n if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;\n if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;\n mode = MODE_SPACE;\n overlay.attr(\"cursor\", cursors.selection);\n move();\n }\n break;\n }\n default: return;\n }\n noevent();\n }\n\n function keyupped() {\n switch (event.keyCode) {\n case 16: { // SHIFT\n if (shifting) {\n lockX = lockY = shifting = false;\n move();\n }\n break;\n }\n case 18: { // ALT\n if (mode === MODE_CENTER) {\n if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;\n if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;\n mode = MODE_HANDLE;\n move();\n }\n break;\n }\n case 32: { // SPACE\n if (mode === MODE_SPACE) {\n if (event.altKey) {\n if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n mode = MODE_CENTER;\n } else {\n if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;\n if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;\n mode = MODE_HANDLE;\n }\n overlay.attr(\"cursor\", cursors[type]);\n move();\n }\n break;\n }\n default: return;\n }\n noevent();\n }\n }\n\n function initialize() {\n var state = this.__brush || {selection: null};\n state.extent = extent.apply(this, arguments);\n state.dim = dim;\n return state;\n }\n\n brush.extent = function(_) {\n return arguments.length ? (extent = typeof _ === \"function\" ? _ : constant([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;\n };\n\n brush.filter = function(_) {\n return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant(!!_), brush) : filter;\n };\n\n brush.handleSize = function(_) {\n return arguments.length ? (handleSize = +_, brush) : handleSize;\n };\n\n brush.on = function() {\n var value = listeners.on.apply(listeners, arguments);\n return value === listeners ? brush : value;\n };\n\n return brush;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-brush/src/brush.js\n// module id = 302\n// module chunks = 0","export {default as drag} from \"./src/drag\";\nexport {default as dragDisable, yesdrag as dragEnable} from \"./src/nodrag\";\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-drag/index.js\n// module id = 303\n// module chunks = 0","import {dispatch} from \"d3-dispatch\";\nimport {event, customEvent, select, mouse, touch} from \"d3-selection\";\nimport nodrag, {yesdrag} from \"./nodrag\";\nimport noevent, {nopropagation} from \"./noevent\";\nimport constant from \"./constant\";\nimport DragEvent from \"./event\";\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter() {\n return !event.button;\n}\n\nfunction defaultContainer() {\n return this.parentNode;\n}\n\nfunction defaultSubject(d) {\n return d == null ? {x: event.x, y: event.y} : d;\n}\n\nfunction touchable() {\n return \"ontouchstart\" in this;\n}\n\nexport default function() {\n var filter = defaultFilter,\n container = defaultContainer,\n subject = defaultSubject,\n gestures = {},\n listeners = dispatch(\"start\", \"drag\", \"end\"),\n active = 0,\n mousedownx,\n mousedowny,\n mousemoving,\n touchending,\n clickDistance2 = 0;\n\n function drag(selection) {\n selection\n .on(\"mousedown.drag\", mousedowned)\n .filter(touchable)\n .on(\"touchstart.drag\", touchstarted)\n .on(\"touchmove.drag\", touchmoved)\n .on(\"touchend.drag touchcancel.drag\", touchended)\n .style(\"touch-action\", \"none\")\n .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\");\n }\n\n function mousedowned() {\n if (touchending || !filter.apply(this, arguments)) return;\n var gesture = beforestart(\"mouse\", container.apply(this, arguments), mouse, this, arguments);\n if (!gesture) return;\n select(event.view).on(\"mousemove.drag\", mousemoved, true).on(\"mouseup.drag\", mouseupped, true);\n nodrag(event.view);\n nopropagation();\n mousemoving = false;\n mousedownx = event.clientX;\n mousedowny = event.clientY;\n gesture(\"start\");\n }\n\n function mousemoved() {\n noevent();\n if (!mousemoving) {\n var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny;\n mousemoving = dx * dx + dy * dy > clickDistance2;\n }\n gestures.mouse(\"drag\");\n }\n\n function mouseupped() {\n select(event.view).on(\"mousemove.drag mouseup.drag\", null);\n yesdrag(event.view, mousemoving);\n noevent();\n gestures.mouse(\"end\");\n }\n\n function touchstarted() {\n if (!filter.apply(this, arguments)) return;\n var touches = event.changedTouches,\n c = container.apply(this, arguments),\n n = touches.length, i, gesture;\n\n for (i = 0; i < n; ++i) {\n if (gesture = beforestart(touches[i].identifier, c, touch, this, arguments)) {\n nopropagation();\n gesture(\"start\");\n }\n }\n }\n\n function touchmoved() {\n var touches = event.changedTouches,\n n = touches.length, i, gesture;\n\n for (i = 0; i < n; ++i) {\n if (gesture = gestures[touches[i].identifier]) {\n noevent();\n gesture(\"drag\");\n }\n }\n }\n\n function touchended() {\n var touches = event.changedTouches,\n n = touches.length, i, gesture;\n\n if (touchending) clearTimeout(touchending);\n touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!\n for (i = 0; i < n; ++i) {\n if (gesture = gestures[touches[i].identifier]) {\n nopropagation();\n gesture(\"end\");\n }\n }\n }\n\n function beforestart(id, container, point, that, args) {\n var p = point(container, id), s, dx, dy,\n sublisteners = listeners.copy();\n\n if (!customEvent(new DragEvent(drag, \"beforestart\", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {\n if ((event.subject = s = subject.apply(that, args)) == null) return false;\n dx = s.x - p[0] || 0;\n dy = s.y - p[1] || 0;\n return true;\n })) return;\n\n return function gesture(type) {\n var p0 = p, n;\n switch (type) {\n case \"start\": gestures[id] = gesture, n = active++; break;\n case \"end\": delete gestures[id], --active; // nobreak\n case \"drag\": p = point(container, id), n = active; break;\n }\n customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]);\n };\n }\n\n drag.filter = function(_) {\n return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant(!!_), drag) : filter;\n };\n\n drag.container = function(_) {\n return arguments.length ? (container = typeof _ === \"function\" ? _ : constant(_), drag) : container;\n };\n\n drag.subject = function(_) {\n return arguments.length ? (subject = typeof _ === \"function\" ? _ : constant(_), drag) : subject;\n };\n\n drag.on = function() {\n var value = listeners.on.apply(listeners, arguments);\n return value === listeners ? drag : value;\n };\n\n drag.clickDistance = function(_) {\n return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);\n };\n\n return drag;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-drag/src/drag.js\n// module id = 304\n// module chunks = 0","export default function(x) {\n return function() {\n return x;\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-drag/src/constant.js\n// module id = 305\n// module chunks = 0","export default function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {\n this.target = target;\n this.type = type;\n this.subject = subject;\n this.identifier = id;\n this.active = active;\n this.x = x;\n this.y = y;\n this.dx = dx;\n this.dy = dy;\n this._ = dispatch;\n}\n\nDragEvent.prototype.on = function() {\n var value = this._.on.apply(this._, arguments);\n return value === this._ ? this : value;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-drag/src/event.js\n// module id = 306\n// module chunks = 0","export default function(x) {\n return function() {\n return x;\n };\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-brush/src/constant.js\n// module id = 307\n// module chunks = 0","export default function(target, type, selection) {\n this.target = target;\n this.type = type;\n this.selection = selection;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-brush/src/event.js\n// module id = 308\n// module chunks = 0","import {event} from \"d3-selection\";\n\nexport function nopropagation() {\n event.stopImmediatePropagation();\n}\n\nexport default function() {\n event.preventDefault();\n event.stopImmediatePropagation();\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/d3-brush/src/noevent.js\n// module id = 309\n// module chunks = 0"],"sourceRoot":""}